// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/CachedScriptCompilation.java
// public class CachedScriptCompilation implements ScriptCompilation {
// 
//   /**
//    * We cache compiled scripts to save time during initialization and tests.
//    */
//   private class CompilationKey {
// 
//     private final WeakReference<Context> context;
//     private final String source;
//     private final String name;
//     private final int hash;
// 
//     public CompilationKey(Context context, String source, String name) {
//       this.context = new WeakReference<Context>(context);
//       this.source = source;
//       this.name = name;
//       this.hash = Objects.hashCode(source, name);
//     }
// 
// 
//     @Override
//     public boolean equals(Object o) {
//       if (this == o) {
//         return true;
//       }
//       if (o == null || getClass() != o.getClass()) {
//         return false;
//       }
// 
//       CompilationKey other = (CompilationKey) o;
// 
//       return this.hash == other.hash
//           && this.name.equals(other.name)
//           && this.source.equals(other.source);
//     }
// 
// 
//     @Override
//     public int hashCode() {
//       return this.hash;
//     }
//   }
// 
//   private final LoadingCache<CompilationKey, Script> compilationCache;
// 
// 
//   public CachedScriptCompilation(final ScriptCompilation compilation) {
//     this.compilationCache = CacheBuilder.newBuilder()
//         .maximumSize(500)
//         .build(new CacheLoader<CompilationKey, Script>() {
//           @Override
//           public org.mozilla.javascript.Script load(CompilationKey key) throws Exception {
//             return compilation.compile(key.context.get(), key.name, key.source);
//           }
//         });
//   }
// 
// 
//   @Override
//   public Script compile(Context c, String name, String source) {
//     return this.compilationCache.getUnchecked(new CompilationKey(c, source, name));
//   }
// 
// }
// 
// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/ScriptCompilation.java
// public interface ScriptCompilation {
// 
//   Script compile(Context c, String name, String source);
// 
// }
// 
// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/SimpleScriptCompilation.java
// public class SimpleScriptCompilation implements ScriptCompilation {
// 
//   private final int optimizationLevel;
// 
// 
//   public SimpleScriptCompilation(int optimizationLevel) {
//     this.optimizationLevel = optimizationLevel;
//   }
// 
// 
//   @Override
//   public Script compile(Context c, String name, String source) {
//     int oldLevel = c.getOptimizationLevel();
//     c.setOptimizationLevel(this.optimizationLevel);
//     Script result = c.compileString(source, name, 1, null);
//     c.setOptimizationLevel(oldLevel);
//     return result;
//   }
// 
// }


