@Override
  protected IStructureComparator createStructureComparator(
      Object input,
      IDocument document,
      ISharedDocumentAdapter sharedDocumentAdapter,
      IProgressMonitor monitor)
      throws CoreException {

    if (input instanceof CeylonDocumentRangeNode) {
      return (CeylonDocumentRangeNode) input;
    }

    final boolean isEditable;
    if (input instanceof IEditableContent) {
      IEditableContent ec = (IEditableContent) input;
      isEditable = ec.isEditable();
    } else {
      isEditable = false;
    }

    StructureRootNode structureRootNode =
        new StructureRootNode(document, input, this, sharedDocumentAdapter) {
          @Override
          public boolean isEditable() {
            return isEditable;
          }
        };

    CeylonParseController pc = new CeylonParseController();
    if (input instanceof ResourceNode) {
      ResourceNode node = (ResourceNode) input;
      IResource file = node.getResource();
      pc.initialize(file.getProjectRelativePath(), file.getProject(), null);
    } else {
      pc.initialize(null, null, null);
    }

    if (pc.parseAndTypecheck(document, 10, monitor, null) != null) {
      // now visit the model, creating TreeCompareNodes for each ModelTreeNode
      CeylonOutlineNode tree =
          new CeylonOutlineBuilder() {
            // don't create nodes for shortcut refinement
            // because we can't distinguish them w/o a
            // full typecheck
            public void visit(Tree.SpecifierStatement that) {}
          }.buildTree(pc);
      if (tree != null) {
        buildCompareTree(tree, structureRootNode, document);
      }
    }

    return structureRootNode;
  }
 private CeylonParseController parse() {
   CeylonParseController cpc = new CeylonParseController();
   cpc.initialize(
       editor.getParseController().getPath(), editor.getParseController().getProject(), null);
   cpc.parse(editor.getCeylonSourceViewer().getDocument(), new NullProgressMonitor(), null);
   return cpc;
 }