private static boolean invoke(
      final PsiMethod method,
      final Project project,
      @Nullable final Editor editor,
      ChangeSignatureHandler initSubstisutor) {
    PsiMethod newMethod =
        SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
    if (newMethod == null) return false;

    if (!newMethod.equals(method)) {
      ChangeSignatureUtil.invokeChangeSignatureOn(newMethod, project);
      return true;
    }

    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return false;

    final PsiClass containingClass = method.getContainingClass();
    final PsiReferenceExpression refExpr =
        editor != null ? TargetElementUtil.findReferenceExpression(editor) : null;
    final boolean allowDelegation = containingClass != null && !containingClass.isInterface();
    final DialogWrapper dialog =
        new GosuChangeSignatureDialog(
            project,
            new GosuMethodDescriptor((IGosuMethod) method, initSubstisutor),
            allowDelegation,
            refExpr,
            initSubstisutor);
    return dialog.showAndGet();
  }
 private static boolean isSuperMethod(PsiMethod method, PsiMethod movedMethod) {
   final PsiMethod[] superMethods = movedMethod.findSuperMethods();
   for (PsiMethod testMethod : superMethods) {
     if (testMethod.equals(method)) {
       return true;
     }
   }
   return false;
 }
 public static boolean isUsedInExistingAccessor(
     PsiClass aClass, PsiMethod prototype, PsiElement element) {
   PsiMethod existingAccessor = aClass.findMethodBySignature(prototype, false);
   if (existingAccessor != null) {
     PsiElement parent = element;
     while (parent != null) {
       if (existingAccessor.equals(parent)) return true;
       parent = parent.getParent();
     }
   }
   return false;
 }
 @Nullable
 static PsiMethod findExistingImplementation(final PsiClass aClass, PsiMethod method) {
   final PsiMethod[] methods = aClass.findMethodsByName(method.getName(), false);
   for (PsiMethod candidate : methods) {
     final PsiMethod[] superMethods = candidate.findSuperMethods(false);
     for (PsiMethod superMethod : superMethods) {
       if (superMethod.equals(method)) {
         return candidate;
       }
     }
   }
   return null;
 }
 private static boolean newExpressionsAreEquivalent(
     @NotNull GrNewExpression newExp1, @NotNull GrNewExpression newExp2) {
   final PsiMethod constructor1 = newExp1.resolveMethod();
   final PsiMethod constructor2 = newExp2.resolveMethod();
   if (constructor1 == null || constructor2 == null || constructor1.equals(constructor2)) {
     return false;
   }
   final GrArgumentList argumentList1 = newExp1.getArgumentList();
   if (argumentList1 == null) {
     return false;
   }
   final GrExpression[] args1 = argumentList1.getExpressionArguments();
   final GrArgumentList argumentList2 = newExp2.getArgumentList();
   if (argumentList2 == null) {
     return false;
   }
   final GrExpression[] args2 = argumentList2.getExpressionArguments();
   return expressionListsAreEquivalent(args1, args2);
 }
 @Override
 public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
   if (hasSuperCall) {
     return;
   }
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (qualifier == null) {
     return;
   }
   final String text = qualifier.getText();
   if (!PsiKeyword.SUPER.equals(text)) {
     return;
   }
   final PsiMethod method = expression.resolveMethod();
   if (method == null) {
     return;
   }
   if (method.equals(methodToSearchFor)) {
     hasSuperCall = true;
   }
 }
  private static void invoke(
      final PsiMethod method, final Project project, @Nullable final Editor editor) {
    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return;

    PsiMethod newMethod =
        SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
    if (newMethod == null) return;

    if (!newMethod.equals(method)) {
      invoke(newMethod, project, editor);
      return;
    }

    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return;

    final PsiClass containingClass = method.getContainingClass();
    final PsiReferenceExpression refExpr =
        editor != null ? TargetElementUtil.findReferenceExpression(editor) : null;
    final DialogWrapper dialog =
        new JavaChangeSignatureDialog(
            project, method, containingClass != null && !containingClass.isInterface(), refExpr);
    dialog.show();
  }
  public Result weigh(
      @NotNull final LookupElement element, @NotNull final CompletionLocation location) {
    if (location == null) {
      return null;
    }
    if (location.getCompletionType() != CompletionType.BASIC
        && location.getCompletionType() != CompletionType.SMART) return Result.normal;

    final Object object = element.getObject();
    if (!(object instanceof PsiModifierListOwner) && !(object instanceof PsiExpression))
      return Result.normal;

    final PsiMethod positionMethod = JavaCompletionUtil.POSITION_METHOD.getValue(location);
    if (positionMethod == null) return Result.normal;

    final PsiElement position = location.getCompletionParameters().getPosition();
    final ElementFilter filter = JavaCompletionUtil.recursionFilter(position);
    if (filter != null && !filter.isAcceptable(object, position)) {
      return Result.recursive;
    }

    final PsiMethodCallExpression expression =
        PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class, true, PsiClass.class);
    final PsiReferenceExpression reference =
        expression != null
            ? expression.getMethodExpression()
            : PsiTreeUtil.getParentOfType(position, PsiReferenceExpression.class);
    if (reference == null) return Result.normal;

    final PsiExpression qualifier = reference.getQualifierExpression();
    boolean isDelegate = qualifier != null && !(qualifier instanceof PsiThisExpression);

    if (isPassingObjectToItself(object, qualifier, isDelegate)) {
      return Result.passingObjectToItself;
    }

    if (expression != null) {
      final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
      if (expectedInfos != null) {
        final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
        if (itemType != null) {
          for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
            if (positionMethod.equals(expectedInfo.getCalledMethod())
                && expectedInfo.getType().isAssignableFrom(itemType)) {
              return isDelegate ? Result.delegation : Result.recursive;
            }
          }
        }
      }
      return Result.normal;
    }

    if (object instanceof PsiMethod) {
      final PsiMethod method = (PsiMethod) object;
      if (PsiTreeUtil.isAncestor(reference, position, false)
          && Comparing.equal(method.getName(), positionMethod.getName())
          && method.getParameterList().getParametersCount()
              == positionMethod.getParameterList().getParametersCount()) {
        if (findDeepestSuper(method).equals(findDeepestSuper(positionMethod))) {
          return isDelegate ? Result.delegation : Result.recursive;
        }
      }
    }

    return Result.normal;
  }
  // uses hierarchy signature tree if available, traverses class structure by itself otherwise
  public static boolean isSuperMethodSmart(
      @NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
    // boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod);

    if (method == superMethod) return false;
    PsiClass aClass = method.getContainingClass();
    PsiClass superClass = superMethod.getContainingClass();

    if (aClass == null || superClass == null || superClass == aClass) return false;

    if (!canHaveSuperMethod(method, true, false)) return false;

    PsiMethod[] superMethods = null;
    Map<MethodSignature, HierarchicalMethodSignature> cachedMap =
        SIGNATURES_KEY.getCachedValueOrNull(aClass);
    if (cachedMap != null) {
      HierarchicalMethodSignature signature =
          cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY));
      if (signature != null) {
        superMethods =
            MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures());
      }
    }
    if (superMethods == null) {
      PsiClassType[] directSupers = aClass.getSuperTypes();
      List<PsiMethod> found = null;
      boolean canceled = false;
      for (PsiClassType directSuper : directSupers) {
        PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics();
        if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) {
          // generics
          canceled = true;
          break;
        }
        PsiClass directSuperClass = resolveResult.getElement();
        if (directSuperClass == null) continue;
        PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false);
        if (candidates.length != 0) {
          if (found == null) found = new ArrayList<PsiMethod>();
          for (PsiMethod candidate : candidates) {
            if (PsiUtil.canBeOverriden(candidate)) found.add(candidate);
          }
        }
      }
      superMethods =
          canceled
              ? null
              : found == null ? PsiMethod.EMPTY_ARRAY : found.toArray(new PsiMethod[found.size()]);
    }
    if (superMethods == null) {
      superMethods =
          MethodSignatureUtil.convertMethodSignaturesToMethods(
              method.getHierarchicalMethodSignature().getSuperSignatures());
    }

    for (PsiMethod superCandidate : superMethods) {
      if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod))
        return true;
    }
    return false;
  }