/* (non-Javadoc)
   * @see javassist.Translator#onWrite(javassist.ClassPool, java.lang.String)
   */
  public void onWrite(ClassPool pool, String classname)
      throws NotFoundException, CannotCompileException {

    // LOG.info(++logCounter+" Searching component for "+classname+" in repository with #cop =
    // "+ComponentRepository.Instance().getComponentResources().size());
    //  COMPONENT MUST HAVE BEEN PUT IN REPOSITORY MAP ALREADY (before initComponent())
    IComponentResource loadingCop =
        UpgradeableComponentResourceFactory.getComponentResourceByContent(classname);

    /* DEBUGGING ONLY: check if have to load from dependency: // MUST NOT happen: load from wrong cop!!!
    if (loadingCop == null) {
    	LOG.error(cp+" "+v+": class "+classname+" belongs to no cop ");
    	return;
    } else if( !((UpgradeableComponentResource)loadingCop).contains(classname))  {
    	// wrong cop: hack , check for loadingCop.knowsClass(classname) instead
    	LOG.error(cp+" "+v+": class "+classname+" belongs not to cop "+loadingCop);
    	return;

    }*/
    String cb = ProxyComponentResourceFactory.getProxyCodebase(loadingCop);
    IComponentResource proxyCop = ComponentRepository.Instance().getComponentResourceByCodebase(cb);
    if (proxyCop instanceof ProxyComponentResource) {
      // during an upgrade, check if current version of cop was retreived
      loadingCop = ((ProxyComponentResource) proxyCop).getOriginalComponent();
    }

    // LOG.info(loadingCop+", "+loadingCop.getVersion()+": pool.get("+classname+")");
    // if (loadingCop instanceof ProxyComponentResource) return;

    int extRefCount = searchExternalReferences(classname, pool, loadingCop);
    if (extRefCount == 0) return;
    CtClass toManipulate = pool.get(classname);
    manipulate(classname, toManipulate, extRefCount);
  }
  /**
   * looks for classes that are referenced within the code of the class named <code>classname</code>
   * that do neither belong to system classes nor to the same component as the class searched. Any
   * external reference found must belong to a dependency component of the component of the class
   * being searched. For each occurrence of such an external reference, <code>foundExternalReference
   * </code> is invoked.
   *
   * @param classname
   * @param pool
   * @param loadingCop
   * @return
   */
  protected int searchExternalReferences(
      String classname, ClassPool pool, IComponentResource loadingCop) {
    //		LOG.info(logCounter+"                     found it ... in pool
    // "+loadingCop.getExtResLocation() + loadingCop.getCodeBase());
    // search for external references in code of class "className" using CtClass.getRefClasses() and
    // create an externalPool for each cop in dependencies
    CtClass toSearch = null;
    try {
      // LOG.info(cp+" "+v+": searching for external references in "+classname);
      toSearch = pool.get(classname);

      CtClass[] ifcs = toSearch.getInterfaces();
      CtClass superClass = toSearch.getSuperclass();

    } catch (IllegalStateException e) {
      LOG.error("Zipfile is not open", e);
    } catch (NotFoundException e) {
      LOG.error(
          "javassist.NotFoundException: class " + classname + " not found in " + cp + " " + v);

      throw new RuntimeException(); // loadClassBytes fails -> loadFromDep
    }
    Vector externalClasses = new Vector();
    Iterator referencedClasses = toSearch.getRefClasses().iterator();
    int extRefCount = 0;
    while (referencedClasses.hasNext()) {
      String toWrap = (String) referencedClasses.next();
      IComponentResource dependencyCop;
      Object cached = class2cop.get(toSearch.getName());
      if (cached instanceof UpgradeableComponentResource) {
        dependencyCop = (UpgradeableComponentResource) cached;
      } else {
        dependencyCop = UpgradeableComponentResourceFactory.getComponentResourceByContent(toWrap);
      }
      if ((dependencyCop instanceof UpgradeableComponentResource)
          && (!loadingCop
              .getCodeBase()
              .equals(
                  dependencyCop
                      .getCodeBase()))) { // compare jar names (different versions are considered
                                          // equal: java.** and internal Classes seems to be
                                          // external of new cop version (found inside old cop
                                          // version))
        // a dependency that may be uncoupled has been found
        // dependency is ignored if the dependency class is already hidden behind a proxy
        // or the dependency class may be in use already or the dependency class lies in a previous
        // version of the loading cop
        // LOG.info("Found dependency to external class "+toWrap+" in cop "+dependencyCop+" while
        // loading class "+toSearch.getName()+" in cop "+loadingCop);

        foundExternalReference(loadingCop, toWrap, (UpgradeableComponentResource) dependencyCop);

        extRefCount++;
      } else {
        // if (dependencyCop == null) LOG.error("Nullpointer, dependencyCop is null (system
        // class?)");
        // else if (dependencyCop != loadingCop) LOG.info("dependency is NOT evolvable
        // "+dependencyCop.getCodeBase()+" : "+dependencyCop.getClass().getName());
      }
    }
    // LOG.info(logCounter+" onWrite: Found "+extRefCount+" external reference(s) in
    // "+loadingCop.getCodeBase()+"."+classname);
    return extRefCount;
  }