/**
   * Protocol processes messages being received and sent in the applciation
   *
   * @param message
   */
  public String Protocol(String message) {
    if (message.contains("ID")) {
      String firstWordOfMessage = message.toUpperCase().trim().split("\\s+")[0];
      if (firstWordOfMessage.equals(Settings.Version.toUpperCase()))
        return this.IDQueryResponseProcess(this.genResponse(message)).toString();
      else return this.IDQueryRequestProcess(this.genRequest(message)).toString();
    } else if (message.contains("NEXT")) {
      String firstWordOfMessage = message.toUpperCase().trim().split("\\s+")[0];
      if (firstWordOfMessage.equals(Settings.Version.toUpperCase()))
        return this.NextQueryResponseProcess(this.genResponse(message)).toString();
      else return this.NEXTQueryReuqestProcess(this.genRequest(message)).toString();
    } else if (message.contains("PULL")) {
      String firstWordOfMessage = message.toUpperCase().trim().split("\\s+")[0];
      if (firstWordOfMessage.equals(Settings.Version.toUpperCase()))
        return this.PullQueryResponseProcess(this.genResponse(message)).toString();
      else return this.PullQueryRequestProcess(this.genRequest(message)).toString();
    } else if (message.contains("ADD")) {
      String firstWordOfMessage = message.toUpperCase().trim().split("\\s+")[0];
      if (firstWordOfMessage.equals(Settings.Version.toUpperCase()))
        return this.AddQueryResponseProcess(this.genResponse(message)).toString();
      else return this.AddQueryRequestProcess(this.genRequest(message)).toString();
    } else if (message.contains("QUERY")) {
      String firstWordOfMessage = message.toUpperCase().trim().split("\\s+")[0];
      if (firstWordOfMessage.equals(Settings.Version.toUpperCase()))
        return this.QueryResponseProcess(this.genResponse(message)).toString();
      else return this.QueryRequestProcess(this.genRequest(message)).toString();

    } else if (message.contains("info")) {
      return this.toString();
    }
    return "";
  }
 /**
  * Processes an ID query request
  *
  * @param request
  * @return
  */
 public Response IDQueryRequestProcess(Request request) {
   ArrayList<String> responseMessage = new ArrayList<String>();
   if (getInt(this.getID()) < getInt(this.NextPeerID)
       && getInt(request.getPeerID()) > getInt(this.getID())
       && getInt(request.getPeerID()) > getInt(this.getNextPeerID())) {
     responseMessage.add(this.getNextPeerHostName() + " " + this.getNextPeerPort());
     return new Response(Settings.Version, "ID", "1", "301", "redirect", responseMessage);
   } else if (getInt(request.getPeerID()) > getInt(this.getID())
           && getInt(request.getPeerID()) < getInt(this.getNextPeerID())
       || getInt(this.getID()) > getInt(this.NextPeerID)
           && getInt(request.getPeerID()) > getInt(this.getID())) {
     return new Response(Settings.Version, "ID", "0", "200", "ok", responseMessage);
   } else if (this.getID() == this.NextPeerID) {
     if (getInt(this.getID()) > getInt(request.getPeerID())) {
       return new Response(Settings.Version, "ID", "0", "200", "ok", responseMessage);
     } else {
       // This condition requires more coding time
       return NEXTQueryReuqestProcess(request);
     }
   } else if (getInt(request.getPeerID()) == getInt(this.getID())) {
     return new Response(Settings.Version, "ID", "0", "400", "peerexist", responseMessage);
   } else if (!request.getVersion().trim().equals(Settings.Version.trim())) {
     return new Response(Settings.Version, "ID", "0", "401", "versionError", responseMessage);
   } else {
     return new Response(Settings.Version, "ID", "0", "503", "UnknownCondition", responseMessage);
   }
 }
 public Request genRequest(String message) {
   String[] ArrayMessage = message.trim().split("CRLF");
   String version = null;
   String operation = null;
   int numOfLines = 0;
   String peerID = null;
   ArrayList<String> Message = new ArrayList<String>();
   for (String strValue : ArrayMessage) {
     if (strValue.toUpperCase().contains(Settings.Version.toUpperCase())) {
       String[] wordsInLine = strValue.trim().split("\\s+");
       operation = wordsInLine[0];
       version = wordsInLine[1];
       numOfLines = Integer.parseInt(wordsInLine[2]);
       if (wordsInLine.length == 4) {
         peerID = wordsInLine[3];
       }
     } else {
       Message.add(strValue);
     }
   }
   if (peerID == null & Message.size() == 0) {
     return new Request(operation, version, numOfLines);
   } else if (peerID == null & Message.size() > 0) {
     return new Request(operation, version, numOfLines, Message);
   } else {
     return new Request(operation, version, numOfLines, peerID, Message);
   }
 }