[84391] Fixes to API Scanner from Jeffrey Liu.
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/TestMain.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/TestMain.java
index 8a94b1d..2538aab 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/TestMain.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/TestMain.java
@@ -12,6 +12,8 @@
 package org.eclipse.wtp.releng.tools.component;
 
 import java.io.IOException;
+import org.eclipse.wtp.releng.tools.component.api.APITestCoverageEmitter;
+import org.eclipse.wtp.releng.tools.component.api.ComponentAPIEmitter;
 import org.eclipse.wtp.releng.tools.component.model.ComponentEmitter;
 import org.eclipse.wtp.releng.tools.component.violation.ComponentViolationEmitter;
 
@@ -61,6 +63,8 @@
     {
       "-eclipseDir",
       eclipseDir,
+      "-testDir",
+      compAPIDir,
       "-compXMLDir",
       compXMLDir + "wtp-components/",
       "-compRefDir",
@@ -83,7 +87,8 @@
       "-genUsage",
       "-debug"
     };
-    ComponentViolationEmitter.main(compViolationEmitterArgs);
+    APITestCoverageEmitter.main(compViolationEmitterArgs);
+    //ComponentViolationEmitter.main(compViolationEmitterArgs);
   }
 
   public static void radMain(String[] args) throws IOException
@@ -122,6 +127,8 @@
       "D:/rad_v600/rwdrpt_shared/",
       "D:/rad_v600/sdpisv/",
       "D:/rad_v600/updater/",
+      "-testDir",
+      compAPIDir,
       "-compXMLDir",
       compXMLDir,
       "-compAPIDir",
@@ -143,7 +150,8 @@
       "-genAPI",
       "-genUsage",
       "-debug",
-    };                                         
+    };
+    //APITestCoverageEmitter.main(compViolationEmitterArgs);
     ComponentViolationEmitter.main(compViolationEmitterArgs);
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/APITestCoverageEmitter.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/APITestCoverageEmitter.java
new file mode 100644
index 0000000..b2daffc
--- /dev/null
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/APITestCoverageEmitter.java
@@ -0,0 +1,314 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.wtp.releng.tools.component.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.wtp.releng.tools.component.internal.AbstractEmitter;
+import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
+import org.eclipse.wtp.releng.tools.component.use.ComponentUse;
+import org.eclipse.wtp.releng.tools.component.use.ComponentUseEmitter;
+import org.eclipse.wtp.releng.tools.component.util.CommandOptionParser;
+
+public class APITestCoverageEmitter extends AbstractEmitter
+{
+  public static final String CONST_COMPONENT_API_TEST_COVERAGE_XML = "component-api-tc.xml";
+  public static final String CONST_COMPONENT_API_TEST_COVERAGE_HTML = "component-api-tc.html";
+  public static final String OPTION_ECLIPSE_DIR = "eclipseDir";
+  public static final String OPTION_TEST_DIR = "testDir";
+  public static final String OPTION_COMPONENT_XML_DIR = "compXMLDir";
+  public static final String OPTION_COMPONENT_API_DIR = "compAPIDir";  
+  public static final String OPTION_GEN_HTML = "genHTML";
+  public static final String OPTION_GEN_API = "genAPI";
+  public static final String OPTION_DEBUG = "debug";
+
+  private String compAPIDir;
+  private Map id2Plugin;
+  private Map id2Fragment;
+  private Map id2TestPlugin;
+  private Map id2TestFragment;
+  private Map compLoc2CompXML;
+  private boolean genHTML;
+  private boolean genAPI;
+  private boolean debug;
+  private ComponentAPIEmitter compAPIEmitter;
+  private ComponentUseEmitter compUseEmitter;
+
+  public APITestCoverageEmitter(String compAPIDir)
+  {
+    this.compAPIDir = addTrailingSeperator(compAPIDir);
+    genHTML = false;
+    genAPI = false;
+    debug = false;
+  }
+
+  public void init(List eclipseDirs, List testDirs, List compXMLDirs)
+  {
+    id2Plugin = new HashMap();
+    id2Fragment = new HashMap();
+    for (Iterator it = eclipseDirs.iterator(); it.hasNext();)
+    {
+      File eclipseFile = new File(addTrailingSeperator((String)it.next()));
+      if (eclipseFile.exists())
+        harvestPlugins(eclipseFile, id2Plugin, id2Fragment);
+    }
+    linkPluginsAndFragments(id2Plugin, id2Fragment);
+    id2TestPlugin = new HashMap();
+    id2TestFragment = new HashMap();
+    for (Iterator it = testDirs.iterator(); it.hasNext();)
+    {
+      File testFile = new File(addTrailingSeperator((String)it.next()));
+      if (testFile.exists())
+        harvestPlugins(testFile, id2TestPlugin, id2TestFragment);
+    }
+    linkPluginsAndFragments(id2TestPlugin, id2TestFragment);
+    compLoc2CompXML = new HashMap();
+    for (Iterator it = compXMLDirs.iterator(); it.hasNext();)
+    {
+      File compXMLFile = new File(addTrailingSeperator((String)it.next()));
+      if (compXMLFile.exists())
+        harvestComponents(compXMLFile, compLoc2CompXML);
+    }
+    init();
+  }
+
+  public void init(Map compLoc2CompXML, Map id2Plugin, Map id2Fragment, Map id2TestPlugin, Map id2TestFragment)
+  {
+    this.compLoc2CompXML = compLoc2CompXML;
+    this.id2Plugin = id2Plugin;
+    this.id2Fragment = id2Fragment;
+    this.id2TestPlugin = id2TestPlugin;
+    this.id2TestFragment = id2TestFragment;
+    init();
+  }
+
+  private void init()
+  {
+    compAPIEmitter = new ComponentAPIEmitter(genAPI ? compAPIDir : null);
+    compAPIEmitter.init(compLoc2CompXML, id2Plugin, id2Fragment);
+    compUseEmitter = new ComponentUseEmitter(null);
+    compUseEmitter.setDebug(true);
+    compUseEmitter.init(compLoc2CompXML, id2Plugin, id2Fragment);
+  }
+
+  /**
+   * @return Returns the genHTML.
+   */
+  public boolean isGenHTML()
+  {
+    return genHTML;
+  }
+
+  /**
+   * @param genHTML The genHTML to set.
+   */
+  public void setGenHTML(boolean genHTML)
+  {
+    this.genHTML = genHTML;
+  }
+
+  public boolean getGenAPI()
+  {
+    return genAPI;
+  }
+
+  public void setGenAPI(boolean genAPI)
+  {
+    this.genAPI = genAPI;
+  }
+
+  /**
+   * @return Returns the debug.
+   */
+  public boolean isDebug()
+  {
+    return debug;
+  }
+
+  /**
+   * @param debug The debug to set.
+   */
+  public void setDebug(boolean debug)
+  {
+    this.debug = debug;
+  }
+
+  public void genAPITestCoverageXML() throws IOException
+  {
+    for (Iterator it = compLoc2CompXML.keySet().iterator(); it.hasNext();)
+      genAPITestCoverageXML((String)it.next());
+    /*
+    ComponentViolationSummary summary = new ComponentViolationSummary();
+    for (Iterator it = compLoc2CompXML.keySet().iterator(); it.hasNext();)
+      summary.add(genComponentViolationXML((String)it.next()));
+    if (compViolationDir != null)
+    {
+      summary.save(new FileLocation(new File(compViolationDir + "index.xml")));
+      if (genHTML)
+      {
+        try
+        {
+          summary.saveAsHTML(new FileLocation(new File(compViolationDir + "index.html")));
+        }
+        catch (TransformerConfigurationException e)
+        {
+          e.printStackTrace();
+        }
+        catch (TransformerException e)
+        {
+          e.printStackTrace();
+        }
+      }
+    }
+    */
+  }
+
+  public ComponentUse genAPITestCoverageXML(String compLoc) throws IOException
+  {
+    ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
+    if (componentXML != null)
+    {
+      componentXML.load();
+      ComponentAPI compAPI = compAPIEmitter.genComponentApiXml(compLoc);
+      compAPI.save();
+      List pkgAPIs = compAPI.getExternalAPIs().getPackageAPIs();
+      List pkgNames = new ArrayList(pkgAPIs.size());
+      for (Iterator it = pkgAPIs.iterator(); it.hasNext();)
+        pkgNames.add(((PackageAPI)it.next()).getName());
+      compUseEmitter.setClassUseIncludes(pkgNames);
+    }
+    return null;
+    /*
+    ComponentUse compUse = null;
+    ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
+    if (componentXML != null)
+    {
+      componentXML.load();
+      compUse = compUseEmitter.genComponentUseXML(compLoc);
+      compUse.save();
+      for (Iterator pluginsIt = componentXML.getPlugins().iterator(); pluginsIt.hasNext();)
+      {
+        IPluginXML pluginXML = (IPluginXML)pluginId2Plugin.get(((Plugin)pluginsIt.next()).getId());
+        if (pluginXML != null)
+          validateComponentUse(pluginXML, compUse);
+      }
+      ComponentDepends depends = componentXML.getComponentDepends();
+      boolean unrestricted = depends.isUnrestricted();
+      List dependNames = null;
+      if (!unrestricted)
+      {
+        dependNames = new ArrayList();
+        List compRefs = depends.getComponentRefs();
+        for (Iterator it = compRefs.iterator(); it.hasNext();)
+          dependNames.add(((ComponentRef)it.next()).getName());
+      }
+      for (Iterator it = compLoc2CompXML.values().iterator(); it.hasNext() && compUse.getSources().size() > 0;)
+      {
+        ComponentXML compXML = (ComponentXML)it.next();
+        if (unrestricted || dependNames.contains(compXML.getName()))
+        {
+          compXML.load();
+          validateComponentUse(compXML, compUse);
+        }
+      }
+      for (Iterator it = compLoc2CompRef.values().iterator(); it.hasNext() && compUse.getSources().size() > 0;)
+      {
+        ComponentXML compXML = (ComponentXML)it.next();
+        if (unrestricted || dependNames.contains(compXML.getName()))
+        {
+          compXML.load();
+          validateComponentUse(compXML, compUse);
+        }
+      }
+      if (compViolationDir != null)
+      {
+        String compName = compUse.getName();
+        System.out.println("Writing component-violation.xml for " + compName);
+        StringBuffer sb = new StringBuffer(compViolationDir);
+        sb.append(compName);
+        sb.append('/');
+        compUse.setLocation(new FileLocation(new File(sb.toString() + CONST_COMPONENT_VIOLATION_XML)));
+        compUse.save();
+        if (genHTML)
+        {
+          try
+          {
+            ILocation html = new FileLocation(new File(sb.toString() + CONST_COMPONENT_VIOLATION_HTML));
+            compUse.setLocation(html);
+            compUse.saveAsHTML(html);
+          }
+          catch (TransformerConfigurationException e)
+          {
+            e.printStackTrace();
+          }
+          catch (TransformerException e)
+          {
+            e.printStackTrace();
+          }
+        }
+      }
+    }
+    return compUse;
+    */
+  }
+
+  public static void main(String[] args)
+  {
+    CommandOptionParser optionParser = new CommandOptionParser(args);
+    Map options = optionParser.getOptions();
+    List eclipseDir = (List)options.get(APITestCoverageEmitter.OPTION_ECLIPSE_DIR);
+    List testDir = (List)options.get(APITestCoverageEmitter.OPTION_TEST_DIR);
+    List compXMLDir = (List)options.get(APITestCoverageEmitter.OPTION_COMPONENT_XML_DIR);
+    List compAPIDir = (List)options.get(APITestCoverageEmitter.OPTION_COMPONENT_API_DIR);
+    List genHTML = (List)options.get(APITestCoverageEmitter.OPTION_GEN_HTML);
+    List genAPI = (List)options.get(APITestCoverageEmitter.OPTION_GEN_API);
+    List debug = (List)options.get(APITestCoverageEmitter.OPTION_DEBUG);
+    if (eclipseDir == null || testDir == null || compXMLDir == null || compAPIDir == null || eclipseDir.size() < 1 || testDir.size() < 1 || compXMLDir.size() < 1 || compAPIDir.size() < 1)
+    {
+      printUsage();
+      System.exit(-1);
+    }
+    APITestCoverageEmitter apiTestCoverageEmitter = new APITestCoverageEmitter((String)compAPIDir.get(0));
+    apiTestCoverageEmitter.setGenHTML(genHTML != null);
+    apiTestCoverageEmitter.setGenAPI(genAPI != null);
+    apiTestCoverageEmitter.setDebug(debug != null);
+    apiTestCoverageEmitter.init(eclipseDir, testDir, compXMLDir);
+    try
+    {
+      apiTestCoverageEmitter.genAPITestCoverageXML();
+    }
+    catch (IOException ioe)
+    {
+      ioe.printStackTrace();
+    }
+  }
+
+  private static void printUsage()
+  {
+    System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.APITestCoverageEmitter -eclipseDir <eclipseDir> -testDir <testDir> -compXMLDir <compXMLDir> -compAPIDir <compAPIDir> [-options]");
+    System.out.println("");
+    System.out.println("\t-eclipseDir\t<eclipseDir>\tspace seperated list of directories containing Eclipse plugins");
+    System.out.println("\t-testDir\t<testDir>\tspace separated list of directories containing test plugins");
+    System.out.println("\t-compXMLDir\t<compXMLDir>\tdirectories containing component.xml that will be checked for API test coverage");
+    System.out.println("\t-compAPIDir\t<compVioDir>\toutput directory of component-api-tc.xml");
+    System.out.println("");
+    System.out.println("where options include:");
+    System.out.println("");
+    System.out.println("\t-genHTML\tgenerate test coverage report in HTML");
+    System.out.println("\t-genAPI\t\tgenerate component-api.xml");
+    System.out.println("\t-debug\t\tgenerate debug information (ex. line numbers)");
+  }
+}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPI.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPI.java
index 4ac8ec3..5de034f 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPI.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPI.java
@@ -173,18 +173,26 @@
 
   private void saveInternalAPIs(StringBuffer sb, APIs apis)
   {
-    sb.append("<internal-apis>");
-    for (Iterator it = apis.getPackageAPIs().iterator(); it.hasNext();)
-      savePackageAPI(sb, (PackageAPI)it.next());
-    sb.append("</internal-apis>");
+    List pkgAPIs = apis.getPackageAPIs();
+    if (pkgAPIs.size() > 0)
+    {
+      sb.append("<internal-apis>");
+      for (Iterator it = pkgAPIs.iterator(); it.hasNext();)
+        savePackageAPI(sb, (PackageAPI)it.next());
+      sb.append("</internal-apis>");
+    }
   }
 
   private void saveExternalAPIs(StringBuffer sb, APIs apis)
   {
-    sb.append("<external-apis>");
-    for (Iterator it = apis.getPackageAPIs().iterator(); it.hasNext();)
-      savePackageAPI(sb, (PackageAPI)it.next());
-    sb.append("</external-apis>");
+    List pkgAPIs = apis.getPackageAPIs();
+    if (pkgAPIs.size() > 0)
+    {
+      sb.append("<external-apis>");
+      for (Iterator it = pkgAPIs.iterator(); it.hasNext();)
+        savePackageAPI(sb, (PackageAPI)it.next());
+      sb.append("</external-apis>");
+    }
   }
 
   private void savePackageAPI(StringBuffer sb, PackageAPI pkgAPI)
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPIEmitter.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPIEmitter.java
index 3b720c5..0876106 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPIEmitter.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/api/ComponentAPIEmitter.java
@@ -39,17 +39,19 @@
   public static final String OPTION_COMPONENT_XML_DIR = "compXMLDir";
   public static final String OPTION_COMPONENT_API_DIR = "compAPIDir";
   private String compAPIDir;
