/// <summary>
        /// Runs the method, specified by method, on the server specified by i, with parameters given by parameters.
        /// Correctly handles exceptions thrown in the running of that method, and bool and BufferGenerationStatus
        /// type return values from the server.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="i"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public ServerActionStatus runMethodOnServer(MethodInfo method, ServerInfo i, object[] parameters, int msTimeout, EventHandler<MessageEvent> messageLog)
        {
            if (verifyConnection(i) == ServerActionStatus.Failed_No_Connection)
                return ServerActionStatus.Failed_No_Connection;

            ServerCommunicator communicator = communicators[i];

            Object returnValue;

            try
            {
                InvokeMethodOnServer_Parameters invoke_parameters = new InvokeMethodOnServer_Parameters(method, parameters, communicator);
                Thread invokeMethodThread = new Thread(new ParameterizedThreadStart(InvokeMethodOnServer_Proc));
                invokeMethodThread.Start(invoke_parameters);

               // invokeMethodThread.Join(msTimeout);
                invokeMethodThread.Join();

                if (invokeMethodThread.ThreadState == ThreadState.Running)
                {
                    invokeMethodThread.Abort();

                    throw new Exception("Method on server " + i.ToString() + "." + method.Name + " took longer than " + msTimeout + " ms timeout. Aborting.");
                }

                returnValue = invoke_parameters.returnValue;

                if (invoke_parameters.runException != null)
                {
                    throw new Exception("Caught an exception when attempting to run method " + i.ToString() + "." + method.Name+ ": " + invoke_parameters.runException.Message);
                }
            }
            catch (Exception e)
            {
                if (messageLog != null)
                    messageLog(this, new MessageEvent("Caught exception when attempting to run method on server " + i.ToString() + ": " + e.Message + e.StackTrace));

                serverGotDisconnectedInError(i);
                return ServerActionStatus.Failed_Loss_Of_Connection;
            }

            if (returnValue is bool)
            {
                bool attempt = (bool) returnValue;
                if (attempt)
                    return ServerActionStatus.Success;
                return ServerActionStatus.Failed_On_Server;
            }
            else if (returnValue is ServerCommunicator.BufferGenerationStatus)
            {
                ServerCommunicator.BufferGenerationStatus bufferStatus = (ServerCommunicator.BufferGenerationStatus) returnValue;
                if (bufferStatus == ServerCommunicator.BufferGenerationStatus.Success)
                    return ServerActionStatus.Success;
                return ServerActionStatus.Failed_On_Server;
            }

            return ServerActionStatus.Success;
        }