private static void appendConstructorSignature(
     final StringBuilder builder, final DartComponent component, final DartClass dartClass) {
   if (component instanceof DartNamedConstructorDeclaration
       || component instanceof DartFactoryConstructorDeclaration) {
     builder.append("<b>").append(dartClass.getName()).append(".</b>");
   }
   appendFunctionSignature(builder, component, dartClass.getName());
 }
  private static void appendClassSignature(final StringBuilder builder, final DartClass dartClass) {
    if (dartClass.isEnum()) {
      builder.append("enum <b>").append(dartClass.getName()).append("</b>");
      return;
    }

    if (dartClass.isAbstract()) {
      builder.append("abstract ");
    }

    builder.append("class <b>").append(dartClass.getName()).append("</b>");
    appendTypeParams(builder, dartClass.getTypeParameters());

    final List<DartType> mixins = dartClass.getMixinsList();
    final DartType superClass = dartClass.getSuperClass();
    if (superClass != null) {
      builder.append(" extends ").append(StringUtil.escapeXml(superClass.getText()));
    }

    if (!mixins.isEmpty()) {
      builder.append(" with ");
      appendDartTypeList(builder, mixins);
    }

    final List<DartType> implementsList = dartClass.getImplementsList();
    if (!implementsList.isEmpty()) {
      builder.append(" implements ");
      appendDartTypeList(builder, implementsList);
    }
  }
  public static String generateDoc(final PsiElement element) {
    if (!(element instanceof DartComponent) && !(element.getParent() instanceof DartComponent)) {
      return null;
    }
    final DartComponent namedComponent =
        (DartComponent) (element instanceof DartComponent ? element : element.getParent());

    final String signatureHtml;
    {
      final StringBuilder builder = new StringBuilder();
      appendSignature(namedComponent, builder);
      signatureHtml = builder.toString();
    }

    final String containingLibraryName;
    final PsiFile file = element.getContainingFile();
    if (file != null) {
      containingLibraryName = DartResolveUtil.getLibraryName(file);
    } else {
      containingLibraryName = null;
    }

    final String containingClassDescription;
    final DartClass dartClass = PsiTreeUtil.getParentOfType(namedComponent, DartClass.class);
    if (dartClass != null) {
      final StringBuilder builder = new StringBuilder();
      builder.append(dartClass.getName());
      appendTypeParams(builder, dartClass.getTypeParameters());
      containingClassDescription = builder.toString();
    } else {
      containingClassDescription = null;
    }

    final String docText = getDocumentationText(namedComponent);
    return generateDoc(
        signatureHtml,
        true,
        docText,
        containingLibraryName,
        containingClassDescription,
        null,
        null);
  }
  public static Collection<String> getSuggestedNames(
      final DartExpression expression, @Nullable Collection<String> additionalUsedNames) {
    Collection<String> candidates = new LinkedHashSet<String>();

    String text = expression.getText();
    if (expression instanceof DartReference) {
      DartClass dartClass = ((DartReference) expression).resolveDartClass().getDartClass();
      String dartClassName = dartClass == null ? null : dartClass.getName();
      if (dartClassName != null && !dartClassName.equals(StringUtil.decapitalize(dartClassName))) {
        candidates.add(StringUtil.decapitalize(dartClassName));
      }
    }

    if (expression instanceof DartCallExpression) {
      final DartExpression callee = ((DartCallExpression) expression).getExpression();
      text = callee.getText();
    }

    if (text != null) {
      candidates.addAll(generateNames(text));
    }

    final Set<String> usedNames = DartRefactoringUtil.collectUsedNames(expression);
    if (additionalUsedNames != null && !additionalUsedNames.isEmpty()) {
      usedNames.addAll(additionalUsedNames);
    }
    final Collection<String> result = new ArrayList<String>();

    for (String candidate : candidates) {
      int index = 0;
      String suffix = "";
      while (usedNames.contains(candidate + suffix)) {
        suffix = Integer.toString(++index);
      }
      result.add(candidate + suffix);
    }

    if (result.isEmpty()) {
      result.add("o"); // never empty
    }

    return result;
  }