@Override
  public String generateDocumentationContentStub(PsiComment contextComment) {
    if (!(contextComment instanceof GrDocComment)) {
      return null;
    }

    final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment);
    if (owner == null) return null;

    Project project = contextComment.getProject();
    final CodeDocumentationAwareCommenter commenter =
        (CodeDocumentationAwareCommenter)
            LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage());

    StringBuilder builder = StringBuilderSpinAllocator.alloc();
    try {
      if (owner instanceof GrMethod) {
        final GrMethod method = (GrMethod) owner;
        JavaDocumentationProvider.generateParametersTakingDocFromSuperMethods(
            project, builder, commenter, method);

        final PsiType returnType = method.getInferredReturnType();
        if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF))
            && !PsiType.VOID.equals(returnType)) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter));
          builder.append(LINE_SEPARATOR);
        }

        final PsiClassType[] references = method.getThrowsList().getReferencedTypes();
        for (PsiClassType reference : references) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter));
          builder.append(reference.getClassName());
          builder.append(LINE_SEPARATOR);
        }
      } else if (owner instanceof GrTypeDefinition) {
        final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList();
        if (typeParameterList != null) {
          JavaDocumentationProvider.createTypeParamsListComment(
              builder, project, commenter, typeParameterList);
        }
      }
      return builder.length() > 0 ? builder.toString() : null;
    } finally {
      StringBuilderSpinAllocator.dispose(builder);
    }
  }
  public String generateDocumentationContentStub(PsiComment contextComment) {
    if (!(contextComment instanceof GrDocComment)) {
      return null;
    }

    final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment);
    if (owner == null) return null;

    Project project = contextComment.getProject();
    final CodeDocumentationAwareCommenter commenter =
        (CodeDocumentationAwareCommenter)
            LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage());

    StringBuilder builder = StringBuilderSpinAllocator.alloc();
    try {
      if (owner instanceof GrMethod) {
        final GrMethod method = (GrMethod) owner;
        final GrParameter[] parameters = method.getParameters();
        final Map<String, String> param2Description = new HashMap<String, String>();
        final PsiMethod[] superMethods = method.findSuperMethods();

        for (PsiMethod superMethod : superMethods) {
          final PsiDocComment comment = superMethod.getDocComment();
          if (comment != null) {
            final PsiDocTag[] params = comment.findTagsByName("param");
            for (PsiDocTag param : params) {
              final PsiElement[] dataElements = param.getDataElements();
              if (dataElements != null) {
                String paramName = null;
                for (PsiElement dataElement : dataElements) {
                  if (dataElement instanceof PsiDocParamRef) {
                    paramName = dataElement.getReference().getCanonicalText();
                    break;
                  }
                }
                if (paramName != null) {
                  param2Description.put(paramName, param.getText());
                }
              }
            }
          }
        }
        for (PsiParameter parameter : parameters) {
          String description = param2Description.get(parameter.getName());
          if (description != null) {
            builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
            if (description.indexOf('\n') > -1)
              description = description.substring(0, description.lastIndexOf('\n'));
            builder.append(description);
          } else {
            builder.append(
                CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
            builder.append(parameter.getName());
          }
          builder.append(LINE_SEPARATOR);
        }

        final PsiType returnType = method.getInferredReturnType();
        if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF))
            && returnType != PsiType.VOID) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter));
          builder.append(LINE_SEPARATOR);
        }

        final PsiClassType[] references = method.getThrowsList().getReferencedTypes();
        for (PsiClassType reference : references) {
          builder.append(
              CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter));
          builder.append(reference.getClassName());
          builder.append(LINE_SEPARATOR);
        }
      } else if (owner instanceof GrTypeDefinition) {
        final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList();
        if (typeParameterList != null) {
          createTypeParamsListComment(builder, project, commenter, typeParameterList);
        }
      }
      return builder.length() > 0 ? builder.toString() : null;
    } finally {
      StringBuilderSpinAllocator.dispose(builder);
    }
  }
  private static boolean processPrimaryMethodInner(
      JavaChangeInfo changeInfo, GrMethod method, @Nullable PsiMethod baseMethod) {
    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());
      if (newName != null && !newName.equals(method.getName())) {
        method.setName(changeInfo.getNewName());
      }
    }

    final GrModifierList modifierList = method.getModifierList();
    if (changeInfo.isVisibilityChanged()) {
      modifierList.setModifierProperty(changeInfo.getNewVisibility(), true);
    }

    PsiSubstitutor substitutor =
        baseMethod != null ? calculateSubstitutor(method, baseMethod) : PsiSubstitutor.EMPTY;

    final PsiMethod context = changeInfo.getMethod();
    GrTypeElement oldReturnTypeElement = method.getReturnTypeElementGroovy();
    if (changeInfo.isReturnTypeChanged()) {
      CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType();
      if (newReturnType == null) {
        if (oldReturnTypeElement != null) {
          oldReturnTypeElement.delete();
          if (modifierList.getModifiers().length == 0) {
            modifierList.setModifierProperty(GrModifier.DEF, true);
          }
        }
      } else {
        PsiType type = newReturnType.getType(context, method.getManager());
        GrReferenceAdjuster.shortenAllReferencesIn(
            method.setReturnType(substitutor.substitute(type)));
        if (oldReturnTypeElement == null) {
          modifierList.setModifierProperty(GrModifier.DEF, false);
        }
      }
    }

    JavaParameterInfo[] newParameters = changeInfo.getNewParameters();
    final GrParameterList parameterList = method.getParameterList();
    GrParameter[] oldParameters = parameterList.getParameters();
    final PsiParameter[] oldBaseParams =
        baseMethod != null ? baseMethod.getParameterList().getParameters() : null;

    Set<GrParameter> toRemove = new HashSet<GrParameter>(oldParameters.length);
    ContainerUtil.addAll(toRemove, oldParameters);

    GrParameter anchor = null;
    final GrDocComment docComment = method.getDocComment();
    final GrDocTag[] tags = docComment == null ? null : docComment.getTags();

    for (JavaParameterInfo newParameter : newParameters) {
      // if old parameter name differs from base method parameter name we don't change it
      final String newName;
      final int oldIndex = newParameter.getOldIndex();
      if (oldIndex >= 0 && oldBaseParams != null) {
        final String oldName = oldParameters[oldIndex].getName();
        if (oldName.equals(oldBaseParams[oldIndex].getName())) {
          newName = newParameter.getName();
        } else {
          newName = oldName;
        }
      } else {
        newName = newParameter.getName();
      }

      final GrParameter oldParameter = oldIndex >= 0 ? oldParameters[oldIndex] : null;

      if (docComment != null && oldParameter != null) {
        final String oldName = oldParameter.getName();
        for (GrDocTag tag : tags) {
          if ("@param".equals(tag.getName())) {
            final GrDocParameterReference parameterReference = tag.getDocParameterReference();
            if (parameterReference != null && oldName.equals(parameterReference.getText())) {
              parameterReference.handleElementRename(newName);
            }
          }
        }
      }

      GrParameter grParameter =
          createNewParameter(substitutor, context, parameterList, newParameter, newName);
      if (oldParameter != null) {
        grParameter.getModifierList().replace(oldParameter.getModifierList());
      }

      if ("def".equals(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, true);
      } else if (StringUtil.isEmpty(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, false);
      }

      anchor = (GrParameter) parameterList.addAfter(grParameter, anchor);
    }

    for (GrParameter oldParameter : toRemove) {
      oldParameter.delete();
    }
    JavaCodeStyleManager.getInstance(parameterList.getProject())
        .shortenClassReferences(parameterList);
    CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList);

    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final ThrownExceptionInfo[] infos = changeInfo.getNewExceptions();
      PsiClassType[] exceptionTypes = new PsiClassType[infos.length];
      for (int i = 0; i < infos.length; i++) {
        ThrownExceptionInfo info = infos[i];
        exceptionTypes[i] = (PsiClassType) info.createType(method, method.getManager());
      }

      PsiReferenceList thrownList =
          GroovyPsiElementFactory.getInstance(method.getProject()).createThrownList(exceptionTypes);
      thrownList = (PsiReferenceList) method.getThrowsList().replace(thrownList);
      JavaCodeStyleManager.getInstance(thrownList.getProject()).shortenClassReferences(thrownList);
      CodeStyleManager.getInstance(method.getProject()).reformat(method.getThrowsList());
    }
    return true;
  }