private static void generateNameByString(
      Set<String> possibleNames,
      String value,
      NameValidator validator,
      boolean forStaticVariable,
      Project project) {
    if (!JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(value)) return;
    if (forStaticVariable) {
      StringBuilder buffer = new StringBuilder(value.length() + 10);
      char[] chars = new char[value.length()];
      value.getChars(0, value.length(), chars, 0);
      boolean wasLow = Character.isLowerCase(chars[0]);

      buffer.append(Character.toUpperCase(chars[0]));
      for (int i = 1; i < chars.length; i++) {
        if (Character.isUpperCase(chars[i])) {
          if (wasLow) {
            buffer.append('_');
            wasLow = false;
          }
        } else {
          wasLow = true;
        }

        buffer.append(Character.toUpperCase(chars[i]));
      }
      possibleNames.add(validator.validateName(buffer.toString(), true));
    } else {
      possibleNames.add(validator.validateName(value, true));
    }
  }
  private static void generateNamesForCollectionType(
      PsiType type, Set<String> possibleNames, NameValidator validator) {
    PsiType componentType = getCollectionComponentType(type, validator.getProject());
    if (!(type instanceof PsiClassType) || componentType == null) return;
    PsiClass clazz = ((PsiClassType) type).resolve();
    if (clazz == null) return;
    String collectionName = clazz.getName();
    assert collectionName != null;

    String componentName = cleanTypeName(componentType.getPresentableText());
    if (componentType instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType) componentType;
      PsiClass psiClass = classType.resolve();
      if (psiClass == null) return;
      componentName = psiClass.getName();
    }

    assert componentName != null;
    String candidateName = StringUtil.pluralize(GroovyNamesUtil.fromLowerLetter(componentName));
    generateCamelNames(possibleNames, validator, candidateName);

    ArrayList<String> camelizedName = GroovyNamesUtil.camelizeString(candidateName);
    candidateName = camelizedName.get(camelizedName.size() - 1);
    candidateName = collectionName.toLowerCase() + "Of" + fromUpperLetter(candidateName);
    possibleNames.add(validator.validateName(candidateName, true));
  }
 private static void generateNamesForExceptions(
     PsiType type, Set<String> possibleNames, NameValidator validator) {
   if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ERROR)) {
     possibleNames.add(validator.validateName("error", true));
   } else if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_EXCEPTION)) {
     possibleNames.add(validator.validateName("e", true));
   }
 }
 private static void generateCamelNames(
     Set<String> possibleNames, NameValidator validator, String typeName) {
   ArrayList<String> camelTokens = GroovyNamesUtil.camelizeString(typeName);
   Collections.reverse(camelTokens);
   if (!camelTokens.isEmpty()) {
     String possibleName = "";
     for (String camelToken : camelTokens) {
       possibleName = camelToken + fromUpperLetter(possibleName);
       String candidate = validator.validateName(possibleName, true);
       // todo generify
       if (candidate.equals("class")) {
         candidate = validator.validateName("clazz", true);
       }
       if (!possibleNames.contains(candidate) && GroovyNamesUtil.isIdentifier(candidate)) {
         possibleNames.add(candidate);
       }
     }
   }
 }
 private static void generateNameByExpr(
     GrExpression expr,
     Set<String> possibleNames,
     NameValidator validator,
     boolean forStaticVariable) {
   if (expr instanceof GrReferenceExpression
       && ((GrReferenceExpression) expr).getReferenceName() != null) {
     if (PsiUtil.isThisReference(expr)) {
       possibleNames.add(validator.validateName("thisInstance", true));
     }
     if (PsiUtil.isSuperReference(expr)) {
       possibleNames.add(validator.validateName("superInstance", true));
     }
     GrReferenceExpression refExpr = (GrReferenceExpression) expr;
     String name = refExpr.getReferenceName();
     if (name != null && name.toUpperCase().equals(name)) {
       possibleNames.add(validator.validateName(name.toLowerCase(), true));
     } else {
       generateCamelNames(possibleNames, validator, name);
     }
     if (expr.getText().equals(name)) {
       possibleNames.remove(name);
     }
   }
   if (expr instanceof GrMethodCallExpression) {
     generateNameByExpr(
         ((GrMethodCallExpression) expr).getInvokedExpression(),
         possibleNames,
         validator,
         forStaticVariable);
   }
   if (expr instanceof GrLiteral) {
     final Object value = ((GrLiteral) expr).getValue();
     if (value instanceof String) {
       generateNameByString(
           possibleNames, (String) value, validator, forStaticVariable, expr.getProject());
     }
   }
 }
 private static void generateByType(
     PsiType type, Set<String> possibleNames, NameValidator validator) {
   String typeName = type.getPresentableText();
   generateNamesForCollectionType(type, possibleNames, validator);
   generateNamesForArrayType(type, possibleNames, validator);
   generateNamesForExceptions(type, possibleNames, validator);
   typeName = cleanTypeName(typeName);
   if (typeName.equals("String")) {
     possibleNames.add(validator.validateName("s", true));
   }
   if (typeName.equals("Closure")) {
     possibleNames.add(validator.validateName("cl", true));
   }
   if (typeName.toUpperCase().equals(typeName)) {
     possibleNames.add(
         validator.validateName(
             GroovyNamesUtil.deleteNonLetterFromString(typeName.toLowerCase()), true));
   } else if (!typeName.equals(typeName.toLowerCase())) {
     generateCamelNames(possibleNames, validator, typeName);
     possibleNames.remove(typeName);
   }
 }
  public static String[] suggestVariableNames(
      @NotNull GrExpression expr, NameValidator validator, boolean forStaticVariable) {
    Set<String> possibleNames = new LinkedHashSet<String>();
    PsiType type = expr.getType();
    generateNameByExpr(expr, possibleNames, validator, forStaticVariable);
    if (type != null && !PsiType.VOID.equals(type)) {
      generateVariableNameByTypeInner(type, possibleNames, validator);
    }

    possibleNames.remove("");
    if (possibleNames.isEmpty()) {
      possibleNames.add(validator.validateName("var", true));
    }
    return ArrayUtil.toStringArray(possibleNames);
  }
 private static void generateVariableNameByTypeInner(
     PsiType type, Set<String> possibleNames, NameValidator validator) {
   String unboxed = PsiTypesUtil.unboxIfPossible(type.getCanonicalText());
   if (unboxed != null && !unboxed.equals(type.getCanonicalText())) {
     String name = generateNameForBuiltInType(unboxed);
     name = validator.validateName(name, true);
     if (GroovyNamesUtil.isIdentifier(name)) {
       possibleNames.add(name);
     }
   } else if (type instanceof PsiIntersectionType) {
     for (PsiType psiType : ((PsiIntersectionType) type).getConjuncts()) {
       generateByType(psiType, possibleNames, validator);
     }
   } else {
     generateByType(type, possibleNames, validator);
   }
 }
  private static void generateNamesForArrayType(
      PsiType type, Set<String> possibleNames, NameValidator validator) {
    int arrayDim = type.getArrayDimensions();
    if (arrayDim == 0) return;
    PsiType deepType = type.getDeepComponentType();
    String candidateName = cleanTypeName(deepType.getPresentableText());
    if (deepType instanceof PsiClassType) {
      PsiClass clazz = ((PsiClassType) deepType).resolve();
      if (clazz == null) return;
      candidateName = GroovyNamesUtil.fromLowerLetter(clazz.getName());
    }
    candidateName = StringUtil.pluralize(GroovyNamesUtil.fromLowerLetter(candidateName));
    generateCamelNames(possibleNames, validator, candidateName);

    ArrayList<String> camelizedName = GroovyNamesUtil.camelizeString(candidateName);
    candidateName = camelizedName.get(camelizedName.size() - 1);
    candidateName = "arrayOf" + fromUpperLetter(candidateName);
    possibleNames.add(validator.validateName(candidateName, true));
  }