// Path: core/src/main/java/com/sinnerschrader/aem/react/ReactScriptEngine.java
// public static class RenderResult {
//   public String html;
//   public String cache;
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/api/Cqx.java
// public class Cqx {
// 
// 	private Sling sling;
// 	private OsgiServiceFinder finder;
// 	private ModelFactory modelFactory;
// 
// 	public Cqx(Sling sling, OsgiServiceFinder finder, ModelFactory modelFactory) {
// 		super();
// 		this.sling = sling;
// 		this.finder = finder;
// 		this.modelFactory = modelFactory;
// 	}
// 
// 	/**
// 	 * get an osgi service
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getOsgiService(String name) {
// 		return finder.get(name);
// 	}
// 
// 	/**
// 	 * get a request sling model
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getRequestModel(String path, String name) {
// 		return modelFactory.createRequestModel(path, name);
// 	}
// 
// 	/**
// 	 * get a resource sling model
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getResourceModel(String path, String name) {
// 		return modelFactory.createResourceModel(path, name);
// 	}
// 
// 	/**
// 	 * get access to resource via the sling objects
// 	 * 
// 	 * @return
// 	 */
// 	public Sling getSling() {
// 		return sling;
// 	}
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/exception/TechnicalException.java
// public class TechnicalException extends RuntimeException {
// 
// 	private static final long serialVersionUID = 3287666209672379245L;
// 
// 	public TechnicalException (String msg, Throwable cause) {
// 		super(msg, cause);
// 	}
// 
//   public TechnicalException(String msg) {
//     super(msg);
//   }
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/loader/HashedScript.java
// public class HashedScript {
//   private String checksum;
//   private String script;
//   private String id;
// 
//   public HashedScript(String checksum, String script, String id) {
//     super();
//     this.checksum = checksum;
//     this.script = script;
//     this.id = id;
//   }
// 
//   /**
//    *
//    * @return checksum of javascript
//    */
//   public String getChecksum() {
//     return checksum;
//   }
// 
//   /**
//    *
//    * @return javascript
//    */
//   public String getScript() {
//     return script;
//   }
// 
//   /**
//    *
//    * @return path to javascript
//    */
//   public String getId() {
//     return id;
//   }
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/loader/ScriptCollectionLoader.java
// public interface ScriptCollectionLoader {
//   /**
//    * get all scripts
//    * 
//    * @return
//    */
//   public Iterator<HashedScript> iterator();
// }


import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sinnerschrader.aem.react.ReactScriptEngine.RenderResult;
import com.sinnerschrader.aem.react.api.Cqx;
import com.sinnerschrader.aem.react.exception.TechnicalException;
import com.sinnerschrader.aem.react.loader.HashedScript;
import com.sinnerschrader.aem.react.loader.ScriptCollectionLoader;
        HashedScript next = iterator.next();
        String checksum = scriptChecksums.get(next.getId());
        if (reload || checksum == null || !checksum.equals(next.getChecksum())) {
          reload = true;
          engine.eval(next.getScript());
          scriptChecksums.put(next.getId(), next.getChecksum());
        }
      } catch (ScriptException e) {
        throw new TechnicalException("cannot eval library script", e);
      }
    }

  }

  /**
   * render the given react component
   *
   * @param path
   * @param resourceType
   * @param wcmmode
   * @param cqx
   *          API object for current request
   * @return
   */
  public RenderResult render(String path, String resourceType, String wcmmode, Cqx cqx, boolean renderRootDialog) {

    Invocable invocable = ((Invocable) engine);
    try {
      engine.getBindings(ScriptContext.ENGINE_SCOPE).put("Cqx", cqx);
      Object AemGlobal = engine.get("AemGlobal");
// Path: core/src/main/java/com/sinnerschrader/aem/react/ReactScriptEngine.java
// public static class RenderResult {
//   public String html;
//   public String cache;
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/api/Cqx.java
// public class Cqx {
// 
// 	private Sling sling;
// 	private OsgiServiceFinder finder;
// 	private ModelFactory modelFactory;
// 
// 	public Cqx(Sling sling, OsgiServiceFinder finder, ModelFactory modelFactory) {
// 		super();
// 		this.sling = sling;
// 		this.finder = finder;
// 		this.modelFactory = modelFactory;
// 	}
// 
// 	/**
// 	 * get an osgi service
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getOsgiService(String name) {
// 		return finder.get(name);
// 	}
// 
// 	/**
// 	 * get a request sling model
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getRequestModel(String path, String name) {
// 		return modelFactory.createRequestModel(path, name);
// 	}
// 
// 	/**
// 	 * get a resource sling model
// 	 *
// 	 * @param name
// 	 *            fully qualified class name
// 	 * @return
// 	 */
// 	public JsProxy getResourceModel(String path, String name) {
// 		return modelFactory.createResourceModel(path, name);
// 	}
// 
// 	/**
// 	 * get access to resource via the sling objects
// 	 * 
// 	 * @return
// 	 */
// 	public Sling getSling() {
// 		return sling;
// 	}
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/exception/TechnicalException.java
// public class TechnicalException extends RuntimeException {
// 
// 	private static final long serialVersionUID = 3287666209672379245L;
// 
// 	public TechnicalException (String msg, Throwable cause) {
// 		super(msg, cause);
// 	}
// 
//   public TechnicalException(String msg) {
//     super(msg);
//   }
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/loader/HashedScript.java
// public class HashedScript {
//   private String checksum;
//   private String script;
//   private String id;
// 
//   public HashedScript(String checksum, String script, String id) {
//     super();
//     this.checksum = checksum;
//     this.script = script;
//     this.id = id;
//   }
// 
//   /**
//    *
//    * @return checksum of javascript
//    */
//   public String getChecksum() {
//     return checksum;
//   }
// 
//   /**
//    *
//    * @return javascript
//    */
//   public String getScript() {
//     return script;
//   }
// 
//   /**
//    *
//    * @return path to javascript
//    */
//   public String getId() {
//     return id;
//   }
// 
// }
// 
// Path: core/src/main/java/com/sinnerschrader/aem/react/loader/ScriptCollectionLoader.java
// public interface ScriptCollectionLoader {
//   /**
//    * get all scripts
//    * 
//    * @return
//    */
//   public Iterator<HashedScript> iterator();
// }


// Path: core/src/main/java/com/sinnerschrader/aem/react/JavascriptEngine.java
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sinnerschrader.aem.react.ReactScriptEngine.RenderResult;
import com.sinnerschrader.aem.react.api.Cqx;
import com.sinnerschrader.aem.react.exception.TechnicalException;
import com.sinnerschrader.aem.react.loader.HashedScript;
import com.sinnerschrader.aem.react.loader.ScriptCollectionLoader;

        HashedScript next = iterator.next();
        String checksum = scriptChecksums.get(next.getId());
        if (reload || checksum == null || !checksum.equals(next.getChecksum())) {
          reload = true;
          engine.eval(next.getScript());
          scriptChecksums.put(next.getId(), next.getChecksum());
        }
      } catch (ScriptException e) {
        throw new TechnicalException("cannot eval library script", e);
      }
    }

  }

  /**
   * render the given react component
   *
   * @param path
   * @param resourceType
   * @param wcmmode
   * @param cqx
   *          API object for current request
   * @return
   */
  public RenderResult render(String path, String resourceType, String wcmmode, Cqx cqx, boolean renderRootDialog) {

    Invocable invocable = ((Invocable) engine);
    try {
      engine.getBindings(ScriptContext.ENGINE_SCOPE).put("Cqx", cqx);
      Object AemGlobal = engine.get("AemGlobal");
      Object value = invocable.invokeMethod(AemGlobal, "renderReactComponent", path, resourceType, wcmmode, renderRootDialog);