public Class defineClass(ICompilableTypeInternal gsClass, boolean useSingleServingLoader)
      throws ClassNotFoundException {
    try {
      if (gsClass instanceof IGosuClassInternal
          && ((IGosuClassInternal) gsClass).hasBackingClass()) {
        return ((IGosuClassInternal) gsClass).getBackingClass();
      }

      // there is no point in defining eval classes in a single serving class loader (it wastes
      // memory)
      if (useSingleServingLoader
          || TypeLord.isEvalProgram(gsClass)
          || isThrowawayProgram(gsClass)
          || isEnclosingTypeInSingleServingLoader(gsClass)
          || hasDiscreteNamespace(gsClass.getNamespace())) {
        // These classes are "fire and forget"; they need to be disposable after they run,
        // so we load them in a separate class loader so we can unload them -- it's the only
        // way to unload a class in java.
        return defineClassInLoader(gsClass, true);
      }

      return findOrDefineClass(gsClass);
    } catch (Exception e) {
      throw GosuExceptionUtil.forceThrow(e, gsClass.getName());
    }
  }
 private boolean shouldUseSingleServingLoader(ICompilableTypeInternal gsClass) {
   List<IGosuClassLoadingObserver> observers =
       CommonServices.getEntityAccess().getGosuClassLoadingObservers();
   if (observers != null) {
     for (IGosuClassLoadingObserver observer : observers) {
       if (observer.shouldUseSingleServingLoader(gsClass)) {
         return true;
       }
     }
   }
   return hasDiscreteNamespace(gsClass.getNamespace());
 }
 private SingleServingGosuClassLoader getOrCreateSingleServingLoader(
     ICompilableTypeInternal gsClass) {
   ICompilableTypeInternal enclosingType = gsClass.getEnclosingType();
   ClassLoader enclosingLoader =
       isOldStyleGosuAnnotationExpression(gsClass) ? null : getClassLoader(enclosingType);
   if (enclosingLoader instanceof SingleServingGosuClassLoader) {
     return (SingleServingGosuClassLoader) enclosingLoader;
   }
   SingleServingGosuClassLoader namespaceLoader =
       getDiscreteNamespaceLoader(gsClass.getNamespace());
   return namespaceLoader == null ? new SingleServingGosuClassLoader(this) : namespaceLoader;
 }