/// <summary>
        ///
        /// </summary>
        /// <param name="Msg"></param>
        private void SolicitRemoteActionRecieved(NetMessage_SolicitRemoteAction Msg)
        {
            bool Accepted = false;

            // Don't accept if we are running any other actions.
            if (!IsRunningRemoteActions())
            {
                if (Msg.Type == RemoteActionType.Install)
                {
                    Guid ManifestId = Guid.Parse(Msg.Settings["ManifestId"]);

                    ManifestDownloadState State = DownloadManager.GetDownload(ManifestId);
                    if (State != null && State.State == ManifestDownloadProgressState.Complete)
                    {
                        try
                        {
                            // TODO: We don't support json files here. Should we just remove them? Nobody uses them.

                            string ConfigFilePath = Path.Combine(State.LocalFolder, "buildsync.cs");

                            BuildSettings Settings = new BuildSettings();
                            Settings.ScriptSource = File.ReadAllText(ConfigFilePath);

                            List <BuildLaunchMode> Modes;
                            Modes = Settings.Compile();

                            Accepted = (Modes.Count > 0);
                        }
                        catch (Exception Ex)
                        {
                            // We cannot compile or use this script :(
                        }
                    }
                }
            }

            if (Accepted)
            {
                NetMessage_SolicitAcceptRemoteAction Reply = new NetMessage_SolicitAcceptRemoteAction();
                Reply.ActionId = Msg.ActionId;
                Client.Connection.Send(Reply);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public void Poll()
        {
            for (int i = 0; i < States.Count; i++)
            {
                RemoteActionServerState State = States[i];

                // If this action has been allocated a client, wait for result.
                if (State.AllocatedClient != null)
                {
                    // Client has not updated us in quite a while :(
                    if (TimeUtils.Ticks - State.LastUpdateRecieved > RemoteActionServerState.LastUpdateTimeout)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as no response has been heard from allocated client.", State.Id.ToString());

                        State.ResultMessage = "Remote client failed to send update in time.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // Client who was allocated this action has disconnected, so abort.
                    else if (!State.AllocatedClient.IsConnected)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as allocated client disconnected.", State.Id.ToString());

                        State.ResultMessage = "Remote client unexpected disconnected.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }
                }

                // Otherwise send out a solicitation to perform action.
                else
                {
                    // Client who requested this action has disconnected, so abort.
                    if (!State.ForClient.IsConnected)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as requesting client disconnected.", State.Id.ToString());

                        State.ResultMessage = "Requesting client unexpected disconnected.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // Client has cancelled this state.
                    else if (State.Cancelled)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as client cancelled it.", State.Id.ToString());

                        State.ResultMessage = "Cancelled by user.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;

                        // Tell client allocated the job to cancel.
                        if (State.AllocatedClient != null && State.AllocatedClient.IsConnected)
                        {
                            NetMessage_CancelRemoteAction Msg = new NetMessage_CancelRemoteAction();
                            Msg.ActionId = State.Id;
                            State.AllocatedClient.Send(Msg);
                        }
                    }

                    // Send new solicitation.
                    else if (TimeUtils.Ticks - State.LastSolicitBroadcast > RemoteActionServerState.SolicitInterval)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' sending new solicitation request.", State.Id.ToString());

                        List <NetConnection> Clients = Server.ListenConnection.AllClients;
                        foreach (NetConnection ClientConnection in Clients)
                        {
                            if (ClientConnection != State.ForClient && ClientConnection.Metadata != null)
                            {
                                ServerConnectedClient ClientState = ClientConnection.Metadata as ServerConnectedClient;
                                if (ClientState.AllowRemoteActions)
                                {
                                    NetMessage_SolicitRemoteAction Msg = new NetMessage_SolicitRemoteAction();
                                    Msg.ActionId = State.Id;
                                    Msg.Type     = State.Type;
                                    Msg.Settings = State.Settings;
                                    ClientConnection.Send(Msg);
                                }
                            }
                        }

                        State.LastSolicitBroadcast = TimeUtils.Ticks;
                    }

                    // Nobody responded saying they can perform the action :|
                    else if (TimeUtils.Ticks - State.RecievedTime > RemoteActionServerState.SolicitTimeout)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as nobody responded to solicitation.", State.Id.ToString());

                        State.ResultMessage = "No remote clients accepted request.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // We have a client who can do the job!
                    else if (State.SolicitationReplies.Count > 0 && TimeUtils.Ticks - State.LastSolicitBroadcast > RemoteActionServerState.MinSolicitWait)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' recieved solicitation reply and is starting.", State.Id.ToString());

                        State.AllocatedClient = State.SolicitationReplies[SolicitSelectionRandom.Next(0, State.SolicitationReplies.Count - 1)];
                        State.SolicitationReplies.Clear();
                        State.LastUpdateRecieved = TimeUtils.Ticks;

                        NetMessage_RequestRemoteAction Msg = new NetMessage_RequestRemoteAction();
                        Msg.ActionId = State.Id;
                        Msg.Type     = State.Type;
                        Msg.Settings = State.Settings;
                        State.AllocatedClient.Send(Msg);
                    }
                }

                // Send progress update to the client.
                if (TimeUtils.Ticks - State.LastUpdateSent > RemoteActionServerState.UpdateInterval || State.Dirty)
                {
                    if (State.ForClient.IsConnected)
                    {
                        if (State.Completed || TimeUtils.Ticks - State.LastUpdateSent > RemoteActionClientState.MinUpdateInterval)
                        {
                            NetMessage_RemoteActionProgress Msg = new NetMessage_RemoteActionProgress();
                            Msg.ActionId      = State.Id;
                            Msg.Completed     = State.Completed;
                            Msg.Failed        = State.Failed;
                            Msg.ResultMessage = State.ResultMessage;
                            Msg.Progress      = State.Progress;
                            Msg.ProgressText  = State.ProgressText;
                            State.ForClient.Send(Msg);

                            State.LastUpdateSent = TimeUtils.Ticks;
                        }
                    }

                    State.Dirty = false;

                    // If completed, clean up state.
                    if (State.Completed)
                    {
                        RemoveActionState(State.Id);
                    }
                }
            }
        }