public dynamic ExecuteExpression(string expression, ScriptScope scope)
        {
            try
            {
                using (var context = new JavascriptContext())
                {
                    foreach (var variable in scope.Variables)
                    {
                        context.SetParameter(variable.Key, variable.Value);
                    }

                    context.SetParameter("Factory", new TypeFactory(scope.Assemblies));

                    var workContext = _wcaWork.Value.GetContext();
                    var orchardGlobal = new Dictionary<string, dynamic>();
                    orchardGlobal["WorkContext"] = workContext;
                    orchardGlobal["OrchardServices"] = workContext.Resolve<IOrchardServices>();
                    orchardGlobal["Layout"] = new StaticShape(workContext.Layout);

                    var existing = scope.GetVariable("Orchard");
                    if (existing != null)
                    {
                        if (!(existing is IDictionary<string, object>)) throw new ArgumentException("The Orchard global variable should be an IDictionary<string, dynamic>.");

                        var existingDictionary = existing as IDictionary<string, dynamic>;
                        foreach (var existingItem in existingDictionary)
                        {
                            orchardGlobal[existingItem.Key] = existingItem.Value;
                        }
                    }

                    context.SetParameter("Orchard", orchardGlobal);

                    _eventHandler.BeforeExecution(new BeforeJavaScriptExecutionContext(scope, context));
                    var output = context.Run(expression);
                    _eventHandler.AfterExecution(new AfterJavaScriptExecutionContext(scope, context));

                    foreach (var variableName in scope.Variables.Select(kvp => kvp.Key))
                    {
                        scope.SetVariable(variableName, context.GetParameter(variableName));
                    }

                    return output;
                }
            }
            catch (Exception ex)
            {
                if (ex.IsFatal()) throw;

                throw new ScriptRuntimeException("The JavaScript script could not be executed.", ex);
            }
        }
        public void Render(ViewContext context, TextWriter writer)
        {
            var filename = context.HttpContext.Server.MapPath(ViewPath);

            var scope = new ScriptScopeImpl(ViewPath);
            var orchardGlobal = new Dictionary<string, dynamic>();
            orchardGlobal["VIEW_CONTEXT"] = context;
            orchardGlobal["MODEL"] = new StaticShape(context.ViewData.Model);
            scope.SetVariable("_ORCHARD", orchardGlobal);

            var output = _phpRuntime.ExecuteFile(filename, scope);
            writer.Write(output);
        }
        private dynamic RunPhpExecutor(Action<RequestContext> executor, ScriptScope scope)
        {
            try
            {
                var workContext = _wcaWork.Value.GetContext();

                using (var requestContext = RequestContext.Initialize(ApplicationContext.Default, workContext.HttpContext.ApplicationInstance.Context))
                {
                    var scriptContext = requestContext.ScriptContext;
                    using (scriptContext.OutputStream = new MemoryStream())
                    {
                        using (scriptContext.Output = new StreamWriter(scriptContext.OutputStream))
                        {
                            var assemblyLoader = scriptContext.ApplicationContext.AssemblyLoader;
                            assemblyLoader.Load(typeof(PhpHash).Assembly, null); // PhpNetClassLibrary.dll

                            foreach (var assembly in scope.Assemblies)
                            {
                                assemblyLoader.Load(assembly, null);
                            }

                            var orchardGlobal = new Dictionary<string, dynamic>();
                            orchardGlobal["WORK_CONTEXT"] = workContext;
                            orchardGlobal["ORCHARD_SERVICES"] = workContext.Resolve<IOrchardServices>();
                            orchardGlobal["LAYOUT"] = new StaticShape(workContext.Layout);

                            var existing = scope.GetVariable("_ORCHARD");
                            if (existing != null)
                            {
                                if (!(existing is IDictionary<string, object>)) throw new ArgumentException("The $_ORCHARD superglobal variable should be an IDictionary<string, dynamic>.");

                                var existingDictionary = existing as IDictionary<string, dynamic>;
                                foreach (var existingItem in existingDictionary)
                                {
                                    orchardGlobal[existingItem.Key] = existingItem.Value;
                                }
                            }

                            scope.SetVariable("_ORCHARD", orchardGlobal);

                            foreach (var item in scope.Variables)
                            {
                                scriptContext.Globals.TrySetMember(item.Key, item.Value);
                            }

                            // Setting globals like this only works for primitive types.
                            // Operators.SetVariable(scriptContext, null, "test", "");

                            _eventHandler.BeforeExecution(new BeforePhpExecutionContext(scope, scriptContext));
                            executor(requestContext);
                            _eventHandler.AfterExecution(new AfterPhpExecutionContext(scope, scriptContext));

                            foreach (var variable in scriptContext.GlobalVariables)
                            {
                                scope.SetVariable(variable.Key.ToString(), variable.Value);
                            }

                            scriptContext.Output.Flush();
                            scriptContext.OutputStream.Position = 0;
                            using (var streamReader = new StreamReader(scriptContext.OutputStream))
                            {
                                return streamReader.ReadToEnd();
                            }
                        }
                    }
                }
            }
            catch (PhpException ex)
            {
                throw new ScriptRuntimeException("The PHP script could not be executed.", ex);
            }
        }