private static void generateTraitType(
     @NotNull StringBuilder buffer, @NotNull GrTraitType type, PsiElement context) {
   appendTypeString(buffer, type.getExprType(), context);
   buffer.append(" as ");
   for (PsiType traitType : type.getTraitTypes()) {
     appendTypeString(buffer, traitType, context);
     buffer.append(", ");
   }
   buffer.delete(buffer.length() - 2, buffer.length());
 }
  @NotNull
  @Override
  public PsiTypeParameter createTypeParameter(String name, PsiClassType[] superTypes) {
    @NonNls StringBuilder builder = new StringBuilder();
    builder.append("public <").append(name);
    if (superTypes.length > 1
        || superTypes.length == 1
            && !superTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
      builder.append(" extends ");
      for (PsiClassType type : superTypes) {
        if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) continue;
        builder.append(type.getCanonicalText()).append('&');
      }

      builder.delete(builder.length() - 1, builder.length());
    }
    builder.append("> void foo(){}");
    try {
      return createMethodFromText(builder.toString(), null).getTypeParameters()[0];
    } catch (RuntimeException e) {
      throw new IncorrectOperationException("type parameter text: " + builder.toString());
    }
  }
  @Override
  @Nullable
  public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
    if (element instanceof GrVariable || element instanceof GrImplicitVariable) {
      StringBuilder buffer = new StringBuilder();
      PsiVariable variable = (PsiVariable) element;

      if (originalElement instanceof GrVariableDeclaration
          && ((GrVariableDeclaration) originalElement).getVariables().length > 1) {
        for (GrVariable var : ((GrVariableDeclaration) originalElement).getVariables()) {
          generateVariableInfo(originalElement, buffer, var);
          buffer.append("\n\n");
        }
      } else {
        generateVariableInfo(originalElement, buffer, variable);
      }
      return buffer.toString();
    } else if (element instanceof PsiMethod) {
      StringBuilder buffer = new StringBuilder();
      PsiMethod method = (PsiMethod) element;
      if (method instanceof GrGdkMethod) {
        buffer.append("[GDK] ");
      } else {
        PsiClass hisClass = method.getContainingClass();
        if (hisClass != null) {
          String qName = hisClass.getQualifiedName();
          if (qName != null) {
            buffer.append(qName).append("\n");
          }
        }
      }

      PsiSubstitutor substitutor = calcSubstitutor(originalElement);
      if (!method.isConstructor()) {
        final PsiType substituted = substitutor.substitute(PsiUtil.getSmartReturnType(method));
        PsiImplUtil.appendTypeString(buffer, substituted, originalElement);
        buffer.append(" ");
      }
      buffer.append(method.getName()).append(" ");
      buffer.append("(");
      PsiParameter[] parameters = method.getParameterList().getParameters();
      for (int i = 0; i < parameters.length; i++) {
        PsiParameter parameter = parameters[i];
        if (i > 0) buffer.append(", ");
        if (parameter instanceof GrParameter) {
          GroovyPresentationUtil.appendParameterPresentation(
              (GrParameter) parameter, substitutor, TypePresentation.LINK, buffer);
        } else {
          PsiType type = parameter.getType();
          PsiImplUtil.appendTypeString(buffer, substitutor.substitute(type), originalElement);
          buffer.append(" ");
          buffer.append(parameter.getName());
        }
      }
      buffer.append(")");
      final PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes();
      if (referencedTypes.length > 0) {
        buffer.append("\nthrows ");
        for (PsiClassType referencedType : referencedTypes) {
          PsiImplUtil.appendTypeString(buffer, referencedType, originalElement);
          buffer.append(", ");
        }
        buffer.delete(buffer.length() - 2, buffer.length());
      }
      return buffer.toString();
    } else if (element instanceof GrTypeDefinition) {
      return generateClassInfo((GrTypeDefinition) element);
    }

    return null;
  }