/**
   * Adds the necessary imports for an AST node to the specified compilation unit.
   *
   * @param rewrite the compilation unit rewrite whose compilation unit's imports should be updated
   * @param node the AST node specifying the element for which imports should be added
   * @param typeImports the map of name nodes to strings (element type: Map <Name, String>).
   * @param staticImports the map of name nodes to strings (element type: Map <Name, String>).
   * @param excludeBindings the set of bindings to exclude (element type: Set <IBinding>).
   * @param declarations <code>true</code> if method declarations are treated as abstract, <code>
   *     false</code> otherwise
   */
  public static void addImports(
      final CompilationUnitRewrite rewrite,
      final ASTNode node,
      final Map typeImports,
      final Map staticImports,
      final Collection excludeBindings,
      final boolean declarations) {
    Assert.isNotNull(rewrite);
    Assert.isNotNull(node);
    Assert.isNotNull(typeImports);
    Assert.isNotNull(staticImports);
    final Set types = new HashSet();
    final Set members = new HashSet();
    final ImportReferencesCollector collector =
        new ImportReferencesCollector(
            rewrite.getCu().getJavaScriptProject(), null, types, members) {

          public final boolean visit(final Block block) {
            Assert.isNotNull(block);
            if (declarations && block.getParent() instanceof FunctionDeclaration) return false;
            return super.visit(block);
          }
        };
    node.accept(collector);
    final ImportRewrite rewriter = rewrite.getImportRewrite();
    final ImportRemover remover = rewrite.getImportRemover();
    Name name = null;
    IBinding binding = null;
    for (final Iterator iterator = types.iterator(); iterator.hasNext(); ) {
      name = (Name) iterator.next();
      binding = name.resolveBinding();
      if (binding instanceof ITypeBinding) {
        final ITypeBinding type = (ITypeBinding) binding;
        if (excludeBindings == null || !excludeBindings.contains(type)) {
          typeImports.put(name, rewriter.addImport(type));
          remover.registerAddedImport(type.getQualifiedName());
        }
      }
    }
    for (final Iterator iterator = members.iterator(); iterator.hasNext(); ) {
      name = (Name) iterator.next();
      binding = name.resolveBinding();
      if (binding instanceof IVariableBinding) {
        final IVariableBinding variable = (IVariableBinding) binding;
        final ITypeBinding declaring = variable.getDeclaringClass();
        if (declaring != null && (excludeBindings == null || !excludeBindings.contains(variable))) {
          staticImports.put(name, rewriter.addStaticImport(variable));
          remover.registerAddedStaticImport(declaring.getQualifiedName(), variable.getName(), true);
        }
      } else if (binding instanceof IFunctionBinding) {
        final IFunctionBinding method = (IFunctionBinding) binding;
        final ITypeBinding declaring = method.getDeclaringClass();
        if (declaring != null && (excludeBindings == null || !excludeBindings.contains(method))) {
          staticImports.put(name, rewriter.addStaticImport(method));
          remover.registerAddedStaticImport(declaring.getQualifiedName(), method.getName(), false);
        }
      }
    }
  }
 public boolean visit(TypeDeclaration node) {
   if (fBinding.getKind() == IBinding.METHOD) {
     IFunctionBinding binding = (IFunctionBinding) fBinding;
     if (binding.isConstructor() && binding.getDeclaringClass() == node.resolveBinding()) {
       fResult.add(node.getName());
     }
   }
   return true;
 }
    public boolean visit(SimpleName node) {
      IBinding binding = node.resolveBinding();
      if (binding == null || binding.getKind() != fBinding.getKind()) {
        return false;
      }
      binding = getDeclaration(binding);

      if (fBinding == binding) {
        fResult.add(node);
      } else if (binding.getKind() == IBinding.METHOD) {
        IFunctionBinding curr = (IFunctionBinding) binding;
        IFunctionBinding methodBinding = (IFunctionBinding) fBinding;
        if (methodBinding.overrides(curr) || curr.overrides(methodBinding)) {
          fResult.add(node);
        }
      }
      return false;
    }