
/* Local variable to store results */
std::string result("");

if(GV_debug_flag==5)
{
	/* Lets print out the states of each of the flags that this code block is either influenced by or influences */
    std::cerr << "DIDERO_PC:DivSQL.cpp:: For the Client " << MW_ID->Mark() << " the value of the Slower_Server flag is: " << Slower_Server->Mark() << std::endl;
	std::cerr << "DIDERO_PC:DivSQL.cpp:: For the Client " << MW_ID->Mark() << " the value of the Server_1_Waiting_For_Client flag is: " << Server_1_Waiting_For_Client->Mark() << std::endl;	
	std::cerr << "DIDERO_PC:DivSQL.cpp:: For the Client " << MW_ID->Mark() << " the value of the Server_2_Waiting_For_Client flag is: " << Server_2_Waiting_For_Client->Mark() << std::endl;		
	std::cerr << "DIDERO_PC:DivSQL.cpp:: For the Client " << MW_ID->Mark() << " the value of the Waiting_for_Faster_Server flag is: " << Waiting_for_Faster_Server->Mark() << std::endl;
	std::cerr << "DIDERO_PC:DivSQL.cpp:: For the Client " << MW_ID->Mark() << " the values of the flags [Slower_Server->Mark(), Begin->Mark(), Request_Operation_Client->Mark(), Commit->Mark(), Begin_Success_Server_1->Mark(), Begin_Success_Server_2->Mark(), Start_Clients_and_Servers->Mark(), All_Server_1_Transactions->Mark(), All_Server_2_Transactions->Mark()] are: " << Slower_Server->Mark() << " , " << Begin->Mark() << " , " << Request_Operation_Client->Mark() << " , " << Commit->Mark() << " , " << Begin_Success_Server_1->Mark() << " , " << Begin_Success_Server_2->Mark() << " , " << Start_Clients_and_Servers->Mark() << " , " << All_Server_1_Transactions->Mark() << " , " << All_Server_2_Transactions->Mark() << std::endl;
}

/* Process the next request from the Client, unless it is a "Commit" */
if((Commit->Mark()==0)&&(Begin_Success_Server_1->Mark()==0)&&(Begin_Success_Server_2->Mark()==0)&&(Begin->Mark()==0))
{
    result = DivSQL_Requests(MW_ID->Mark(),Slower_Server->Mark());

}else
{
     /* Reset Commit/Begin Flag; it might have already been set from a previous attempt */
     if(Commit->Mark()==1)
     {
        Commit->Mark()=0;
        result=std::string("Commit");
     }
	 
	 if(Begin->Mark()==1)
     {		
		Begin->Mark()=0;
        result=((Oper_Data_for_Replicas[MW_ID->Mark()])[(Oper_Data_for_Replicas[MW_ID->Mark()]).size()])[0];
     }
		
	/* Don't reset these; they will be reset later!!! */	
	 if((Begin_Success_Server_1->Mark()==1)&&(Begin_Success_Server_2->Mark()==1))
	 {
        result=((Oper_Data_for_Replicas[MW_ID->Mark()])[(Oper_Data_for_Replicas[MW_ID->Mark()]).size()])[0];	 
	 }
}


if(GV_debug_flag==5)
{
    std::cerr << "DIDERO_PC:DivSQL.cpp:: The next operation to be performed in the transaction for Client " << MW_ID->Mark() << " is: " << result << std::endl;
}

