/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.refactorings.extractstring;

import static com.android.SdkConstants.QUOT_ENTITY;
import static com.android.SdkConstants.STRING_PREFIX;

import com.android.SdkConstants;
import com.android.ide.common.res2.ValueXmlHelper;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ReferenceAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.ui.IEditorPart;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Node;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

/**
 * This refactoring extracts a string from a file and replaces it by an Android resource ID
 * such as R.string.foo.
 * <p/>
 * There are a number of scenarios, which are not all supported yet. The workflow works as
 * such:
 * <ul>
 * <li> User selects a string in a Java and invokes the {@link ExtractStringAction}.
 * <li> The action finds the {@link ICompilationUnit} being edited as well as the current
 *      {@link ITextSelection}. The action creates a new instance of this refactoring as
 *      well as an {@link ExtractStringWizard} and runs the operation.
 * <li> Step 1 of the refactoring is to check the preliminary conditions. Right now we check
 *      that the java source is not read-only and is in sync. We also try to find a string under
 *      the selection. If this fails, the refactoring is aborted.
 * <li> On success, the wizard is shown, which lets the user input the new ID to use.
 * <li> The wizard sets the user input values into this refactoring instance, e.g. the new string
 *      ID, the XML file to update, etc. The wizard does use the utility method
 *      {@link XmlStringFileHelper#valueOfStringId(IProject, String, String)} to check whether
 *      the new ID is already defined in the target XML file.
 * <li> Once Preview or Finish is selected in the wizard, the
 *      {@link #checkFinalConditions(IProgressMonitor)} is called to double-check the user input
 *      and compute the actual changes.
 * <li> When all changes are computed, {@link #createChange(IProgressMonitor)} is invoked.
 * </ul>
 *
 * The list of changes are:
 * <ul>
 * <li> If the target XML does not exist, create it with the new string ID.
 * <li> If the target XML exists, find the <resources> node and add the new string ID right after.
 *      If the node is <resources/>, it needs to be opened.
 * <li> Create an AST rewriter to edit the source Java file and replace all occurrences by the
 *      new computed R.string.foo. Also need to rewrite imports to import R as needed.
 *      If there's already a conflicting R included, we need to insert the FQCN instead.
 * <li> TODO: Have a pref in the wizard: [x] Change other XML Files
 * <li> TODO: Have a pref in the wizard: [x] Change other Java Files
 * </ul>
 */
@SuppressWarnings("restriction")
public class ExtractStringRefactoring extends Refactoring {

    public enum Mode {
        /**
         * the Extract String refactoring is called on an <em>existing</em> source file.
         * Its purpose is then to get the selected string of the source and propose to
         * change it by an XML id. The XML id may be a new one or an existing one.
         */
        EDIT_SOURCE,
        /**
         * The Extract String refactoring is called without any source file.
         * Its purpose is then to create a new XML string ID or select/modify an existing one.
         */
        SELECT_ID,
        /**
         * The Extract String refactoring is called without any source file.
         * Its purpose is then to create a new XML string ID. The ID must not already exist.
         */
        SELECT_NEW_ID
    }

    /** The {@link Mode} of operation of the refactoring. */
    private final Mode mMode;
    /** Non-null when editing an Android Resource XML file: identifies the attribute name
     * of the value being edited. When null, the source is an Android Java file. */
    private String mXmlAttributeName;
    /** The file model being manipulated.
     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
    private final IFile mFile;
    /** The editor. Non-null when invoked from {@link ExtractStringAction}. Null otherwise. */
    private final IEditorPart mEditor;
    /** The project that contains {@link #mFile} and that contains the target XML file to modify. */
    private final IProject mProject;
    /** The start of the selection in {@link #mFile}.
     * Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. */
    private final int mSelectionStart;
    /** The end of the selection in {@link #mFile}.
     * Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. */
    private final int mSelectionEnd;

    /** The compilation unit, only defined if {@link #mFile} points to a usable Java source file. */
    private ICompilationUnit mUnit;
    /** The actual string selected, after UTF characters have been escaped, good for display.
     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
    private String mTokenString;

    /** The XML string ID selected by the user in the wizard. */
    private String mXmlStringId;
    /** The XML string value. Might be different than the initial selected string. */
    private String mXmlStringValue;
    /** The path of the XML file that will define {@link #mXmlStringId}, selected by the user
     *  in the wizard. This is relative to the project, e.g. "/res/values/string.xml" */
    private String mTargetXmlFileWsPath;
    /** True if we should find & replace in all Java files. */
    private boolean mReplaceAllJava;
    /** True if we should find & replace in all XML files of the same name in other res configs
     * (other than the main {@link #mTargetXmlFileWsPath}.) */
    private boolean mReplaceAllXml;

    /** The list of changes computed by {@link #checkFinalConditions(IProgressMonitor)} and
     *  used by {@link #createChange(IProgressMonitor)}. */
    private ArrayList<Change> mChanges;

    private XmlStringFileHelper mXmlHelper = new XmlStringFileHelper();

    private static final String KEY_MODE = "mode";                      //$NON-NLS-1$
    private static final String KEY_FILE = "file";                      //$NON-NLS-1$
    private static final String KEY_PROJECT = "proj";                   //$NON-NLS-1$
    private static final String KEY_SEL_START = "sel-start";            //$NON-NLS-1$
    private static final String KEY_SEL_END = "sel-end";                //$NON-NLS-1$
    private static final String KEY_TOK_ESC = "tok-esc";                //$NON-NLS-1$
    private static final String KEY_XML_ATTR_NAME = "xml-attr-name";    //$NON-NLS-1$
    private static final String KEY_RPLC_ALL_JAVA = "rplc-all-java";    //$NON-NLS-1$
    private static final String KEY_RPLC_ALL_XML  = "rplc-all-xml";     //$NON-NLS-1$

    /**
     * This constructor is solely used by {@link ExtractStringDescriptor},
     * to replay a previous refactoring.
     * <p/>
     * To create a refactoring from code, please use one of the two other constructors.
     *
     * @param arguments A map previously created using {@link #createArgumentMap()}.
     * @throws NullPointerException
     */
    public ExtractStringRefactoring(Map<String, String> arguments) throws NullPointerException {

        mReplaceAllJava = Boolean.parseBoolean(arguments.get(KEY_RPLC_ALL_JAVA));
        mReplaceAllXml  = Boolean.parseBoolean(arguments.get(KEY_RPLC_ALL_XML));
        mMode = Mode.valueOf(arguments.get(KEY_MODE));

        IPath path = Path.fromPortableString(arguments.get(KEY_PROJECT));
        mProject = (IProject) ResourcesPlugin.getWorkspace().getRoot().findMember(path);

        if (mMode == Mode.EDIT_SOURCE) {
            path = Path.fromPortableString(arguments.get(KEY_FILE));
            mFile = (IFile) ResourcesPlugin.getWorkspace().getRoot().findMember(path);

            mSelectionStart   = Integer.parseInt(arguments.get(KEY_SEL_START));
            mSelectionEnd     = Integer.parseInt(arguments.get(KEY_SEL_END));
            mTokenString      = arguments.get(KEY_TOK_ESC);
            mXmlAttributeName = arguments.get(KEY_XML_ATTR_NAME);
        } else {
            mFile = null;
            mSelectionStart = mSelectionEnd = -1;
            mTokenString = null;
            mXmlAttributeName = null;
        }

        mEditor = null;
    }

    private Map<String, String> createArgumentMap() {
        HashMap<String, String> args = new HashMap<String, String>();
        args.put(KEY_RPLC_ALL_JAVA, Boolean.toString(mReplaceAllJava));
        args.put(KEY_RPLC_ALL_XML,  Boolean.toString(mReplaceAllXml));
        args.put(KEY_MODE,      mMode.name());
        args.put(KEY_PROJECT,   mProject.getFullPath().toPortableString());
        if (mMode == Mode.EDIT_SOURCE) {
            args.put(KEY_FILE,      mFile.getFullPath().toPortableString());
            args.put(KEY_SEL_START, Integer.toString(mSelectionStart));
            args.put(KEY_SEL_END,   Integer.toString(mSelectionEnd));
            args.put(KEY_TOK_ESC,   mTokenString);
            args.put(KEY_XML_ATTR_NAME, mXmlAttributeName);
        }
        return args;
    }

