static void Main()
        {
            Console.WriteLine("Launching Application");

            Manager = new ReversiServerManagerModel();
            Manager.ConfigureManager();
            Manager.ListenerSocket = Manager.StartManager();  // Returns the TcoListener for this server
            Manager.StartServer();

            // Now listen for incoming connections and add them to the connections list as they come in.
            // The server managers HandleServerThread will assign them to appropriate game and/or chat servers.
            while (!Manager.ShouldShutdown)
            {
                // Listen for connections
                TcpClient newTcpClientSocket = Manager.ListenForConnections();

                // Receive the response from the client, and readd the connection socket to the object since it's not serialized.
                ReversiClientModel newTcpClientModel = DataTransmission.DeserializeData <ReversiClientModel>(newTcpClientSocket);
                newTcpClientModel.ConnectionSocket = newTcpClientSocket;

                // Determine what we should do with the connection and send the appropriate response
                newTcpClientModel = Manager.AcceptOrRefuseConnection(newTcpClientModel, out var status);

                // If the connection was accepted then add the model to the connected models list
                if (status == ConnectionStatusTypes.StatusConnectionAccepted)
                {
                    Manager.AddClientModelToConnectionList(newTcpClientModel);
                    Console.WriteLine("Server manager #" + Manager.Id + " has accepted client " + newTcpClientModel.Id + ".");
                }
                else if (status == ConnectionStatusTypes.StatusConnectionRefused)
                {
                    Console.WriteLine("Server manager #" + Manager.Id + " has refused client" + newTcpClientModel.Id + ".");
                }

                // List our connected clients for testing.
                Console.WriteLine(Manager.ListConnectedClients());

                // Dispose of the temporary client
                newTcpClientModel = null;
            }


            // Shutdown the server manager
            Manager.Shutdown();
        }
        ///// <summary>
        ///// Removes a player from the staging area to the gameroom.
        ///// </summary>
        //private static void RemovePlayersFromStaging()
        //{
        //    for (int i = ReversiSettings.ReversiPlayersPerGame - 1; i >= 0; i--)
        //    {
        //        StagingArea.RemoveAt(i);
        //    }
        //}



        /// <summary>
        /// The main thread routine for each game
        /// </summary>
        /// <param name="data">The game staging area list of client models</param>
        private void InitializeMatchup(object data)
        {
            List <ReversiClientModel> clientModels = (List <ReversiClientModel>)data;

            //// Create the game instance which moves the players to the game room
            ReversiGameModel game = new ReversiGameModel(clientModels);

            RunningGames.Add(game.GameId, game);  // add the game to the dictionary of running games

            Console.WriteLine("... GameServer: Matchup pairing complete. Game " + game.GameId.ToString() + " is ready to start.");
            Console.WriteLine(game.DisplayGameInfoComplete());

            // Send the game object to each of the clients.
            foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList)
            {
                ReversiClientModel client = (ReversiClientModel)item.Value;

                // Send the game data to each of the players
                Console.WriteLine("Sending initial game matchup to players");
                DataTransmission.SerializeData <ReversiGameModel>(game, client.ConnectionSocket);

                // And remove the players from the Staging area.
                StagingArea.Remove(client);
            }

            //// The main game loop. Process individual moves here
            List <TcpClient> sockets = game.GetPlayersSocketList();

            while (!game.GameIsOver)
            {
                // If the game is paused ignore the user input
                if (game.GameIsPaused == true)
                {
                    continue;
                }

                if (game.GameOverCheckRequired)
                {
                    if (game.CheckGameOver(game.CurrentPlayer) == true)
                    {
                        Console.WriteLine("No available moves for " + game.CurrentPlayer);
                        game.GameIsOver = true;
                        break;
                    }

                    Console.WriteLine("Valid moves available for " + game.CurrentPlayer);
                    game.AvailableMovesList.ForEach(Console.WriteLine);
                    game.GameOverCheckRequired = false;
                }

                // If the current turn is valid and complete, switch to the next player
                if (game.TurnComplete)
                {
                    Console.WriteLine(game.Gameboard.DrawGameboardString());
                    game.NextPlayer();
                    game.TurnComplete          = false;
                    game.GameOverCheckRequired = true;

                    // Update the game model for all players...
                    SendGameToAll(game);
                }

                List <ClientModel> disconnectList = new List <ClientModel>();
                foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList)
                {
                    ClientModel client = item.Value;
                    Socket      s      = client.ConnectionSocket.Client;

                    // Check for disconnected sockets
                    if (!SocketConnected(s))
                    {
                        Console.WriteLine("GameServer: (GameID #" + game.GameId + ")");

                        disconnectList.Add(client);
                    }
                }

                // Remove any disconnected players from the game...
                foreach (ClientModel disconnectClient in disconnectList)
                {
                    ClientDisconnectedEventArgs args = new ClientDisconnectedEventArgs
                    {
                        client           = disconnectClient,
                        TimeOfDisconnect = DateTime.Now
                    };
                    game.GameIsPaused = true;
                    OnClientDisconnected(args);

                    game.RemovePlayerFromGame(((ClientModel)disconnectClient));
                    try
                    {
                        disconnectClient.ConnectionSocket.Close();
                    }
                    catch
                    {
                        // Do nothing
                    }
                }

                // Now proceed through the current player list, looking for moves sent by the clients
                foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList)
                {
                    NetworkStream stream;
                    try
                    {
                        stream = item.Value.ConnectionSocket.GetStream();
                    }
                    catch (ObjectDisposedException e)
                    {
                        // Catches a disposed socket possibility here in case it hasn't been fully disposed yet.
                        continue;
                    }

                    if (stream.DataAvailable)
                    {
                        GameMoveModel move = DataTransmission.DeserializeData <GameMoveModel>(item.Value.ConnectionSocket);
                        Console.WriteLine("GameServer: (GameID #" + game.GameId + ")" + move.ByPlayer + " move request received");

                        if (move.ByPlayer == game.CurrentPlayer)
                        {
                            game.CurrentMoveIndex = move.MoveIndex;

                            // Check that the move was valid.
                            if (game.PlayTurn())
                            {
                                Console.WriteLine("GameServer: (GameID #" + game.GameId + ")" + move.ByPlayer + " submitted a valid move");
                                game.TurnComplete     = true;
                                game.CurrentMoveIndex = move.MoveIndex;
                            }
                        }
                        else
                        {
                            Console.WriteLine("GameServer: (GameID #" + game.GameId + ") Move received by opponent.  Ignoring...");
                        }
                    }
                }
            }

            // At this point the game is over.
            Console.WriteLine("The game is over...");
        }