/// <summary>
        /// Checks if this agent is able to execute the given render job and sends an according message to the client.
        /// </summary>
        /// <param name="renderJob">The render job to execute</param>
        /// <returns>True if this agent is able to execute the job, false otherwise.</returns>
        private bool CheckExecutionAbility(RCS_Render_Job renderJob)
        {
            bool capable = false;
            RCS_Render_Job_Message msg = null;
            IResource resource = renderJob.Configuration.JobToDo.Resource;

            if (renderJob == null ||
                renderJob.Configuration == null ||
                renderJob.Configuration.JobToDo == null)
            {
                return false;
            }

            if (resource is FileResource)
            {
                // check if a program exists which can open the file
                string filepath = ((FileResource)resource).Path;
                capable = ProgramFinder.FindExecutable(filepath) != string.Empty;
            }
            else if (resource is ProcessResource)
            {
                // check if process with given ID is running
                int pid = ((ProcessResource)resource).ProcessID;

                try
                {
                    Process.GetProcessById(pid);
                    capable = true;
                }
                catch
                {
                }
            }
            else
            {
                throw new NotSupportedException("Only FileResource and ProcessResource are supported.");
            }

            if (capable)
            {
                msg = new RCS_Render_Job_Message(RenderMessage.Supported, renderJob.Id, RemoteType.Agent);
            }
            else
            {
                msg = new RCS_Render_Job_Message(RenderMessage.NotSupported, renderJob.Id, RemoteType.Agent);
            }
            
            try
            {
                this.SendMessage(MessageCode.MC_Render_Job_Message, msg);
            }
            catch
            {
            }

            return capable;
        }
        /// <summary>
        /// Sends a message to the client indicating that the captured process has exited.
        /// </summary>
        private void Capturer_OnProcessExited(object sender, CaptureFinishEventArgs e)
        {
            lock (this.runningRenderJobs)
            {
                this.runningRenderJobs.Remove(e.RenderJobId);
            }

            var msg = new RCS_Render_Job_Message(RenderMessage.ProcessExited, e.RenderJobId, RemoteType.Agent);

            try
            {
                this.SendMessage(MessageCode.MC_Render_Job_Message, msg);
            }
            catch
            {
            }
        }
        private async void Worker_OnMessageReceived(WorkingAgent agent, RCS_Render_Job_Message message)
        {
            if (message.Message == RenderMessage.ProcessExited)
            {
                Job todo = agent.Configuration.JobToDo;

                if (this.OnAgentAborted != null)
                {
                    this.OnAgentAborted(todo, agent.Agent);
                }

                // Solution 1: F**k it. We just say that the resource is not available anymore.
                /*if (this.OnResourceNotAvailable != null)
                {
                    this.OnResourceNotAvailable(agent.Configuration.JobToDo.Resource);
                }*/

                // Solution 2: try it with another agent, except the current.
                this.CancelJob(todo);

                List<Agent> excluded = this.agentSelectors[todo].AvailableAgents.Where(x => !x.IP.Equals(agent.Agent.IP)).ToList();

                RenderConfiguration config = this.GetNewRenderConfiguration(todo);
                WorkingAgent worker = await this.agentSelectors[todo].GetCompatibleAgentFromList(config, excluded);

                this.HandleFoundWorkingAgent(todo, worker);
            }
        }