private void Processor()
        {
            while (_pending.Count > 0)
            {
                GitHub_Commit commit;
                if (_pending.TryDequeue (out commit))
                {
                    //Generate the clone directory
                    var cloneDirectory = GetProjectPath (commit.CommitId);

                    #if !DEBUG
                    using (var db = new RepoContext ())
                    {
                        var commit = db.Commits.SingleOrDefault (x => x.RepositoryId == _repoId && x.SHA == sha);
                        if (null == commit)
                        {
                            commit = new GitHook_Mono.Data.Models.Commit () {
                                RepositoryId = _repoId,
                                SHA = sha
                            };
                            db.Commits.Add (commit);
                        }

                        commit.Status = GitHook_Mono.Data.Models.CommitStatus.Processing;
                        db.SaveChanges ();
                    #endif
                    BuildConfig current = null;
                    try
                    {
                        var logPath = commit.CommitId + ".log";
                        var logger = new BuildLogger (logPath);

                        //Clone
                        logger.WriteLine ("Cloning...");
                        Clone (logger, cloneDirectory, commit);
                        logger.WriteLine ("Clone Completed.");

                        //Load config
                        var cfg = System.IO.Path.Combine (cloneDirectory, BuildFile);
                        BuildConfig[] config;
                        try
                        {
                            config = MainClass.LoadConfig<BuildConfig[]> (cfg);
                        }
                        catch
                        {
                            config = new BuildConfig[] { MainClass.LoadConfig<BuildConfig> (cfg) };
                        }
                        if (null == config)
                        {
                            logger.WriteLine ($"Failed to load configuration file at: {cfg}");
                            return;
                        }
            //						Console.WriteLine ("Config: " + config.ToString ());

                        foreach (var build in config)
                        {
                            current = build;
                            //For each build configuration we must ensure we are working with the freshest copy
                            Run (logger, "git", "reset --hard origin/master", cloneDirectory);

                            //Now that we have a clone, we can attempt to load some config
                            if (String.IsNullOrEmpty (build.SolutionFile))
                            {
                                var sln = System.IO.Directory.GetFiles (cloneDirectory, "*.sln");
                                if (sln != null && sln.Length > 0)
                                {
                                    if (sln.Length == 1)
                                    {
                                        /*if (config == null) build = new BuildConfig () {
                                                SolutionFile = sln.First ()
                                            };
                                        else*/
                                        build.SolutionFile = sln.First ();
                                    }
                                    else
                                    {
                                        throw new CompilerException (1, $"Too many solution files detected, please specify one in your {BuildFile}");
                                    }
                                }
                                else
                                {
                                    throw new CompilerException (1, $"No solution file specified in {BuildFile}");
                                }
                            }

                            //Start compilation
                            logger.WriteLine ("Compiling...");
                            Compile (logger, build, cloneDirectory, commit);
                            logger.WriteLine ("Compiling Completed.");

                            MainClass.Plugins.ForEachPlugin ((plugin) =>
                            {
                                plugin.OnPass (this, cloneDirectory, commit, current);
                            });
                        }

                        logger.Close ();
                        MainClass.Plugins.ForEachPlugin ((plugin) =>
                        {
                            plugin.LogClosed (this, logPath);
                        });
                        #if !DEBUG
                            commit.Status = GitHook_Mono.Data.Models.CommitStatus.Passed;
                        #endif
                    }
                    catch (CompilerException ex)
                    {
                        #if !DEBUG
                            commit.Status = GitHook_Mono.Data.Models.CommitStatus.Failed;
                        #endif
                        Console.WriteLine (ex.ToString ());

                        MainClass.Plugins.ForEachPlugin ((plugin) =>
                        {
                            plugin.OnFail (this, cloneDirectory, commit, current);
                        });
                    }
                    #if !DEBUG
                        db.Repositories.Single (x => x.Id == _repoId).Builds++;
                        _builds++;
                        db.SaveChanges ();
                    }
                    #endif
                }
            }
        }
        public void Run(BuildLogger logger, string command, string args, string workingPath = WorkingDirectory)
        {
            logger.WriteLine ($"{command} {args}");
            var pc = new Process () {
                StartInfo = new ProcessStartInfo () {
                    FileName = command,
                    Arguments = args,
                    WorkingDirectory = workingPath,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false
                }
            };

            if (pc == null)
            {
                Console.WriteLine ("Failed to start process");
                throw new CompilerException (1);
            }

            using (var ar = new AutoResetEvent (false))
            using (var outputWaitHandle = new AutoResetEvent (false))
            using (var errorWaitHandle = new AutoResetEvent (false))
            {
                pc.ErrorDataReceived += (sender, e) =>
                {
                    if (!String.IsNullOrEmpty (e.Data)) logger.WriteLine (e.Data);
                    else if(e.Data == null) outputWaitHandle.Set ();
                };

                pc.OutputDataReceived += (sender, e) =>
                {
                    if (!String.IsNullOrEmpty (e.Data)) logger.WriteLine (e.Data);
                    else if(e.Data == null) errorWaitHandle.Set ();
                };

                pc.Exited += (sender, e) =>
                {
                    ar.Set ();
                };

                pc.Start ();

                pc.BeginErrorReadLine ();
                pc.BeginOutputReadLine ();

                Console.WriteLine ("Waiting");
                var timeout = 1000 * 60 * 5;
                if (pc.WaitForExit (timeout) && outputWaitHandle.WaitOne (timeout) && errorWaitHandle.WaitOne (timeout))
                {
                    Console.WriteLine ("Done");

                    if (0 != pc.ExitCode)
                    {
                        throw new CompilerException (pc.ExitCode);
                    }
                }
                else
                {
                    Console.WriteLine ("Process timed out");
                    throw new CompilerException (1);
                }
            }
        }