private void deregisterHelper(IEditingSupport helper) {
   if (fEditor == null) return;
   ISourceViewer viewer = fEditor.getViewer();
   if (viewer instanceof IEditingSupportRegistry) {
     IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
     registry.unregister(helper);
   }
 }
  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 static void applyProposal(
      ICompletionProposal proposal,
      ITextViewer viewer,
      char trigger,
      int stateMask,
      final int offset) {
    Assert.isTrue(proposal instanceof ICompletionProposalExtension2);

    IRewriteTarget target = null;
    IEditingSupportRegistry registry = null;
    IEditingSupport helper =
        new IEditingSupport() {

          public boolean isOriginator(DocumentEvent event, IRegion focus) {
            return focus.getOffset() <= offset && focus.getOffset() + focus.getLength() >= offset;
          }

          public boolean ownsFocusShell() {
            return false;
          }
        };

    try {
      IDocument document = viewer.getDocument();

      if (viewer instanceof ITextViewerExtension) {
        ITextViewerExtension extension = (ITextViewerExtension) viewer;
        target = extension.getRewriteTarget();
      }

      if (target != null) target.beginCompoundChange();

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

      ((ICompletionProposalExtension2) proposal).apply(viewer, trigger, stateMask, offset);

      Point selection = proposal.getSelection(document);
      if (selection != null) {
        viewer.setSelectedRange(selection.x, selection.y);
        viewer.revealRange(selection.x, selection.y);
      }
    } finally {
      if (target != null) target.endCompoundChange();

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

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

    try {
      fLinkedPositionGroup = new LinkedPositionGroup();
      prepareElement();
      if (fDartElement == null) {
        return;
      }

      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.getName();
      final int pos = nameNode.getOffset();
      final List<ASTNode> sameNodes = Lists.newArrayList();
      nameNode
          .getRoot()
          .accept(
              new RecursiveASTVisitor<Void>() {
                @Override
                public Void visitSimpleIdentifier(SimpleIdentifier node) {
                  Element element = node.getElement();
                  element = getCanonicalElement(element);
                  if (Objects.equal(element, fDartElement)) {
                    sameNodes.add(node);
                  }
                  return super.visitSimpleIdentifier(node);
                }
              });

      // TODO: copied from LinkedNamesAssistProposal#apply(..):
      // sort for iteration order, starting with the node @ offset
      Collections.sort(
          sameNodes,
          new Comparator<ASTNode>() {
            @Override
            public int compare(ASTNode o1, ASTNode o2) {
              return rank(o1) - rank(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.getOffset() + node.getLength() - pos;
              if (relativeRank < 0) {
                return Integer.MAX_VALUE + relativeRank;
              } else {
                return relativeRank;
              }
            }
          });
      for (int i = 0; i < sameNodes.size(); i++) {
        ASTNode elem = sameNodes.get(i);
        LinkedPosition linkedPosition =
            new LinkedPosition(document, elem.getOffset(), 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();

      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) {
      DartToolsPlugin.log(e);
    }
  }
  public void start() {
    if (getActiveLinkedMode() != null) {
      // for safety; should already be handled in RenameDartElementAction
      fgActiveLinkedMode.startFullDialog();
      return;
    }

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

    try {
      DartUnit root =
          ASTProvider.getASTProvider().getAST(getCompilationUnit(), ASTProvider.WAIT_YES, null);

      fLinkedPositionGroup = new LinkedPositionGroup();
      DartNode selectedNode = NodeFinder.perform(root, fOriginalSelection.x, fOriginalSelection.y);
      if (!(selectedNode instanceof DartIdentifier)) {
        return; // TODO: show dialog
      }
      DartIdentifier nameNode = (DartIdentifier) 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.getName();
      final int pos = nameNode.getSourceInfo().getOffset();
      DartNode[] sameNodes = LinkedNodeFinder.findByNode(root, nameNode);

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

            /**
             * Returns the absolute rank of an <code>DartNode</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(DartNode node) {
              int relativeRank =
                  node.getSourceInfo().getOffset() + node.getSourceInfo().getLength() - pos;
              if (relativeRank < 0) {
                return Integer.MAX_VALUE + relativeRank;
              } else {
                return relativeRank;
              }
            }
          });
      for (int i = 0; i < sameNodes.length; i++) {
        DartNode elem = sameNodes[i];
        LinkedPosition linkedPosition =
            new LinkedPosition(
                document, elem.getSourceInfo().getOffset(), elem.getSourceInfo().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();

      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) {
      DartToolsPlugin.log(e);
    }
  }