public String initialize(JavaScriptUnit root, ASTNode node) {
   fAST = root.getAST();
   if (!(node instanceof Name)) {
     return SearchMessages.ExceptionOccurrencesFinder_no_exception;
   }
   fSelectedName = ASTNodes.getTopMostName((Name) node);
   ASTNode parent = fSelectedName.getParent();
   FunctionDeclaration decl = resolveMethodDeclaration(parent);
   if (decl != null && methodThrowsException(decl, fSelectedName)) {
     fException = fSelectedName.resolveTypeBinding();
     fStart = decl.getBody();
   } else if (parent instanceof Type) {
     parent = parent.getParent();
     if (parent instanceof SingleVariableDeclaration
         && parent.getParent() instanceof CatchClause) {
       CatchClause catchClause = (CatchClause) parent.getParent();
       TryStatement tryStatement = (TryStatement) catchClause.getParent();
       if (tryStatement != null) {
         IVariableBinding var = catchClause.getException().resolveBinding();
         if (var != null && var.getType() != null) {
           fException = var.getType();
           fStart = tryStatement.getBody();
         }
       }
     }
   }
   if (fException == null || fStart == null)
     return SearchMessages.ExceptionOccurrencesFinder_no_exception;
   return null;
 }
  /**
   * 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);
        }
      }
    }
  }
 /*
  * @see ASTVisitor#visit(FunctionDeclaration)
  */
 public boolean visit(FunctionDeclaration node) {
   if (node.getJavadoc() != null) {
     node.getJavadoc().accept(this);
   }
   if (node.getAST().apiLevel() == AST.JLS2) {
     printModifiers(node.getModifiers());
   }
   if (node.getAST().apiLevel() >= AST.JLS3) {
     printModifiers(node.modifiers());
   }
   //		if (!node.isConstructor()) {
   //			if (node.getAST().apiLevel() == AST.JLS2) {
   //				node.getReturnType().accept(this);
   //			} else {
   //				if (node.getReturnType2() != null) {
   //					node.getReturnType2().accept(this);
   //				} else {
   //					// methods really ought to have a return type
   //					this.fBuffer.append("void");//$NON-NLS-1$
   //				}
   //			}
   //			this.fBuffer.append(" ");//$NON-NLS-1$
   //		}
   if (node.getName() != null) node.getName().accept(this);
   this.fBuffer.append("("); // $NON-NLS-1$
   for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
     SingleVariableDeclaration v = (SingleVariableDeclaration) it.next();
     v.accept(this);
     if (it.hasNext()) {
       this.fBuffer.append(","); // $NON-NLS-1$
     }
   }
   this.fBuffer.append(")"); // $NON-NLS-1$
   for (int i = 0; i < node.getExtraDimensions(); i++) {
     this.fBuffer.append("[]"); // $NON-NLS-1$
   }
   if (!node.thrownExceptions().isEmpty()) {
     this.fBuffer.append(" throws "); // $NON-NLS-1$
     for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) {
       Name n = (Name) it.next();
       n.accept(this);
       if (it.hasNext()) {
         this.fBuffer.append(", "); // $NON-NLS-1$
       }
     }
     this.fBuffer.append(" "); // $NON-NLS-1$
   }
   if (node.getBody() == null) {
     this.fBuffer.append(";"); // $NON-NLS-1$
   } else {
     node.getBody().accept(this);
   }
   return false;
 }
 private boolean methodThrowsException(FunctionDeclaration method, Name exception) {
   ASTMatcher matcher = new ASTMatcher();
   for (Iterator iter = method.thrownExceptions().iterator(); iter.hasNext(); ) {
     Name thrown = (Name) iter.next();
     if (exception.subtreeMatch(matcher, thrown)) return true;
   }
   return false;
 }
  /**
   * Collects the necessary imports for an element represented by the specified AST node.
   *
   * @param project the java project containing the element
   * @param node the AST node specifying the element for which imports should be collected
   * @param typeBindings the set of type bindings (element type: Set <ITypeBinding>).
   * @param staticBindings the set of bindings (element type: Set <IBinding>).
   * @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 collectImports(
      final IJavaScriptProject project,
      final ASTNode node,
      final Collection typeBindings,
      final Collection staticBindings,
      final Collection excludeBindings,
      final boolean declarations) {
    Assert.isNotNull(project);
    Assert.isNotNull(node);
    Assert.isNotNull(typeBindings);
    Assert.isNotNull(staticBindings);
    final Set types = new HashSet();
    final Set members = new HashSet();
    final ImportReferencesCollector collector =
        new ImportReferencesCollector(project, 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);
    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)) typeBindings.add(type);
      }
    }
    for (final Iterator iterator = members.iterator(); iterator.hasNext(); ) {
      name = (Name) iterator.next();
      binding = name.resolveBinding();
      if (binding != null && (excludeBindings == null || !excludeBindings.contains(binding)))
        staticBindings.add(binding);
    }
  }