public static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType)
		{
			AppDomain sandboxDomain = SandboxHelper.CreateSandboxDomain(true, GetMappings());

			try
			{
				var containerType = typeof(Container);
				ObjectHandle handle = Activator.CreateInstanceFrom(
					sandboxDomain,
					containerType.Assembly.ManifestModule.FullyQualifiedName,
					containerType.FullName);

				var container = handle.Unwrap() as Container;


				container.InitWorkerSettings(
					WorkerConfiguration.Current.ID,
					WorkerConfiguration.Current.SandboxFolder,
					codeHelperType);

				var runResult = container.Run(opts);

				return runResult;

			}
			finally 
			{
				SandboxHelper.UnloadDomain(sandboxDomain);
			}

		}
 public CompilerResults CompileConsole(RunOptsBase opts, int?warningLevel = null, bool loadAssembyToAppDomain = true)
 {
     return(CompileCode(new List <string>()
     {
         ((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock
     }, warningLevel, loadAssembyToAppDomain));
 }
		protected virtual bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult)
		{
			if (opts.CodeBlock == null)
				opts.CodeBlock = new ConsoleOrScriptCodeBlock { CodeBlock = string.Empty };
			else if (((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock == null)
				((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock = string.Empty;

			return CheckCodeSizeLimit(((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock, ref runResult);
		}
        private void RunConsole(RunOptsBase opts, RunResult result)
        {
            new PermissionSet(PermissionState.Unrestricted).Assert();

            CompilerResults compilerResults;

            compilerResults = CompileConsole(opts, 4);

            if (!IsCompilationSucceed(compilerResults, result))
            {
                PermissionSet.RevertAssert();
                return;
            }


            MethodInfo mainMethodInfo;
            object     ownerInstance;

            mainMethodInfo = GetMainMethodAndOwnerInstance(compilerResults.CompiledAssembly, out ownerInstance);

            if (mainMethodInfo == null || !mainMethodInfo.IsPublic || !mainMethodInfo.DeclaringType.IsPublic)
            {
                result.IsSuccess         = false;
                result.FailureType       = RunResultFailureType.FatalError;
                result.FatalErrorMessage = "Public Main() method is required in a public class";
                return;
            }


            try
            {
                this.OnStartingExecution();
                PermissionSet.RevertAssert();

                //Add timer so doesn't execute for more then 5 secs
                var paramInfos = mainMethodInfo.GetParameters();
                mainMethodInfo.Invoke(ownerInstance, paramInfos.Select(pi => (object)null).ToArray());

                this.OnFinishedExecution();
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                result.IsSuccess        = false;
                result.FailureType      = RunResultFailureType.RunTimeException;
                result.RunTimeException = new ExceptionInfo(ex.InnerException ?? ex);
            }
            finally
            {
                result.ConsoleOutput = _consoleWriter.ToString().TrimEnd();
            }
        }
        private static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType, AppDomain sandboxDomain)
        {
            Container container = new Container();

            container.InitWorkerSettings(
                WorkerConfiguration.Current.ID,
                WorkerConfiguration.Current.SandboxFolder,
                codeHelperType);

            var runResult = container.Run(opts);

            return runResult;
        }
        public static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType)
        {
            AppDomain sandboxDomain = SandboxHelper.CreateSandboxDomain(true, GetMappings());

            try
            {
                return ExecuteCode(opts, codeHelperType, sandboxDomain);

            }
            finally
            {
                SandboxHelper.UnloadDomain(sandboxDomain);
            }
        }
		protected override bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult)
		{
			if (opts.CodeBlock == null)
				opts.CodeBlock = new MvcCodeBlock
					{
						Model = string.Empty,
						View = string.Empty,
						Controller = string.Empty
					};

			var codeBlock = (MvcCodeBlock) opts.CodeBlock;

			return CheckCodeSizeLimit(codeBlock.Model, ref runResult) &&
					CheckCodeSizeLimit(codeBlock.Controller, ref runResult);
		}
		public static RunResult RunInThread(CodeHelper codeHelper, RunOptsBase runOpts)
		{
			RunResult result = null;
			try
			{
				codeHelper.RequestedConsoleInput += CodeHelper_RequestedConsoleInput;
				var newThread = new Thread(() => { result = codeHelper.Run(runOpts); });
				newThread.Start();
				newThread.Join(TimeSpan.FromSeconds(10));
			}
			finally
			{
				codeHelper.RequestedConsoleInput -= CodeHelper_RequestedConsoleInput;
			}
			return result;
		}
        private static Assembly CurrentDomain_AssemblyResolve(RunOptsBase opts, ResolveEventArgs args)
        {
            // when we have different version of the same assembly, we need to map it to that that we already loaded.
            // for example we use System.Core v4, but AutoMapper requiest System.Core v2.0.5, so we need to map it
            var ind = args.Name.IndexOf(",");

            if (ind == -1)
            {
                return(null);
            }

            var result = SandboxHelper.ExecuteInFullTrust(
                () =>
            {
                string name = args.Name.Substring(0, ind);

                var assemblies = AppDomain.CurrentDomain.GetAssemblies();

                foreach (var assembly in assemblies)
                {
                    var asName = assembly.GetName().Name;
                    if (asName.Equals(name, StringComparison.CurrentCultureIgnoreCase))
                    {
                        return(assembly);
                    }
                }

                foreach (var reference in opts.NuGetDllReferences)
                {
                    var fileName = Path.GetFileNameWithoutExtension(reference);
                    if (string.Equals(fileName, name, StringComparison.CurrentCultureIgnoreCase))
                    {
                        string reference1 = reference;

                        var assembly = Assembly.LoadFile(reference1);

                        return(assembly);
                    }
                }

                return(null);
            });

            return(result);
        }
        protected ValidateCodeResult ValidateCodeWithCompilation(string code)
        {
            var result = new ValidateCodeResult();

            RunOptsBase runOpts         = GetRunOpts(code);
            var         compilerResults = CompileConsole(runOpts, 4, false);

            if (compilerResults.Errors.HasErrors)
            {
                result.IsSuccess = false;
                result.Errors    = GetValidationErrorsFromCompilerErrors(compilerResults.Errors);
            }
            else
            {
                result.IsSuccess = true;
                // clean up compiled assembly
                if (File.Exists(compilerResults.PathToAssembly))
                {
                    File.Delete(compilerResults.PathToAssembly);
                }
            }

            return(result);
        }
 protected virtual bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result)
 {
     return(VerifyDeniedCode(((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock, result));
 }
        public RunResult Run(RunOptsBase opts)
        {
            var result = new RunResult();

            result.IsSuccess = true;

            _consoleReader.InputLines = opts.ConsoleInputLines;

            if (!VerifyDeniedCodeBlock(opts, result))
            {
                return(result);
            }

            ResolveEventHandler handler = (o, e) => CurrentDomain_AssemblyResolve(opts, e);

            TextWriter defaultConsoleOut = Console.Out;
            TextReader defaultConsoleIn  = Console.In;

            SandboxHelper.ExecuteInFullTrust(
                () =>
            {
                Console.SetOut(_consoleWriter);
                Console.SetIn(_consoleReader);
            });

            try
            {
                AppDomain.CurrentDomain.AssemblyResolve += handler;

                switch (ProjectType)
                {
                case ProjectType.Console:
                    RunConsole(opts, result);
                    break;

                case ProjectType.Script:
                    RunInteractive(opts, result);
                    break;

                case ProjectType.Mvc:
                    RunMvc(opts, result);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            catch (ThreadAbortException ex)
            {
                var consoleInputRequest = ex.ExceptionState as ConsoleInputRequest;
                if (consoleInputRequest != null)
                {
                    result.IsSuccess = true;
                    result.IsConsoleInputRequested = true;
                }
                else
                {
                    result.IsSuccess = false;

                    var limit = ex.ExceptionState as LimitExceededException;
                    if (limit != null)
                    {
                        result.FailureType       = RunResultFailureType.FatalError;
                        result.FatalErrorMessage = LimitExceededException.FormatMessage(limit.LimitType);
                    }
                }

                SandboxHelper.ExecuteInFullTrust(Thread.ResetAbort);
            }
            finally
            {
                //Restore Console Out just in case
                SandboxHelper.ExecuteInFullTrust(
                    () =>
                {
                    Console.SetOut(defaultConsoleOut);
                    Console.SetIn(defaultConsoleIn);
                });

                // unsubscribe
                AppDomain.CurrentDomain.AssemblyResolve -= handler;
            }

            return(result);
        }
		protected override void RunInteractive(RunOptsBase opts, RunResult result)
		{
			new PermissionSet(PermissionState.Unrestricted).Assert();

			CommonScriptEngine scriptEngine = this.CreateSciptEngine();
			Session session = scriptEngine.CreateSession();
			var codeBlock = (ConsoleOrScriptCodeBlock) opts.CodeBlock;
			var referencedDlls = this.GetGacDlls(codeBlock.CodeBlock);
			foreach (var referenceDll in referencedDlls)
				session.AddReference(referenceDll);

			var libs = GetNonGacDlls();

			foreach (var path in libs)
			{
				session.AddReference(path);
			}

			Submission<object> submission;
			try
			{
				// we compile code there
				submission = session.CompileSubmission<object>(codeBlock.CodeBlock);
			}
			catch (ThreadAbortException)
			{
				throw;
			}
			catch (Exception ex)
			{
				if (!string.IsNullOrEmpty(ex.Message) && ex.Message.Contains(ErrorWhenCompileConsoleProjectAsScript))
				{/*Case 4067: DotNetFiddle throws exception on VbNet Script
				  * https://entech.fogbugz.com/default.asp?4067#31607
				  * This issue occurs, when user is trying to compile VB.Net Console project as VB.Net Script project.
				  * So, there is main entry point 'Module Sub Main' in snippet.
				  * Then Roslyn throws following exception "(3) : error BC35000: Requested operation is not available because the runtime library function 'Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute..ctor' is not defined."
				  * In same case for C#, Roslyn just ignores 'console' code.
				  * So for VB.Net case we just return 'success' and empty string.
				  */
					result.IsSuccess = true;
					result.ConsoleOutput = "";
				}
				else
				{
					ValidateCodeResult validateCodeResult = ValidateCode(codeBlock.CodeBlock);

					result.IsSuccess = false;
					result.FailureType = RunResultFailureType.CompilerErrors;
					result.CompilerErrors = validateCodeResult.Errors;
				}

				if (result.CompilerErrors == null)
				{
					result.CompilerErrors = new List<ValidationError> {ValidationError.CreateFromException(ex)};
				}

				TryCleanRoslynCacheHack();
				PermissionSet.RevertAssert();
				return;
			}


			object execResult = null;
			try
			{
				this.OnStartingExecution();
				
				PermissionSet.RevertAssert();

				execResult = submission.Execute();

				this.OnFinishedExecution();
			}
			catch (ThreadAbortException)
			{
				throw;
			}
			catch (Exception ex)
			{
				result.IsSuccess = false;
				result.FailureType = RunResultFailureType.RunTimeException;
				result.RunTimeException = new ExceptionInfo(ex);
			}
			finally
			{
				result.ConsoleOutput = _consoleWriter.ToString().TrimEnd();

				if (execResult != null)
				{
					result.ConsoleOutput += Environment.NewLine;
					result.ConsoleOutput += "[Return value]: " + execResult;
				}

				// don't need it as we modified Roslyn assemblies and made fix in them
				// TryCleanRoslynCacheHack();
			}
		}
		protected virtual RunResult ExecuteCodeBlock(RunOptsBase opts, CodeHelper codeHelper)
		{
			RunResult result;
			result = codeHelper.Run(opts);
			return result;
		}
		protected virtual void RunMvc(RunOptsBase opts, RunResult result)
		{
			throw new NotImplementedException();
		}
 protected override bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result)
 {
     var codeBlock = ((NancyFxCodeBlock) opts.CodeBlock);
     var aggregateCode = codeBlock.Controller + codeBlock.Module;
     return VerifyDeniedCode(aggregateCode, result);
 }
 public RunResult Execute(RunOptsBase opts, Type codeHelperType)
 {
     return ExecuteCode(opts, codeHelperType, sandboxDomain);
 }
		protected abstract void RunInteractive(RunOptsBase opts, RunResult result);
	    private void RunConsole(RunOptsBase opts, RunResult result)
	    {
            CompilerResults compilerResults;
            compilerResults = CompileConsole(opts, 4);

	        RunConsole(compilerResults, result);
	    }
		public RunResult Run(RunOptsBase opts)
		{
			var result = new RunResult();
			result.IsSuccess = true;

			_consoleReader.InputLines = opts.ConsoleInputLines;

			if (!VerifyDeniedCodeBlock(opts, result))
			{
				return result;
			}

			ResolveEventHandler handler = (o, e) => CurrentDomain_AssemblyResolve(opts, e);

			TextWriter defaultConsoleOut = Console.Out;
			TextReader defaultConsoleIn = Console.In;

			SandboxHelper.ExecuteInFullTrust(
				() =>
				{
					Console.SetOut(_consoleWriter);
					Console.SetIn(_consoleReader);
				});

			try
			{
				AppDomain.CurrentDomain.AssemblyResolve += handler;

				switch (ProjectType)
				{
					case ProjectType.Console:
						RunConsole(opts, result);
						break;
					case ProjectType.Script:
						RunInteractive(opts, result);
						break;
					case ProjectType.Mvc:
						RunMvc(opts, result);
						break;
					default:
						throw new NotImplementedException();
				}
			}
			catch (ThreadAbortException ex)
			{
				var consoleInputRequest = ex.ExceptionState as ConsoleInputRequest;
				if (consoleInputRequest != null)
				{
					result.IsSuccess = true;
					result.IsConsoleInputRequested = true;
				}
				else
				{
					result.IsSuccess = false;

					var limit = ex.ExceptionState as LimitExceededException;
					if (limit != null)
					{
						result.FailureType = RunResultFailureType.FatalError;
						result.FatalErrorMessage = LimitExceededException.FormatMessage(limit.LimitType);
					}
				}

				SandboxHelper.ExecuteInFullTrust(Thread.ResetAbort);
			}
			finally
			{
				//Restore Console Out just in case
				SandboxHelper.ExecuteInFullTrust(
					() =>
					{
						Console.SetOut(defaultConsoleOut);
						Console.SetIn(defaultConsoleIn);
					});

				// unsubscribe
				AppDomain.CurrentDomain.AssemblyResolve -= handler;
			}

			return result;
		}
        protected virtual void RunNancyFx(RunOptsBase opts, RunResult result)
        {
            CompilerResults compilerResults;
            compilerResults = CompileNancyFx(opts, 4);

            RunConsole(compilerResults, result);
        }
        protected override CompilerResults CompileNancyFx(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true)
        {
            CompilerResults result;

            var nancyFxRunOpts = (NancyFxRunOpts)opts;
            var codeBlock = ((NancyFxCodeBlock) opts.CodeBlock);

            List<string> CodeBlocks = new List<string>()
            {
                NancySelfHostingHelper.Instance.GenerateNancySelfHostingCode(nancyFxRunOpts.HostIndex),
                codeBlock.Controller,
                codeBlock.Module,
            };


            //ToDo: Add view as embded resources to assembly???
            if (!string.IsNullOrEmpty(codeBlock.View))
            {
                lock (SyncObj)
                {
                    
                    string path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), @"index.html"); 
                    // Write the stream contents to a new file named "index.html".
                    using (StreamWriter outfile = new StreamWriter(path))
                    {
                        outfile.Write(codeBlock.View);
                    }

                    result = CompileCode(
                        CodeBlocks,
                        new List<string>(){path},
                        warningLevel,
                        loadAssembyToAppDomain);
                }
            }
            else
            {
                result = CompileCode(
                        CodeBlocks,
                        null,
                        warningLevel,
                        loadAssembyToAppDomain);
            }

            return result;
        }
		public RunResult Run(RunOptsBase opts)
		{
			RunResult result = null;
			if (!CheckCodeBlock(opts, ref result))
				return result;

			// we should copy it before running, becuase it can be changed during execution
			var sandboxFolder = _sandboxFolder;

			var codeHelper = SandboxHelper.ExecuteInFullTrust(() =>(CodeHelper)Activator.CreateInstance(_codeHelperType));
			codeHelper.NuGetDllReferences = opts.NuGetDllReferences;

			codeHelper.StartingExecution += this.CodeHelper_StartingExecution;
			codeHelper.FinishedExecution += this.CodeHelper_FinishedExecution;
			codeHelper.RequestedConsoleInput += this.CodeHelper_RequestedConsoleInput;

			_executingThread = new Thread(
				() =>
				{
					try
					{
						_runAt = DateTime.Now;
						result = this.ExecuteCodeBlock(opts, codeHelper);
					}
					finally
					{
						// in theory in can be null at this point if something bad happened....
						if (result == null)
						{
							result = new RunResult() { FailureType = RunResultFailureType.FatalError, IsSuccess = false };
						}

						result.Stats = SandboxHelper.ExecuteInFullTrust(() => GatherStatistics());
						_compilationCompleted.Set();
					}
				});

			_executingThread.Start();

			var monitoringTask = Task.Factory.StartNew(MonitorHealth, _tokenSource.Token);

			// wait for compilation. Just to be sure we have 15 seconds timeout
			_compilationCompleted.WaitOne(TimeSpan.FromSeconds(15));

			// if something happened during compilation, then we fire _compilationCompleted on exit, and result will be filled, so we just need to return it
			if (result != null)
			{
				return result;
			}

			// it will use some time for compilation
			// it can hungs for some unmanaged call like Console.ReadKey(), so we wait with timeout
			// we might need to rewrite it to ManualEvent that will be fired when CodeHelper starts execution
			_executingThread.Join(WorkerConfiguration.Current.ExecutionLimitTimeoutMs * 2);

			_tokenSource.Cancel();

			// we can't move it to new method, as it can be executed via reflection
			SandboxHelper.ExecuteInFullTrust(
				() =>
				{
					try
					{
						if (Directory.Exists(sandboxFolder))
						{
							foreach (var file in Directory.EnumerateFiles(sandboxFolder, "*", SearchOption.AllDirectories))
							{
								File.Delete(file);
							}
						}
					}
					catch
					{
						if (result != null)
							result.SandboxUnloadReason = SandboxUnloadReason.ClearDirFailed;
					}
				});

			return result;
		}
		public CompilerResults CompileConsole(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true)
		{
			return CompileCode(new List<string>() {((ConsoleOrScriptCodeBlock) opts.CodeBlock).CodeBlock}, warningLevel, loadAssembyToAppDomain);
		}
 protected abstract void RunInteractive(RunOptsBase opts, RunResult result);
		private static Assembly CurrentDomain_AssemblyResolve(RunOptsBase opts, ResolveEventArgs args)
		{
			// when we have different version of the same assembly, we need to map it to that that we already loaded.
			// for example we use System.Core v4, but AutoMapper requiest System.Core v2.0.5, so we need to map it
			var ind = args.Name.IndexOf(",");
			if (ind == -1)
				return null;

			var result = SandboxHelper.ExecuteInFullTrust(
				() =>
				{
					string name = args.Name.Substring(0, ind);

					var assemblies = AppDomain.CurrentDomain.GetAssemblies();

					foreach (var assembly in assemblies)
					{
						var asName = assembly.GetName().Name;
						if (asName.Equals(name, StringComparison.CurrentCultureIgnoreCase))
						{
							return assembly;
						}
					}

					foreach (var reference in opts.NuGetDllReferences)
					{
						var fileName = Path.GetFileNameWithoutExtension(reference);
						if (string.Equals(fileName, name, StringComparison.CurrentCultureIgnoreCase))
						{
							string reference1 = reference;

							var assembly = Assembly.LoadFile(reference1);

							return assembly;
						}
					}

					return null;
				});

			return result;
		}
		protected virtual bool VerifyDeniedCodeBlock(RunOptsBase opts, RunResult result)
		{
			return VerifyDeniedCode(((ConsoleOrScriptCodeBlock) opts.CodeBlock).CodeBlock, result);
		}
        protected virtual CompilerResults CompileNancyFx(RunOptsBase opts, int? warningLevel = null, bool loadAssembyToAppDomain = true)
	    {
            throw new NotImplementedException();
	    }
 protected virtual void RunMvc(RunOptsBase opts, RunResult result)
 {
     throw new NotImplementedException();
 }
		private void RunConsole(RunOptsBase opts, RunResult result)
		{
			new PermissionSet(PermissionState.Unrestricted).Assert();

			CompilerResults compilerResults;
			compilerResults = CompileConsole(opts, 4);

			if (!IsCompilationSucceed(compilerResults, result))
			{
				PermissionSet.RevertAssert();
				return;
			}


			MethodInfo mainMethodInfo;
			object ownerInstance;

			mainMethodInfo = GetMainMethodAndOwnerInstance(compilerResults.CompiledAssembly, out ownerInstance);

			if (mainMethodInfo == null || !mainMethodInfo.IsPublic || !mainMethodInfo.DeclaringType.IsPublic)
			{
				result.IsSuccess = false;
				result.FailureType = RunResultFailureType.FatalError;
				result.FatalErrorMessage = "Public Main() method is required in a public class";
				return;
			}


			try
			{
				this.OnStartingExecution();
				PermissionSet.RevertAssert();

				//Add timer so doesn't execute for more then 5 secs
				var paramInfos = mainMethodInfo.GetParameters();
				mainMethodInfo.Invoke(ownerInstance, paramInfos.Select(pi => (object)null).ToArray());

				this.OnFinishedExecution();
			}
			catch (ThreadAbortException)
			{
				throw;
			}
			catch (Exception ex)
			{
				result.IsSuccess = false;
				result.FailureType = RunResultFailureType.RunTimeException;
				result.RunTimeException = new ExceptionInfo(ex.InnerException ?? ex);
			}
			finally
			{
				result.ConsoleOutput = _consoleWriter.ToString().TrimEnd();
			}
		}