    /**
     * Constructor to use when the Extract String refactoring is called on an
     * *existing* source file. Its purpose is then to get the selected string of
     * the source and propose to change it by an XML id. The XML id may be a new one
     * or an existing one.
     *
     * @param file The source file to process. Cannot be null. File must exist in workspace.
     * @param editor The editor.
     * @param selection The selection in the source file. Cannot be null or empty.
     */
    public ExtractStringRefactoring(IFile file, IEditorPart editor, ITextSelection selection) {
        mMode = Mode.EDIT_SOURCE;
        mFile = file;
        mEditor = editor;
        mProject = file.getProject();
        mSelectionStart = selection.getOffset();
        mSelectionEnd = mSelectionStart + Math.max(0, selection.getLength() - 1);
    }

    /**
     * Constructor to use when the Extract String refactoring is called without
     * any source file. Its purpose is then to create a new XML string ID.
     * <p/>
     * For example this is currently invoked by the ResourceChooser when
     * the user wants to create a new string rather than select an existing one.
     *
     * @param project The project where the target XML file to modify is located. Cannot be null.
     * @param enforceNew If true the XML ID must be a new one.
     *                   If false, an existing ID can be used.
     */
    public ExtractStringRefactoring(IProject project, boolean enforceNew) {
        mMode = enforceNew ? Mode.SELECT_NEW_ID : Mode.SELECT_ID;
        mFile = null;
        mEditor = null;
        mProject = project;
        mSelectionStart = mSelectionEnd = -1;
    }

    /**
     * Sets the replacement string ID. Used by the wizard to set the user input.
     */
    public void setNewStringId(String newStringId) {
        mXmlStringId = newStringId;
    }

    /**
     * Sets the replacement string ID. Used by the wizard to set the user input.
     */
    public void setNewStringValue(String newStringValue) {
        mXmlStringValue = newStringValue;
    }

    /**
     * Sets the target file. This is a project path, e.g. "/res/values/strings.xml".
     * Used by the wizard to set the user input.
     */
    public void setTargetFile(String targetXmlFileWsPath) {
        mTargetXmlFileWsPath = targetXmlFileWsPath;
    }

    public void setReplaceAllJava(boolean replaceAllJava) {
        mReplaceAllJava = replaceAllJava;
    }

    public void setReplaceAllXml(boolean replaceAllXml) {
        mReplaceAllXml = replaceAllXml;
    }

    /**
     * @see org.eclipse.ltk.core.refactoring.Refactoring#getName()
     */
    @Override
    public String getName() {
        if (mMode == Mode.SELECT_ID) {
            return "Create or Use Android String";
        } else if (mMode == Mode.SELECT_NEW_ID) {
            return "Create New Android String";
        }

        return "Extract Android String";
    }

    public Mode getMode() {
        return mMode;
    }

    /**
     * Gets the actual string selected, after UTF characters have been escaped,
     * good for display. Value can be null.
     */
    public String getTokenString() {
        return mTokenString;
    }

    /** Returns the XML string ID selected by the user in the wizard. */
    public String getXmlStringId() {
        return mXmlStringId;
    }

    /**
     * Step 1 of 3 of the refactoring:
     * Checks that the current selection meets the initial condition before the ExtractString
     * wizard is shown. The check is supposed to be lightweight and quick. Note that at that
     * point the wizard has not been created yet.
     * <p/>
     * Here we scan the source buffer to find the token matching the selection.
     * The check is successful is a Java string literal is selected, the source is in sync
     * and is not read-only.
     * <p/>
     * This is also used to extract the string to be modified, so that we can display it in
     * the refactoring wizard.
     *
     * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
     *
     * @throws CoreException
     */
    @Override
    public RefactoringStatus checkInitialConditions(IProgressMonitor monitor)
            throws CoreException, OperationCanceledException {

        mUnit = null;
        mTokenString = null;

        RefactoringStatus status = new RefactoringStatus();

        try {
            monitor.beginTask("Checking preconditions...", 6);

            if (mMode != Mode.EDIT_SOURCE) {
                monitor.worked(6);
                return status;
            }

            if (!checkSourceFile(mFile, status, monitor)) {
                return status;
            }

            // Try to get a compilation unit from this file. If it fails, mUnit is null.
            try {
                mUnit = JavaCore.createCompilationUnitFrom(mFile);

                // Make sure the unit is not read-only, e.g. it's not a class file or inside a Jar
                if (mUnit.isReadOnly()) {
                    status.addFatalError("The file is read-only, please make it writeable first.");
                    return status;
                }

                // This is a Java file. Check if it contains the selection we want.
                if (!findSelectionInJavaUnit(mUnit, status, monitor)) {
                    return status;
                }

            } catch (Exception e) {
                // That was not a Java file. Ignore.
            }

            if (mUnit != null) {
                monitor.worked(1);
                return status;
            }

            // Check this a Layout XML file and get the selection and its context.
            if (mFile != null && SdkConstants.EXT_XML.equals(mFile.getFileExtension())) {

                // Currently we only support Android resource XML files, so they must have a path
                // similar to
                //    project/res/<type>[-<configuration>]/*.xml
                //    project/AndroidManifest.xml
                // There is no support for sub folders, so the segment count must be 4 or 2.
                // We don't need to check the type folder name because a/ we only accept
                // an AndroidXmlEditor source and b/ aapt generates a compilation error for
                // unknown folders.

                IPath path = mFile.getFullPath();
                if ((path.segmentCount() == 4 &&
                     path.segment(1).equalsIgnoreCase(SdkConstants.FD_RESOURCES)) ||
                    (path.segmentCount() == 2 &&
                     path.segment(1).equalsIgnoreCase(SdkConstants.FN_ANDROID_MANIFEST_XML))) {
                    if (!findSelectionInXmlFile(mFile, status, monitor)) {
                        return status;
                    }
                }
            }

            if (!status.isOK()) {
                status.addFatalError(
                        "Selection must be inside a Java source or an Android Layout XML file.");
            }

        } finally {
            monitor.done();
        }

        return status;
    }

    /**
     * Try to find the selected Java element in the compilation unit.
     *
     * If selection matches a string literal, capture it, otherwise add a fatal error
     * to the status.
     *
     * On success, advance the monitor by 3.
     * Returns status.isOK().
     */
    private boolean findSelectionInJavaUnit(ICompilationUnit unit,
            RefactoringStatus status, IProgressMonitor monitor) {
        try {
            IBuffer buffer = unit.getBuffer();

            IScanner scanner = ToolFactory.createScanner(
                    false, //tokenizeComments
                    false, //tokenizeWhiteSpace
                    false, //assertMode
                    false  //recordLineSeparator
                    );
            scanner.setSource(buffer.getCharacters());
            monitor.worked(1);

            for(int token = scanner.getNextToken();
                    token != ITerminalSymbols.TokenNameEOF;
                    token = scanner.getNextToken()) {
                if (scanner.getCurrentTokenStartPosition() <= mSelectionStart &&
                        scanner.getCurrentTokenEndPosition() >= mSelectionEnd) {
                    // found the token, but only keep if the right type
                    if (token == ITerminalSymbols.TokenNameStringLiteral) {
                        mTokenString = new String(scanner.getCurrentTokenSource());
                    }
                    break;
                } else if (scanner.getCurrentTokenStartPosition() > mSelectionEnd) {
                    // scanner is past the selection, abort.
                    break;
                }
            }
        } catch (JavaModelException e1) {
            // Error in unit.getBuffer. Ignore.
        } catch (InvalidInputException e2) {
            // Error in scanner.getNextToken. Ignore.
        } finally {
            monitor.worked(1);
        }

        if (mTokenString != null) {
            // As a literal string, the token should have surrounding quotes. Remove them.
            // Note: unquoteAttrValue technically removes either " or ' paired quotes, whereas
            // the Java token should only have " quotes. Since we know the type to be a string
            // literal, there should be no confusion here.
            mTokenString = unquoteAttrValue(mTokenString);

            // We need a non-empty string literal
            if (mTokenString.length() == 0) {
                mTokenString = null;
            }
        }

        if (mTokenString == null) {
            status.addFatalError("Please select a Java string literal.");
        }

        monitor.worked(1);
        return status.isOK();
    }