import com.cueup.hegemon.annotations.ReferencedByJavascript;
import com.cueup.hegemon.compilation.CachedScriptCompilation;
import com.cueup.hegemon.compilation.ScriptCompilation;
import com.cueup.hegemon.compilation.SimpleScriptCompilation;
import com.google.common.base.Splitter;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EcmaError;
import org.mozilla.javascript.NativeJavaClass;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Wrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
   * @param globalFiles - Files to load to run this source.
   * @throws LoadError when files don't load properly.
   */
  public Script(final String name,
                final String source,
                final LoadPath loadPath,
                final String... globalFiles) throws LoadError {
    this(name, source, new CachedScriptCompilation(new SimpleScriptCompilation(0)), loadPath, globalFiles);
  }


  /**
   * Load a new script context from a source, found with a locator,
   * loading globalFiles. 'hegemon/core' is loaded by default.
   *
   * For each file in globalFiles, a module will be loaded and a variable with the name of the globalFile's basename
   * will be injected into the environment. For example, passing a name to globalFiles like "foo/bar/baz" will result
   * in `baz` being made available in the script, just as `let baz = core.load('foo/bar/baz');` had been written.
   *
   * @param name - The name of the script.
   * @param source - The source code to be run.
   * @param scriptCompilation - The compilation strategy to use.
   * @param loadPath - How to find any files loaded.
   * @param globalFiles - Files to load to run this source.
   * @throws LoadError when files don't load properly.
   */
  public Script(final String name,
                final String source,
                final ScriptCompilation scriptCompilation,
                final LoadPath loadPath,
// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/CachedScriptCompilation.java
// public class CachedScriptCompilation implements ScriptCompilation {
// 
//   /**
//    * We cache compiled scripts to save time during initialization and tests.
//    */
//   private class CompilationKey {
// 
//     private final WeakReference<Context> context;
//     private final String source;
//     private final String name;
//     private final int hash;
// 
//     public CompilationKey(Context context, String source, String name) {
//       this.context = new WeakReference<Context>(context);
//       this.source = source;
//       this.name = name;
//       this.hash = Objects.hashCode(source, name);
//     }
// 
// 
//     @Override
//     public boolean equals(Object o) {
//       if (this == o) {
//         return true;
//       }
//       if (o == null || getClass() != o.getClass()) {
//         return false;
//       }
// 
//       CompilationKey other = (CompilationKey) o;
// 
//       return this.hash == other.hash
//           && this.name.equals(other.name)
//           && this.source.equals(other.source);
//     }
// 
// 
//     @Override
//     public int hashCode() {
//       return this.hash;
//     }
//   }
// 
//   private final LoadingCache<CompilationKey, Script> compilationCache;
// 
// 
//   public CachedScriptCompilation(final ScriptCompilation compilation) {
//     this.compilationCache = CacheBuilder.newBuilder()
//         .maximumSize(500)
//         .build(new CacheLoader<CompilationKey, Script>() {
//           @Override
//           public org.mozilla.javascript.Script load(CompilationKey key) throws Exception {
//             return compilation.compile(key.context.get(), key.name, key.source);
//           }
//         });
//   }
// 
// 
//   @Override
//   public Script compile(Context c, String name, String source) {
//     return this.compilationCache.getUnchecked(new CompilationKey(c, source, name));
//   }
// 
// }
// 
// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/ScriptCompilation.java
// public interface ScriptCompilation {
// 
//   Script compile(Context c, String name, String source);
// 
// }
// 
// Path: hegemon-core/src/main/java/com/cueup/hegemon/compilation/SimpleScriptCompilation.java
// public class SimpleScriptCompilation implements ScriptCompilation {
// 
//   private final int optimizationLevel;
// 
// 
//   public SimpleScriptCompilation(int optimizationLevel) {
//     this.optimizationLevel = optimizationLevel;
//   }
// 
// 
//   @Override
//   public Script compile(Context c, String name, String source) {
//     int oldLevel = c.getOptimizationLevel();
//     c.setOptimizationLevel(this.optimizationLevel);
//     Script result = c.compileString(source, name, 1, null);
//     c.setOptimizationLevel(oldLevel);
//     return result;
//   }
// 
// }


// Path: hegemon-core/src/main/java/com/cueup/hegemon/Script.java
import com.cueup.hegemon.annotations.ReferencedByJavascript;
import com.cueup.hegemon.compilation.CachedScriptCompilation;
import com.cueup.hegemon.compilation.ScriptCompilation;
import com.cueup.hegemon.compilation.SimpleScriptCompilation;
import com.google.common.base.Splitter;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EcmaError;
import org.mozilla.javascript.NativeJavaClass;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Wrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

   * @param globalFiles - Files to load to run this source.
   * @throws LoadError when files don't load properly.
   */
  public Script(final String name,
                final String source,
                final LoadPath loadPath,
                final String... globalFiles) throws LoadError {
    this(name, source, new CachedScriptCompilation(new SimpleScriptCompilation(0)), loadPath, globalFiles);
  }


  /**
   * Load a new script context from a source, found with a locator,
   * loading globalFiles. 'hegemon/core' is loaded by default.
   *
   * For each file in globalFiles, a module will be loaded and a variable with the name of the globalFile's basename
   * will be injected into the environment. For example, passing a name to globalFiles like "foo/bar/baz" will result
   * in `baz` being made available in the script, just as `let baz = core.load('foo/bar/baz');` had been written.
   *
   * @param name - The name of the script.
   * @param source - The source code to be run.
   * @param scriptCompilation - The compilation strategy to use.
   * @param loadPath - How to find any files loaded.
   * @param globalFiles - Files to load to run this source.
   * @throws LoadError when files don't load properly.
   */
  public Script(final String name,
                final String source,
                final ScriptCompilation scriptCompilation,
                final LoadPath loadPath,
                final String... globalFiles) throws LoadError {