public GotoElementAction(
     ResourceBundle bundle, String prefix, ITextEditor editor, Direction direction) {
   super(bundle, prefix, editor);
   this.direction = direction;
   CALModelManager modelManager = CALModelManager.getCALModelManager();
   sourceMetrics = modelManager.getSourceMetrics();
 }
  /*
   * @see org.eclipse.jface.action.Action#run()
   */
  @Override
  public void run() {
    // update has been called by the framework
    if (!isEnabled()) return;

    if (!CoreUtility.builderEnabledCheck(errorTitle)) {
      return;
    }

    final CALEditor textEditor = (CALEditor) getTextEditor();
    final ITextSelection selection = ActionUtilities.getSelection(textEditor);
    final IDocument document = ActionUtilities.getDocument(textEditor);

    if (document != null) {
      final int offset = selection.getOffset();
      try {
        CoreUtility.initializeCALBuilder(null, 100, 100);

        final int firstLine = document.getLineOfOffset(offset);
        final int column = offset - document.getLineOffset(firstLine);
        CALModelManager cmm = CALModelManager.getCALModelManager();
        FileEditorInput ei = (FileEditorInput) textEditor.getEditorInput();
        final IFile memberFile = ei.getFile();
        ModuleName moduleName = cmm.getModuleName(memberFile);
        if (moduleName == null) {
          final String errorMessage =
              Messages.format(
                  ActionMessages.error_invalidFileName_message, textEditor.getStorage().getName());
          CoreUtility.showMessage(errorTitle, errorMessage, IStatus.ERROR);
          return;
        }
        CompilerMessageLogger messageLogger = new MessageLogger();
        final SourceRange range;
        if (direction == Direction.Previous) {
          range =
              sourceMetrics.findPreviousTopLevelElement(
                  moduleName, firstLine + 1, column + 1, messageLogger);
        } else if (direction == Direction.Next) {
          range =
              sourceMetrics.findNextTopLevelElement(
                  moduleName, firstLine + 1, column + 1, messageLogger);
        } else {
          throw new IllegalArgumentException();
        }
        if (range != null) {
          IStorage definitionFile = cmm.getInputSourceFile(moduleName);
          IEditorPart editorPart = CoreUtility.openInEditor(definitionFile, true);
          CoreUtility.showPosition(editorPart, definitionFile, range, true);
        }
      } catch (BadLocationException e) {
        // will only happen on concurrent modification
        CALEclipseUIPlugin.log(
            new Status(
                IStatus.ERROR, CALEclipseUIPlugin.PLUGIN_ID, IStatus.OK, "", e)); // $NON-NLS-1$
        return;
      } catch (PartInitException e) {
        CALEclipseUIPlugin.log(
            new Status(
                IStatus.ERROR, CALEclipseUIPlugin.PLUGIN_ID, IStatus.OK, "", e)); // $NON-NLS-1$
        return;
      }
    }
  }