public Map<String, Object> createModel(ScriptContext scriptContext) {
    Map<String, Object> model = new HashMap<>();
    Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
    for (Object entryObj : bindings.entrySet()) {
      Map.Entry<?, ?> entry = (Map.Entry<?, ?>) entryObj;
      model.put((String) entry.getKey(), entry.getValue());
    }

    model.put("properties", new ScriptContextAdapter(scriptContext).getResource().getValueMap());
    return model;
  }
  private ScriptEngines createScriptEngines() {
    // plugins already on the path - ones static to the classpath
    final List<GremlinPlugin> globalPlugins = new ArrayList<>();
    ServiceLoader.load(GremlinPlugin.class).forEach(globalPlugins::add);

    return new ScriptEngines(
        se -> {
          // this first part initializes the scriptengines Map
          for (Map.Entry<String, EngineSettings> config : settings.entrySet()) {
            final String language = config.getKey();
            se.reload(
                language,
                new HashSet<>(config.getValue().getImports()),
                new HashSet<>(config.getValue().getStaticImports()),
                config.getValue().getConfig());
          }

          // use grabs dependencies and returns plugins to load
          final List<GremlinPlugin> pluginsToLoad = new ArrayList<>(globalPlugins);
          use.forEach(
              u -> {
                if (u.size() != 3)
                  logger.warn(
                      "Could not resolve dependencies for [{}].  Each entry for the 'use' configuration must include [groupId, artifactId, version]",
                      u);
                else {
                  logger.info("Getting dependencies for [{}]", u);
                  pluginsToLoad.addAll(se.use(u.get(0), u.get(1), u.get(2)));
                }
              });

          // now that all dependencies are in place, the imports can't get messed up if a plugin
          // tries to execute
          // a script (as the script engine appends the import list to the top of all scripts passed
          // to the engine).
          // only enable those plugins that are configured to be enabled.
          se.loadPlugins(
              pluginsToLoad
                  .stream()
                  .filter(plugin -> enabledPlugins.contains(plugin.getName()))
                  .collect(Collectors.toList()));

          // initialization script eval can now be performed now that dependencies are present with
          // "use"
          for (Map.Entry<String, EngineSettings> config : settings.entrySet()) {
            final String language = config.getKey();

            // script engine initialization files that fail will only log warnings - not fail server
            // initialization
            final AtomicBoolean hasErrors = new AtomicBoolean(false);
            config
                .getValue()
                .getScripts()
                .stream()
                .map(File::new)
                .filter(
                    f -> {
                      if (!f.exists()) {
                        logger.warn(
                            "Could not initialize {} ScriptEngine with {} as file does not exist",
                            language,
                            f);
                        hasErrors.set(true);
                      }

                      return f.exists();
                    })
                .map(
                    f -> {
                      try {
                        return Pair.with(f, Optional.of(new FileReader(f)));
                      } catch (IOException ioe) {
                        logger.warn(
                            "Could not initialize {} ScriptEngine with {} as file could not be read - {}",
                            language,
                            f,
                            ioe.getMessage());
                        hasErrors.set(true);
                        return Pair.with(f, Optional.<FileReader>empty());
                      }
                    })
                .filter(p -> p.getValue1().isPresent())
                .map(p -> Pair.with(p.getValue0(), p.getValue1().get()))
                .forEachOrdered(
                    p -> {
                      try {
                        final Bindings bindings = new SimpleBindings();
                        bindings.putAll(this.globalBindings);

                        // evaluate init scripts with hard reference so as to ensure it doesn't get
                        // garbage collected
                        bindings.put(
                            GremlinGroovyScriptEngine.KEY_REFERENCE_TYPE,
                            GremlinGroovyScriptEngine.REFERENCE_TYPE_HARD);

                        se.eval(p.getValue1(), bindings, language);

                        // re-assign graph bindings back to global bindings and grab TraversalSource
                        // creations.
                        // prevent assignment of non-graph implementations just in case someone
                        // tries to overwrite
                        // them in the init
                        bindings
                            .entrySet()
                            .stream()
                            .filter(promoteBinding)
                            .forEach(kv -> this.globalBindings.put(kv.getKey(), kv.getValue()));

                        logger.info("Initialized {} ScriptEngine with {}", language, p.getValue0());
                      } catch (ScriptException sx) {
                        hasErrors.set(true);
                        logger.warn(
                            "Could not initialize {} ScriptEngine with {} as script could not be evaluated - {}",
                            language,
                            p.getValue0(),
                            sx.getMessage());
                      }
                    });
          }
        });
  }