    /**
     * Try to find the selected XML element. This implementation replies on the refactoring
     * originating from an Android Layout Editor. We rely on some internal properties of the
     * Structured XML editor to retrieve file content to avoid parsing it again. We also rely
     * on our specific Android XML model to get element & attribute descriptor properties.
     *
     * If selection matches a string literal, capture it, otherwise add a fatal error
     * to the status.
     *
     * On success, advance the monitor by 1.
     * Returns status.isOK().
     */
    private boolean findSelectionInXmlFile(IFile file,
            RefactoringStatus status,
            IProgressMonitor monitor) {

        try {
            if (!(mEditor instanceof AndroidXmlEditor)) {
                status.addFatalError("Only the Android XML Editor is currently supported.");
                return status.isOK();
            }

            AndroidXmlEditor editor = (AndroidXmlEditor) mEditor;
            IStructuredModel smodel = null;
            Node node = null;
            String currAttrName = null;

            try {
                // See the portability note in AndroidXmlEditor#getModelForRead() javadoc.
                smodel = editor.getModelForRead();
                if (smodel != null) {
                    // The structured model gives the us the actual XML Node element where the
                    // offset is. By using this Node, we can find the exact UiElementNode of our
                    // model and thus we'll be able to get the properties of the attribute -- to
                    // check if it accepts a string reference. This does not however tell us if
                    // the selection is actually in an attribute value, nor which attribute is
                    // being edited.
                    for(int offset = mSelectionStart; offset >= 0 && node == null; --offset) {
                        node = (Node) smodel.getIndexedRegion(offset);
                    }

                    if (node == null) {
                        status.addFatalError(
                                "The selection does not match any element in the XML document.");
                        return status.isOK();
                    }

                    if (node.getNodeType() != Node.ELEMENT_NODE) {
                        status.addFatalError("The selection is not inside an actual XML element.");
                        return status.isOK();
                    }

                    IStructuredDocument sdoc = smodel.getStructuredDocument();
                    if (sdoc != null) {
                        // Portability note: all the structured document implementation is
                        // under wst.sse.core.internal.provisional so we can expect it to change in
                        // a distant future if they start cleaning their codebase, however unlikely
                        // that is.

                        int selStart = mSelectionStart;
                        IStructuredDocumentRegion region =
                            sdoc.getRegionAtCharacterOffset(selStart);
                        if (region != null &&
                                DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
                            // Find if any sub-region representing an attribute contains the
                            // selection. If it does, returns the name of the attribute in
                            // currAttrName and returns the value in the field mTokenString.
                            currAttrName = findSelectionInRegion(region, selStart);

                            if (mTokenString == null) {
                                status.addFatalError(
                                    "The selection is not inside an actual XML attribute value.");
                            }
                        }
                    }

                    if (mTokenString != null && node != null && currAttrName != null) {

                        // Validate that the attribute accepts a string reference.
                        // This sets mTokenString to null by side-effect when it fails and
                        // adds a fatal error to the status as needed.
                        validateSelectedAttribute(editor, node, currAttrName, status);

                    } else {
                        // We shouldn't get here: we're missing one of the token string, the node
                        // or the attribute name. All of them have been checked earlier so don't
                        // set any specific error.
                        mTokenString = null;
                    }
                }
            } catch (Throwable t) {
                // Since we use some internal APIs, use a broad catch-all to report any
                // unexpected issue rather than crash the whole refactoring.
                status.addFatalError(
                        String.format("XML parsing error: %1$s", t.getMessage()));
            } finally {
                if (smodel != null) {
                    smodel.releaseFromRead();
                }
            }

        } finally {
            monitor.worked(1);
        }

        return status.isOK();
    }

    /**
     * The region gives us the textual representation of the XML element
     * where the selection starts, split using sub-regions. We now just
     * need to iterate through the sub-regions to find which one
     * contains the actual selection. We're interested in an attribute
     * value however when we find one we want to memorize the attribute
     * name that was defined just before.
     *
     * @return When the cursor is on a valid attribute name or value, returns the string of
     * attribute name. As a side-effect, returns the value of the attribute in {@link #mTokenString}
     */
    private String findSelectionInRegion(IStructuredDocumentRegion region, int selStart) {

        String currAttrName = null;

        int startInRegion = selStart - region.getStartOffset();

        int nb = region.getNumberOfRegions();
        ITextRegionList list = region.getRegions();
        String currAttrValue = null;

        for (int i = 0; i < nb; i++) {
            ITextRegion subRegion = list.get(i);
            String type = subRegion.getType();

            if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
                currAttrName = region.getText(subRegion);

                // I like to select the attribute definition and invoke
                // the extract string wizard. So if the selection is on
                // the attribute name part, find the value that is just
                // after and use it as if it were the selection.

                if (subRegion.getStart() <= startInRegion &&
                        startInRegion < subRegion.getTextEnd()) {
                    // A well-formed attribute is composed of a name,
                    // an equal sign and the value. There can't be any space
                    // in between, which makes the parsing a lot easier.
                    if (i <= nb - 3 &&
                            DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS.equals(
                                                   list.get(i + 1).getType())) {
                        subRegion = list.get(i + 2);
                        type = subRegion.getType();
                        if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(
                                type)) {
                            currAttrValue = region.getText(subRegion);
                        }
                    }
                }

            } else if (subRegion.getStart() <= startInRegion &&
                    startInRegion < subRegion.getTextEnd() &&
                    DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
                currAttrValue = region.getText(subRegion);
            }

