gt:         CtClass cached = (CtClass)classes.get(classname);
context: /*
   * Javassist, a Java-bytecode translator toolkit.
   * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
   *
   * The contents of this file are subject to the Mozilla Public License Version
   * 1.1 (the "License"); you may not use this file except in compliance with
   * the License.  Alternatively, the contents of this file may be used under
   * the terms of the GNU Lesser General Public License Version 2.1 or later.
   *
   * Software distributed under the License is distributed on an "AS IS" basis,
   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   * for the specific language governing rights and limitations under the
   * License.
   */
  
  package javassist.scopedpool;
  
  import java.lang.ref.WeakReference;
  import java.security.ProtectionDomain;
  import java.util.Iterator;
  import java.util.Map;
  import javassist.CannotCompileException;
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.LoaderClassPath;
  import javassist.NotFoundException;
  
  /**
   * A scoped class pool.
   * 
   * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
   * @author <a href="adrian@jboss.com">Adrian Brock</a>
   * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
   * @version $Revision: 1.8 $
   */
  public class ScopedClassPool extends ClassPool {
      protected ScopedClassPoolRepository repository;
  
      protected WeakReference classLoader;
  
      protected LoaderClassPath classPath;
  
      protected SoftValueHashMap softcache = new SoftValueHashMap();
      
      boolean isBootstrapCl = true;
  
      static {
          ClassPool.doPruning = false;
          ClassPool.releaseUnmodifiedClassFile = false;
      }
  
      /**
       * Create a new ScopedClassPool.
       * 
       * @param cl
       *            the classloader
       * @param src
       *            the original class pool
       * @param repository
       *            the repository
       *@deprecated
       */
      protected ScopedClassPool(ClassLoader cl, ClassPool src,
              ScopedClassPoolRepository repository) {
         this(cl, src, repository, false);
      }
      
      /**
       * Create a new ScopedClassPool.
       * 
       * @param cl
       *            the classloader
       * @param src
       *            the original class pool
       * @param repository
       *            the repository
       * @param isTemp
       *            Whether this is a temporary pool used to resolve references
       */
      protected ScopedClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository, boolean isTemp)
      {
         super(src);
         this.repository = repository;
         this.classLoader = new WeakReference(cl);
         if (cl != null) {
             classPath = new LoaderClassPath(cl);
             this.insertClassPath(classPath);
         }
         childFirstLookup = true;
         if (!isTemp && cl == null)
         {
            isBootstrapCl = true;
         }
      }
  
      /**
       * Get the class loader
       * 
       * @return the class loader
       */
      public ClassLoader getClassLoader() {
         ClassLoader cl = getClassLoader0();
         if (cl == null && !isBootstrapCl)
         {
            throw new IllegalStateException(
                    "ClassLoader has been garbage collected");
         }
         return cl;
      }
  
      protected ClassLoader getClassLoader0() {
         return (ClassLoader)classLoader.get();
      }
  
      /**
       * Close the class pool
       */
      public void close() {
          this.removeClassPath(classPath);
          classPath.close();
          classes.clear();
          softcache.clear();
      }
  
      /**
       * Flush a class
       * 
       * @param classname
       *            the class to flush
       */
      public synchronized void flushClass(String classname) {
          classes.remove(classname);
          softcache.remove(classname);
      }
  
      /**
       * Soften a class
       * 
       * @param clazz
       *            the class
       */
      public synchronized void soften(CtClass clazz) {
          if (repository.isPrune())
              clazz.prune();
          classes.remove(clazz.getName());
          softcache.put(clazz.getName(), clazz);
      }
  
      /**
       * Whether the classloader is loader
       * 
       * @return false always
       */
      public boolean isUnloadedClassLoader() {
          return false;
      }
  
      /**
       * Get the cached class
       * 
       * @param classname
       *            the class name
       * @return the class
       */
      protected CtClass getCached(String classname) {
          CtClass clazz = getCachedLocally(classname);
          if (clazz == null) {
              boolean isLocal = false;
  
              ClassLoader dcl = getClassLoader0();
              if (dcl != null) {
                  final int lastIndex = classname.lastIndexOf('$');
                  String classResourceName = null;
                  if (lastIndex < 0) {
                      classResourceName = classname.replaceAll("[\\.]", "/")
                              + ".class";
                  }
                  else {
                      classResourceName = classname.substring(0, lastIndex)
                              .replaceAll("[\\.]", "/")
                              + classname.substring(lastIndex) + ".class";
                  }
  
                  isLocal = dcl.getResource(classResourceName) != null;
              }
  
              if (!isLocal) {
                  Map registeredCLs = repository.getRegisteredCLs();
                  synchronized (registeredCLs) {
                      Iterator it = registeredCLs.values().iterator();
                      while (it.hasNext()) {
                          ScopedClassPool pool = (ScopedClassPool)it.next();
                          if (pool.isUnloadedClassLoader()) {
                              repository.unregisterClassLoader(pool
                                      .getClassLoader());
                              continue;
                          }
  
                          clazz = pool.getCachedLocally(classname);
                          if (clazz != null) {
                              return clazz;
                          }
                      }
                  }
              }
          }
          // *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!!
          return clazz;
      }
  
      /**
       * Cache a class
       * 
       * @param classname
       *            the class name
       * @param c
       *            the ctClass
       * @param dynamic
       *            whether the class is dynamically generated
       */
      protected void cacheCtClass(String classname, CtClass c, boolean dynamic) {
          if (dynamic) {
              super.cacheCtClass(classname, c, dynamic);
          }
          else {
              if (repository.isPrune())
                  c.prune();
              softcache.put(classname, c);
          }
      }
  
      /**
       * Lock a class into the cache
       * 
       * @param c
       *            the class
       */
      public void lockInCache(CtClass c) {
          super.cacheCtClass(c.getName(), c, false);
      }
  
      /**
       * Whether the class is cached in this pooled
       * 
       * @param classname
       *            the class name
       * @return the cached class
       */
      protected CtClass getCachedLocally(String classname) {
  