public static List<? extends PsiElement> resolveSimpleReference(
      PsiElement scopeElement, String name) {
    final List<DartComponentName> result = new ArrayList<DartComponentName>();
    // local
    final ResolveScopeProcessor resolveScopeProcessor =
        new ResolveScopeProcessor(result, name, DartResolveUtil.isLValue(scopeElement));
    PsiTreeUtil.treeWalkUp(resolveScopeProcessor, scopeElement, null, new ResolveState());
    // supers
    final DartClass dartClass = PsiTreeUtil.getParentOfType(scopeElement, DartClass.class);
    final boolean inClass =
        PsiTreeUtil.getParentOfType(scopeElement, DartClassBody.class, false) != null;
    if (result.isEmpty() && dartClass != null && inClass) {
      final DartComponent field = filterAccess(scopeElement, dartClass.findMembersByName(name));
      if (field != null) {
        return toResult(field.getComponentName());
      }
    }
    // global
    if (result.isEmpty()) {
      final List<VirtualFile> libraryFiles =
          DartResolveUtil.findLibrary(scopeElement.getContainingFile());
      DartResolveUtil.processTopLevelDeclarations(
          scopeElement, resolveScopeProcessor, libraryFiles, name);
    }
    // dart:core
    if (result.isEmpty() && !"void".equals(name)) {
      final List<VirtualFile> libraryFiles =
          DartLibraryIndex.findLibraryClass(scopeElement, "dart:core");
      DartResolveUtil.processTopLevelDeclarations(
          scopeElement, resolveScopeProcessor, libraryFiles, name);
    }

    return result;
  }
 private static List<? extends PsiElement> resolveSimpleReference(
     @NotNull DartReference reference) {
   final List<? extends PsiElement> result =
       resolveSimpleReference(reference, reference.getCanonicalText());
   final PsiElement parent = reference.getParent();
   final PsiElement superParent = parent.getParent();
   final boolean isSimpleConstructor =
       parent instanceof DartType
           && superParent instanceof DartNewExpression
           && ((DartNewExpression) superParent).getReferenceExpression() == null;
   if (!isSimpleConstructor || result.isEmpty()) {
     return result;
   }
   final List<PsiElement> filteredResult = new ArrayList<PsiElement>(result.size());
   for (PsiElement element : result) {
     final PsiElement elementParent = element.getParent();
     if (element instanceof DartComponentName && elementParent instanceof DartClass) {
       final DartComponent component =
           ((DartClass) elementParent).findNamedConstructor(reference.getCanonicalText());
       if (component != null
           && DartComponentType.typeOf(component) == DartComponentType.CONSTRUCTOR) {
         filteredResult.add(component.getComponentName());
         continue;
       }
     }
     filteredResult.add(element);
   }
   return filteredResult;
 }
 private static void appendSignature(
     final DartComponent namedComponent, final StringBuilder builder) {
   if (namedComponent instanceof DartClass) {
     appendClassSignature(builder, (DartClass) namedComponent);
   } else if (namedComponent instanceof DartFunctionDeclarationWithBodyOrNative) {
     appendFunctionSignature(
         builder,
         namedComponent,
         ((DartFunctionDeclarationWithBodyOrNative) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartFunctionTypeAlias) {
     builder.append("typedef ");
     appendFunctionSignature(
         builder, namedComponent, ((DartFunctionTypeAlias) namedComponent).getReturnType());
   } else if (namedComponent.isConstructor()) {
     appendConstructorSignature(
         builder, namedComponent, PsiTreeUtil.getParentOfType(namedComponent, DartClass.class));
   } else if (namedComponent instanceof DartMethodDeclaration) {
     appendFunctionSignature(
         builder, namedComponent, ((DartMethodDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartVarAccessDeclaration) {
     appendVariableSignature(
         builder, namedComponent, ((DartVarAccessDeclaration) namedComponent).getType());
   } else if (namedComponent instanceof DartGetterDeclaration) {
     builder.append("get ");
     appendFunctionSignature(
         builder, namedComponent, ((DartGetterDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartSetterDeclaration) {
     builder.append("set ");
     appendFunctionSignature(
         builder, namedComponent, ((DartSetterDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartEnumConstantDeclaration) {
     builder.append(((DartEnumDefinition) namedComponent.getParent()).getName()).append(" ");
     builder.append("<b>").append(namedComponent.getName()).append("</b>");
   }
 }
  @Nullable
  @Override
  public List<? extends PsiElement> resolve(
      @NotNull DartReference reference, boolean incompleteCode) {
    if (reference instanceof DartThisExpression) {
      return toResult(PsiTreeUtil.getParentOfType(reference, DartClass.class));
    }
    if (reference instanceof DartParameterNameReferenceExpression) {
      final DartCallExpression callExpression =
          PsiTreeUtil.getParentOfType(reference, DartCallExpression.class);
      final DartExpression expression =
          callExpression != null ? callExpression.getExpression() : null;
      final PsiElement target =
          expression instanceof DartReference ? ((DartReference) expression).resolve() : null;
      final DartFormalParameterList parameters =
          PsiTreeUtil.getChildOfType(
              target != null ? target.getParent() : null, DartFormalParameterList.class);
      return toResult(DartResolveUtil.findParameterByName(parameters, reference.getText()));
    }
    if (DartResolveUtil.aloneOrFirstInChain(reference)) {
      return resolveSimpleReference(reference);
    }
    final DartReference leftReference = DartResolveUtil.getLeftReference(reference);
    // reference [node, node]
    final DartReference[] references =
        PsiTreeUtil.getChildrenOfType(reference, DartReference.class);
    if (references != null && references.length == 2) {
      // prefix
      final List<DartComponentName> names =
          DartResolveUtil.findComponentsInLibraryByPrefix(
              reference, references[0].getCanonicalText(), references[1].getCanonicalText());
      if (!names.isEmpty()) {
        return toResult(names);
      }
      return toResult(references[1].resolve());
    } else if (leftReference != null) {
      final DartClassResolveResult classResolveResult = leftReference.resolveDartClass();
      final DartClass dartClass = classResolveResult.getDartClass();
      if (dartClass != null) {
        final String name = reference.getCanonicalText();
        final DartComponent subComponent =
            leftReference instanceof DartType
                ? dartClass.findNamedConstructor(name)
                : filterAccess(reference, dartClass.findMembersByName(name));
        return toResult(subComponent == null ? null : subComponent.getComponentName());
      }
      // prefix
      final List<DartComponentName> names =
          DartResolveUtil.findComponentsInLibraryByPrefix(
              reference, leftReference.getCanonicalText(), reference.getCanonicalText());
      if (!names.isEmpty()) {
        return toResult(names);
      }
    }

    return null;
  }
 private static void appendFunctionSignature(
     final StringBuilder builder, final DartComponent function, final String returnType) {
   builder.append("<b>").append(function.getName()).append("</b>");
   if (!function.isGetter()) {
     builder.append('(');
     builder.append(
         StringUtil.escapeXml(
             DartPresentableUtil.getPresentableParameterList(
                 function, new DartGenericSpecialization(), true, true)));
     builder.append(')');
   }
   builder.append(' ');
   builder.append(DartPresentableUtil.RIGHT_ARROW);
   builder.append(' ');
   builder.append(returnType);
 }
 private static void appendVariableSignature(
     final StringBuilder builder, final DartComponent component, final DartType type) {
   if (type == null) {
     builder.append("var ");
   } else {
     builder.append(type.getReferenceExpression().getText());
     appendTypeArguments(builder, type);
     builder.append(" ");
   }
   builder.append("<b>").append(component.getName()).append("</b>");
 }
  @Nullable
  private static String getDocumentationText(final DartComponent dartComponent) {
    // PSI is not perfect currently, doc comment may be not part of the corresponding DartComponent
    // element, so docs are searched for in several places:
    // - direct child of this DartComponent
    // - previous sibling (or previous sibling of parent element if this element is first child of
    // its parent DartClassMembers)
    // Consequent line doc comments (///) are joined

    // 1. Look for multiline doc comment as direct child
    final DartDocComment multilineComment =
        PsiTreeUtil.getChildOfType(dartComponent, DartDocComment.class);
    if (multilineComment != null) return getMultilineDocCommentText(multilineComment);

    // 2. Look for single line doc comments as direct children
    final PsiComment[] childComments =
        PsiTreeUtil.getChildrenOfType(dartComponent, PsiComment.class);
    if (childComments != null) {
      //
      final String docText = getSingleLineDocCommentsText(childComments);
      if (docText != null) return docText;
    }

    PsiElement anchorElement = dartComponent;

    final PsiElement parent = dartComponent.getParent();
    if (parent instanceof DartClassMembers && parent.getFirstChild() == dartComponent
        || dartComponent instanceof DartVarAccessDeclaration) {
      anchorElement = parent;
    }

    // 3. Look for multiline doc comment or line doc comments as previous siblings
    final List<PsiComment> siblingComments = new ArrayList<PsiComment>();
    PsiElement previous = anchorElement;
    while ((previous = UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpaces(previous, true))
        instanceof PsiComment) {
      if (previous instanceof DartDocComment) {
        return getMultilineDocCommentText((DartDocComment) previous);
      }
      siblingComments.add(0, (PsiComment) previous);
    }

    if (!siblingComments.isEmpty()) {
      return getSingleLineDocCommentsText(
          siblingComments.toArray(new PsiComment[siblingComments.size()]));
    }

    return null;
  }