/**
  * Returns a runnable that creates the method stubs for overridden methods.
  *
  * @param astRoot the AST of the compilation unit to work on. The AST must have been created from
  *     a {@link ICompilationUnit}, that means {@link ASTParser#setSource(ICompilationUnit)} was
  *     used.
  * @param type the binding of the type to add the new methods to. The type binding must correspond
  *     to a type declaration in the AST.
  * @param methodToOverride the bindings of methods to override or <code>null</code> to implement
  *     all unimplemented, abstract methods from super types.
  * @param insertPos a hint for a location in the source where to insert the new methods or <code>
  *     -1</code> to use the default behavior.
  * @param createComments if set, comments will be added to the new methods.
  * @return returns a runnable that creates the methods stubs.
  * @throws IllegalArgumentException a {@link IllegalArgumentException} is thrown if the AST passed
  *     has not been created from a {@link ICompilationUnit}.
  * @since 3.2
  */
 public static IWorkspaceRunnable createRunnable(
     CompilationUnit astRoot,
     ITypeBinding type,
     IMethodBinding[] methodToOverride,
     int insertPos,
     boolean createComments) {
   AddUnimplementedMethodsOperation operation =
       new AddUnimplementedMethodsOperation(
           astRoot, type, methodToOverride, insertPos, true, true, false);
   operation.setCreateComments(createComments);
   return operation;
 }
  private void run(Shell shell, IType type) throws CoreException {
    final OverrideMethodDialog dialog = new OverrideMethodDialog(shell, fEditor, type, false);
    if (!dialog.hasMethodsToOverride()) {
      MessageDialog.openInformation(
          shell, getDialogTitle(), ActionMessages.OverrideMethodsAction_error_nothing_found);
      notifyResult(false);
      return;
    }
    if (dialog.open() != Window.OK) {
      notifyResult(false);
      return;
    }

    final Object[] selected = dialog.getResult();
    if (selected == null) {
      notifyResult(false);
      return;
    }

    ArrayList<IMethodBinding> methods = new ArrayList<IMethodBinding>();
    for (int i = 0; i < selected.length; i++) {
      Object elem = selected[i];
      if (elem instanceof IMethodBinding) {
        methods.add((IMethodBinding) elem);
      }
    }
    IMethodBinding[] methodToOverride = methods.toArray(new IMethodBinding[methods.size()]);

    final IEditorPart editor = JavaUI.openInEditor(type.getCompilationUnit());
    final IRewriteTarget target =
        editor != null ? (IRewriteTarget) editor.getAdapter(IRewriteTarget.class) : null;
    if (target != null) target.beginCompoundChange();
    try {
      CompilationUnit astRoot = dialog.getCompilationUnit();
      final ITypeBinding typeBinding = ASTNodes.getTypeBinding(astRoot, type);
      int insertPos = dialog.getInsertOffset();

      AddUnimplementedMethodsOperation operation =
          (AddUnimplementedMethodsOperation)
              createRunnable(
                  astRoot, typeBinding, methodToOverride, insertPos, dialog.getGenerateComment());
      IRunnableContext context = JavaPlugin.getActiveWorkbenchWindow();
      if (context == null) context = new BusyIndicatorRunnableContext();
      PlatformUI.getWorkbench()
          .getProgressService()
          .runInUI(
              context,
              new WorkbenchRunnableAdapter(operation, operation.getSchedulingRule()),
              operation.getSchedulingRule());
      final String[] created = operation.getCreatedMethods();
      if (created == null || created.length == 0)
        MessageDialog.openInformation(
            shell, getDialogTitle(), ActionMessages.OverrideMethodsAction_error_nothing_found);
    } catch (InvocationTargetException exception) {
      ExceptionHandler.handle(exception, shell, getDialogTitle(), null);
    } catch (InterruptedException exception) {
      // Do nothing. Operation has been canceled by user.
    } finally {
      if (target != null) target.endCompoundChange();
    }
    notifyResult(true);
  }