public void ruN(int index1)
        {
            StringBuilder result = new StringBuilder("");
            List<Client> clientList = Server.getInstance().getShallowCopyClients();
            Client[] clients = clientList.ToArray();

            Client[] clientsOtherThanThis = Server.getInstance()
                                .getClientsArrayOtherThan(clients[index1]);


            //set the state of this client to wanted, because
            //it wants to access critical section
            clients[index1].setWanted(true);


            //and before submitting request, the client must update its
            //logical clock, so
            //update clock, which will increment default timestamp
            //basically Ricart&Agrawala is using extended Lamport clock
            //in extended lamport clock, for each send event, the node
            //has to update its clock (increment timestamp)
            clients[index1].updateClock();

            Client clienT = new Client(Server.getInstance().getSocketAddress(), Utils.getDefaultSocketAddress());
            object reply = null;
            node = clienT.nodeList.Values.Last();
            foreach( Client client in clientsOtherThanThis)
            {
                bool isRequestSendingOK = false;
                try
                {
                    Console.WriteLine("Client " + clients[index1].getIP()
                                        + " with timeStamp " + clients[index1].getClock()
                                        + " sending \"request\" to client " + client.getIP()
                                        + "\n");
                    result.Append("Client " + clients[index1].getIP()
                            + " with timeStamp " + clients[index1].getClock()
                            + " sending \"request\" to client " + client.getIP()
                            + "\n");
                    reply = node.sendmessage("request", clients[index1].getIP(), clients[index1].getClock(), client.getIP());
                    //if we have reached here request sending has been successful
                    isRequestSendingOK = true;
                }
                catch(Exception e)
                {
                    Console.WriteLine("Exception while executing the "
                                        + "RequestProcessor.sendMessage method for"
                                        + " each client other than this client");
                    result.Append("Exception while executing the "
                                        + "RequestProcessor.sendMessage method for"
                                        + " each client other than this client\n");
                }

                if (isRequestSendingOK)
                {
                    //cast reply to string
                    string replyString = (string)reply;


                    if (replyString.Contains(","))
                    {
                        //now split and get OK sender's timestamp
                        string[] splitComponents = replyString.Split(',');

                        if (splitComponents[0].Equals("OK", StringComparison.InvariantCultureIgnoreCase))
                        {
                            //update the logical clock, when received OK
                            //from the other node, because it is receive event
                            clients[index1].updateClock(int.Parse(splitComponents[1]));

                            //increment the OK count for this client
                            clients[index1].incrementOKCount();
                        } 

                    }

                }
            }

            //so,  number of OKCount is the same as number of clients
            //other than this. In other words, if received "OK" from
            //all clients that this client has sent the request to

            while (clients[index1].getOKCount() != clientsOtherThanThis.Length)
            {
                //wait
            }


            if (clients[index1].getOKCount() == clientsOtherThanThis.Length)
            {                
                //now this client can enter the critical section
                    //set the using flag for this client
                clients[index1].setUsing(true);


                Server.getInstance().assignToCriticalSection(clients[index1].getIP());
                // get the random English word
                string randomEnglishWord = Server.getInstance().generateRandomEnglishWord();

                    // method to write this generated word to
                    // client's
                    // buffer to check it later whether or not
                    // written
                    // word exists in the resulting master string
                clients[index1].rememberWord(randomEnglishWord);

                

                // now enter the critical section where the word
                // will be written
                // to the coordinator's master string

                // boolean variable to hold whether
                // criticalSection entrance was OK
                bool isCriticalSectionSuccess = false;

                    try
                    {
                        // params will contain the client's ip who
                        // will enter
                        // the critical section and and the
                        // randomEnglishWord
                        reply = node.enterCS(clients[index1].getIP(), randomEnglishWord);

                        // reply could be like
                        // "Node with ip has written some word"
                        Console.WriteLine((string)reply);
                        result.Append((string)reply);

                        //if we have reached here critical section completed successfully
                        isCriticalSectionSuccess = true;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Exception while calling method"
                                            + " RequestProcessor.enterCS\n");
                    }

                    if (isCriticalSectionSuccess)
                    {

                         // update clock when sending OK
                        clients[index1].updateClock();
                        int oksSent = 0;
                        int numberOfNodesOkToBeSent = clients[index1].getRequestQueue().Count();
                        //get the queue, send OK to all processes in own queue
                        //and empty queue.
                        foreach (string IP in clients[index1].getRequestQueue())
                        {
                            try
                            {
                                result.Append("Client " + clients[index1].getIP()
                                                    + " with timeStamp " + clients[index1].getClock()
                                                    + " sending \"OK\" to client " + IP
                                                    + "\n");
                                node.sendmessage("OK", clients[index1].getIP(), clients[index1].getClock(), IP);
                                oksSent++;
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Exception while executing the "
                                                    + "RequestProcessor.sendMessage method for"
                                                    + " each client other than this client");
                            }
                        
                        
                        }

                        //if all oks sent successfully
                        if (oksSent == numberOfNodesOkToBeSent)
                        {

                            Server.getInstance().removeFromCriticalSection(clients[index1].getIP());
                        //now empty queue, set using and wanted flags to false
                        //and resetOKCount to 0.
                            clients[index1].emptyRequestQueue();
                            clients[index1].setUsing(false);
                            clients[index1].setWanted(false);
                            clients[index1].resetOKCount();
                        }
                    }
             }
          
        }
        public void run()
        {
            // if everything in critical section was OK
            // send "release" message to the coordinator

            Client client = new Client(Server.getInstance().getSocketAddress(), Utils.getDefaultSocketAddress());
            try
            {
                node = client.nodeList.Values.Last();
                node.sendMessage("release", client.getIP());
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception while calling method"
                                                + " RequestProcessor.sendMessage "
                                                + "with message RELEASE\n");
            }
        }
        public void run(int index)
        {
            
            StringBuilder result = new StringBuilder("");
            
            List<Client> clientList = Server.getInstance().getShallowCopyClients();
            Client[] clients = clientList.ToArray();

            IRequestProcessor node;
            Client client = new Client(Server.getInstance().getSocketAddress(), Utils.getDefaultSocketAddress());

            // boolean variable to achieve consistency in the code
            bool isMessageSendOk = false;
            
            node = client.nodeList.Values.Last(); 

            // reply will contains the string GRANTED or DENIED
            object reply = null;
            
            try
            {
                reply = node.sendMessage("request",clients[index].getIP());
                isMessageSendOk = true;
                
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Exception in executing the "
                   + "RequestProcessor.sendMessage method\n");
                result.Append("Exception in executing the "
                + "RequestProcessor.sendMessage method\n");
            }

            if (isMessageSendOk)
            {
                string replyString = (string)reply;

                // if reply was GRANTED
                if (replyString.Equals("GRANTED", StringComparison.InvariantCultureIgnoreCase))
                {
                    string randomEnglishWord = Server.getInstance().generateRandomEnglishWord();

                    clients[index].rememberWord(randomEnglishWord);

                    // boolean variable to hold whether
                    // criticalSection entrance was OK
                    bool isCriticalSectionSuccess = false;

                    try
                    {
                        reply = node.enterCS(clients[index].getIP(),
                                        randomEnglishWord);
                                            
                        // reply could be like
                        // "Node with ip has written some word"
                        Console.WriteLine((string)reply);
                        result.Append((string)reply);
                        isCriticalSectionSuccess = true;
                    }
                    catch(Exception e)
                    {
                        Console.Error.WriteLine("Exception while calling method"
                         + " RequestProcessor.enterCS\n");
                        result.Append("Exception while calling method"
                                + " RequestProcessor.enterCS\n");
                    }

                    // if everything in critical section was OK
                    // send "release" message to the coordinator
                    if (isCriticalSectionSuccess)
                    {
                        Console.WriteLine(clients[index].getIP()
                                            + " sending \"release\" message\n");
                        result.Append(clients[index].getIP()
                                + " sending \"release\" message\n");

                        try
                        {
                            node.sendMessage("release",clients[index].getIP());
                        }
                        catch(Exception e)
                        {
                            Console.WriteLine("Exception while calling method"
                            + " RequestProcessor.sendMessage with message RELEASE\n");
                            result.Append("Exception while calling method"
                            + " RequestProcessor.sendMessage with message RELEASE\n");
                        }
                    }
                }
                   
                    
            }
        }
 /// <summary>
 /// This method is for updating 'clients' list.
 /// </summary>
 /// <param name="clientSocketAddress">Socket address of client</param>
 public void updateClientList(string clientSocketAddress)
 {
     try
     {
         Client client = new Client(getSocketAddress(), clientSocketAddress);
         client.setPriority(Server.getInstance().getNextPriority());
         clients.Add(client);
     }
     catch (Exception e)
     {
         Console.Error.WriteLine("Exception in updating client's list on the server."
                 + "\nClient's list will not be changed");
     } 
 }
        /// <summary>
        /// This method do the same broadcasting thing for clients.
        /// </summary>
        /// <returns>The clients to broadcast messages.</returns>
        public Client[] getBroadcastClients()
        {
            //last added client won't be broadcasted.
            Client[] broadCastClients = new Client[clients.Count - 1];
            for (int index = 0; index < broadCastClients.Length; index++)
            {
                broadCastClients[index] = clients[index];
            } 

            return broadCastClients;
        }
        /// <summary>
        /// This method gets all clients except than this client.
        /// </summary>
        /// <param name="thisClient"></param>
        /// <returns></returns>
        public List<Client> getClientsOtherThan(Client thisClient)
        {
            // get the clients, create a list and different clients
            // other than this client in list
            List<Client> clientList = new List<Client>();

            // for each client add the client to the copy list
            foreach (Client client in clients)
            {
                if (!client.Equals(thisClient))
                {
                    clientList.Add(client);
                } 
            } 

            return clientList;
        }
 /// <summary>
 /// Convenient array representation for getClientsOtherThan method.
 /// </summary>
 /// <param name="thisClient"></param>
 /// <returns></returns>
 public Client[] getClientsArrayOtherThan(Client thisClient)
 {
     return getClientsOtherThan(thisClient).ToArray();
 }
        static void Main(string[] args)
        {
            Client client = null;
            IRequestProcessor node;

            bool joinOK = false;
            bool signOffOK = false;

            Console.WriteLine("Enter server's socket address - IP:PORT ");

            string serverSocketAddress = Console.ReadLine();

            while(true) 
            {
                if (Utils.isValidSocketAddress(Utils.getIPFromSocketAddress(serverSocketAddress)))
                {
                    break;
                }
                else
                {
                    serverSocketAddress = Console.ReadLine();
                }
            }

            Server server = Server.getInstance(serverSocketAddress);
            server.start();


            while (true)
                {
                    Console.WriteLine("Press ENTER to continue...");

                    try
                    {
                        Console.ReadLine();
                        showCommands();
                    }
                    catch (IOException e)
                    {
                        server.stop();
                        break;
                    }

                int command = int.Parse(Console.ReadLine());

                switch (command)
                {
                    case 1:
                        {
                            if (server.isNetworkAvailable())
                            {
                                Console.WriteLine("Enter socket address of new host in form IP:PORT, that you want to join: ");
                                string socketAddress = Console.ReadLine();

                                while (true)
                                {
                                    if (Utils.isValidSocketAddress(Utils.getIPFromSocketAddress(socketAddress)))
                                    {

                                        if (checkHostEligibility(Utils.getIPFromSocketAddress(socketAddress)))
                                        {
                                            Console.WriteLine("Host is already in the network! Type in another IP:PORT ");
                                            socketAddress = Console.ReadLine();
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        socketAddress = Console.ReadLine();
                                }
                                }
                                try
                                {
                                    client = new Client(server.getSocketAddress(), socketAddress);
                                    
                                }
                                catch (Exception e)
                                {
                                    Console.Error.WriteLine("Error Setting the server url for this client.");
                                    client = null;
                                }


                                if (client != null)
                                {
                                    object response = null;
                                    beautifyOutput();
                                    try
                                    {
                                       
                                        node = client.nodeList.Values.Last();
                                        response = node.joinNode(client.getSocketAddress());
                                        Console.WriteLine(response);
                                        
                                        try
                                        {
                                           // propagatemessagetoall in java 
                                            response = node.propagateJoinRequest(client.getSocketAddress());
                                            Console.WriteLine(response);
                                            checkClients();
                                            beautifyOutput();
                                            joinOK = true;

                                        }
                                        catch (Exception e)
                                        {
                                            Console.Error.WriteLine("Failed to broadcast join request");
                                        }

                                    }
                                    catch (Exception e)
                                    {
                                        Console.Error.WriteLine("Error executing join request, response is null");
                                    }
                                    

                                    if (joinOK)
                                    {
                                        Console.WriteLine("Master node Election ");

                                        try
                                        {

                                            node = client.nodeList.Values.Last();
                                            response = node.startElection("join" + "," + client.getIP());

                                            if (response != null)
                                            {
                                                Console.WriteLine(response);

                                                //propagatemessagetoall in java
                                                response = node.propagateCoordinatorMessage(client.getIP());

                                                Console.WriteLine(response);
                                                beautifyOutput();
                                            }

                                            // Master election is done. because of it joinOK is false now.
                                            joinOK = false;
                                        }
                                        catch (Exception e)
                                        {
                                            Console.Error.WriteLine("Failed to broadcast coordinator message");
                                        }
                                    }

                                }
                                else
                                {
                                    Console.WriteLine("Try to correct server's socket address"
                                        + " or clients' socket address");
                                    break;
                                }
                            }
                            else
                            {
                                Console.WriteLine("Please first add your server to the network");
                            }
                            break;
                        }
                    case 2:
                        {
                            if(server.isNetworkAvailable())
                            {
                                bool isOneHostAvailable = false;

                                try
                                {
                                    client = new Client(server.getSocketAddress(),
                                            Utils.getDefaultSocketAddress());

                                    node = client.nodeList.Values.Last();
                                    object response = node.atLeastOneHostAvailable();
                                    isOneHostAvailable = (bool) response;
                                }
                                catch (Exception e1)
                                {
                                    Console.WriteLine("Exception in executing method "
                                            + "RequestProcessor.atLeastOneHostAvailable");
                                } 

                                if (isOneHostAvailable)
                                {
                                    showNetwork();
                                    Console.WriteLine("Enter the node ID to sign it off from the network:");
                                    int nodeIdToSignOff = int.Parse(Console.ReadLine());

                                    while (nodeIdToSignOff == 0)
                                    {
                                        Console.WriteLine("Server cannot be signed off from the network!"+ "\n");
                                        Console.WriteLine("Enter the node ID to sign it off from the network: ");
                                        nodeIdToSignOff = int.Parse(Console.ReadLine());
                                    }

                                    try
                                    { 
                                        client = new Client(server.getSocketAddress(),
                                                Utils.getDefaultSocketAddress());
                                    } 
                                    catch (Exception e)
                                    {
                                        Console.Error.WriteLine("Error Setting the server url for this client.");
                                        client = null;
                                    }

                                    if(client != null)
                                    {
                                        object response = null;

                                        beautifyOutput();

                                        try
                                        {
                                            node = client.nodeList.Values.Last();
                                            response = node.signOffNode(nodeIdToSignOff);
                                            Console.WriteLine(response);

                                            try
                                            {
                                                response = node.propagateSignOffRequest(nodeIdToSignOff);
                                                Console.WriteLine(response);

                                                beautifyOutput();
                                                signOffOK = true;
                                            }
                                            catch(Exception e)
                                            {
                                                Console.WriteLine("Failed to broadcast signoff request");
                                            }
                                        }
                                        catch(Exception e)
                                        {
                                            Console.WriteLine("Error executing signoff request, response is null");

                                        }

                                        if(signOffOK)
                                        {
                                            Console.WriteLine("Master Node Election: ");

                                            try
                                            { 
                                                node = client.nodeList.Values.Last();
                                                response = node.startElection("signOff" + "," + Utils.getDefaultIP());

                                                if (response != null)
                                                {
                                                    Console.WriteLine(response);
                                                    response = node.propagateCoordinatorMessage(Utils.getDefaultIP());
                                                    Console.WriteLine(response);

                                                    beautifyOutput();
                                                }

                                                signOffOK = false;

                                            }
                                            catch(Exception e)
                                            {
                                                Console.WriteLine("Exception in master election process ");
                                            }
                                        } 
                                    }
                                    else
                                    {
                                        Console.Error.WriteLine("Try to correct servers' socket address"
                                            + " or clients' socket address");
                                        break;
                                    }

                                }
                                else
                                {
                                    Console.WriteLine("There is no host in the network, try to join at least one");
                                }

                            }
                            else
                            {
                                Console.WriteLine("Please first add your server to the network");
                            }
                            break;
                        }
                    case 3:
                        {
                            showNetwork();
                            break;
                        }
                    case 4:
                        {
                            break;
                        }
                    case 5:
                        {
                            server.stop();
                            Console.WriteLine("DONE");
                            Console.ReadLine();
                            return;
                        }
                        default:
                            {
                                break;
                            }
                    }
                }
            }
        /// <summary>
        /// This methoc checks host's ip address's eligibility
        /// </summary>
        /// <param name="IP">Address that user enters</param>
        /// <returns></returns>
        private static bool checkHostEligibility(string IP)
        {
            // check whether or not there is at least one host in the
            // network
            bool isHostWithGivenIPEligible = false;

            // create the temporary client with server socket address and
            // its own socket address and do remote procedure call
            try
            {
                Client client = new Client(Server.getInstance().getSocketAddress(),
                        Utils.getDefaultSocketAddress());

                //send the given ip to request processor to check whether
                //the host with given ip already exists, if exists
                //response will false

                IRequestProcessor node = client.nodeList.Values.Last();
                object response = node.checkHostEligibility(IP);
                isHostWithGivenIPEligible = (bool)response;
            }
            catch (Exception e1)
            {
                Console.WriteLine("Exception in executing method "
                        + "RequestProcessor.checkHostEligibility");
            } 
            return isHostWithGivenIPEligible;

        }
        /// <summary>
        /// This method shows all the nodes in the network with specified ids.
        /// </summary>
        public static void showNetwork()
        {
            object response = null;
            try
            {
                //temporary client for executing showNetworkState message
                Client client = new Client(Server.getInstance().getSocketAddress(),
                        Utils.getDefaultSocketAddress());

                //execute showNetworkState method on server's handler
                IRequestProcessor cl = client.nodeList.Values.Last();
                response = cl.showNetworkState();

                if (response != null)
                {
                    Console.WriteLine(response);
                } 

            }
            catch (Exception e)
            {

                Console.Error.WriteLine("Exception in execution of remote showNetworkState() method");
            } 
            beautifyOutput();
        }