            if (currAttrValue != null) {
                // We found the value. Only accept it if not empty
                // and if we found an attribute name before.
                String text = currAttrValue;

                // The attribute value contains XML quotes. Remove them.
                text = unquoteAttrValue(text);
                if (text.length() > 0 && currAttrName != null) {
                    // Setting mTokenString to non-null marks the fact we
                    // accept this attribute.
                    mTokenString = text;
                }

                break;
            }
        }

        return currAttrName;
    }

    /**
     * Attribute values found as text for {@link DOMRegionContext#XML_TAG_ATTRIBUTE_VALUE}
     * contain XML quotes. This removes the quotes (either single or double quotes).
     *
     * @param attrValue The attribute value, as extracted by
     *                  {@link IStructuredDocumentRegion#getText(ITextRegion)}.
     *                  Must not be null.
     * @return The attribute value, without quotes. Whitespace is not trimmed, if any.
     *         String may be empty, but not null.
     */
    static String unquoteAttrValue(String attrValue) {
        int len = attrValue.length();
        int len1 = len - 1;
        if (len >= 2 &&
                attrValue.charAt(0) == '"' &&
                attrValue.charAt(len1) == '"') {
            attrValue = attrValue.substring(1, len1);
        } else if (len >= 2 &&
                attrValue.charAt(0) == '\'' &&
                attrValue.charAt(len1) == '\'') {
            attrValue = attrValue.substring(1, len1);
        }

        return attrValue;
    }

    /**
     * Validates that the attribute accepts a string reference.
     * This sets mTokenString to null by side-effect when it fails and
     * adds a fatal error to the status as needed.
     */
    private void validateSelectedAttribute(AndroidXmlEditor editor, Node node,
            String attrName, RefactoringStatus status) {
        UiElementNode rootUiNode = editor.getUiRootNode();
        UiElementNode currentUiNode =
            rootUiNode == null ? null : rootUiNode.findXmlNode(node);
        ReferenceAttributeDescriptor attrDesc = null;

        if (currentUiNode != null) {
            // remove any namespace prefix from the attribute name
            String name = attrName;
            int pos = name.indexOf(':');
            if (pos > 0 && pos < name.length() - 1) {
                name = name.substring(pos + 1);
            }

            for (UiAttributeNode attrNode : currentUiNode.getAllUiAttributes()) {
                if (attrNode.getDescriptor().getXmlLocalName().equals(name)) {
                    AttributeDescriptor desc = attrNode.getDescriptor();
                    if (desc instanceof ReferenceAttributeDescriptor) {
                        attrDesc = (ReferenceAttributeDescriptor) desc;
                    }
                    break;
                }
            }
        }

        // The attribute descriptor is a resource reference. It must either accept
        // of any resource type or specifically accept string types.
        if (attrDesc != null &&
                (attrDesc.getResourceType() == null ||
                 attrDesc.getResourceType() == ResourceType.STRING)) {
            // We have one more check to do: is the current string value already
            // an Android XML string reference? If so, we can't edit it.
            if (mTokenString != null && mTokenString.startsWith("@")) {                             //$NON-NLS-1$
                int pos1 = 0;
                if (mTokenString.length() > 1 && mTokenString.charAt(1) == '+') {
                    pos1++;
                }
                int pos2 = mTokenString.indexOf('/');
                if (pos2 > pos1) {
                    String kind = mTokenString.substring(pos1 + 1, pos2);
                    if (ResourceType.STRING.getName().equals(kind)) {
                        mTokenString = null;
                        status.addFatalError(String.format(
                                "The attribute %1$s already contains a %2$s reference.",
                                attrName,
                                kind));
                    }
                }
            }

            if (mTokenString != null) {
                // We're done with all our checks. mTokenString contains the
                // current attribute value. We don't memorize the region nor the
                // attribute, however we memorize the textual attribute name so
                // that we can offer replacement for all its occurrences.
                mXmlAttributeName = attrName;
            }

        } else {
            mTokenString = null;
            status.addFatalError(String.format(
                    "The attribute %1$s does not accept a string reference.",
                    attrName));
        }
    }

    /**
     * Tests from org.eclipse.jdt.internal.corext.refactoringChecks#validateEdit()
     * Might not be useful.
     *
     * On success, advance the monitor by 2.
     *
     * @return False if caller should abort, true if caller should continue.
     */
    private boolean checkSourceFile(IFile file,
            RefactoringStatus status,
            IProgressMonitor monitor) {
        // check whether the source file is in sync
        if (!file.isSynchronized(IResource.DEPTH_ZERO)) {
            status.addFatalError("The file is not synchronized. Please save it first.");
            return false;
        }
        monitor.worked(1);

        // make sure we can write to it.
        ResourceAttributes resAttr = file.getResourceAttributes();
        if (resAttr == null || resAttr.isReadOnly()) {
            status.addFatalError("The file is read-only, please make it writeable first.");
            return false;
        }
        monitor.worked(1);

        return true;
    }

    /**
     * Step 2 of 3 of the refactoring:
     * Check the conditions once the user filled values in the refactoring wizard,
     * then prepare the changes to be applied.
     * <p/>
     * In this case, most of the sanity checks are done by the wizard so essentially this
     * should only be called if the wizard positively validated the user input.
     *
     * Here we do check that the target resource XML file either does not exists or
     * is not read-only.
     *
     * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(IProgressMonitor)
     *
     * @throws CoreException
     */
    @Override
    public RefactoringStatus checkFinalConditions(IProgressMonitor monitor)
            throws CoreException, OperationCanceledException {
        RefactoringStatus status = new RefactoringStatus();

        try {
            monitor.beginTask("Checking post-conditions...", 5);

            if (mXmlStringId == null || mXmlStringId.length() <= 0) {
                // this is not supposed to happen
                status.addFatalError("Missing replacement string ID");
            } else if (mTargetXmlFileWsPath == null || mTargetXmlFileWsPath.length() <= 0) {
                // this is not supposed to happen
                status.addFatalError("Missing target xml file path");
            }
            monitor.worked(1);

            // Either that resource must not exist or it must be a writable file.
            IResource targetXml = getTargetXmlResource(mTargetXmlFileWsPath);
            if (targetXml != null) {
                if (targetXml.getType() != IResource.FILE) {
                    status.addFatalError(
                            String.format("XML file '%1$s' is not a file.", mTargetXmlFileWsPath));
                } else {
                    ResourceAttributes attr = targetXml.getResourceAttributes();
                    if (attr != null && attr.isReadOnly()) {
                        status.addFatalError(
                                String.format("XML file '%1$s' is read-only.",
                                        mTargetXmlFileWsPath));
                    }
                }
            }
            monitor.worked(1);

            if (status.hasError()) {
                return status;
            }

            mChanges = new ArrayList<Change>();


            // Prepare the change to create/edit the String ID in the res/values XML file.
            if (!mXmlStringValue.equals(
                    mXmlHelper.valueOfStringId(mProject, mTargetXmlFileWsPath, mXmlStringId))) {
                // We actually change it only if the ID doesn't exist yet or has a different value
                Change change = createXmlChanges((IFile) targetXml, mXmlStringId, mXmlStringValue,
                        status, SubMonitor.convert(monitor, 1));
                if (change != null) {
                    mChanges.add(change);
                }
            }

            if (status.hasError()) {
                return status;
            }

            if (mMode == Mode.EDIT_SOURCE) {
                List<Change> changes = null;
                if (mXmlAttributeName != null) {
                    // Prepare the change to the Android resource XML file
                    changes = computeXmlSourceChanges(mFile,
                            mXmlStringId,
                            mTokenString,
                            mXmlAttributeName,
                            true, // allConfigurations
                            status,
                            monitor);

                } else if (mUnit != null) {
                    // Prepare the change to the Java compilation unit
                    changes = computeJavaChanges(mUnit, mXmlStringId, mTokenString,
                            status, SubMonitor.convert(monitor, 1));
                }
                if (changes != null) {
                    mChanges.addAll(changes);
                }
            }

            if (mReplaceAllJava) {
                String currentIdentifier = mUnit != null ? mUnit.getHandleIdentifier() : ""; //$NON-NLS-1$

                SubMonitor submon = SubMonitor.convert(monitor, 1);
                for (ICompilationUnit unit : findAllJavaUnits()) {
                    // Only process Java compilation units that exist, are not derived
                    // and are not read-only.
                    if (unit == null || !unit.exists()) {
                        continue;
                    }
                    IResource resource = unit.getResource();
                    if (resource == null || resource.isDerived()) {
                        continue;
                    }

                    // Ensure that we don't process the current compilation unit (processed
                    // as mUnit above) twice
                    if (currentIdentifier.equals(unit.getHandleIdentifier())) {
                        continue;
                    }

                    ResourceAttributes attrs = resource.getResourceAttributes();
                    if (attrs != null && attrs.isReadOnly()) {
                        continue;
                    }

                    List<Change> changes = computeJavaChanges(
                            unit, mXmlStringId, mTokenString,
                            status, SubMonitor.convert(submon, 1));
                    if (changes != null) {
                        mChanges.addAll(changes);
                    }
                }
            }

            if (mReplaceAllXml) {
                SubMonitor submon = SubMonitor.convert(monitor, 1);
                for (IFile xmlFile : findAllResXmlFiles()) {
                    if (xmlFile != null) {
                        List<Change> changes = computeXmlSourceChanges(xmlFile,
                                mXmlStringId,
                                mTokenString,
                                mXmlAttributeName,
                                false, // allConfigurations
                                status,
                                SubMonitor.convert(submon, 1));
                        if (changes != null) {
                            mChanges.addAll(changes);
                        }
                    }
                }
            }

            monitor.worked(1);
        } finally {
            monitor.done();
        }

        return status;
    }

    // --- XML changes ---

    /**
     * Returns a foreach-compatible iterator over all XML files in the project's
     * /res folder, excluding the target XML file (the one where we'll write/edit
     * the string id).
     */
    private Iterable<IFile> findAllResXmlFiles() {
        return new Iterable<IFile>() {
            @Override
            public Iterator<IFile> iterator() {
                return new Iterator<IFile>() {
                    final Queue<IFile> mFiles = new LinkedList<IFile>();
                    final Queue<IResource> mFolders = new LinkedList<IResource>();
                    IPath mFilterPath1 = null;
                    IPath mFilterPath2 = null;
                    {
                        // Filter out the XML file where we'll be writing the XML string id.
                        IResource filterRes = mProject.findMember(mTargetXmlFileWsPath);
                        if (filterRes != null) {
                            mFilterPath1 = filterRes.getFullPath();
                        }
                        // Filter out the XML source file, if any (e.g. typically a layout)
                        if (mFile != null) {
                            mFilterPath2 = mFile.getFullPath();
                        }

                        // We want to process the manifest
                        IResource man = mProject.findMember("AndroidManifest.xml"); // TODO find a constant
                        if (man.exists() && man instanceof IFile && !man.equals(mFile)) {
                            mFiles.add((IFile) man);
                        }

                        // Add all /res folders (technically we don't need to process /res/values
                        // XML files that contain resources/string elements, but it's easier to
                        // not filter them out.)
                        IFolder f = mProject.getFolder(AdtConstants.WS_RESOURCES);
                        if (f.exists()) {
                            try {
                                mFolders.addAll(
                                        Arrays.asList(f.members(IContainer.EXCLUDE_DERIVED)));
                            } catch (CoreException e) {
                                // pass
                            }
                        }
                    }

                    @Override
                    public boolean hasNext() {
                        if (!mFiles.isEmpty()) {
                            return true;
                        }

                        while (!mFolders.isEmpty()) {
                            IResource res = mFolders.poll();
                            if (res.exists() && res instanceof IFolder) {
                                IFolder f = (IFolder) res;
                                try {
                                    getFileList(f);
                                    if (!mFiles.isEmpty()) {
                                        return true;
                                    }
                                } catch (CoreException e) {
                                    // pass
                                }
                            }
                        }
                        return false;
                    }

                    private void getFileList(IFolder folder) throws CoreException {
                        for (IResource res : folder.members(IContainer.EXCLUDE_DERIVED)) {
                            // Only accept file resources which are not derived and actually exist
                            if (res.exists() && !res.isDerived() && res instanceof IFile) {
                                IFile file = (IFile) res;
                                // Must have an XML extension
                                if (SdkConstants.EXT_XML.equals(file.getFileExtension())) {
                                    IPath p = file.getFullPath();
                                    // And not be either paths we want to filter out
                                    if ((mFilterPath1 != null && mFilterPath1.equals(p)) ||
                                            (mFilterPath2 != null && mFilterPath2.equals(p))) {
                                        continue;
                                    }
                                    mFiles.add(file);
                                }
                            }
                        }
                    }

                    @Override
                    public IFile next() {
                        IFile file = mFiles.poll();
                        hasNext();
                        return file;
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException(
                            "This iterator does not support removal");  //$NON-NLS-1$
                    }
                };
            }
        };
    }

    /**
     * Internal helper that actually prepares the {@link Change} that adds the given
     * ID to the given XML File.
     * <p/>
     * This does not actually modify the file.
     *
     * @param targetXml The file resource to modify.
     * @param xmlStringId The new ID to insert.
     * @param tokenString The old string, which will be the value in the XML string.
     * @return A new {@link TextEdit} that describes how to change the file.
     */
    private Change createXmlChanges(IFile targetXml,
            String xmlStringId,
            String tokenString,
            RefactoringStatus status,
            SubMonitor monitor) {

        TextFileChange xmlChange = new TextFileChange(getName(), targetXml);
        xmlChange.setTextType(SdkConstants.EXT_XML);

        String error = "";                  //$NON-NLS-1$
        TextEdit edit = null;
        TextEditGroup editGroup = null;

        try {
            if (!targetXml.exists()) {
                // Kludge: use targetXml==null as a signal this is a new file being created
                targetXml = null;
            }

            edit = createXmlReplaceEdit(targetXml, xmlStringId, tokenString, status,
                    SubMonitor.convert(monitor, 1));
        } catch (IOException e) {
            error = e.toString();
        } catch (CoreException e) {
            // Failed to read file. Ignore. Will handle error below.
            error = e.toString();
        }

        if (edit == null) {
            status.addFatalError(String.format("Failed to modify file %1$s%2$s",
                    targetXml == null ? "" : targetXml.getFullPath(),   //$NON-NLS-1$
                    error == null ? "" : ": " + error));                //$NON-NLS-1$
            return null;
        }

        editGroup = new TextEditGroup(targetXml == null ? "Create <string> in new XML file"
                                                        : "Insert <string> in XML file",
                                      edit);

        xmlChange.setEdit(edit);
        // The TextEditChangeGroup let the user toggle this change on and off later.
        xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, editGroup));

        monitor.worked(1);
        return xmlChange;
    }

    /**
     * Scan the XML file to find the best place where to insert the new string element.
     * <p/>
     * This handles a variety of cases, including replacing existing ids in place,
     * adding the top resources element if missing and the XML PI if not present.
     * It tries to preserve indentation when adding new elements at the end of an existing XML.
     *
     * @param file The XML file to modify, that must be present in the workspace.
     *             Pass null to create a change for a new file that doesn't exist yet.
     * @param xmlStringId The new ID to insert.
     * @param tokenString The old string, which will be the value in the XML string.
     * @param status The in-out refactoring status. Used to log a more detailed error if the
     *          XML has a top element that is not a resources element.
     * @param monitor A monitor to track progress.
     * @return A new {@link TextEdit} for either a replace or an insert operation, or null in case
     *          of error.
     * @throws CoreException - if the file's contents or description can not be read.
     * @throws IOException   - if the file's contents can not be read or its detected encoding does
     *                         not support its contents.
     */
    private TextEdit createXmlReplaceEdit(IFile file,
            String xmlStringId,
            String tokenString,
            RefactoringStatus status,
            SubMonitor monitor)
                throws IOException, CoreException {

        IModelManager modelMan = StructuredModelManager.getModelManager();

        final String NODE_RESOURCES = SdkConstants.TAG_RESOURCES;
        final String NODE_STRING = SdkConstants.TAG_STRING;
        final String ATTR_NAME = SdkConstants.ATTR_NAME;


        // Scan the source to find the best insertion point.

        // 1- The most common case we need to handle is the one of inserting at the end
        //    of a valid XML document, respecting the whitespace last used.
        //
        // Ideally we have this structure:
        // <xml ...>
        // <resource>
        // ...ws1...<string>blah</string>...ws2...
        // </resource>
        //
        // where ws1 and ws2 are the whitespace respectively before and after the last element
        // just before the closing </resource>.
        // In this case we want to generate the new string just before ws2...</resource> with
        // the same whitespace as ws1.
        //
        // 2- Another expected case is there's already an existing string which "name" attribute
        //    equals to xmlStringId and we just want to replace its value.
        //
        // Other cases we need to handle:
        // 3- There is no element at all -> create a full new <resource>+<string> content.
        // 4- There is <resource/>, that is the tag is not opened. This can be handled as the
        //    previous case, generating full content but also replacing <resource/>.
        // 5- There is a top element that is not <resource>. That's a fatal error and we abort.

        IStructuredModel smodel = null;

        // Single and double quotes must be escaped in the <string>value</string> declaration
        tokenString = ValueXmlHelper.escapeResourceString(tokenString);

        try {
            IStructuredDocument sdoc = null;
            boolean checkTopElement = true;
            boolean replaceStringContent = false;
            boolean hasPiXml = false;
            int newResStart = 0;
            int newResLength = 0;
            String lineSep = "\n";                  //$NON-NLS-1$

            if (file != null) {
                smodel = modelMan.getExistingModelForRead(file);
                if (smodel != null) {
                    sdoc = smodel.getStructuredDocument();
                } else if (smodel == null) {
                    // The model is not currently open.
                    if (file.exists()) {
                        sdoc = modelMan.createStructuredDocumentFor(file);
                    } else {
                        sdoc = modelMan.createNewStructuredDocumentFor(file);
                    }
                }
            }

            if (sdoc == null && file != null) {
                // Get a document matching the actual saved file
                sdoc = modelMan.createStructuredDocumentFor(file);
            }

            if (sdoc != null) {
                String wsBefore = "";   //$NON-NLS-1$
                String lastWs = null;

                lineSep = sdoc.getLineDelimiter();
                if (lineSep == null || lineSep.length() == 0) {
                    // That wasn't too useful, let's go back to a reasonable default
                    lineSep = "\n"; //$NON-NLS-1$
                }

                for (IStructuredDocumentRegion regions : sdoc.getStructuredDocumentRegions()) {
                    String type = regions.getType();

                    if (DOMRegionContext.XML_CONTENT.equals(type)) {

                        if (replaceStringContent) {
                            // Generate a replacement for a <string> value matching the string ID.
                            return new ReplaceEdit(
                                    regions.getStartOffset(), regions.getLength(), tokenString);
                        }

                        // Otherwise capture what should be whitespace content
                        lastWs = regions.getFullText();
                        continue;

                    } else if (DOMRegionContext.XML_PI_OPEN.equals(type) && !hasPiXml) {

                        int nb = regions.getNumberOfRegions();
                        ITextRegionList list = regions.getRegions();
                        for (int i = 0; i < nb; i++) {
                            ITextRegion region = list.get(i);
                            type = region.getType();
                            if (DOMRegionContext.XML_TAG_NAME.equals(type)) {
                                String name = regions.getText(region);
                                if ("xml".equals(name)) {   //$NON-NLS-1$
                                    hasPiXml = true;
                                    break;
                                }
                            }
                        }
                        continue;

                    } else if (!DOMRegionContext.XML_TAG_NAME.equals(type)) {
                        // ignore things which are not a tag nor text content (such as comments)
                        continue;
                    }

                    int nb = regions.getNumberOfRegions();
                    ITextRegionList list = regions.getRegions();

                    String name = null;
                    String attrName = null;
                    String attrValue = null;
                    boolean isEmptyTag = false;
                    boolean isCloseTag = false;

                    for (int i = 0; i < nb; i++) {
                        ITextRegion region = list.get(i);
                        type = region.getType();

                        if (DOMRegionContext.XML_END_TAG_OPEN.equals(type)) {
                            isCloseTag = true;
                        } else if (DOMRegionContext.XML_EMPTY_TAG_CLOSE.equals(type)) {
                            isEmptyTag = true;
                        } else if (DOMRegionContext.XML_TAG_NAME.equals(type)) {
                            name = regions.getText(region);
                        } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type) &&
                                NODE_STRING.equals(name)) {
                            // Record the attribute names into a <string> element.
                            attrName = regions.getText(region);
                        } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type) &&
                                ATTR_NAME.equals(attrName)) {
                            // Record the value of a <string name=...> attribute
                            attrValue = regions.getText(region);

                            if (attrValue != null &&
                                    unquoteAttrValue(attrValue).equals(xmlStringId)) {
                                // We found a <string name=> matching the string ID to replace.
                                // We'll generate a replacement when we process the string value
                                // (that is the next XML_CONTENT region.)
                                replaceStringContent = true;
                            }
                        }
                    }

                    if (checkTopElement) {
                        // Check the top element has a resource name
                        checkTopElement = false;
                        if (!NODE_RESOURCES.equals(name)) {
                            status.addFatalError(
                                    String.format("XML file lacks a <resource> tag: %1$s",
                                            mTargetXmlFileWsPath));
                            return null;

                        }

                        if (isEmptyTag) {
                            // The top element is an empty "<resource/>" tag. We need to do
                            // a full new resource+string replacement.
                            newResStart = regions.getStartOffset();
                            newResLength = regions.getLength();
                        }
                    }

                    if (NODE_RESOURCES.equals(name)) {
                        if (isCloseTag) {
                            // We found the </resource> tag and we want
                            // to insert just before this one.

                            StringBuilder content = new StringBuilder();
                            content.append(wsBefore)
                                   .append("<string name=\"")                   //$NON-NLS-1$
                                   .append(xmlStringId)
                                   .append("\">")                               //$NON-NLS-1$
                                   .append(tokenString)
                                   .append("</string>");                        //$NON-NLS-1$

                            // Backup to insert before the whitespace preceding </resource>
                            IStructuredDocumentRegion insertBeforeReg = regions;
                            while (true) {
                                IStructuredDocumentRegion previous = insertBeforeReg.getPrevious();
                                if (previous != null &&
                                        DOMRegionContext.XML_CONTENT.equals(previous.getType()) &&
                                        previous.getText().trim().length() == 0) {
                                    insertBeforeReg = previous;
                                } else {
                                    break;
                                }
                            }
                            if (insertBeforeReg == regions) {
                                // If we have not found any whitespace before </resources>,
                                // at least add a line separator.
                                content.append(lineSep);
                            }

                            return new InsertEdit(insertBeforeReg.getStartOffset(),
                                                  content.toString());
                        }
                    } else {
                        // For any other tag than <resource>, capture whitespace before and after.
                        if (!isCloseTag) {
                            wsBefore = lastWs;
                        }
                    }
                }
            }

            // We reach here either because there's no XML content at all or because
            // there's an empty <resource/>.
            // Provide a full new resource+string replacement.
            StringBuilder content = new StringBuilder();
            if (!hasPiXml) {
                content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); //$NON-NLS-1$
                content.append(lineSep);
            } else if (newResLength == 0 && sdoc != null) {
                // If inserting at the end, check if the last region is some whitespace.
                // If there's no newline, insert one ourselves.
                IStructuredDocumentRegion lastReg = sdoc.getLastStructuredDocumentRegion();
                if (lastReg != null && lastReg.getText().indexOf('\n') == -1) {
                    content.append('\n');
                }
            }

            // FIXME how to access formatting preferences to generate the proper indentation?
            content.append("<resources>").append(lineSep);                  //$NON-NLS-1$
            content.append("    <string name=\"")                           //$NON-NLS-1$
                   .append(xmlStringId)
                   .append("\">")                                           //$NON-NLS-1$
                   .append(tokenString)
                   .append("</string>")                                     //$NON-NLS-1$
                   .append(lineSep);
            content.append("</resources>").append(lineSep);                 //$NON-NLS-1$

            if (newResLength > 0) {
                // Replace existing piece
                return new ReplaceEdit(newResStart, newResLength, content.toString());
            } else {
                // Insert at the end.
                int offset = sdoc == null ? 0 : sdoc.getLength();
                return new InsertEdit(offset, content.toString());
            }
        } catch (IOException e) {
            // This is expected to happen and is properly reported to the UI.
            throw e;
        } catch (CoreException e) {
            // This is expected to happen and is properly reported to the UI.
            throw e;
        } catch (Throwable t) {
            // Since we use some internal APIs, use a broad catch-all to report any
            // unexpected issue rather than crash the whole refactoring.
            status.addFatalError(
                    String.format("XML replace error: %1$s", t.getMessage()));
        } finally {
            if (smodel != null) {
                smodel.releaseFromRead();
            }
        }

        return null;
    }

    /**
     * Computes the changes to be made to the source Android XML file and
     * returns a list of {@link Change}.
     * <p/>
     * This function scans an XML file, looking for an attribute value equals to
     * <code>tokenString</code>. If non null, <code>xmlAttrName</code> limit the search
     * to only attributes that have that name.
     * If found, a change is made to replace each occurrence of <code>tokenString</code>
     * by a new "@string/..." using the new <code>xmlStringId</code>.
     *
     * @param sourceFile The file to process.
     *          A status error will be generated if it does not exists.
     *          Must not be null.
     * @param tokenString The string to find. Must not be null or empty.
     * @param xmlAttrName Optional attribute name to limit the search. Can be null.
     * @param allConfigurations True if this function should can all XML files with the same
     *          name and the same resource type folder but with different configurations.
     * @param status Status used to report fatal errors.
     * @param monitor Used to log progress.
     */
    private List<Change> computeXmlSourceChanges(IFile sourceFile,
            String xmlStringId,
            String tokenString,
            String xmlAttrName,
            boolean allConfigurations,
            RefactoringStatus status,
            IProgressMonitor monitor) {

        if (!sourceFile.exists()) {
            status.addFatalError(String.format("XML file '%1$s' does not exist.",
                    sourceFile.getFullPath().toOSString()));
            return null;
        }

        // We shouldn't be trying to replace a null or empty string.
        assert tokenString != null && tokenString.length() > 0;
        if (tokenString == null || tokenString.length() == 0) {
            return null;
        }

        // Note: initially this method was only processing files using a pattern
        //   /project/res/<type>-<configuration>/<filename.xml>
        // However the last version made that more generic to be able to process any XML
        // files. We should probably revisit and simplify this later.
        HashSet<IFile> files = new HashSet<IFile>();
        files.add(sourceFile);

        if (allConfigurations && SdkConstants.EXT_XML.equals(sourceFile.getFileExtension())) {
            IPath path = sourceFile.getFullPath();
            if (path.segmentCount() == 4 && path.segment(1).equals(SdkConstants.FD_RESOURCES)) {
                IProject project = sourceFile.getProject();
                String filename = path.segment(3);
                String initialTypeName = path.segment(2);
                ResourceFolderType type = ResourceFolderType.getFolderType(initialTypeName);

                IContainer res = sourceFile.getParent().getParent();
                if (type != null && res != null && res.getType() == IResource.FOLDER) {
                    try {
                        for (IResource r : res.members()) {
                            if (r != null && r.getType() == IResource.FOLDER) {
                                String name = r.getName();
                                // Skip the initial folder name, it's already in the list.
                                if (!name.equals(initialTypeName)) {
                                    // Only accept the same folder type (e.g. layout-*)
                                    ResourceFolderType t =
                                        ResourceFolderType.getFolderType(name);
                                    if (type.equals(t)) {
                                        // recompute the path
                                        IPath p = res.getProjectRelativePath().append(name).
                                                                               append(filename);
                                        IResource f = project.findMember(p);
                                        if (f != null && f instanceof IFile) {
                                            files.add((IFile) f);
                                        }
                                    }
                                }
                            }
                        }
                    } catch (CoreException e) {
                        // Ignore.
                    }
                }
            }
        }

        SubMonitor subMonitor = SubMonitor.convert(monitor, Math.min(1, files.size()));

        ArrayList<Change> changes = new ArrayList<Change>();

        // Portability note: getModelManager is part of wst.sse.core however the
        // interface returned is part of wst.sse.core.internal.provisional so we can
        // expect it to change in a distant future if they start cleaning their codebase,
        // however unlikely that is.
        IModelManager modelManager = StructuredModelManager.getModelManager();

        for (IFile file : files) {

            IStructuredModel smodel = null;
            MultiTextEdit multiEdit = null;
            TextFileChange xmlChange = null;
            ArrayList<TextEditGroup> editGroups = null;

            try {
                IStructuredDocument sdoc = null;

                smodel = modelManager.getExistingModelForRead(file);
                if (smodel != null) {
                    sdoc = smodel.getStructuredDocument();
                } else if (smodel == null) {
                    // The model is not currently open.
                    if (file.exists()) {
                        sdoc = modelManager.createStructuredDocumentFor(file);
                    } else {
                        sdoc = modelManager.createNewStructuredDocumentFor(file);
                    }
                }

                if (sdoc == null) {
                    status.addFatalError("XML structured document not found");     //$NON-NLS-1$
                    continue;
                }

                multiEdit = new MultiTextEdit();
                editGroups = new ArrayList<TextEditGroup>();
                xmlChange = new TextFileChange(getName(), file);
                xmlChange.setTextType("xml");   //$NON-NLS-1$

                String quotedReplacement = quotedAttrValue(STRING_PREFIX + xmlStringId);

                // Prepare the change set
                for (IStructuredDocumentRegion regions : sdoc.getStructuredDocumentRegions()) {
                    // Only look at XML "top regions"
                    if (!DOMRegionContext.XML_TAG_NAME.equals(regions.getType())) {
                        continue;
                    }

                    int nb = regions.getNumberOfRegions();
                    ITextRegionList list = regions.getRegions();
                    String lastAttrName = null;

                    for (int i = 0; i < nb; i++) {
                        ITextRegion subRegion = list.get(i);
                        String type = subRegion.getType();

                        if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
                            // Memorize the last attribute name seen
                            lastAttrName = regions.getText(subRegion);

                        } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
                            // Check this is the attribute and the original string
                            String text = regions.getText(subRegion);

                            // Remove " or ' quoting present in the attribute value
                            text = unquoteAttrValue(text);

                            if (tokenString.equals(text) &&
                                    (xmlAttrName == null || xmlAttrName.equals(lastAttrName))) {

                                // Found an occurrence. Create a change for it.
                                TextEdit edit = new ReplaceEdit(
                                        regions.getStartOffset() + subRegion.getStart(),
                                        subRegion.getTextLength(),
                                        quotedReplacement);
                                TextEditGroup editGroup = new TextEditGroup(
                                        "Replace attribute string by ID",
                                        edit);

                                multiEdit.addChild(edit);
                                editGroups.add(editGroup);
                            }
                        }
                    }
                }
            } catch (Throwable t) {
                // Since we use some internal APIs, use a broad catch-all to report any
                // unexpected issue rather than crash the whole refactoring.
                status.addFatalError(
                        String.format("XML refactoring error: %1$s", t.getMessage()));
            } finally {
                if (smodel != null) {
                    smodel.releaseFromRead();
                }

                if (multiEdit != null &&
                        xmlChange != null &&
                        editGroups != null &&
                        multiEdit.hasChildren()) {
                    xmlChange.setEdit(multiEdit);
                    for (TextEditGroup group : editGroups) {
                        xmlChange.addTextEditChangeGroup(
                                new TextEditChangeGroup(xmlChange, group));
                    }
                    changes.add(xmlChange);
                }
                subMonitor.worked(1);
            }
        } // for files

        if (changes.size() > 0) {
            return changes;
        }
        return null;
    }

    /**
     * Returns a quoted attribute value suitable to be placed after an attributeName=
     * statement in an XML stream.
     *
     * According to http://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
     * the attribute value can be either quoted using ' or " and the corresponding
     * entities &apos; or &quot; must be used inside.
     */
    private String quotedAttrValue(String attrValue) {
        if (attrValue.indexOf('"') == -1) {
            // no double-quotes inside, use double-quotes around.
            return '"' + attrValue + '"';
        }
        if (attrValue.indexOf('\'') == -1) {
            // no single-quotes inside, use single-quotes around.
            return '\'' + attrValue + '\'';
        }
        // If we get here, there's a mix. Opt for double-quote around and replace
        // inner double-quotes.
        attrValue = attrValue.replace("\"", QUOT_ENTITY);  //$NON-NLS-1$
        return '"' + attrValue + '"';
    }

    // --- Java changes ---

    /**
     * Returns a foreach compatible iterator over all ICompilationUnit in the project.
     */
    private Iterable<ICompilationUnit> findAllJavaUnits() {
        final IJavaProject javaProject = JavaCore.create(mProject);

        return new Iterable<ICompilationUnit>() {
            @Override
            public Iterator<ICompilationUnit> iterator() {
                return new Iterator<ICompilationUnit>() {
                    final Queue<ICompilationUnit> mUnits = new LinkedList<ICompilationUnit>();
                    final Queue<IPackageFragment> mFragments = new LinkedList<IPackageFragment>();
                    {
                        try {
                            IPackageFragment[] tmpFrags = javaProject.getPackageFragments();
                            if (tmpFrags != null && tmpFrags.length > 0) {
                                mFragments.addAll(Arrays.asList(tmpFrags));
                            }
                        } catch (JavaModelException e) {
                            // pass
                        }
                    }

                    @Override
                    public boolean hasNext() {
                        if (!mUnits.isEmpty()) {
                            return true;
                        }

                        while (!mFragments.isEmpty()) {
                            try {
                                IPackageFragment fragment = mFragments.poll();
                                if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
                                    ICompilationUnit[] tmpUnits = fragment.getCompilationUnits();
                                    if (tmpUnits != null && tmpUnits.length > 0) {
                                        mUnits.addAll(Arrays.asList(tmpUnits));
                                        return true;
                                    }
                                }
                            } catch (JavaModelException e) {
                                // pass
                            }
                        }
                        return false;
                    }

                    @Override
                    public ICompilationUnit next() {
                        ICompilationUnit unit = mUnits.poll();
                        hasNext();
                        return unit;
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException(
                                "This iterator does not support removal");  //$NON-NLS-1$
                    }
                };
            }
        };
    }

    /**
     * Computes the changes to be made to Java file(s) and returns a list of {@link Change}.
     * <p/>
     * This function scans a Java compilation unit using {@link ReplaceStringsVisitor}, looking
     * for a string literal equals to <code>tokenString</code>.
     * If found, a change is made to replace each occurrence of <code>tokenString</code> by
     * a piece of Java code that somehow accesses R.string.<code>xmlStringId</code>.
     *
     * @param unit The compilated unit to process. Must not be null.
     * @param tokenString The string to find. Must not be null or empty.
     * @param status Status used to report fatal errors.
     * @param monitor Used to log progress.
     */
    private List<Change> computeJavaChanges(ICompilationUnit unit,
            String xmlStringId,
            String tokenString,
            RefactoringStatus status,
            SubMonitor monitor) {

        // We shouldn't be trying to replace a null or empty string.
        assert tokenString != null && tokenString.length() > 0;
        if (tokenString == null || tokenString.length() == 0) {
            return null;
        }

        // Get the Android package name from the Android Manifest. We need it to create
        // the FQCN of the R class.
        String packageName = null;
        String error = null;
        IResource manifestFile = mProject.findMember(SdkConstants.FN_ANDROID_MANIFEST_XML);
        if (manifestFile == null || manifestFile.getType() != IResource.FILE) {
            error = "File not found";
        } else {
            ManifestData manifestData = AndroidManifestHelper.parseForData((IFile) manifestFile);
            if (manifestData == null) {
                error = "Invalid content";
            } else {
                packageName = manifestData.getPackage();
                if (packageName == null) {
                    error = "Missing package definition";
                }
            }
        }

        if (error != null) {
            status.addFatalError(
                    String.format("Failed to parse file %1$s: %2$s.",
                            manifestFile == null ? "" : manifestFile.getFullPath(),  //$NON-NLS-1$
                            error));
            return null;
        }

        // Right now the changes array will contain one TextFileChange at most.
        ArrayList<Change> changes = new ArrayList<Change>();

        // This is the unit that will be modified.
        TextFileChange change = new TextFileChange(getName(), (IFile) unit.getResource());
        change.setTextType("java"); //$NON-NLS-1$

        // Create an AST for this compilation unit
        ASTParser parser = ASTParser.newParser(AST.JLS3);
        parser.setProject(unit.getJavaProject());
        parser.setSource(unit);
        parser.setResolveBindings(true);
        ASTNode node = parser.createAST(monitor.newChild(1));

        // The ASTNode must be a CompilationUnit, by design
        if (!(node instanceof CompilationUnit)) {
            status.addFatalError(String.format("Internal error: ASTNode class %s",  //$NON-NLS-1$
                    node.getClass()));
            return null;
        }

        // ImportRewrite will allow us to add the new type to the imports and will resolve
        // what the Java source must reference, e.g. the FQCN or just the simple name.
        ImportRewrite importRewrite = ImportRewrite.create((CompilationUnit) node, true);
        String Rqualifier = packageName + ".R"; //$NON-NLS-1$
        Rqualifier = importRewrite.addImport(Rqualifier);

        // Rewrite the AST itself via an ASTVisitor
        AST ast = node.getAST();
        ASTRewrite astRewrite = ASTRewrite.create(ast);
        ArrayList<TextEditGroup> astEditGroups = new ArrayList<TextEditGroup>();
        ReplaceStringsVisitor visitor = new ReplaceStringsVisitor(
                ast, astRewrite, astEditGroups,
                tokenString, Rqualifier, xmlStringId);
        node.accept(visitor);

        // Finally prepare the change set
        try {
            MultiTextEdit edit = new MultiTextEdit();

            // Create the edit to change the imports, only if anything changed
            TextEdit subEdit = importRewrite.rewriteImports(monitor.newChild(1));
            if (subEdit.hasChildren()) {
                edit.addChild(subEdit);
            }

            // Create the edit to change the Java source, only if anything changed
            subEdit = astRewrite.rewriteAST();
            if (subEdit.hasChildren()) {
                edit.addChild(subEdit);
            }

            // Only create a change set if any edit was collected
            if (edit.hasChildren()) {
                change.setEdit(edit);

                // Create TextEditChangeGroups which let the user turn changes on or off
                // individually. This must be done after the change.setEdit() call above.
                for (TextEditGroup editGroup : astEditGroups) {
                    TextEditChangeGroup group = new TextEditChangeGroup(change, editGroup);
                    if (editGroup instanceof EnabledTextEditGroup) {
                        group.setEnabled(((EnabledTextEditGroup) editGroup).isEnabled());
                    }
                    change.addTextEditChangeGroup(group);
                }

                changes.add(change);
            }

            monitor.worked(1);

            if (changes.size() > 0) {
                return changes;
            }

        } catch (CoreException e) {
            // ImportRewrite.rewriteImports failed.
            status.addFatalError(e.getMessage());
        }
        return null;
    }

    // ----

    /**
     * Step 3 of 3 of the refactoring: returns the {@link Change} that will be able to do the
     * work and creates a descriptor that can be used to replay that refactoring later.
     *
     * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
     *
     * @throws CoreException
     */
    @Override
    public Change createChange(IProgressMonitor monitor)
            throws CoreException, OperationCanceledException {

        try {
            monitor.beginTask("Applying changes...", 1);

            CompositeChange change = new CompositeChange(
                    getName(),
                    mChanges.toArray(new Change[mChanges.size()])) {
                @Override
                public ChangeDescriptor getDescriptor() {

                    String comment = String.format(
                            "Extracts string '%1$s' into R.string.%2$s",
                            mTokenString,
                            mXmlStringId);

                    ExtractStringDescriptor desc = new ExtractStringDescriptor(
                            mProject.getName(), //project
                            comment, //description
                            comment, //comment
                            createArgumentMap());

                    return new RefactoringChangeDescriptor(desc);
                }
            };

            monitor.worked(1);

            return change;

        } finally {
            monitor.done();
        }

    }

    /**
     * Given a file project path, returns its resource in the same project than the
     * compilation unit. The resource may not exist.
     */
    private IResource getTargetXmlResource(String xmlFileWsPath) {
        IResource resource = mProject.getFile(xmlFileWsPath);
        return resource;
    }
}