+  private boolean genInternalAPIs;
+  private boolean noFieldAPIs;
   private Map compLoc2CompXML;
   private Map pluginId2Plugin;
   private Map fragmentId2Fragment;
-
-  // Session object
   private ComponentXML compXML;
   private ComponentAPI compAPI;
 
   public ComponentAPIEmitter(String compAPIDir)
   {
     this.compAPIDir = addTrailingSeperator(compAPIDir);
+    genInternalAPIs = false;
+    noFieldAPIs = false;
   }
 
   public void init(List eclipseDirs, List compXMLDirs)
@@ -79,29 +81,14 @@
     this.fragmentId2Fragment = fragmentId2Fragment;
   }
 
-  public ComponentAPI getSessionComponentAPI(ComponentXML compXML)
+  public boolean getNoFieldAPIs()
   {
-    return getSessionComponentAPI(compXML, false);
+    return noFieldAPIs;
   }
 
-  public ComponentAPI getSessionComponentAPI(ComponentXML compXML, boolean newSession)
+  public void setNoFieldAPIs(boolean noFieldAPIs)
   {
-    if (newSession || compAPI == null)
-    {
-      this.compXML = compXML;
-      String compName = compXML.getName();
-      ILocation location = null;
-      if (compAPIDir != null)
-      {
-        StringBuffer sb = new StringBuffer(compAPIDir);
-        sb.append(compName);
-        sb.append('/');
-        sb.append(ComponentAPI.CONST_COMPONENT_API_XML);
-        location = new FileLocation(new File(sb.toString()));
-      }
-      compAPI = newComponentAPI(compName, location);
-    }
-    return compAPI;
+    this.noFieldAPIs = noFieldAPIs;
   }
 
   public void genComponentApiXml() throws IOException
@@ -117,7 +104,7 @@
     {
       compXML.load();
       String compName = compXML.getName();
-      compAPI = getSessionComponentAPI(compXML);
+      compAPI = newComponentAPI(compXML);
       for (Iterator pluginsIt = compXML.getPlugins().iterator(); pluginsIt.hasNext();)
       {
         IPluginXML plugin = (IPluginXML)pluginId2Plugin.get(((Plugin)pluginsIt.next()).getId());
@@ -125,7 +112,8 @@
           plugin.accept(this);
       }
       compXML = null;
-      System.out.println("Writing component-api.xml for " + compName);
+      if (compAPIDir != null)
+        System.out.println("Writing component-api.xml for " + compName);
       compAPI.save();
       return compAPI;
     }
@@ -134,6 +122,8 @@
 
   public boolean visit(IClazz clazz)
   {
+    if (compXML == null || compAPI == null)
+      return false;
     ClassAPI classAPI = addClassAPI(compXML, clazz, compAPI);
     if (classAPI != null)
     {
@@ -155,24 +145,22 @@
           addMethodAPI(classAPI, newMethodAPI(new String(methodInfos[i].getName()), access, new String(methodInfos[i].getDescriptor()), exs));
         }
       }
-      IFieldInfo[] fieldInfos = clazz.getFieldInfo();
-      for (int i = 0; i < fieldInfos.length; i++)
+      if (!noFieldAPIs)
       {
-        int access = fieldInfos[i].getAccessFlags();
-        if (!isBit(access, IModifierConstants.ACC_PRIVATE))
+        IFieldInfo[] fieldInfos = clazz.getFieldInfo();
+        for (int i = 0; i < fieldInfos.length; i++)
         {
-          addFieldAPI(classAPI, newFieldAPI(new String(fieldInfos[i].getName()), access, new String(fieldInfos[i].getDescriptor())));
+          int access = fieldInfos[i].getAccessFlags();
+          if (!isBit(access, IModifierConstants.ACC_PRIVATE))
+          {
+            addFieldAPI(classAPI, newFieldAPI(new String(fieldInfos[i].getName()), access, new String(fieldInfos[i].getDescriptor())));
+          }
         }
       }
     }
     return true;
   }
 
-  public Object changed(IClazz clazz)
-  {
-    return null;
-  }
-
   private ClassAPI addClassAPI(ComponentXML compXML, IClazz clazz, ComponentAPI compAPI)
   {
     String typeName = clazz.getName();
@@ -189,9 +177,12 @@
       pkgName = "";
       localName = typeName;
     }
-    ClassAPI internalClassAPI = new ClassAPI();
-    internalClassAPI.setName(typeName);
-    addClassAPI(compAPI, true, pkgName, internalClassAPI);
+    if (genInternalAPIs)
+    {
+      ClassAPI internalClassAPI = new ClassAPI();
+      internalClassAPI.setName(typeName);
+      addClassAPI(compAPI, true, pkgName, internalClassAPI);
+    }
     if (!isBit(clazz.getAccessFlags(), IModifierConstants.ACC_PRIVATE))
     {
       boolean isInterface = clazz.isInterface();
@@ -279,6 +270,21 @@
     return pkg;
   }
 