/* Determine if this is a "Normal" situation, where at least one of the servers is waiting for the next operation from the Client */
if(((((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][1] ) >= 1)&&( ((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][2] ) >= 1))&&((Slower_Server->Mark()==0)))
{
	/* Enable the next operation to be executed on the appropriate Server */
	if((result.compare(std::string("Abort"))!=0)&&(result.compare(std::string("Commit"))!=0))
	{
		if(Waiting_for_Faster_Server->Mark()==0)
		{
			/* If this is not the beginning of a transaction that should be blocked then proceed as normal */
			if((((Oper_Data_for_Replicas[MW_ID->Mark()]).size()==1)&&((All_Server_1_Transactions->Mark()==1)||(All_Server_2_Transactions->Mark()==1)))==false)
			{
				if(((Oper_Data_for_Replicas[MW_ID->Mark()]).size()==1)&&(Begin_Success_Server_1->Mark()==0)&&(Begin_Success_Server_2->Mark()==0))
				{
					if(GV_debug_flag==5)
					{
						std::cerr << "DIDERO_PC:DivSQL.cpp:: 1) For Client " << MW_ID->Mark() << " the value of the All_Server_*_Transactions places are " << All_Server_1_Transactions->Mark() << " and "<< All_Server_2_Transactions->Mark() << std::endl;
					}
				
					Begin_Server_1->Mark()=1;
					Begin_Server_2->Mark()=1;

					All_Server_1_Transactions->Mark()=1;
					All_Server_2_Transactions->Mark()=1;
										
					if(GV_debug_flag==5)
					{
						std::cerr << "DIDERO_PC:DivSQL.cpp:: 1) For Client " << MW_ID->Mark() << " the All_Server_*_Transactions places in the Middleware are being set to indicate that the begin of a transaction is taking place on the servers!!!!" << std::endl;
					}
				
				}else
				{					
					/* Perform the latest operation requested by the Client */
					if(Server_1_Waiting_For_Client->Mark()!=0)
					{
						Server_1_Waiting_For_Client->Mark()=0;
						Request_Operation_Server_1->Mark() = 1;
						
						/* Update the count of currently executing transaction operations for the respective Server */
						Current_Num_of_Oper[1] = Current_Num_of_Oper[1] + 1;
						
						/* Set the flag that will cause all other operations on the respective Server to reactivate */
						Start_Oper_Server_1->Mark() = 1;
						
						if(GV_debug_flag==5)
						{
							std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on Server 1" << std::endl;
						}				
					}
					
					if(Server_2_Waiting_For_Client->Mark()!=0)
					{
						Server_2_Waiting_For_Client->Mark()=0;
						Request_Operation_Server_2->Mark() = 1;
						
						/* Update the count of currently executing transaction operations for the respective Server */
						Current_Num_of_Oper[2] = Current_Num_of_Oper[2] + 1;
						
						/* Set the flag that will cause all other operations on the respective Server to reactivate */
						Start_Oper_Server_2->Mark() = 1;						
						
						if(GV_debug_flag==5)
						{
							std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on Server 2" << std::endl;
						}			
					}
				}
				
			}else
			{
				if(((Begin_Success_Server_1->Mark()==1)&&(Begin_Success_Server_2->Mark()==1))&&((Oper_Data_for_Replicas[MW_ID->Mark()]).size()==1))
				{
					Begin_Success_Server_1->Mark()=0;
					Begin_Success_Server_2->Mark()=0;

					All_Server_1_Transactions->Mark()=0;
					All_Server_2_Transactions->Mark()=0;
										
					/* The servers can now perform the first operation in this transaction */					
					if(Server_1_Waiting_For_Client->Mark()!=0)
					{
						Server_1_Waiting_For_Client->Mark()=0;
						Request_Operation_Server_1->Mark() = 1;
						/* Update the count of currently executing transaction operations for the respective Server */
						Current_Num_of_Oper[1] = Current_Num_of_Oper[1] + 1;
						/* Set the flag that will cause all other operations on the respective Server to reactivate */
						Start_Oper_Server_1->Mark() = 1;						
		
						if(GV_debug_flag==5)
						{
							std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on Server 1" << std::endl;
						}				
					}
					
					if(Server_2_Waiting_For_Client->Mark()!=0)
					{
						Server_2_Waiting_For_Client->Mark()=0;
						Request_Operation_Server_2->Mark() = 1;
						/* Update the count of currently executing transaction operations for the respective Server */
						Current_Num_of_Oper[2] = Current_Num_of_Oper[2] + 1;
						/* Set the flag that will cause all other operations on the respective Server to reactivate */
						Start_Oper_Server_2->Mark() = 1;						
						
						if(GV_debug_flag==5)
						{
							std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on Server 2" << std::endl;
						}
					}
										
					if(GV_debug_flag==5)
					{
						std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the All_Server_*_Transactions places in the Middleware are being RELEASED to indicate that the begin of a transaction has taken place on the servers!!!!" << std::endl;
					}									

				}else
				{
					/* Do Nothing. Simply wait for the "All_Servers" places to be freed up, and then try again */
					Begin_Started->Mark()=1;
					
					if(GV_debug_flag==5)
					{
						std::cerr << "DIDERO_PC:DivSQL.cpp:: 2) For Client " << MW_ID->Mark() << " the Begin_Started gate in the Middleware is being enabled since a concurrent begin has already started on the servers!!!!" << std::endl;
					}				
				}
			}
		
		}else
		{
			/* Interrupt the faster server from performing any more operations from the Client if the slower Server has thrown an exception */
			Waiting_for_Faster_Server->Mark() = 0;
			Slower_Server->Mark() = 1;	
		}
		
		Request_Operation_Client->Mark() = 0;
		
	}else if(/* Commit */result.compare(std::string("Commit"))==0)
	{
		//if((((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][1] ) == 1)&&( ((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][2] ) == 1)&&(Server_1_Waiting_For_Client->Mark()==1)&&(Server_2_Waiting_For_Client->Mark()==1))
		if((Server_1_Waiting_For_Client->Mark()==1)&&(Server_2_Waiting_For_Client->Mark()==1))
		{
			
			if((All_Server_1_Transactions->Mark()==0)&&(All_Server_2_Transactions->Mark()==0))
			{
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: 1) For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on both servers " << std::endl;
				}
				
				/* Both Servers are ready to Commit */
				Server_1_Waiting_For_Client->Mark()=0;
				Request_Operation_Server_1->Mark() = 1;

				Server_2_Waiting_For_Client->Mark()=0;
				Request_Operation_Server_2->Mark() = 1;

				/* Update the count of currently executing transaction operations for the respective Server */
				Current_Num_of_Oper[1] = Current_Num_of_Oper[1] + 1;				
				Current_Num_of_Oper[2] = Current_Num_of_Oper[2] + 1;

				/* Set the flag that will cause all other operations on the respective Server to reactivate */
				Start_Oper_Server_1->Mark() = 1;
				Start_Oper_Server_2->Mark() = 1;
				
				/* Set the flags that tell each Server to coordinate the commits and the execution of concurrent transactions */
				
				All_Server_1_Transactions->Mark()=1;			
				All_Server_2_Transactions->Mark()=1;
				Commit_Trans_Server_1->Mark()=1;			
				Commit_Trans_Server_2->Mark()=1;
				
			}else
			{
				/* Do Nothing. Wait for ongoing commit to complete */
				Queued_Commit->Mark()=1;
				
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: 1) For Client " << MW_ID->Mark() << " the Queued_Commit flag has been enabled!!!!" << std::endl;
				}
			}
						
			Request_Operation_Client->Mark() = 0;			
		
		}else if(((Server_1_Waiting_For_Client->Mark()==0)||(Server_2_Waiting_For_Client->Mark()==0))&&((((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][1] ) == 1)&&( ((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][2] ) == 1)))
		{
			/* Wait for slower server */
			if(GV_debug_flag==5)
			{
				std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " cannot be performed on both servers yet!: the other server is busy!!!!!!!" << std::endl;
			}
			Waiting_for_Slower_Server->Mark()=1;
			Request_Operation_Client->Mark() = 0;
			
		}else if((((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][1] ) == 1)&&( ((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][2] ) != 1))
		{
			/* One Server is not yet ready */		
			if(Waiting_for_Faster_Server->Mark()!=0)
			{
				/* Only one of the Servers is ready to commit; the other Server has an exception it wishes the faster server to know about */			
				Slower_Server->Mark() = 1;
				Waiting_for_Faster_Server->Mark()=0;
				Request_Operation_Client->Mark() = 0;
			}else
			{
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " cannot be performed on both servers yet!: the other server is busy!!!!!!!" << std::endl;
				}
				Waiting_for_Slower_Server->Mark()=1;
				Request_Operation_Client->Mark() = 0;
			}
		}else if((((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][1] ) != 1)&&( ((Oper_Data_for_Replicas[MW_ID->Mark()]).size() - Server_oper_index[MW_ID->Mark()][2] ) == 1))
		{
			/* One Server is not yet ready */		
			if(Waiting_for_Faster_Server->Mark()!=0)
			{
				/* Only one of the Servers is ready to commit; the other Server has an exception it wishes the faster server to know about */			
				Slower_Server->Mark() = 1;
				Waiting_for_Faster_Server->Mark()=0;
				Request_Operation_Client->Mark() = 0;
			}else
			{
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " cannot be performed on both servers yet!: the other server is busy!!!!!!" << std::endl;
				}
				Waiting_for_Slower_Server->Mark()=1;
				Request_Operation_Client->Mark() = 0;
			}					
		}else
		{
			if(GV_debug_flag==5)
			{
				std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " cannot be performed on both servers!!!!!!!" << std::endl;
			}
		}

	}else if(/*Abort*/result.compare(std::string("Abort"))==0)
	{
		if(GV_debug_flag==5)
		{
			std::cerr << "DIDERO_PC:DivSQL.cpp:: For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on both servers.." << std::endl;
		}		
		/* Both Servers are ready to Abort */
		Server_1_Waiting_For_Client->Mark()=0;
		Request_Operation_Server_1->Mark() = 1;

		Server_2_Waiting_For_Client->Mark()=0;
		Request_Operation_Server_2->Mark() = 1;

		Current_Num_of_Oper[1] = Current_Num_of_Oper[1] + 1;
		Current_Num_of_Oper[2] = Current_Num_of_Oper[2] + 1;
		
		/* Set the flag that will cause all other operations on the respective Server to reactivate */
		Start_Oper_Server_1->Mark() = 1;
		Start_Oper_Server_2->Mark() = 1;		
				
		Request_Operation_Client->Mark() = 0;	
	}

}else if(Slower_Server->Mark()!=0)
{
	/* Otherwise, the faster server is waiting for the slower server */
	if(/* Commit*/result.compare(std::string("Commit"))==0)
	{
			if((All_Server_1_Transactions->Mark()==0)&&(All_Server_2_Transactions->Mark()==0))
			{
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: 2) For Client " << MW_ID->Mark() << " the operation: " << result << " will be performed on both servers.." << std::endl;
				}
				
				/* Both Servers are ready to Commit */
				Server_1_Waiting_For_Client->Mark()=0;
				Request_Operation_Server_1->Mark() = 1;

				Server_2_Waiting_For_Client->Mark()=0;
				Request_Operation_Server_2->Mark() = 1;

				Current_Num_of_Oper[1] = Current_Num_of_Oper[1] + 1;
				Current_Num_of_Oper[2] = Current_Num_of_Oper[2] + 1;
				
				/* Set the flag that will cause all other operations on the respective Server to reactivate */
				Start_Oper_Server_1->Mark() = 1;
				Start_Oper_Server_2->Mark() = 1;				
																
				/* Set the flags that tell each Server to coordinate the commits and the execution of concurrent transactions */
				
				All_Server_1_Transactions->Mark()=1;			
				All_Server_2_Transactions->Mark()=1;
				Commit_Trans_Server_1->Mark()=1;			
				Commit_Trans_Server_2->Mark()=1;
			}else
			{
				/* Do Nothing. Wait for ongoing commit/begin to complete */
				Queued_Commit->Mark()=1;
				
				if(GV_debug_flag==5)
				{
					std::cerr << "DIDERO_PC:DivSQL.cpp:: 2) For Client " << MW_ID->Mark() << " the Queued_Commit flag has been enabled!!!!" << std::endl;
				}					
				
			}			
			
		Request_Operation_Client->Mark() = 0;	
		
	}else if(/* Abort*/(result.compare(std::string("Abort"))==0))
	{
		if(GV_debug_flag==5)
		{
			std::cerr << "DIDERO_PC:DivSQL.cpp:: ... But Client " << MW_ID->Mark() << " has to be informed about the operation: " << result << std::endl;
		}

		/* The Client has to be informed of the Exception generated from the slower server and, consequently, both servers have to be aborted */
		Server_1_Waiting_For_Client->Mark()=1;

		Server_2_Waiting_For_Client->Mark()=1;
		
		Request_Operation_Client->Mark() = 0;		
		
		Operation_Executed_Client->Mark() = 1;			
	}
	
	/* Reset the "Slower server" flag */
	Slower_Server->Mark()=0;
	
}else if(((Server_1_Waiting_For_Client->Mark()==0)&&(Server_2_Waiting_For_Client->Mark()==0))&&((Slower_Server->Mark()==0)))
{
	if(GV_debug_flag==5)
	{
		std::cerr << "DIDERO_PC:DivSQL.cpp:: Upon DivREP being given the next operation by Client " << MW_ID->Mark() << " , the simulation has reached a seemingly impossible state!!!!!!!!!! " << result << std::endl;
	}	
}
