mychangedetector.copyclasses.MyRenameLinkedMode.java Source code

Java tutorial

Introduction

Here is the source code for mychangedetector.copyclasses.MyRenameLinkedMode.java

Source

package mychangedetector.copyclasses;
/*******************************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;
import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenamingNameSuggestor;
import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jdt.internal.ui.javaeditor.EditorHighlightingSynchronizer;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.refactoring.DelegateUIHelper;
import org.eclipse.jdt.internal.ui.refactoring.reorg.RenameInformationPopup;
import org.eclipse.jdt.internal.ui.refactoring.reorg.RenameLinkedMode;
import org.eclipse.jdt.internal.ui.refactoring.reorg.RenameRefactoringWizard;
import org.eclipse.jdt.internal.ui.refactoring.reorg.ReorgMessages;
import org.eclipse.jdt.internal.ui.text.correction.proposals.LinkedNamesAssistProposal.DeleteBlockingExitPolicy;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jdt.ui.refactoring.RenameSupport;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IEditingSupport;
import org.eclipse.jface.text.IEditingSupportRegistry;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension6;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedModeUI;
import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.ui.refactoring.RefactoringWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;

public class MyRenameLinkedMode extends RenameLinkedMode {

    private class FocusEditingSupport implements IEditingSupport {
        public boolean ownsFocusShell() {
            if (fInfoPopup == null)
                return false;
            if (fInfoPopup.ownsFocusShell()) {
                return true;
            }

            Shell editorShell = fEditor.getSite().getShell();
            Shell activeShell = editorShell.getDisplay().getActiveShell();
            if (editorShell == activeShell)
                return true;
            return false;
        }

        public boolean isOriginator(DocumentEvent event, IRegion subjectRegion) {
            return false; //leave on external modification outside positions
        }
    }

    private class EditorSynchronizer implements ILinkedModeListener {
        public void left(LinkedModeModel model, int flags) {
            linkedModeLeft();
            if ((flags & ILinkedModeListener.UPDATE_CARET) != 0) {
                doRename(fShowPreview);
            }
        }

        public void resume(LinkedModeModel model, int flags) {
        }

        public void suspend(LinkedModeModel model) {
        }
    }

    private class ExitPolicy extends DeleteBlockingExitPolicy {
        public ExitPolicy(IDocument document) {
            super(document);
        }

        public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {
            fShowPreview = (event.stateMask & SWT.CTRL) != 0
                    && (event.character == SWT.CR || event.character == SWT.LF);
            return super.doExit(model, event, offset, length);
        }
    }

    private static RenameLinkedMode fgActiveLinkedMode;

    private final CompilationUnitEditor fEditor;
    private final IJavaElement fJavaElement;

    private RenameInformationPopup fInfoPopup;

    private Point fOriginalSelection;
    private String fOriginalName;

    private LinkedPosition fNamePosition;
    private LinkedModeModel fLinkedModeModel;
    private LinkedPositionGroup fLinkedPositionGroup;
    private final FocusEditingSupport fFocusEditingSupport;
    private boolean fShowPreview;
    private CompilationUnitEditor myfEditor;

    private Runnable callback;

    /**
     * The operation on top of the undo stack when the rename is {@link #start()}ed, or
     * <code>null</code> if rename has not been started or the undo stack was empty.
     * 
     * @since 3.5
     */
    private IUndoableOperation fStartingUndoOperation;

    private Object prohibitted_name;

    private Runnable linked_mode_entered_callback;

    public MyRenameLinkedMode(IJavaElement element, CompilationUnitEditor editor) {
        super(element, editor);

        Assert.isNotNull(element);
        Assert.isNotNull(editor);
        fEditor = editor;
        myfEditor = editor;
        fJavaElement = element;
        fFocusEditingSupport = new FocusEditingSupport();
    }

    public void setSuccessCallback(Runnable callback) {
        this.callback = callback;
    }

    public void start() {
        if (getActiveLinkedMode() != null) {
            // for safety; should already be handled in RenameJavaElementAction
            fgActiveLinkedMode.startFullDialog();
            return;
        }

        ISourceViewer viewer = fEditor.getViewer();
        IDocument document = viewer.getDocument();
        fOriginalSelection = viewer.getSelectedRange();
        int offset = fOriginalSelection.x;

        try {
            CompilationUnit root = SharedASTProvider.getAST(getCompilationUnit(), SharedASTProvider.WAIT_YES, null);

            fLinkedPositionGroup = new LinkedPositionGroup();
            ASTNode selectedNode = NodeFinder.perform(root, fOriginalSelection.x, fOriginalSelection.y);
            if (!(selectedNode instanceof SimpleName)) {
                return; // TODO: show dialog
            }
            SimpleName nameNode = (SimpleName) selectedNode;

            if (viewer instanceof ITextViewerExtension6) {
                IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager();
                if (undoManager instanceof IUndoManagerExtension) {
                    IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager;
                    IUndoContext undoContext = undoManagerExtension.getUndoContext();
                    IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory();
                    fStartingUndoOperation = operationHistory.getUndoOperation(undoContext);
                }
            }

            fOriginalName = nameNode.getIdentifier();
            final int pos = nameNode.getStartPosition();
            ASTNode[] sameNodes = LinkedNodeFinder.findByNode(root, nameNode);

            //TODO: copied from LinkedNamesAssistProposal#apply(..):
            // sort for iteration order, starting with the node @ offset
            Arrays.sort(sameNodes, new Comparator() {
                public int compare(Object o1, Object o2) {
                    return rank((ASTNode) o1) - rank((ASTNode) o2);
                }

                /**
                 * Returns the absolute rank of an <code>ASTNode</code>. Nodes
                 * preceding <code>pos</code> are ranked last.
                 *
                 * @param node the node to compute the rank for
                 * @return the rank of the node with respect to the invocation offset
                 */
                private int rank(ASTNode node) {
                    int relativeRank = node.getStartPosition() + node.getLength() - pos;
                    if (relativeRank < 0)
                        return Integer.MAX_VALUE + relativeRank;
                    else
                        return relativeRank;
                }
            });
            for (int i = 0; i < sameNodes.length; i++) {
                ASTNode elem = sameNodes[i];
                LinkedPosition linkedPosition = new LinkedPosition(document, elem.getStartPosition(),
                        elem.getLength(), i);
                if (i == 0)
                    fNamePosition = linkedPosition;
                fLinkedPositionGroup.addPosition(linkedPosition);
            }

            fLinkedModeModel = new LinkedModeModel();
            fLinkedModeModel.addGroup(fLinkedPositionGroup);
            fLinkedModeModel.forceInstall();
            fLinkedModeModel.addLinkingListener(new EditorHighlightingSynchronizer(fEditor));
            fLinkedModeModel.addLinkingListener(new EditorSynchronizer());

            LinkedModeUI ui = new EditorLinkedModeUI(fLinkedModeModel, viewer);
            ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE);
            ui.setExitPolicy(new ExitPolicy(document));
            ui.enter();

            linked_mode_entered_callback.run();

            //   viewer.setSelectedRange(fOriginalSelection.x, fOriginalSelection.y); // by default, full word is selected; restore original selection

            if (viewer instanceof IEditingSupportRegistry) {
                IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
                registry.register(fFocusEditingSupport);
            }

            openSecondaryPopup();
            //         startAnimation();
            fgActiveLinkedMode = this;

        } catch (BadLocationException e) {
            JavaPlugin.log(e);
        }
    }

    //   private void startAnimation() {
    //      //TODO:
    //      // - switch off if animations disabled
    //      // - show rectangle around target for 500ms after animation
    //      Shell shell= fEditor.getSite().getShell();
    //      StyledText textWidget= fEditor.getViewer().getTextWidget();
    //
    //      // from popup:
    //      Rectangle startRect= fPopup.getBounds();
    //
    //      // from editor:
    ////      Point startLoc= textWidget.getParent().toDisplay(textWidget.getLocation());
    ////      Point startSize= textWidget.getSize();
    ////      Rectangle startRect= new Rectangle(startLoc.x, startLoc.y, startSize.x, startSize.y);
    //
    //      // from hell:
    ////      Rectangle startRect= shell.getClientArea();
    //
    //      Point caretLocation= textWidget.getLocationAtOffset(textWidget.getCaretOffset());
    //      Point displayLocation= textWidget.toDisplay(caretLocation);
    //      Rectangle targetRect= new Rectangle(displayLocation.x, displayLocation.y, 0, 0);
    //
    //      RectangleAnimation anim= new RectangleAnimation(shell, startRect, targetRect);
    //      anim.schedule();
    //   }

    void doRename(boolean showPreview) {
        cancel();

        Image image = null;
        Label label = null;

        fShowPreview |= showPreview;
        try {
            ISourceViewer viewer = fEditor.getViewer();
            if (viewer instanceof SourceViewer) {
                SourceViewer sourceViewer = (SourceViewer) viewer;
                Control viewerControl = sourceViewer.getControl();
                if (viewerControl instanceof Composite) {
                    Composite composite = (Composite) viewerControl;
                    Display display = composite.getDisplay();

                    // Flush pending redraw requests:
                    while (!display.isDisposed() && display.readAndDispatch()) {
                    }

                    // Copy editor area:
                    GC gc = new GC(composite);
                    Point size;
                    try {
                        size = composite.getSize();
                        image = new Image(gc.getDevice(), size.x, size.y);
                        gc.copyArea(image, 0, 0);
                    } finally {
                        gc.dispose();
                        gc = null;
                    }

                    // Persist editor area while executing refactoring:
                    label = new Label(composite, SWT.NONE);
                    label.setImage(image);
                    label.setBounds(0, 0, size.x, size.y);
                    label.moveAbove(null);
                }
            }

            String newName = fNamePosition.getContent();
            if (fOriginalName.equals(newName) || newName.equals(prohibitted_name)) {
                callback.run();

                return;
            }
            RenameSupport renameSupport = undoAndCreateRenameSupport(newName);
            if (renameSupport == null) {
                callback.run();

                return;
            }

            Shell shell = fEditor.getSite().getShell();
            boolean executed;
            if (fShowPreview) { // could have been updated by undoAndCreateRenameSupport(..)
                executed = renameSupport.openDialog(shell, true);
            } else {
                renameSupport.perform(shell, fEditor.getSite().getWorkbenchWindow());
                executed = true;
            }
            if (executed) {
                restoreFullSelection();
            }
            JavaModelUtil.reconcile(getCompilationUnit());
        } catch (CoreException ex) {
            JavaPlugin.log(ex);
        } catch (InterruptedException ex) {
            // canceling is OK -> redo text changes in that case?
        } catch (InvocationTargetException ex) {
            JavaPlugin.log(ex);
        } catch (BadLocationException e) {
            JavaPlugin.log(e);
        } finally {
            callback.run();

            if (label != null)
                label.dispose();
            if (image != null)
                image.dispose();
        }
    }

    public void cancel() {
        if (fLinkedModeModel != null) {
            fLinkedModeModel.exit(ILinkedModeListener.NONE);
        }
        linkedModeLeft();

    }

    private void restoreFullSelection() {
        if (fOriginalSelection.y != 0) {
            int originalOffset = fOriginalSelection.x;
            LinkedPosition[] positions = fLinkedPositionGroup.getPositions();
            for (int i = 0; i < positions.length; i++) {
                LinkedPosition position = positions[i];
                if (!position.isDeleted() && position.includes(originalOffset)) {
                    fEditor.getViewer().setSelectedRange(position.offset, position.length);
                    return;
                }
            }
        }
    }

    private RenameSupport undoAndCreateRenameSupport(String newName) throws CoreException {
        // Assumption: the linked mode model should be shut down by now.

        final ISourceViewer viewer = fEditor.getViewer();

        try {
            if (!fOriginalName.equals(newName)) {
                fEditor.getSite().getWorkbenchWindow().run(false, true, new IRunnableWithProgress() {
                    public void run(IProgressMonitor monitor)
                            throws InvocationTargetException, InterruptedException {
                        if (viewer instanceof ITextViewerExtension6) {
                            IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager();
                            if (undoManager instanceof IUndoManagerExtension) {
                                IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager;
                                IUndoContext undoContext = undoManagerExtension.getUndoContext();
                                IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory();
                                while (undoManager.undoable()) {
                                    if (fStartingUndoOperation != null && fStartingUndoOperation
                                            .equals(operationHistory.getUndoOperation(undoContext)))
                                        return;
                                    undoManager.undo();
                                }
                            }
                        }
                    }
                });
            }
        } catch (InvocationTargetException e) {
            throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),
                    ReorgMessages.RenameLinkedMode_error_saving_editor, e));
        } catch (InterruptedException e) {
            // canceling is OK
            return null;
        } finally {
            JavaModelUtil.reconcile(getCompilationUnit());
        }

        viewer.setSelectedRange(fOriginalSelection.x, fOriginalSelection.y);

        if (newName.length() == 0)
            return null;

        RenameJavaElementDescriptor descriptor = createRenameDescriptor(fJavaElement, newName);
        RenameSupport renameSupport = RenameSupport.create(descriptor);
        return renameSupport;
    }

    private ICompilationUnit getCompilationUnit() {
        return (ICompilationUnit) EditorUtility.getEditorInputJavaElement(fEditor, false);
    }

    public void startFullDialog() {
        cancel();

        try {
            String newName = fNamePosition.getContent();
            RenameSupport renameSupport = undoAndCreateRenameSupport(newName);
            if (renameSupport != null)
                renameSupport.openDialog(fEditor.getSite().getShell());
        } catch (CoreException e) {
            JavaPlugin.log(e);
        } catch (BadLocationException e) {
            JavaPlugin.log(e);
        }
    }

    /**
     * Creates a rename descriptor.
     * 
     * @param javaElement element to rename 
     * @param newName new name
     * @return a rename descriptor with current settings as used in the refactoring dialogs
     * @throws JavaModelException if an error occurs while accessing the element
     */
    private RenameJavaElementDescriptor createRenameDescriptor(IJavaElement javaElement, String newName)
            throws JavaModelException {
        String contributionId;
        // see RefactoringExecutionStarter#createRenameSupport(..):
        int elementType = javaElement.getElementType();
        switch (elementType) {
        case IJavaElement.JAVA_PROJECT:
            contributionId = IJavaRefactorings.RENAME_JAVA_PROJECT;
            break;
        case IJavaElement.PACKAGE_FRAGMENT_ROOT:
            contributionId = IJavaRefactorings.RENAME_SOURCE_FOLDER;
            break;
        case IJavaElement.PACKAGE_FRAGMENT:
            contributionId = IJavaRefactorings.RENAME_PACKAGE;
            break;
        case IJavaElement.COMPILATION_UNIT:
            contributionId = IJavaRefactorings.RENAME_COMPILATION_UNIT;
            break;
        case IJavaElement.TYPE:
            contributionId = IJavaRefactorings.RENAME_TYPE;
            break;
        case IJavaElement.METHOD:
            final IMethod method = (IMethod) javaElement;
            if (method.isConstructor())
                return createRenameDescriptor(method.getDeclaringType(), newName);
            else
                contributionId = IJavaRefactorings.RENAME_METHOD;
            break;
        case IJavaElement.FIELD:
            IField field = (IField) javaElement;
            if (field.isEnumConstant())
                contributionId = IJavaRefactorings.RENAME_ENUM_CONSTANT;
            else
                contributionId = IJavaRefactorings.RENAME_FIELD;
            break;
        case IJavaElement.TYPE_PARAMETER:
            contributionId = IJavaRefactorings.RENAME_TYPE_PARAMETER;
            break;
        case IJavaElement.LOCAL_VARIABLE:
            contributionId = IJavaRefactorings.RENAME_LOCAL_VARIABLE;
            break;
        default:
            return null;
        }

        RenameJavaElementDescriptor descriptor = (RenameJavaElementDescriptor) RefactoringCore
                .getRefactoringContribution(contributionId).createDescriptor();
        descriptor.setJavaElement(javaElement);
        descriptor.setNewName(newName);
        if (elementType != IJavaElement.PACKAGE_FRAGMENT_ROOT)
            descriptor.setUpdateReferences(true);

        IDialogSettings javaSettings = JavaPlugin.getDefault().getDialogSettings();
        IDialogSettings refactoringSettings = javaSettings.getSection(RefactoringWizardPage.REFACTORING_SETTINGS); //TODO: undocumented API
        if (refactoringSettings == null) {
            refactoringSettings = javaSettings.addNewSection(RefactoringWizardPage.REFACTORING_SETTINGS);
        }

        switch (elementType) {
        case IJavaElement.METHOD:
        case IJavaElement.FIELD:
            descriptor.setDeprecateDelegate(refactoringSettings.getBoolean(DelegateUIHelper.DELEGATE_DEPRECATION));
            descriptor.setKeepOriginal(refactoringSettings.getBoolean(DelegateUIHelper.DELEGATE_UPDATING));
        }
        switch (elementType) {
        case IJavaElement.TYPE:
            //         case IJavaElement.COMPILATION_UNIT: // TODO
            descriptor.setUpdateSimilarDeclarations(
                    refactoringSettings.getBoolean(RenameRefactoringWizard.TYPE_UPDATE_SIMILAR_ELEMENTS));
            int strategy;
            try {
                strategy = refactoringSettings.getInt(RenameRefactoringWizard.TYPE_SIMILAR_MATCH_STRATEGY);
            } catch (NumberFormatException e) {
                strategy = RenamingNameSuggestor.STRATEGY_EXACT;
            }
            descriptor.setMatchStrategy(strategy);
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
            descriptor.setUpdateHierarchy(
                    refactoringSettings.getBoolean(RenameRefactoringWizard.PACKAGE_RENAME_SUBPACKAGES));
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
        case IJavaElement.TYPE:
            String fileNamePatterns = refactoringSettings.get(RenameRefactoringWizard.QUALIFIED_NAMES_PATTERNS);
            if (fileNamePatterns != null && fileNamePatterns.length() != 0) {
                descriptor.setFileNamePatterns(fileNamePatterns);
                boolean updateQualifiedNames = refactoringSettings
                        .getBoolean(RenameRefactoringWizard.UPDATE_QUALIFIED_NAMES);
                descriptor.setUpdateQualifiedNames(updateQualifiedNames);
                fShowPreview |= updateQualifiedNames;
            }
        }
        switch (elementType) {
        case IJavaElement.PACKAGE_FRAGMENT:
        case IJavaElement.TYPE:
        case IJavaElement.FIELD:
            boolean updateTextualOccurrences = refactoringSettings
                    .getBoolean(RenameRefactoringWizard.UPDATE_TEXTUAL_MATCHES);
            descriptor.setUpdateTextualOccurrences(updateTextualOccurrences);
            fShowPreview |= updateTextualOccurrences;
        }
        switch (elementType) {
        case IJavaElement.FIELD:
            descriptor
                    .setRenameGetters(refactoringSettings.getBoolean(RenameRefactoringWizard.FIELD_RENAME_GETTER));
            descriptor
                    .setRenameSetters(refactoringSettings.getBoolean(RenameRefactoringWizard.FIELD_RENAME_SETTER));
        }
        return descriptor;
    }

    private void linkedModeLeft() {
        fgActiveLinkedMode = null;
        if (fInfoPopup != null) {
            fInfoPopup.close();
        }

        ISourceViewer viewer = fEditor.getViewer();
        if (viewer instanceof IEditingSupportRegistry) {
            IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
            registry.unregister(fFocusEditingSupport);
        }
    }

    private void openSecondaryPopup() {
        fInfoPopup = new RenameInformationPopup(fEditor, this);
        fInfoPopup.open();

    }

    public boolean isCaretInLinkedPosition() {
        return getCurrentLinkedPosition() != null;
    }

    public LinkedPosition getCurrentLinkedPosition() {
        Point selection = fEditor.getViewer().getSelectedRange();
        int start = selection.x;
        int end = start + selection.y;
        LinkedPosition[] positions = fLinkedPositionGroup.getPositions();
        for (int i = 0; i < positions.length; i++) {
            LinkedPosition position = positions[i];
            if (position.includes(start) && position.includes(end))
                return position;
        }
        return null;
    }

    public boolean isEnabled() {
        try {
            String newName = fNamePosition.getContent();
            if (fOriginalName.equals(newName))
                return false;
            /*
             * TODO: use JavaRenameProcessor#checkNewElementName(String)
             * but make sure implementations don't access outdated Java Model
             * (cache all necessary information before starting linked mode).
             */
            return JavaConventionsUtil.validateIdentifier(newName, fJavaElement).isOK();
        } catch (BadLocationException e) {
            return false;
        }

    }

    public boolean isOriginalName() {
        try {
            String newName = fNamePosition.getContent();
            return fOriginalName.equals(newName);
        } catch (BadLocationException e) {
            return false;
        }
    }

    public static RenameLinkedMode getActiveLinkedMode() {
        return fgActiveLinkedMode;
    }

    public void setProhibittedName(Object prohibitted_name) {
        this.prohibitted_name = prohibitted_name;
    }

    public void setLinkedModeEnteredCallback(Runnable linked_mode_entered_callback) {
        this.linked_mode_entered_callback = linked_mode_entered_callback;
    }

}