+  private ComponentAPI newComponentAPI(ComponentXML compXML)
+  {
+    String compName = compXML.getName();
+    ILocation location = null;
+    if (compAPIDir != null)
+    {
+      StringBuffer sb = new StringBuffer(compAPIDir);
+      sb.append(compName);
+      sb.append('/');
+      sb.append(ComponentAPI.CONST_COMPONENT_API_XML);
+      location = new FileLocation(new File(sb.toString()));
+    }
+    return newComponentAPI(compName, location);
+  }
+
   private ComponentAPI newComponentAPI(String compName, ILocation location)
   {
     ComponentAPI compAPI = new ComponentAPI();
@@ -321,7 +327,7 @@
 
   private Package findPackage(ComponentXML compXML, String pkgName)
   {
-    if (pkgName != null)
+    if (pkgName != null && compXML != null)
     {
       List pkgs = compXML.getPackages();
       for (Iterator it = pkgs.iterator(); it.hasNext();)
@@ -380,10 +386,10 @@
 
   private static void printUsage()
   {
-    System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.ComponentAPIEmitter -eclipseDir <eclipseDir> -compXMLDir <compDir> -compAPIDir <compAPIDir> -include <include> -exclude <exclude>");
+    System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.ComponentAPIEmitter -eclipseDir <eclipseDir> -compXMLDir <compDir> -compAPIDir <compAPIDir> [-options]");
     System.out.println("");
-    System.out.println("\t-eclipseDir\tspace seperated list of directories containing Eclipse plugins");
-    System.out.println("\t-compXMLDir\tdirectory containing component.xml");
-    System.out.println("\t-compAPIDir\toutput directory of component-api.xml");
+    System.out.println("\t-eclipseDir\t<eclipseDir>\tspace seperated list of directories containing Eclipse plugins");
+    System.out.println("\t-compXMLDir\t<compXMLDir>\tdirectory containing component.xml");
+    System.out.println("\t-compAPIDir\t<compAPIDir>\toutput directory of component-api.xml");
   }
 }
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/AbstractEmitter.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/AbstractEmitter.java
index 4c4887f..41f62de 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/AbstractEmitter.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/AbstractEmitter.java
@@ -21,6 +21,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+import org.eclipse.wtp.releng.tools.component.IFileLocation;
 import org.eclipse.wtp.releng.tools.component.ILocation;
 import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
 import org.xml.sax.Attributes;
@@ -61,6 +62,13 @@
       if (pluginName != null)
         pluginId2Plugin.put(pluginName, plugin);
     }
+    else if (PluginClasspath.CONST_DOT_CLASSPATH.equalsIgnoreCase(file.getName()))
+    {
+      PluginClasspath plugin = getPluginClasspath(new FileLocation(new FileLocation(file.getParentFile()), file.getName()));
+      String pluginName = plugin.getName();
+      if (pluginName != null)
+        pluginId2Plugin.put(pluginName, plugin);
+    }
   }
 
   /**
@@ -140,6 +148,19 @@
     return bundle;
   }
 
+  /**
+   * Creates a <code>PluginClasspath</code> from a location file
+   * 
+   * @param fileLocation
+   *          a location that points to a .classpath file, not
+   *          <code>null</code>.
+   * @return PluginClasspath the PluginClasspath object representation of that file
+   */
+  public PluginClasspath getPluginClasspath(IFileLocation fileLocation)
+  {
+    return new PluginClasspath(fileLocation);
+  }
+
   protected void parse(ILocation location, DefaultHandler handler) throws IOException
   {
     InputStream in = null;
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/PluginClasspath.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/PluginClasspath.java
new file mode 100644
index 0000000..e7c53ae
--- /dev/null
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/PluginClasspath.java
@@ -0,0 +1,215 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.wtp.releng.tools.component.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.eclipse.wtp.releng.tools.component.IClazzVisitor;
+import org.eclipse.wtp.releng.tools.component.IFileLocation;
+import org.eclipse.wtp.releng.tools.component.ILibrary;
+import org.eclipse.wtp.releng.tools.component.ILocation;
+import org.eclipse.wtp.releng.tools.component.IPluginXML;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class PluginClasspath implements IPluginXML
+{
+  public static final String CONST_DOT_CLASSPATH = ".classpath";
+  private IFileLocation dotClasspath;
+  private List libraries;
+  private String name;
+  private String version;
+  private String path;
+
+  public PluginClasspath(IFileLocation dotClasspath)
+  {
+    this.dotClasspath = dotClasspath;
+  }
+
+  private void init()
+  {
+    SAXParser saxParser = null;
+    try
+    {
+      SAXParserFactory factory = SAXParserFactory.newInstance();
+      factory.setNamespaceAware(false);
+      factory.setValidating(false);
+      saxParser = factory.newSAXParser();
+    }
+    catch (ParserConfigurationException e)
+    {
+      e.printStackTrace();
+    }
+    catch (SAXException e)
+    {
+      e.printStackTrace();
+    }
+    if (saxParser != null)
+    {
+      InputStream is = null;
+      try
+      {
+        is = dotClasspath.getInputStream();
+        saxParser.parse(new InputSource(is), new DotClasspathHandler());
+      }
+      catch (SAXException e)
+      {
+        e.printStackTrace();
+      }
+      catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+      finally
+      {
+        if (is != null)
+        {
+          try
+          {
+            is.close();
+          }
+          catch (IOException e)
+          {
+            e.printStackTrace();
+          }
+        }
+      }
+      is = null;
+      try
+      {
+        ILocation location = new FileLocation(new FileLocation(dotClasspath.getFile().getParentFile()), IPluginXML.CONST_PLUGIN_XML);
+        is = location.getInputStream();
+        saxParser.parse(new InputSource(is), new PluginHandler());
+      }
+      catch (SAXException e)
+      {
+        e.printStackTrace();
+      }
+      catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+      finally
+      {
+        if (is != null)
+        {
+          try
+          {
+            is.close();
+          }
+          catch (IOException e)
+          {
+            e.printStackTrace();
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Answers the libraries that are declared in this plugin.
+   * 
+   * @return List libraries in this plugin
+   */
+  public List getLibraries()
+  {
+    if (libraries == null)
+    {
+      libraries = new ArrayList(1);
+      ILocation location = new FileLocation(new FileLocation(dotClasspath.getFile().getParentFile()), path);
+      libraries.add(new Library(location));
+    }
+    return libraries;
+  }
+
+  /**
+   * Answers the name of this plugin. Plugin names do not contain the version
+   * identifier, for example, org.eclipse.core.resources.
+   * 
+   * @return String the name of the plugin, not <code>null</code>.
+   */
+  public String getName()
+  {
+    if (name == null)
+      init();
+    return name;
+  }
+
+  /**
+   * Answers the version identifier for the plugin. A version identifier is a
+   * '.' delimited set of numbers, for example, 2.0.1.5.
+   * 
+   * @return String the plugin version, not <code>null</code>.
+   */
+  public String getVersion()
+  {
+    if (version == null)
+      init();
+    return version;
+  }
+
+  /**
+   * The unique identifier is a concatination of the plugin name, and '_' and
+   * the plugin version.
+   * 
+   * @return String the unique identifier of the plugin.
+   */
+  public String getUniqueIdentifier()
+  {
+    return getName() + "_" + getVersion();
+  }
+
+  public void accept(IClazzVisitor visitor)
+  {
+    for (Iterator it = getLibraries().iterator(); it.hasNext();)
+    {
+      ILibrary lib = (ILibrary)it.next();
+      lib.accept(visitor);
+      lib.resetTypes();
+    }
+  }
+
+  private class PluginHandler extends DefaultHandler
+  {
+    public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
+    {
+      if (elementName.equals("plugin") || qName.equals("plugin"))
+      {
+        name = attributes.getValue("id");
+        version = attributes.getValue("version");
+      }
+    }
+  }
+
+  private class DotClasspathHandler extends DefaultHandler
+  {
+    public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
+    {
+      if (elementName.equals("classpathentry") || qName.equals("classpathentry"))
+      {
+        String kind = attributes.getValue("kind");
+        if (kind != null && kind.equals("output"))
+        {
+          path = attributes.getValue("path");
+        }
+      }
+    }
+  }
+}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/model/ComponentDepends.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/model/ComponentDepends.java
index 35cc5b2..081a227 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/model/ComponentDepends.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/model/ComponentDepends.java
@@ -58,7 +58,7 @@
   {
     ComponentDepends clone = new ComponentDepends();
     clone.setUnrestricted(getUnrestricted());
-    List refsClone = new ArrayList(getComponentRefs().size());
+    List refsClone = clone.getComponentRefs();
     for (Iterator it = getComponentRefs().iterator(); it.hasNext();)
       refsClone.add(((ComponentRef)it.next()).clone());
     return clone;
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUse.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUse.java
index 0a0d9d5..c668719 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUse.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUse.java
@@ -110,6 +110,19 @@
     }
   }
 
+  public String toString()
+  {
+    try
+    {
+      return new String(getBytes());
+    }
+    catch (UnsupportedEncodingException e)
+    {
+      e.printStackTrace();
+    }
+    return super.toString();
+  }
+
   private byte[] getBytes() throws UnsupportedEncodingException
   {
     StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUseEmitter.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUseEmitter.java
index 709f3df..3e69a7f 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUseEmitter.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/use/ComponentUseEmitter.java
@@ -49,7 +49,6 @@
   private List classUseExcludes;
   private boolean classRefOnly;
   private boolean debug;
-  // Session object
   private ComponentUse compUse;
 
   public ComponentUseEmitter(String compUseDir)
@@ -140,30 +139,6 @@
     this.classUseExcludes = excludes;
   }
 
-  public ComponentUse getSessionComponentUse(ComponentXML compXML)
-  {
-    return getSessionComponentUse(compXML, false);
-  }
-
-  public ComponentUse getSessionComponentUse(ComponentXML compXML, boolean newSession)
-  {
-    if (newSession || compUse == null)
-    {
-      String compName = compXML.getName();
-      ILocation location = null;
-      if (compUseDir != null)
-      {
-        StringBuffer sb = new StringBuffer(compUseDir);
-        sb.append(compName);
-        sb.append('/');
-        sb.append(ComponentUse.CONST_COMPONENT_USE_XML);
-        location = new FileLocation(new File(sb.toString()));
-      }
-      compUse = newComponentUse(compName, location);
-    }
-    return compUse;
-  }
-
   public void genComponentUseXML() throws IOException
   {
     for (Iterator it = compLoc2CompXML.keySet().iterator(); it.hasNext();)
@@ -177,7 +152,7 @@
     {
       compXML.load();
       String compName = compXML.getName();
-      compUse = getSessionComponentUse(compXML);
+      compUse = newComponentUse(compXML);
       for (Iterator pluginsIt = compXML.getPlugins().iterator(); pluginsIt.hasNext();)
       {
         IPluginXML pluginXML = (IPluginXML)pluginId2Plugin.get(((Plugin)pluginsIt.next()).getId());
@@ -185,39 +160,32 @@
           pluginXML.accept(this);
       }
       compXML = null;
-      System.out.println("Writing component-use.xml for " + compName);
+      if (compUseDir != null)
+        System.out.println("Writing component-use.xml for " + compName);
       compUse.save();
       return compUse;
     }
     return null;
   }
 
-  public boolean visit(IClazz clazz)
+  public Source genUse(IClazz clazz)
   {
-    newSource(clazz);
-    return true;
+    return newSource(clazz);
   }
 
-  public Object changed(IClazz clazz)
+  public boolean visit(IClazz clazz)
   {
-    List sources = compUse.getSources();
-    int size = sources.size();
-    for (int i = 0; i < size; i++)
-    {
-      if (((Source)sources.get(i)).getName().equals(clazz.getName()))
-      {
-        sources.remove(i);
-        break;
-      }
-    }
-    return newSource(clazz);
+    if (compUse == null)
+      return false;
+    Source source = newSource(clazz);
+    addSource(compUse, source);
+    return true;
   }
 
   private Source newSource(IClazz clazz)
   {
     String className = clazz.getName();
     Source source = newSource(clazz.getName());
-    addSource(compUse, source);
     if (!classRefOnly)
     {
       // method references
@@ -362,6 +330,21 @@
     return fieldUse;
   }
 
+  private ComponentUse newComponentUse(ComponentXML compXML)
+  {
+    String compName = compXML.getName();
+    ILocation location = null;
+    if (compUseDir != null)
+    {
+      StringBuffer sb = new StringBuffer(compUseDir);
+      sb.append(compName);
+      sb.append('/');
+      sb.append(ComponentUse.CONST_COMPONENT_USE_XML);
+      location = new FileLocation(new File(sb.toString()));
+    }
+    return newComponentUse(compName, location);
+  }
+
   private ComponentUse newComponentUse(String name, ILocation location)
   {
     ComponentUse compUse = new ComponentUse();
@@ -430,10 +413,10 @@
     System.out.println("");
     System.out.println("\t-eclipseDir\t<eclipseDir>\tspace seperated list of directories containing Eclipse plugins");
     System.out.println("\t-compXMLDir\t<compXMLDir>\tdirectory containing component.xml");
+    System.out.println("\t-compUseDir\t<compUseDir>\toutput directory of component-use.xml");
     System.out.println("");
     System.out.println("where options include:");
     System.out.println("");
-    System.out.println("\t-compUseDir\t<compUseDir>\toutput directory of component-use.xml");
     System.out.println("\t-include\t<include>\tspace seperated packages to include");
     System.out.println("\t-exclude\t<exclude>\tspace seperated packages to exclude");
     System.out.println("\t-classRefOnly\t\t\ttreat all violations as class reference");
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/violation/ComponentViolationEmitter.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/violation/ComponentViolationEmitter.java
index 5eb790e..0560d27 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/violation/ComponentViolationEmitter.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/violation/ComponentViolationEmitter.java
@@ -12,6 +12,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -19,16 +20,17 @@
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
 import org.eclipse.wtp.releng.tools.component.IClazz;
-import org.eclipse.wtp.releng.tools.component.IClazzVisitor;
+import org.eclipse.wtp.releng.tools.component.ILibrary;
 import org.eclipse.wtp.releng.tools.component.ILocation;
 import org.eclipse.wtp.releng.tools.component.IPluginXML;
 import org.eclipse.wtp.releng.tools.component.api.APIs;
 import org.eclipse.wtp.releng.tools.component.api.ClassAPI;
 import org.eclipse.wtp.releng.tools.component.api.ComponentAPI;
-import org.eclipse.wtp.releng.tools.component.api.ComponentAPIEmitter;
 import org.eclipse.wtp.releng.tools.component.api.PackageAPI;
 import org.eclipse.wtp.releng.tools.component.internal.AbstractEmitter;
 import org.eclipse.wtp.releng.tools.component.internal.FileLocation;
+import org.eclipse.wtp.releng.tools.component.model.ComponentDepends;
+import org.eclipse.wtp.releng.tools.component.model.ComponentRef;
 import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
 import org.eclipse.wtp.releng.tools.component.model.Package;
 import org.eclipse.wtp.releng.tools.component.model.Plugin;
@@ -39,7 +41,7 @@
 import org.eclipse.wtp.releng.tools.component.use.Source;
 import org.eclipse.wtp.releng.tools.component.util.CommandOptionParser;
 
-public class ComponentViolationEmitter extends AbstractEmitter implements IClazzVisitor
+public class ComponentViolationEmitter extends AbstractEmitter
 {
   public static final String CONST_COMPONENT_VIOLATION_XML = "component-violation.xml";
   public static final String CONST_COMPONENT_VIOLATION_HTML = "component-violation.html";
@@ -50,7 +52,6 @@
   public static final String OPTION_INCLUDE = "include";
   public static final String OPTION_EXCLUDE = "exclude";
   public static final String OPTION_GEN_HTML = "genHTML";
-  public static final String OPTION_GEN_API = "genAPI";
   public static final String OPTION_GEN_USAGE = "genUsage";
   public static final String OPTION_DEBUG = "debug";
 
@@ -61,21 +62,15 @@
   private Map compLoc2CompRef;
   private List classUseIncludes;
   private List classUseExcludes;
-  private ComponentAPIEmitter compAPIEmitter;
-  private ComponentUseEmitter compUseEmitter;
   private boolean genHTML;
-  private boolean genAPI;
   private boolean genUsage;
   private boolean classRefOnly;
   private boolean debug;
-  
-  // Session object
-  private ComponentXML componentXML;
+  private ComponentUseEmitter compUseEmitter;
 
   public ComponentViolationEmitter(String compViolationDir)
   {
     this.compViolationDir = addTrailingSeperator(compViolationDir);
-    genAPI = false;
     genUsage = false;
     classRefOnly = false;
     debug = false;
@@ -123,8 +118,6 @@
 
   private void init()
   {
-    compAPIEmitter = new ComponentAPIEmitter(genAPI ? compViolationDir : null);
-    compAPIEmitter.init(compLoc2CompXML, pluginId2Plugin, fragmentId2Fragment);
     compUseEmitter = new ComponentUseEmitter(genUsage ? compViolationDir : null);
     compUseEmitter.setClassUseIncludes(classUseIncludes);
     compUseEmitter.setClassUseExcludes(classUseExcludes);
@@ -133,6 +126,16 @@
     compUseEmitter.init(compLoc2CompXML, pluginId2Plugin, fragmentId2Fragment);
   }
 
+  public Map getCompRefs()
+  {
+    return new HashMap(compLoc2CompRef);
+  }
+
+  public void setCompRefs(Map compLoc2CompRef)
+  {
+    this.compLoc2CompRef = compLoc2CompRef;
+  }
+
   public List getClassUseIncludes()
   {
     return classUseIncludes;
@@ -169,16 +172,6 @@
     this.genHTML = genHTML;
   }
 
-  public boolean getGenAPI()
-  {
-    return genAPI;
-  }
-
-  public void setGenAPI(boolean genAPI)
-  {
-    this.genAPI = genAPI;
-  }
-
   public boolean getGenUsage()
   {
     return genUsage;
@@ -250,35 +243,46 @@
 
   public ComponentUse genComponentViolationXML(String compLoc) throws IOException
   {
-    componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
     ComponentUse compUse = null;
-    ComponentAPI compAPI = null;
+    ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
     if (componentXML != null)
     {
       componentXML.load();
-      compUse = compUseEmitter.getSessionComponentUse(componentXML, true);
-      compAPI = compAPIEmitter.getSessionComponentAPI(componentXML, true);
+      compUse = compUseEmitter.genComponentUseXML(compLoc);
+      compUse.save();
       for (Iterator pluginsIt = componentXML.getPlugins().iterator(); pluginsIt.hasNext();)
       {
         IPluginXML pluginXML = (IPluginXML)pluginId2Plugin.get(((Plugin)pluginsIt.next()).getId());
         if (pluginXML != null)
-          pluginXML.accept(this);
+          validateComponentUse(pluginXML, compUse);
       }
-      compUse.save();
-      compAPI.save();
-      validateComponentUse(compAPI, compUse, true);
-      compAPI = null;
+      ComponentDepends depends = componentXML.getComponentDepends();
+      boolean unrestricted = depends.isUnrestricted();
+      List dependNames = null;
+      if (!unrestricted)
+      {
+        dependNames = new ArrayList();
+        List compRefs = depends.getComponentRefs();
+        for (Iterator it = compRefs.iterator(); it.hasNext();)
+          dependNames.add(((ComponentRef)it.next()).getName());
+      }
       for (Iterator it = compLoc2CompXML.values().iterator(); it.hasNext() && compUse.getSources().size() > 0;)
       {
         ComponentXML compXML = (ComponentXML)it.next();
-        compXML.load();
-        validateComponentUse(compXML, compUse);
+        if (unrestricted || dependNames.contains(compXML.getName()))
+        {
+          compXML.load();
+          validateComponentUse(compXML, compUse);
+        }
       }
       for (Iterator it = compLoc2CompRef.values().iterator(); it.hasNext() && compUse.getSources().size() > 0;)
       {
         ComponentXML compXML = (ComponentXML)it.next();
-        compXML.load();
-        validateComponentUse(compXML, compUse);
+        if (unrestricted || dependNames.contains(compXML.getName()))
+        {
+          compXML.load();
+          validateComponentUse(compXML, compUse);
+        }
       }
       if (compViolationDir != null)
       {
@@ -311,33 +315,109 @@
     return compUse;
   }
 
-  public boolean visit(IClazz clazz)
+  public Source genViolation(String compLoc, IClazz clazz)
   {
-    compAPIEmitter.visit(clazz);
-    compUseEmitter.visit(clazz);
-    return true;
-  }
-
-  public Object changed(IClazz clazz)
-  {
-    Source source = (Source)compUseEmitter.changed(clazz);
-    boolean valid = validateComponentUse(compAPIEmitter.getSessionComponentAPI(componentXML).getInternalAPIs(), source, true);
-    if (!valid)
+    Source source = null;
+    ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
+    if (componentXML != null)
     {
-      for (Iterator it = compLoc2CompRef.values().iterator(); it.hasNext();)
+      boolean valid = false;
+      source = compUseEmitter.genUse(clazz);
+      for (Iterator pluginsIt = componentXML.getPlugins().iterator(); pluginsIt.hasNext();)
       {
-        valid = validateComponentUse((ComponentXML)it.next(), source);
-        if (valid)
-          break;
+        IPluginXML pluginXML = (IPluginXML)pluginId2Plugin.get(((Plugin)pluginsIt.next()).getId());
+        if (pluginXML != null)
+        {
+          if (validateComponentUse(pluginXML, source))
+          {
+            valid = true;
+            break;
+          }
+        }
+      }
+      ComponentDepends depends = componentXML.getComponentDepends();
+      boolean unrestricted = depends.isUnrestricted();
+      List dependNames = null;
+      if (!unrestricted)
+      {
+        dependNames = new ArrayList();
+        List compRefs = depends.getComponentRefs();
+        for (Iterator it = compRefs.iterator(); it.hasNext();)
+          dependNames.add(((ComponentRef)it.next()).getName());
+      }
+      if (!valid)
+      {
+        for (Iterator it = compLoc2CompXML.values().iterator(); it.hasNext();)
+        {
+          ComponentXML comp = (ComponentXML)it.next();
+          if (unrestricted || dependNames.contains(comp.getName()))
+          {
+            valid = validateComponentUse(comp, source);
+            if (valid)
+              break;
+          }
+        }
+      }
+      if (!valid)
+      {
+        for (Iterator it = compLoc2CompRef.values().iterator(); it.hasNext();)
+        {
+          ComponentXML comp = (ComponentXML)it.next();
+          if (unrestricted || dependNames.contains(comp.getName()))
+          {
+            valid = validateComponentUse(comp, source);
+            if (valid)
+              break;
+          }
+        }
       }
     }
-    if (valid)
+    return source;
+  }
+
+  private void validateComponentUse(IPluginXML pluginXML, ComponentUse compUse)
+  {
+    List sources = compUse.getSources();
+    for (int i = 0; i < sources.size(); i++)
     {
-      compUseEmitter.getSessionComponentUse(componentXML).getSources().remove(source);
-      return null;
+      if (validateComponentUse(pluginXML, (Source)sources.get(i)))
+      {
+        sources.remove(i);
+        i--;
+      }
     }
-    else
-      return source;
+  }
+
+  private boolean validateComponentUse(IPluginXML pluginXML, Source source)
+  {
+    List classUses = source.getClassUses();
+    for (int j = 0; j < classUses.size(); j++)
+    {
+      ClassUse classUse = (ClassUse)classUses.get(j);
+      if (validateComponentUse(pluginXML, classUse))
+      {
+        classUses.remove(j);
+        j--;
+      }
+    }
+    return classUses.size() == 0;
+  }
+
+  private boolean validateComponentUse(IPluginXML pluginXML, ClassUse classUse)
+  {
+    String classUseName = classUse.getName();
+    int dollarSign = classUseName.indexOf('$');
+    if (dollarSign != -1)
+      classUseName = classUseName.substring(0, dollarSign);
+    List libs = pluginXML.getLibraries();
+    for (Iterator libsIt = libs.iterator(); libsIt.hasNext();)
+    {
+      ILibrary lib = (ILibrary)libsIt.next();
+      Map types = lib.getTypes();
+      if (types.containsKey(classUseName))
+        return true;
+    }
+    return false;
   }
 
   private void validateComponentUse(ComponentAPI compAPI, ComponentUse compUse, boolean useInternalApis)
@@ -472,7 +552,6 @@
     List includes = (List)options.get(ComponentViolationEmitter.OPTION_INCLUDE);
     List excludes = (List)options.get(ComponentViolationEmitter.OPTION_EXCLUDE);
     List genHTML = (List)options.get(ComponentViolationEmitter.OPTION_GEN_HTML);
-    List genAPI = (List)options.get(ComponentViolationEmitter.OPTION_GEN_API);
     List genUsage = (List)options.get(ComponentViolationEmitter.OPTION_GEN_USAGE);
     List classRefOnly = (List)options.get(ComponentUseEmitter.OPTION_CLASS_REF_ONLY);
     List debug = (List)options.get(ComponentUseEmitter.OPTION_DEBUG);
@@ -485,7 +564,6 @@
     compViolationEmitter.setClassUseIncludes(includes);
     compViolationEmitter.setClassUseExcludes(excludes);
     compViolationEmitter.setGenHTML(genHTML != null);
-    compViolationEmitter.setGenAPI(genAPI != null);
     compViolationEmitter.setGenUsage(genUsage != null);
     compViolationEmitter.setClassRefOnly(classRefOnly != null);
     compViolationEmitter.setDebug(debug != null);
@@ -514,9 +592,8 @@
     System.out.println("\t-include\t<include>\tspace seperated packages to include");
     System.out.println("\t-exclude\t<exclude>\tspace seperated packages to exclude");
     System.out.println("\t-genHTML\t\t\tgenerate violation report in HTML");
-    System.out.println("\t-genAPI\t\t\t\tgenerate component-api.xml");
     System.out.println("\t-genUsage\t\t\tgenerate component-use.xml");
     System.out.println("\t-classRefOnly\t\t\ttreat all violations as class reference");
     System.out.println("\t-debug\t\t\t\tgenerate debug information (ex. line numbers)");
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/plugin.xml b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/plugin.xml
index 078ab40..6216a8f 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/plugin.xml
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/plugin.xml
@@ -38,4 +38,23 @@
       />
    </extension>
 
+   <extension point="org.eclipse.ui.popupMenus">
+      <objectContribution
+         objectClass="org.eclipse.core.resources.IFile"
+         nameFilter="component.xml"
+         id="org.eclipse.wtp.releng.tools.component.ui.internal.action.ScanAPI">
+         <menu
+            label="%LABEL_POPUP_MENU_COMPONENT"
+            path="additions"
+            id="org.eclipse.wtp.releng.tools.component.ui.popupMenu">
+            <separator name="popupActions"/> 
+         </menu>
+         <action
+            label="%LABEL_POPUP_ACTION_API_SCAN_COMPONENT"
+            class="org.eclipse.wtp.releng.tools.component.ui.internal.action.ScanAPI"
+            menubarPath="org.eclipse.wtp.releng.tools.component.ui.popupMenu/popupActions"
+            id="org.eclipse.wtp.releng.tools.component.ui.internal.action.ScanAPI"/> 
+      </objectContribution>
+   </extension>
+
 </plugin>
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/ComponentManager.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/ComponentManager.java
index 35d443b..4677ac9 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/ComponentManager.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/ComponentManager.java
@@ -11,7 +11,6 @@
 
 package org.eclipse.wtp.releng.tools.component.ui;
 
-import java.io.File;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -27,15 +26,12 @@
 import org.eclipse.core.resources.IResourceChangeListener;
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.wtp.releng.tools.component.ILibrary;
 import org.eclipse.wtp.releng.tools.component.ILocation;
 import org.eclipse.wtp.releng.tools.component.IPluginXML;
-import org.eclipse.wtp.releng.tools.component.internal.FileLocation;
 import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
 import org.eclipse.wtp.releng.tools.component.model.Plugin;
 import org.eclipse.wtp.releng.tools.component.ui.internal.BundleAdapter;
@@ -43,18 +39,16 @@
 import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspaceFileLocation;
 import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspacePluginXML;
 import org.eclipse.wtp.releng.tools.component.ui.internal.job.AddComponent;
+import org.eclipse.wtp.releng.tools.component.ui.internal.job.InitComponentManager;
 import org.eclipse.wtp.releng.tools.component.ui.internal.job.RemoveComponent;
-import org.eclipse.wtp.releng.tools.component.ui.internal.job.ScanClass;
 import org.eclipse.wtp.releng.tools.component.ui.internal.job.ScanComponent;
 import org.eclipse.wtp.releng.tools.component.violation.ComponentViolationEmitter;
 import org.osgi.framework.Bundle;
 
-public class ComponentManager implements IResourceChangeListener, IResourceDeltaVisitor, IResourceProxyVisitor
+public class ComponentManager implements IResourceChangeListener, IResourceDeltaVisitor
 {
   public static final String MARKER_COMPONENT_VIOLATION = "marker-comp-vio";
   private static ComponentManager manager;
-  private final int MARKER_LIMIT = 25;
-  private int markerCount;
   private Map scannableComps;
   private Map compRefs;
   private ResourceBundle bundle;
@@ -68,32 +62,27 @@
 
   private ComponentManager()
   {
-    markerCount = 0;
   }
 
   public void init()
   {
-    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
-    for (int i = 0; i < projects.length; i++)
+    InitComponentManager job = new InitComponentManager();
+    job.schedule();
+    boolean interrupted = true;
+    while (interrupted)
     {
       try
       {
-        projects[i].accept(this, IResource.DEPTH_INFINITE | IResource.NONE);
+        job.join();
+        interrupted = false;
       }
-      catch (CoreException e)
+      catch (InterruptedException e)
       {
-        e.printStackTrace();
+        interrupted = true;
       }
     }
   }
 
-  public boolean visit(IResourceProxy resProxy)
-  {
-    if (resProxy.getType() == IResource.FILE && resProxy.getName().equals(ComponentXML.CONST_COMPONENT_XML))
-      addComponentXML((IFile)resProxy.requestResource());
-    return true;
-  }
-
   public void resourceChanged(IResourceChangeEvent event)
   {
     IResourceDelta delta = event.getDelta();
@@ -113,40 +102,125 @@
   public boolean visit(IResourceDelta delta) throws CoreException
   {
     IResource res = delta.getResource();
-    if (res.getType() == IResource.FILE)
+    int type = res.getType();
+    int kind = delta.getKind();
+    if (type == IResource.FILE)
+      handleFileDelta((IFile)res, kind);
+    else if (type == IResource.PROJECT)
+      handleProjectDelta((IProject)res, kind);
+    return true;
+  }
+
+  private boolean handleFileDelta(IFile file, int kind)
+  {
+    if (file.getName().equals(ComponentXML.CONST_COMPONENT_XML))
     {
-      int kind = delta.getKind();
-      if (res.getName().equals(ComponentXML.CONST_COMPONENT_XML))
+      if (kind == IResourceDelta.ADDED)
+        new AddComponent(file).schedule();
+      else if (kind == IResourceDelta.REMOVED)
+        new RemoveComponent(file).schedule();
+      else if (kind == IResourceDelta.CHANGED || kind == IResourceDelta.CONTENT)
       {
-        if (kind == IResourceDelta.ADDED)
-          addComponentXML((IFile)res);
-        else if (kind == IResourceDelta.REMOVED)
-          removeComponentXML((IFile)res);
-        else if (kind == IResourceDelta.CHANGED || kind == IResourceDelta.CONTENT)
-        {
-          removeComponentXML((IFile)res);
-          addComponentXML((IFile)res);
-        }
+        new RemoveComponent(file).schedule();
+        new AddComponent(file).schedule();
       }
-      else if (res.getFileExtension() != null && res.getFileExtension().equals(ILibrary.EXT_CLASS))
+    }
+    else if (file.getFileExtension() != null && file.getFileExtension().equals(ILibrary.EXT_CLASS))
+    {
+      if (kind == IResourceDelta.CHANGED || kind == IResourceDelta.CONTENT || kind == IResourceDelta.ADDED)
       {
-        if (kind == IResourceDelta.CHANGED || kind == IResourceDelta.CONTENT || kind == IResourceDelta.ADDED)
-          addClass((IFile)res);
+        if (scannableComps != null)
+        {
+          IProject project = file.getProject();
+          for (Iterator it = scannableComps.values().iterator(); it.hasNext();)
+          {
+            ScannableComponent scannableComp = (ScannableComponent)it.next();
+            if (scannableComp.isScanningProject(project))
+            {
+              new ScanComponent(scannableComp, false).schedule();
+            }
+          }
+        }
       }
     }
     return true;
   }
 
-  private void addComponentXML(IFile file)
+  private boolean handleProjectDelta(IProject project, int kind)
   {
-    AddComponent job = new AddComponent(file);
-    job.schedule();
+    if (kind == IResourceDelta.REMOVED)
+      handleProjectDeltaRemoved(project, kind);
+    else if (kind == IResourceDelta.ADDED)
+      handleProjectDeltaAdded(project, kind);
+    return true;
   }
 
-  private void removeComponentXML(IFile file)
+  private boolean handleProjectDeltaAdded(IProject project, int kind)
   {
-    RemoveComponent job = new RemoveComponent(file);
-    job.schedule();
+    if (project.findMember(IPluginXML.CONST_PLUGIN_XML) != null)
+    {
+      String pluginId = project.getName();
+      if (scannableComps != null)
+      {
+        Object[] keys = scannableComps.keySet().toArray();
+        for (int i = 0; i < keys.length; i++)
+        {
+          ScannableComponent scannableComp = (ScannableComponent)scannableComps.get(keys[i]);
+          ComponentXML compXML = scannableComp.getCompXML();
+          if (containsPlugin(compXML, pluginId))
+          {
+            scannableComp.addProject(project);
+            return false;
+          }
+        }
+      }
+      if (compRefs != null)
+      {
+        Object[] keys = compRefs.keySet().toArray();
+        for (int i = 0; i < keys.length; i++)
+        {
+          ComponentXML compXML = (ComponentXML)compRefs.get(keys[i]);
+          if (containsPlugin(compXML, pluginId))
+          {
+            addScannableComponent(compXML);
+            return false;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean containsPlugin(ComponentXML compXML, String pluginId)
+  {
+    for (Iterator it = compXML.getPlugins().iterator(); it.hasNext();)
+      if (pluginId.equals(((Plugin)it.next()).getId()))
+        return true;
+    return false;
+  }
+
+  private boolean handleProjectDeltaRemoved(IProject project, int kind)
+  {
+    if (scannableComps != null)
+    {
+      ScannableComponent scannableComp = null;
+      for (Iterator it = scannableComps.values().iterator(); it.hasNext();)
+      {
+        ScannableComponent comp = (ScannableComponent)it.next();
+        if (comp.isScanningProject(project))
+        {
+          scannableComp = comp;
+          break;
+        }
+      }
+      if (scannableComp != null)
+      {
+        scannableComp.removeProject(project.getName());
+        if (scannableComp.getProjects().size() <= 0)
+          scannableComps.remove(scannableComp);
+      }
+    }
+    return false;
   }
 
   public ComponentXML getComponentXML(IFile file)
@@ -170,43 +244,22 @@
     return compNames;
   }
 
-  private void addClass(IFile file)
-  {
-    ScanClass job = new ScanClass(file);
-    job.schedule();
-  }
-
-  public boolean incrMarkerCount()
-  {
-    if (markerCount < MARKER_LIMIT)
-    {
-      markerCount++;
-      return true;
-    }
-    return false;
-  }
-
-  public boolean decrMarkerCount()
-  {
-    if (markerCount > 0)
-      markerCount--;
-    return true;
-  }
-
   public boolean isWorkspacePlugin(String id)
   {
     IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
     for (int i = 0; i < projects.length; i++)
       if (projects[i].getName().equals(id))
-        return true;
+        if (projects[i].findMember(IPluginXML.CONST_PLUGIN_XML) != null)
+          return true;
     return false;
   }
 
   public Map getScannableComponents()
   {
     if (scannableComps == null)
-      scannableComps = new HashMap(0);
-    return scannableComps;
+      return new HashMap(0);
+    else
+      return new HashMap(scannableComps);
   }
 
   public void addScannableComponent(ComponentXML compXML)
@@ -242,7 +295,7 @@
     if (scannableComps == null)
       scannableComps = new HashMap(1);
     scannableComps.put(compXML.getLocation().getAbsolutePath(), scannableComp);
-    ScanComponent job = new ScanComponent(scannableComp);
+    ScanComponent job = new ScanComponent(scannableComp, true);
     job.schedule();
   }
 
@@ -279,8 +332,9 @@
   public Map getCompRefs()
   {
     if (compRefs == null)
-      compRefs = new HashMap(0);
-    return compRefs;
+      return new HashMap(0);
+    else
+      return new HashMap(compRefs);
   }
 
   public void addCompRef(ComponentXML compRef)
@@ -288,14 +342,23 @@
     if (compRefs == null)
       compRefs = new HashMap(1);
     compRefs.put(compRef.getLocation().getAbsolutePath(), compRef);
+    if (scannableComps != null)
+      for (Iterator it = scannableComps.values().iterator(); it.hasNext();)
+        ((ScannableComponent)it.next()).addCompRef(compRef);
   }
 
-  public ComponentXML removeCompRef(ILocation location)
+  public void removeCompRef(ILocation location)
   {
     if (compRefs != null)
-      return (ComponentXML)compRefs.remove(location.getAbsolutePath());
-    else
-      return null;
+      compRefs.remove(location.getAbsolutePath());
+    if (scannableComps != null)
+      for (Iterator it = scannableComps.values().iterator(); it.hasNext();)
+        ((ScannableComponent)it.next()).removeCompRef(location);
+  }
+
+  private void rescanAffectedComps(String compName)
+  {
+    
   }
 
   public String getMessage(String key)
@@ -318,21 +381,4 @@
   {
     return MessageFormat.format(getMessage(key), subsitutes);
   }
-
-  private void harvestComponents(File file, Map compsMap)
-  {
-    if (file.isDirectory())
-    {
-      File[] files = file.listFiles();
-      for (int i = 0; i < files.length; i++)
-        harvestComponents(files[i], compsMap);
-    }
-    else if (ComponentXML.CONST_COMPONENT_XML.equalsIgnoreCase(file.getName()))
-    {
-      ComponentXML compXML = new ComponentXML();
-      ILocation location = new FileLocation(file);
-      compXML.setLocation(location);
-      compsMap.put(location.getAbsolutePath(), compXML);
-    }
-  }
 }
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/component.properties b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/component.properties
index e0305e6..c758496 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/component.properties
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/component.properties
@@ -5,9 +5,6 @@
 VIOLATION_CLASS_IMPLEMENT=Class {0} cannot be implemented.
 VIOLATION_CLASS_INSTANTIATE=Class {0} cannot be instantiated.
 
-TITLE_ALREADY_BEING_SCANNED=Scan component
-ERROR_MSG_ALREADY_BEING_SCANNED=This component is already being scanned.
-
 TITLE_NO_WORKSPACE_PLUGINS=No workspace plugins
 ERROR_MSG_NO_WORKSPACE_PLUGINS=Plugins defined in this component.xml do not exist in the workspace. To scan a component, at least one plugin must be present in the workspace.
 
@@ -15,6 +12,7 @@
 ERROR_MSG_HAS_API_VIOLATIONS=This component has API violations. Please see the problems view for details.
 INFO_MSG_NO_API_VIOLATIONS=This component does not have any API violations.
 
+JOB_INIT_COMPONENT_MANAGER=Initializing component manager...
 JOB_ADD_COMPONENT=Adding component {0}
 JOB_REMOVE_COMPONENT=Removing component {0}
 JOB_SCAN_COMPONENT=Scanning component {0}
@@ -31,6 +29,8 @@
 LABEL_UNRESTRICTED_COMPONENT_DEPENDS=This component can depend on any other component
 LABEL_COMPONENT_REFS=Component references:
 LABEL_ADD=Add...
+LABEL_ADD_PACKAGE=Add package
+LABEL_ADD_TYPE=Add type
 LABEL_PLUGINS=Plug-ins:
 LABEL_PACKAGE_API=Is package public
 LABEL_PACKAGE_EXCLUSIVE=Is package exclusive
@@ -47,4 +47,5 @@
 
 DIALOG_TITLE_ADD_COMPONENT_REFS=Add component references
 DIALOG_TITLE_ADD_PLUGINS=Add plug-ins
-DIALOG_TITLE_ADD_APIS=Add APIs
\ No newline at end of file
+DIALOG_TITLE_ADD_PACKAGES=Add packages
+DIALOG_TITLE_ADD_TYPES=Add types
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/JavaSourceFinder.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/JavaSourceFinder.java
index 2a604b9..e5c1600 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/JavaSourceFinder.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/JavaSourceFinder.java
@@ -23,6 +23,9 @@
   public JavaSourceFinder(String className)
   {
     this.className = className;
+    int dollarSign = className.indexOf('$');
+    if (dollarSign != -1)
+      this.className = className.substring(0, dollarSign);
   }
 
   public IResource getJavaSource()
@@ -47,4 +50,4 @@
     }
     return javaSource == null;
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/ScannableComponent.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/ScannableComponent.java
index b4f788b..da21bca 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/ScannableComponent.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/ScannableComponent.java
@@ -13,27 +13,45 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.wtp.releng.tools.component.IClazz;
 import org.eclipse.wtp.releng.tools.component.ILocation;
+import org.eclipse.wtp.releng.tools.component.internal.Clazz;
+import org.eclipse.wtp.releng.tools.component.model.ComponentDepends;
+import org.eclipse.wtp.releng.tools.component.model.ComponentRef;
 import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
 import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspaceFileLocation;
-import org.eclipse.wtp.releng.tools.component.use.ComponentUse;
+import org.eclipse.wtp.releng.tools.component.ui.internal.job.ScanComponent;
+import org.eclipse.wtp.releng.tools.component.use.Source;
 import org.eclipse.wtp.releng.tools.component.violation.ComponentViolationEmitter;
 
-public class ScannableComponent
+public class ScannableComponent implements IResourceProxyVisitor
 {
   private ComponentXML compXML;
   private ComponentViolationEmitter emitter;
   private List projects;
+  private long lastScan;
+  private List newClasses;
 
   public ScannableComponent(ComponentXML compXML, ComponentViolationEmitter emitter, List projects)
   {
     this.compXML = compXML;
     this.emitter = emitter;
     this.projects = projects;
+    this.lastScan = -1;
+    this.newClasses = new ArrayList();
   }
 
   /**
@@ -62,10 +80,61 @@
     return projects;
   }
 
-  public boolean isScanningComponentXML(IFile file)
+  public void addProject(IProject project)
   {
-    ILocation location = compXML.getLocation();
-    return (location instanceof WorkspaceFileLocation && ((WorkspaceFileLocation)location).getWorkspaceFile() == file);
+    getProjects().add(project);
+    new ScanComponent(this, true).schedule();
+  }
+
+  public IProject removeProject(String projectName)
+  {
+    if (projects != null)
+      for (int i = 0; i < projects.size(); i++)
+        if (((IProject)projects.get(i)).getName().equals(projectName))
+          return (IProject)projects.remove(i);
+    return null;
+  }
+
+  public void addCompRef(ComponentXML compRef)
+  {
+    Map compRefs = emitter.getCompRefs();
+    compRefs.put(compRef.getLocation().getAbsolutePath(), compRef);
+    emitter.setCompRefs(compRefs);
+    if (isDependsOn(compRef.getName()))
+      new ScanComponent(this, true).schedule();
+  }
+
+  public void removeCompRef(ILocation location)
+  {
+    Map compRefs = emitter.getCompRefs();
+    String key = location.getAbsolutePath();
+    if (compRefs.containsKey(key))
+    {
+      ComponentXML compRef = (ComponentXML)compRefs.remove(key);
+      emitter.setCompRefs(compRefs);
+      if (isDependsOn(compRef.getName()))
+      {
+        new ScanComponent(this, true).schedule();
+      }
+    }
+  }
+
+  private boolean isDependsOn(String compRefName)
+  {
+    if (!compRefName.equals(compXML.getName()))
+    {
+      ComponentDepends depends = compXML.getComponentDepends();
+      if (depends.isUnrestricted())
+        return true;
+      else
+      {
+        List compRefs = depends.getComponentRefs();
+        for (Iterator it = compRefs.iterator(); it.hasNext();)
+          if (((ComponentRef)it.next()).getName().equals(compRefName))
+            return true;
+      }
+    }
+    return false;
   }
 
   public boolean isScanningProject(IProject project)
@@ -77,8 +146,55 @@
     return false;
   }
 
-  public ComponentUse scan() throws IOException
+  public List scan() throws IOException
   {
-    return emitter.genComponentViolationXML(compXML.getLocation().getAbsolutePath());
+    return scan(false);
   }
-}
+
+  public synchronized List scan(boolean force) throws IOException
+  {
+    if (force)
+      lastScan = -1;
+    newClasses.clear();
+    List sources = new ArrayList();
+    IJobManager jobManager = Platform.getJobManager();
+    for (int i = 0; i < projects.size(); i++)
+    {
+      IProject project = (IProject)projects.get(i);
+      try
+      {
+        jobManager.beginRule(project, new NullProgressMonitor());
+      }
+      finally
+      {
+        jobManager.endRule(project);
+      }
+      try
+      {
+        project.accept(this, IResource.DEPTH_INFINITE | IResource.NONE);
+      }
+      catch (CoreException e)
+      {
+        // should never happen
+        e.printStackTrace();
+      }
+    }
+    lastScan = Calendar.getInstance().getTimeInMillis();
+    String compLoc = compXML.getLocation().getAbsolutePath();
+    for (Iterator it = newClasses.iterator(); it.hasNext();)
+    {
+      Source source = emitter.genViolation(compLoc, (IClazz)it.next());
+      if (source != null)
+        sources.add(source);
+    }
+    newClasses.clear();
+    return sources;
+  }
+
+  public boolean visit(IResourceProxy resProxy)
+  {
+    if (resProxy.getType() == IResource.FILE && resProxy.getName().endsWith(".class") && resProxy.getModificationStamp() > lastScan)
+      newClasses.add(new Clazz(new WorkspaceFileLocation((IFile)resProxy.requestResource())));
+    return true;
+  }
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/action/ScanAPI.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/action/ScanAPI.java
new file mode 100644
index 0000000..f143f62
--- /dev/null
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/action/ScanAPI.java
@@ -0,0 +1,129 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.wtp.releng.tools.component.ui.internal.action;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionDelegate;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wtp.releng.tools.component.ui.ComponentManager;
+import org.eclipse.wtp.releng.tools.component.ui.internal.ScannableComponent;
+import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspaceFileLocation;
+import org.eclipse.wtp.releng.tools.component.ui.internal.job.ScanComponent;
+import org.eclipse.wtp.releng.tools.component.use.Source;
+
+public class ScanAPI extends Action implements IActionDelegate
+{
+  private ScanComponent job;
+
+  public void run()
+  {
+    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+    if (window != null)
+    {
+      IStructuredSelection selection = (IStructuredSelection)window.getSelectionService().getSelection();
+      if (selection != null && !selection.isEmpty())
+      {
+        Object firstElement = selection.getFirstElement();
+        if (firstElement != null && firstElement instanceof IFile)
+        {
+          ComponentManager manager = ComponentManager.getManager();
+          ScannableComponent scannableComp = getScannableComponent((IFile)firstElement);
+          if (scannableComp != null)
+          {
+            job = new ScanComponent(scannableComp, true);
+            job.schedule();
+            ProgressMonitorDialog dialog = new ProgressMonitorDialog(window.getShell());
+            try
+            {
+              dialog.run(false, false, new IRunnableWithProgress()
+              {
+                public void run(IProgressMonitor monitor)
+                {
+                  boolean interrupted = true;
+                  while (interrupted)
+                  {
+                    try
+                    {
+                      job.join();
+                      interrupted = false;
+                    }
+                    catch (InterruptedException e)
+                    {
+                      interrupted = true;
+                    }
+                  }
+                }
+              });
+            }
+            catch (InterruptedException e)
+            {
+              e.printStackTrace();
+            }
+            catch (InvocationTargetException e)
+            {
+              e.printStackTrace();
+            }
+            if (hasAPIViolation(job.getSources()))
+              MessageDialog.openError(window.getShell(), manager.getMessage("TITLE_HAS_API_VIOLATIONS"), manager.getMessage("ERROR_MSG_HAS_API_VIOLATIONS"));
+            else
+              MessageDialog.openInformation(window.getShell(), manager.getMessage("TITLE_HAS_API_VIOLATIONS"), manager.getMessage("INFO_MSG_NO_API_VIOLATIONS"));
+          }
+          else
+            MessageDialog.openError(window.getShell(), manager.getMessage("TITLE_NO_WORKSPACE_PLUGINS"), manager.getMessage("ERROR_MSG_NO_WORKSPACE_PLUGINS"));
+        }
+      }
+    }
+  }
+
+  private ScannableComponent getScannableComponent(IFile compXML)
+  {
+    for (Iterator it = ComponentManager.getManager().getScannableComponents().values().iterator(); it.hasNext();)
+    {
+      ScannableComponent scannableComp = (ScannableComponent)it.next();
+      String scannableCompLoc = scannableComp.getCompXML().getLocation().getAbsolutePath();
+      String compLoc = new WorkspaceFileLocation(compXML).getAbsolutePath();
+      if (scannableCompLoc.equals(compLoc))
+        return scannableComp;
+    }
+    return null;
+  }
+
+  private boolean hasAPIViolation(List sources)
+  {
+    if (sources != null)
+      for (int i = 0; i < sources.size(); i++)
+        if (((Source)sources.get(i)).getClassUses().size() > 0)
+          return true;
+    return false;
+  }
+
+  public void run(IAction action)
+  {
+    run();
+  }
+
+  public void selectionChanged(IAction action, ISelection selection)
+  {
+  }
+}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIDialog.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIDialog.java
index c1d5071..9d8bfcb 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIDialog.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIDialog.java
@@ -12,24 +12,22 @@
 package org.eclipse.wtp.releng.tools.component.ui.internal.editor;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.wtp.releng.tools.component.ILibrary;
 import org.eclipse.wtp.releng.tools.component.IPluginXML;
 import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
@@ -38,23 +36,32 @@
 import org.eclipse.wtp.releng.tools.component.model.Type;
 import org.eclipse.wtp.releng.tools.component.ui.ComponentManager;
 
-public class APIDialog extends Dialog implements ITreeContentProvider, ILabelProvider
+public class APIDialog extends Dialog implements ITreeContentProvider
 {
-  private Map pluginId2Pkgs;
+  public static final int OPTION_PACKAGE = 0x0;
+  public static final int OPTION_TYPE = 0x1;
+  private int option;
   private ComponentXML compXML;
-  private Tree apis;
-  private List checkedNames;
+  private Package pkg;
+  private List ignoreNames;
+  private Tree tree;
 
-  public APIDialog(Shell shell, ComponentXML compXML)
+  public APIDialog(Shell shell, int option, ComponentXML compXML, Package pkg, List ignoreNames)
   {
     super(shell);
+    this.option = option;
     this.compXML = compXML;
+    this.pkg = pkg;
+    this.ignoreNames = ignoreNames;
   }
 
   protected void configureShell(Shell shell)
   {
     super.configureShell(shell);
-    shell.setText(ComponentManager.getManager().getMessage("DIALOG_TITLE_ADD_APIS"));
+    if (option == OPTION_PACKAGE)
+      shell.setText(ComponentManager.getManager().getMessage("DIALOG_TITLE_ADD_PACKAGES"));
+    else
+      shell.setText(ComponentManager.getManager().getMessage("DIALOG_TITLE_ADD_TYPES"));
   }
 
   protected Control createDialogArea(Composite parent)
@@ -64,22 +71,44 @@
     gl.marginWidth = 5;
     gl.marginHeight = 5;
     GridData gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_VERTICAL);
-    gd.widthHint = 350;
-    gd.heightHint = 400;
+    gd.widthHint = 300;
+    gd.heightHint = 300;
     composite.setLayout(gl);
     composite.setLayoutData(gd);
-    apis = new Tree(composite, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
-    apis.setLayout(gl);
-    apis.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_VERTICAL));
-    TreeViewer apisViewer = new TreeViewer(apis);
+    tree = new Tree(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+    tree.setLayout(gl);
+    tree.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_VERTICAL));
+    TreeViewer apisViewer = new TreeViewer(tree);
     apisViewer.setContentProvider(this);
-    apisViewer.setLabelProvider(this);
+    apisViewer.setLabelProvider(new LabelProvider());
     apisViewer.setInput(compXML);
     return composite;
   }
 
   protected void okPressed()
   {
+    if (option == OPTION_PACKAGE)
+    {
+      List pkgs = compXML.getPackages();
+      TreeItem[] items = tree.getSelection();
+      for (int i = 0; i < items.length; i++)
+      {
+        Package pkg = new Package();
+        pkg.setName(items[i].getText());
+        pkgs.add(pkg);
+      }
+    }
+    else
+    {
+      List types = pkg.getTypes();
+      TreeItem[] items = tree.getSelection();
+      for (int i = 0; i < items.length; i++)
+      {
+        Type type = new Type();
+        type.setName(items[i].getText());
+        types.add(type);
+      }
+    }
     super.okPressed();
   }
 
@@ -98,27 +127,13 @@
     // do nothing
   }
 
-  // ITreeContentProvider
-
   public boolean hasChildren(Object element)
   {
-    return (element instanceof String) || (element instanceof Package);
+    return false;
   }
 
   public Object[] getChildren(Object parentElement)
   {
-    if (parentElement instanceof String)
-    {
-      List pkgs = (List)pluginId2Pkgs.get(parentElement);
-      if (pkgs != null)
-      {
-        return pkgs.toArray(new Package[0]);
-      }
-    }
-    else if (parentElement instanceof Package)
-    {
-      return ((Package)parentElement).getTypes().toArray(new Type[0]);
-    }
     return new Object[0];
   }
 
@@ -129,11 +144,10 @@
 
   public Object[] getElements(Object inputElement)
   {
+    List nameList = new ArrayList();
     if (inputElement instanceof ComponentXML)
     {
       List plugins = ((ComponentXML)inputElement).getPlugins();
-      pluginId2Pkgs = new HashMap(plugins.size());
-      checkedNames = new ArrayList();
       for (Iterator pluginsIt = plugins.iterator(); pluginsIt.hasNext();)
       {
         String pluginId = ((Plugin)pluginsIt.next()).getId();
@@ -151,125 +165,27 @@
               if (typeName.lastIndexOf('$') == -1 && typeName.indexOf(".internal.") == -1)
               {
                 int dot = typeName.lastIndexOf('.');
-                String pkgName;
-                String localName;
-                if (dot != -1)
+                String name = null;
+                if (option == OPTION_PACKAGE && dot != -1)
                 {
-                  pkgName = typeName.substring(0, dot);
-                  localName = typeName.substring(dot + 1);
+                  name = typeName.substring(0, dot);
                 }
                 else
                 {
-                  pkgName = "";
-                  localName = typeName;
+                  String pkgName = pkg.getName();
+                  if (dot != -1 && dot == pkgName.length() && typeName.startsWith(pkgName))
+                  {
+                    name = typeName.substring(dot + 1);
+                  }
                 }
-                Package pkg = addPackage(pluginId, pkgName);
-                Type type = addType(pkg, typeName);
+                if (name != null && !ignoreNames.contains(name) && !nameList.contains(name))
+                  nameList.add(name);
               }
             }
           }
         }
       }
-      return pluginId2Pkgs.keySet().toArray(new String[0]);
     }
-    return new Object[0];
+    return nameList.toArray(new String[0]);
   }
-
-  private Package addPackage(String pluginId, String pkgName)
-  {
-    List pkgs = (List)pluginId2Pkgs.get(pluginId);
-    if (pkgs == null)
-    {
-      pkgs = new ArrayList();
-      pluginId2Pkgs.put(pluginId, pkgs);
-    }
-    if (pkgs.size() > 0)
-    {
-      for (Iterator it = pkgs.iterator(); it.hasNext();)
-      {
-        Package pkg = (Package)it.next();
-        if (pkg.getName().equals(pkgName))
-        {
-          return pkg;
-        }
-      }
-    }
-    for (Iterator it = compXML.getPackages().iterator(); it.hasNext();)
-    {
-      Package pkg = (Package)it.next();
-      if (pkg.getName().equals(pkgName))
-      {
-        Package clone = (Package)pkg.clone();
-        checkedNames.add(pkg.getName());
-        for (Iterator it2 = clone.getTypes().iterator(); it2.hasNext();)
-          checkedNames.add(((Type)it2.next()).getName());
-        pkgs.add(clone);
-        return clone;
-      }
-    }
-    Package pkg = new Package();
-    pkg.setName(pkgName);
-    pkgs.add(pkg);
-    return pkg;
-  }
-
-  private Type addType(Package pkg, String typeName)
-  {
-    List types = pkg.getTypes();
-    if (types.size() > 0)
-    {
-      for (Iterator it = types.iterator(); it.hasNext();)
-      {
-        Type type = (Type)it.next();
-        if (type.getName().equals(typeName))
-        {
-          return type;
-        }
-      }
-    }
-    Type type = new Type();
-    type.setName(typeName);
-    types.add(type);
-    return type;
-  }
-
-  // ILabelProvider
-
-  public void addListener(ILabelProviderListener listener)
-  {
-    // do nothing
-  }
-
-  public boolean isLabelProperty(Object element, String property)
-  {
-    return false;
-  }
-
-  public void removeListener(ILabelProviderListener listener)
-  {
-    // do nothing
-  }
-
-  public Image getImage(Object element)
-  {
-    return null;
-  }
-
-  public String getText(Object element)
-  {
-    if (element instanceof String)
-      return (String)element;
-    else if (element instanceof Package)
-      return ((Package)element).getName();
-    else if (element instanceof Type)
-    {
-      String typeName = ((Type)element).getName();
-      int dot = typeName.lastIndexOf('.');
-      if (dot != -1)
-        return typeName.substring(dot + 1);
-      else
-        return typeName;
-    }
-    return element.toString();
-  }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIPage.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIPage.java
index e6bf17b..addb0ec 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIPage.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/editor/APIPage.java
@@ -11,7 +11,9 @@
 
 package org.eclipse.wtp.releng.tools.component.ui.internal.editor;
 
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
@@ -23,6 +25,8 @@
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.ui.forms.IManagedForm;
@@ -151,30 +155,42 @@
         }
       }
     );
-    Composite buttonComposite = toolkit.createComposite(apiComposite);
-    GridLayout gl3 = new GridLayout();
-    gl3.numColumns = 1;
-    gl3.marginWidth = 1;
-    gl3.marginHeight = 1;
-    buttonComposite.setLayout(gl3);
-    buttonComposite.setLayoutData(new GridData(GridData.GRAB_VERTICAL | GridData.FILL_VERTICAL));
-    Button addAPI = toolkit.createButton(buttonComposite, manager.getMessage("LABEL_ADD"), SWT.PUSH);
-    addAPI.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
-    addAPI.addSelectionListener
+    Menu menu = new Menu(apis);
+    MenuItem addPackage = new MenuItem(menu, SWT.CASCADE);
+    addPackage.setText(manager.getMessage("LABEL_ADD_PACKAGE"));
+    addPackage.addSelectionListener
     (
       new SelectionListener()
       {
         public void widgetSelected(SelectionEvent event)
         {
-          addAPIEvent(event);
+          addPackageEvent(event);
         }
+
         public void widgetDefaultSelected(SelectionEvent event)
         {
-          addAPIEvent(event);
+          addPackageEvent(event);
         }
       }
     );
-    toolkit.paintBordersFor(buttonComposite);
+    MenuItem addType = new MenuItem(menu, SWT.CASCADE);
+    addType.setText(manager.getMessage("LABEL_ADD_TYPE"));
+    addType.addSelectionListener
+    (
+      new SelectionListener()
+      {
+        public void widgetSelected(SelectionEvent event)
+        {
+          addTypeEvent(event);
+        }
+
+        public void widgetDefaultSelected(SelectionEvent event)
+        {
+          addTypeEvent(event);
+        }
+      }
+    );
+    apis.setMenu(menu);
     toolkit.paintBordersFor(apiComposite);
     toolkit.paintBordersFor(parent);
   }
@@ -199,22 +215,85 @@
     usageComposite.setLayout(gl2);
     usageComposite.setLayoutData(gd);
     toolkit.createLabel(usageComposite, manager.getMessage("LABEL_PACKAGE_USAGE"));
+    SelectionListener listener = new SelectionListener()
+    {
+      public void widgetSelected(SelectionEvent event)
+      {
+        selectAPIUsageEvent(event);
+      }
+
+      public void widgetDefaultSelected(SelectionEvent event)
+      {
+        selectAPIUsageEvent(event);
+      }
+    };
     isAPI = toolkit.createButton(usageComposite, manager.getMessage("LABEL_PACKAGE_API"), SWT.CHECK);
     isAPI.setEnabled(false);
+    isAPI.addSelectionListener(listener);
     isExclusive = toolkit.createButton(usageComposite, manager.getMessage("LABEL_PACKAGE_EXCLUSIVE"), SWT.CHECK);
     isExclusive.setEnabled(false);
+    isExclusive.addSelectionListener(listener);
     toolkit.createLabel(usageComposite, manager.getMessage("LABEL_TYPE_USAGE"));
     reference = toolkit.createButton(usageComposite, manager.getMessage("LABEL_REFERENCE"), SWT.CHECK);
     reference.setEnabled(false);
+    reference.addSelectionListener(listener);
     subclass = toolkit.createButton(usageComposite, manager.getMessage("LABEL_SUBCLASS"), SWT.CHECK);
     subclass.setEnabled(false);
+    subclass.addSelectionListener(listener);
     implement = toolkit.createButton(usageComposite, manager.getMessage("LABEL_IMPLEMENT"), SWT.CHECK);
     implement.setEnabled(false);
+    implement.addSelectionListener(listener);
     instantiate = toolkit.createButton(usageComposite, manager.getMessage("LABEL_INSTANTIATE"), SWT.CHECK);
     instantiate.setEnabled(false);
+    instantiate.addSelectionListener(listener);
     toolkit.paintBordersFor(parent);
   }
 
+  private void addPackageEvent(SelectionEvent event)
+  {
+    TreeItem[] items = apis.getItems();
+    List ignoreNames = new ArrayList(items.length);
+    for (int i = 0; i < items.length; i++)
+      ignoreNames.add(items[i].getText());
+    ComponentXMLEditor editor = (ComponentXMLEditor)getEditor();
+    ComponentXML compXML = editor.getComponentXML();
+    APIDialog dialog = new APIDialog(editor.getSite().getShell(), APIDialog.OPTION_PACKAGE, compXML, null, ignoreNames);
+    if (dialog.open() == Dialog.OK)
+    {
+      editor.setDirty(true);
+      apisViewer.refresh();
+    }
+  }
+
+  private void addTypeEvent(SelectionEvent event)
+  {
+    Package pkg = null;
+    TreeItem[] items = apis.getSelection();
+    if (items.length > 0)
+    {
+      Object firstItem = items[0].getData();
+      if (firstItem instanceof Package)
+        pkg = (Package)firstItem;
+      else if (firstItem instanceof Type)
+        pkg = (Package)items[0].getParentItem().getData();
+    }
+    if (pkg != null)
+    {
+      List types = pkg.getTypes();
+      List ignoreNames = new ArrayList(types.size());
+      for (Iterator it = types.iterator(); it.hasNext();)
+        ignoreNames.add(((Type)it.next()).getName());
+      ComponentXMLEditor editor = (ComponentXMLEditor)getEditor();
+      ComponentXML compXML = editor.getComponentXML();
+      APIDialog dialog = new APIDialog(editor.getSite().getShell(), APIDialog.OPTION_TYPE, compXML, pkg, ignoreNames);
+      if (dialog.open() == Dialog.OK)
+      {
+        editor.setDirty(true);
+        apisViewer.refresh();
+      }
+    }
+  }
+
   private void selectAPIEvent(SelectionEvent event)
   {
     Object firstItem = getFirstSelection();
@@ -250,6 +329,21 @@
       instantiate.setEnabled(true);
       instantiate.setSelection(type.isInstantiate());
     }
+    else
+    {
+      isAPI.setEnabled(false);
+      isAPI.setSelection(false);
+      isExclusive.setEnabled(false);
+      isExclusive.setSelection(false);
+      reference.setEnabled(false);
+      reference.setSelection(false);
+      subclass.setEnabled(false);
+      subclass.setSelection(false);
+      implement.setEnabled(false);
+      implement.setSelection(false);
+      instantiate.setEnabled(false);
+      instantiate.setSelection(false);
+    }
   }
 
   private void selectAPIUsageEvent(SelectionEvent event)
@@ -279,16 +373,6 @@
       return null;
   }
 
-  private void addAPIEvent(SelectionEvent event)
-  {
-    ComponentXMLEditor editor = (ComponentXMLEditor)getEditor();
-    APIDialog dialog = new APIDialog(getEditor().getSite().getShell(), editor.getComponentXML());
-    if (dialog.open() == Dialog.OK)
-    {
-      editor.setDirty(true);
-    }
-  }
-
   private void apiKeyEvent(KeyEvent event)
   {
     ComponentXML compXML = ((ComponentXMLEditor)getEditor()).getComponentXML();
@@ -322,4 +406,4 @@
       editor.setDirty(true);
     }
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractModifyMarkersJob.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractModifyMarkersJob.java
index b63db02..d0603f0 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractModifyMarkersJob.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractModifyMarkersJob.java
@@ -112,33 +112,32 @@
 
   private void createMarker(IResource resource, String message, int line) throws CoreException
   {
-    if (ComponentManager.getManager().incrMarkerCount())
+    IJobManager jobManager = Platform.getJobManager();
+    try
     {
-      IJobManager jobManager = Platform.getJobManager();
-      try
-      {
-        jobManager.beginRule(resource, new NullProgressMonitor());
-        IMarker marker = resource.createMarker(IMarker.PROBLEM);
-        marker.setAttribute(ComponentManager.MARKER_COMPONENT_VIOLATION, true);
-        marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
-        marker.setAttribute(IMarker.MESSAGE, message);
-        if (line != -1)
-          marker.setAttribute(IMarker.LINE_NUMBER, line);
-      }
-      catch (Throwable t)
-      {
-        // do nothing here
-      }
-      finally
-      {
-        jobManager.endRule(resource);
-      }
+      jobManager.beginRule(resource, new NullProgressMonitor());
+    }
+    finally
+    {
+      jobManager.endRule(resource);
+    }
+    try
+    {
+      IMarker marker = resource.createMarker(IMarker.PROBLEM);
+      marker.setAttribute(ComponentManager.MARKER_COMPONENT_VIOLATION, true);
+      marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+      marker.setAttribute(IMarker.MESSAGE, message);
+      if (line != -1)
+        marker.setAttribute(IMarker.LINE_NUMBER, line);
+    }
+    catch (Throwable t)
+    {
+      // do nothing here
     }
   }
 
   public void deleteViolationMarksers(IResource res) throws CoreException
   {
-    ComponentManager.getManager().decrMarkerCount();
     IMarker[] markers = res.findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_INFINITE);
     for (int i = 0; i < markers.length; i++)
     {
@@ -148,16 +147,19 @@
         try
         {
           jobManager.beginRule(res, new NullProgressMonitor());
+        }
+        finally
+        {
+          jobManager.endRule(res);
+        }
+        try
+        {
           markers[i].delete();
         }
         catch (Throwable t)
         {
           // do nothing here
         }
-        finally
-        {
-          jobManager.endRule(res);
-        }
       }
     }
   }
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractScanJob.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractScanJob.java
new file mode 100644
index 0000000..d8a17b5
--- /dev/null
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AbstractScanJob.java
@@ -0,0 +1,43 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.wtp.releng.tools.component.ui.internal.job;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.IJobManager;
+
+public abstract class AbstractScanJob extends AbstractModifyMarkersJob
+{
+  public AbstractScanJob(String name)
+  {
+    super(name);
+  }
+
+  protected void joinBuilds()
+  {
+    boolean interrupted = true;
+    while (interrupted)
+    {
+      try
+      {
+        IJobManager jobManager = Platform.getJobManager();
+        jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
+        jobManager.join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null);
+        interrupted = false;
+      }
+      catch (InterruptedException e)
+      {
+        interrupted = true;
+      }
+    }
+  }
+}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AddComponent.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AddComponent.java
index 8258ef6..23c1a9d 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AddComponent.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/AddComponent.java
@@ -46,19 +46,16 @@
       try
       {
         compXML.load();
+        manager.addCompRef(compXML);
         List plugins = compXML.getPlugins();
-        boolean added = false;
         for (Iterator it = plugins.iterator(); it.hasNext();)
         {
           if (manager.isWorkspacePlugin(((Plugin)it.next()).getId()))
           {
             manager.addScannableComponent(compXML);
-            added = true;
             break;
           }
         }
-        if (!added)
-          manager.addCompRef(compXML);
       }
       catch (IOException e)
       {
@@ -67,4 +64,4 @@
     }
     return new Status(IStatus.OK, ComponentUIPlugin.ID, IStatus.OK, "", null);
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/InitComponentManager.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/InitComponentManager.java
new file mode 100644
index 0000000..0235169
--- /dev/null
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/InitComponentManager.java
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+  *
+ * Contributors:
+ *    IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.wtp.releng.tools.component.ui.internal.job;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
+import org.eclipse.wtp.releng.tools.component.model.Plugin;
+import org.eclipse.wtp.releng.tools.component.ui.ComponentManager;
+import org.eclipse.wtp.releng.tools.component.ui.internal.ComponentUIPlugin;
+import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspaceFileLocation;
+
+public class InitComponentManager extends Job implements IResourceProxyVisitor
+{
+  private List scannableComps;
+
+  public InitComponentManager()
+  {
+    super(ComponentManager.getManager().getMessage("JOB_INIT_COMPONENT_MANAGER"));
+  }
+
+  public IStatus run(IProgressMonitor monitor)
+  {
+    init();
+    return new Status(IStatus.OK, ComponentUIPlugin.ID, IStatus.OK, "", null);
+  }
+
+  private void init()
+  {
+    scannableComps = new ArrayList();
+    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+    for (int i = 0; i < projects.length; i++)
+    {
+      try
+      {
+        projects[i].accept(this, IResource.DEPTH_INFINITE | IResource.NONE);
+      }
+      catch (CoreException e)
+      {
+        e.printStackTrace();
+      }
+    }
+    ComponentManager manager = ComponentManager.getManager();
+    for (Iterator it = scannableComps.iterator(); it.hasNext();)
+      manager.addScannableComponent((ComponentXML)it.next());
+    scannableComps = null;
+  }
+
+  public boolean visit(IResourceProxy resProxy)
+  {
+    if (resProxy.getType() == IResource.FILE && resProxy.getName().equals(ComponentXML.CONST_COMPONENT_XML))
+    {
+      IFile file = (IFile)resProxy.requestResource();
+      WorkspaceFileLocation location = new WorkspaceFileLocation(file);
+      ComponentXML compXML = new ComponentXML();
+      compXML.setLocation(location);
+      try
+      {
+        compXML.load();
+      }
+      catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+      ComponentManager manager = ComponentManager.getManager();
+      manager.addCompRef(compXML);
+      List plugins = compXML.getPlugins();
+      for (Iterator it = plugins.iterator(); it.hasNext();)
+      {
+        if (manager.isWorkspacePlugin(((Plugin)it.next()).getId()))
+        {
+          scannableComps.add(compXML);
+          break;
+        }
+      }
+    }
+    return true;
+  }
+}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/RemoveComponent.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/RemoveComponent.java
index d8e5398..c27dab9 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/RemoveComponent.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/RemoveComponent.java
@@ -59,4 +59,4 @@
     manager.removeCompRef(location);
     return status;
   }
-}
+}
\ No newline at end of file
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanClass.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanClass.java
deleted file mode 100644
index 9392611..0000000
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanClass.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
-  *
- * Contributors:
- *    IBM - Initial API and implementation
- **********************************************************************/
-
-package org.eclipse.wtp.releng.tools.component.ui.internal.job;
-
-import java.util.Iterator;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.wtp.releng.tools.component.IClazz;
-import org.eclipse.wtp.releng.tools.component.internal.Clazz;
-import org.eclipse.wtp.releng.tools.component.ui.ComponentManager;
-import org.eclipse.wtp.releng.tools.component.ui.internal.ComponentUIPlugin;
-import org.eclipse.wtp.releng.tools.component.ui.internal.JavaSourceFinder;
-import org.eclipse.wtp.releng.tools.component.ui.internal.ScannableComponent;
-import org.eclipse.wtp.releng.tools.component.ui.internal.WorkspaceFileLocation;
-import org.eclipse.wtp.releng.tools.component.use.ClassUse;
-import org.eclipse.wtp.releng.tools.component.use.Source;
-
-public class ScanClass extends AbstractModifyMarkersJob
-{
-  private IFile classFile;
-
-  public ScanClass(IFile classFile)
-  {
-    super(ComponentManager.getManager().getMessage("JOB_SCAN_CLASS", new String[] {classFile.getFullPath().toString()}));
-    this.classFile = classFile;
-  }
-
-  public IStatus run(IProgressMonitor monitor)
-  {
-    try
-    {
-      for (Iterator it = ComponentManager.getManager().getScannableComponents().values().iterator(); it.hasNext();)
-      {
-        ScannableComponent scannableComp = (ScannableComponent)it.next();
-        IProject project = classFile.getProject();
-        if (scannableComp.isScanningProject(project))
-        {
-          IClazz clazz = new Clazz(new WorkspaceFileLocation(classFile));
-          String name = clazz.getName();
-          JavaSourceFinder javaSourceFinder = new JavaSourceFinder(name);
-          project.accept(javaSourceFinder, IResource.DEPTH_INFINITE | IResource.NONE);
-          IResource javaSource = javaSourceFinder.getJavaSource();
-          if (javaSource != null)
-          {
-            deleteViolationMarksers(javaSource);
-            Source source = (Source)scannableComp.getEmitter().changed(clazz);
-            if (source != null)
-              for (Iterator classUsesIt = source.getClassUses().iterator(); classUsesIt.hasNext();)
-                createClassViolationMarker(javaSource, (ClassUse)classUsesIt.next());
-          }
-          break;
-        }
-      }
-      return new Status(IStatus.OK, ComponentUIPlugin.ID, IStatus.OK, "", null);
-    }
-    catch (Throwable e)
-    {
-      return new Status(IStatus.ERROR, ComponentUIPlugin.ID, IStatus.ERROR, "", e);
-    }
-  }
-}
diff --git a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanComponent.java b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanComponent.java
index 1f101c3..8b75b0c 100644
--- a/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanComponent.java
+++ b/archive/working/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/job/ScanComponent.java
@@ -12,68 +12,117 @@
 package org.eclipse.wtp.releng.tools.component.ui.internal.job;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobManager;
 import org.eclipse.wtp.releng.tools.component.ui.ComponentManager;
 import org.eclipse.wtp.releng.tools.component.ui.internal.ComponentUIPlugin;
 import org.eclipse.wtp.releng.tools.component.ui.internal.JavaSourceFinder;
 import org.eclipse.wtp.releng.tools.component.ui.internal.ScannableComponent;
 import org.eclipse.wtp.releng.tools.component.use.ClassUse;
-import org.eclipse.wtp.releng.tools.component.use.ComponentUse;
 import org.eclipse.wtp.releng.tools.component.use.Source;
 
-public class ScanComponent extends AbstractModifyMarkersJob
+public class ScanComponent extends AbstractScanJob
 {
   private ScannableComponent scannableComponent;
+  private boolean force;
+  private List sources;
 
-  public ScanComponent(ScannableComponent scannableComponent)
+  public ScanComponent(ScannableComponent scannableComponent, boolean force)
   {
     super(ComponentManager.getManager().getMessage("JOB_SCAN_COMPONENT", new String[] {scannableComponent.getCompXML().getName()}));
     this.scannableComponent = scannableComponent;
+    this.force = force;
+    this.sources = null;
+  }
+
+  public ScannableComponent getScannableComponent()
+  {
+    return scannableComponent;
+  }
+
+  public List getSources()
+  {
+    return sources;
   }
 
   public IStatus run(IProgressMonitor monitor)
   {
+    IJobManager jobManager = Platform.getJobManager();
+    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
     try
     {
-      ComponentUse compViolation = scannableComponent.scan();
-      boolean hasAPIViolations = false;
-      List sources = compViolation.getSources();
-      for (Iterator sourcesIt = sources.iterator(); sourcesIt.hasNext();)
-      {
-        Source source = (Source)sourcesIt.next();
-        for (Iterator projectsIt = scannableComponent.getProjects().iterator(); projectsIt.hasNext();)
-        {
-          JavaSourceFinder finder = new JavaSourceFinder(source.getName());
-          ((IProject)projectsIt.next()).accept(finder, IResource.DEPTH_INFINITE | IResource.NONE);
-          IResource javaSource = finder.getJavaSource();
-          if (javaSource != null)
-          {
-            deleteViolationMarksers(javaSource);
-            List classUses = source.getClassUses();
-            for (Iterator it = classUses.iterator(); it.hasNext();)
-            {
-              createClassViolationMarker(javaSource, (ClassUse)it.next());
-              hasAPIViolations = true;
-            }
-          }
-        }
-      }
-      return new Status(IStatus.OK, ComponentUIPlugin.ID, IStatus.OK, "", null);
+      jobManager.beginRule(root, new NullProgressMonitor());
+    }
+    finally
+    {
+      jobManager.endRule(root);
+    }
+    try
+    {
+      sources = scannableComponent.scan(force);
     }
     catch (IOException e)
     {
       return new Status(IStatus.ERROR, ComponentUIPlugin.ID, IStatus.ERROR, "", e);
     }
-    catch (CoreException e)
+    if (sources != null)
     {
-      return new Status(IStatus.ERROR, ComponentUIPlugin.ID, IStatus.ERROR, "", e);
+      List innerClasses = new ArrayList();
+      for (Iterator sourcesIt = sources.iterator(); sourcesIt.hasNext();)
+      {
+        Source source = (Source)sourcesIt.next();
+        String sourceName = source.getName();
+        if (sourceName.indexOf('$') == -1)
+          createMarker(sourceName, source.getClassUses(), false);
+        else
+          innerClasses.add(source);
+      }
+      for (Iterator it = innerClasses.iterator(); it.hasNext();)
+      {
+        Source source = (Source)it.next();
+        createMarker(source.getName(), source.getClassUses(), true);
+      }
+    }
+    return new Status(IStatus.OK, ComponentUIPlugin.ID, IStatus.OK, "", null);
+  }
+
+  private void createMarker(String sourceName, List classUses, boolean isInnerClass)
+  {
+    List projects = scannableComponent.getProjects();
+    for (Iterator projectsIt = projects.iterator(); projectsIt.hasNext();)
+    {
+      JavaSourceFinder finder = new JavaSourceFinder(sourceName);
+      try
+      {
+        ((IProject)projectsIt.next()).accept(finder, IResource.DEPTH_INFINITE | IResource.NONE);
+        IResource javaSource = finder.getJavaSource();
+        if (javaSource != null)
+        {
+          if (!isInnerClass)
+            deleteViolationMarksers(javaSource);
+          for (Iterator it = classUses.iterator(); it.hasNext();)
+          {
+            createClassViolationMarker(javaSource, (ClassUse)it.next());
+          }
+        }
+      }
+      catch (CoreException e)
+      {
+        // should never happen
+        e.printStackTrace();
+      }
     }
   }
-}
+}
\ No newline at end of file