class ScriptResource extends JobRelatedResource {
    protected static ScriptEngineManager MANAGER = new ScriptEngineManager();
    // oddly, ordering is different each call to getEngineFactories, so cache
    protected static LinkedList<ScriptEngineFactory> FACTORIES = new LinkedList<ScriptEngineFactory>();
    static {
        FACTORIES.addAll(MANAGER.getEngineFactories());
        // Sort factories alphabetically so that they appear in the UI consistently
        Collections.sort(FACTORIES, new Comparator<ScriptEngineFactory>() {
            @Override
            public int compare(ScriptEngineFactory sef1, ScriptEngineFactory sef2) {
                return sef1.getEngineName().compareTo(sef2.getEngineName());
            }
        });
    }
    
    protected String chosenEngine = FACTORIES.isEmpty() ? "" : FACTORIES.getFirst().getNames().get(0);

    @Override
    public void init(Context ctx, Request req, Response res) throws ResourceException {
        super.init(ctx, req, res);
        getVariants().add(new Variant(MediaType.TEXT_HTML));
        getVariants().add(new Variant(MediaType.APPLICATION_XML));

        scriptingConsole = new ScriptingConsole(cj);
    }

    private ScriptingConsole scriptingConsole;
    
    @Override
    public Representation post(Representation entity, Variant variant) throws ResourceException {<FILL_FUNCTION_BODY>}

    @Override
    public Representation get(Variant variant) throws ResourceException {
        if (variant.getMediaType() == MediaType.APPLICATION_XML) {
            return new WriterRepresentation(MediaType.APPLICATION_XML) {
                public void write(Writer writer) throws IOException {
                    XmlMarshaller.marshalDocument(writer,"script", makeDataModel());
                }
            };
        } else {
            ViewModel viewModel = new ViewModel();
            viewModel.put("baseResourceRef", getRequest().getRootRef().toString() + "/engine/static/");
            viewModel.put("model", makeDataModel());
            viewModel.put("selectedEngine", chosenEngine);
            viewModel.put("staticRef", getStaticRef(""));
            return render("Script.ftl", viewModel);
        }
    }

    protected Collection<Map<String,String>> getAvailableScriptEngines() {
        List<Map<String,String>> engines = new LinkedList<Map<String,String>>();
        for (ScriptEngineFactory f: FACTORIES) {
            Map<String,String> engine = new LinkedHashMap<String, String>();
            engine.put("engine", f.getNames().get(0));
            engine.put("language", f.getLanguageName());
            engines.add(engine);
        }
        return engines;
    }

    /**
     * Constructs a nested Map data structure with the information represented
     * by this Resource. The result is particularly suitable for use with with
     * {@link XmlMarshaller}.
     * 
     * @return the nested Map data structure
     */
    protected ScriptModel makeDataModel() {
        
        String baseRef = getRequest().getResourceRef().getBaseRef().toString();
        if(!baseRef.endsWith("/")) {
            baseRef += "/";
        }
        Reference baseRefRef = new Reference(baseRef);
        
        ScriptModel model = new ScriptModel(scriptingConsole,
                new Reference(baseRefRef, "..").getTargetRef().toString(),
                getAvailableScriptEngines());

        return model;
    }
}

        Form form = new Form(entity);
        chosenEngine = form.getFirstValue("engine");
        String script = form.getFirstValue("script");
        if(StringUtils.isBlank(script)) {
            script="";
        }

        ScriptEngine eng = MANAGER.getEngineByName(chosenEngine);
        
        scriptingConsole.bind("scriptResource",  this);
        scriptingConsole.execute(eng, script);
        scriptingConsole.unbind("scriptResource");
        
        //TODO: log script, results somewhere; job log INFO? 
        
        return get(variant);
    
<methods>public non-sealed void <init>() ,public void init(Context, Request, Response) <variables>protected static HashSet<java.lang.String> HIDDEN_PROPS,private static final java.util.logging.Logger LOGGER,protected IdentityHashMap<java.lang.Object,java.lang.String> beanToNameMap,protected org.archive.crawler.framework.CrawlJob cj