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());
    }
  }