@Override
  public void processLoop() {
    FloorHolderAdvanced fh2 = (FloorHolderAdvanced) fh;
    long currTime = new Date().getTime();
    if (state == 0) {
      fh.openFloorAfterTimeOut(super.getIsTypingTimeOut());
    } else if (state == 1) {
      /// Server is sendinding intervention
    } else if (state == 2) {
      /// Server is waiting for first keypress of response
      /// This is the gap between sending of intervention AND waiting for first keypress by
      // participant, which should be the response
      /// We need to ensure that if participant doesn't respond for whatever reason, it will open
      // floor to other participant after timeout..
      System.err.println(
          "COUNTING DOWN TO RESPONSE"
              + ((currTime - this.timeOfLastStateChange) - this.timeoutCR_RESP.getValue()));
      synchronized (this) {
        ///
        if (currTime - this.timeOfLastStateChange > this.timeoutCR_RESP.getValue()) {
          // fh2.allowAllIncomingFloorRequests(true);
          // fh2.setAutomaticallyAllowOpenFloorAfterIsTypingTimeout(true);
          // h2.forciblyOpenFloor();
          fh2.resumeNormalOperation();
          String addn = "-";
          if (Debug.showEOFCRSTATES) addn = " ((NORESPONSE: ABORTED-SERVERSTATE FROM 2 to 0))";
          getC()
              .getParticipants()
              .sendAndEnableLabelDisplayToParticipant(
                  apparentOrigin, "Please type " + addn, false, true);
          getC()
              .getParticipants()
              .sendAndEnableLabelDisplayToParticipant(
                  this.mgcSWFTREcipient, "Please type " + addn, false, true);
          setState(0);
        }
      }
    } else if (state
        == 3) { // Server is receiving the response, waiting for a lull so that it can send an
                // acknowledgment
      System.err.println(
          "COUNTING DOWN TO ACK"
              + ((currTime - this.timeOfLastState3DocChange) - this.timeoutRESP_ACK.getValue()));
      System.err.println("COUNTING DOWN:" + (currTime - timeOfLastState3DocChange));

      synchronized (sS) {
        // first docchange has come through....and there has been a pause....
        if (timeOfLastState3DocChange > 0
            && (currTime - this.timeOfLastState3DocChange > this.timeoutRESP_ACK.getValue())) {
          fh2.blockAllIncomingFloorRequests(true);
          if (Debug.trackLockedInterface)
            Conversation.printWSln("Main", "COUNTED DOWN (4) FROM RESPONSE TO ACK");
          fh2.forciblyOpenFloor();
          if (Debug.trackLockedInterface)
            Conversation.printWSln("Main", "COUNTED DOWN (5)FROM RESPONSE TO ACK");
          MazeGameAcknowledgement mga =
              new MazeGameAcknowledgement(
                  sS,
                  this,
                  this.mgcSWFTREcipient.getUsername(),
                  this.apparentOrigin.getUsername(),
                  this.cycACK.getNext(this.mgcSWFTREcipient),
                  this.ackDelayMINIMALVALUE.getValue(),
                  this.ackDelayPLUSRANDOMAMOUNT.getValue());
          mga.setType("ACK");
          sS.addRecordedSequenceFromApparentOrigin(mga);
          setState(4);
        }
      }

      // MUST ADD A RESET SO THAT THE PARTICIPANT DCAN REQUEST THE FLOOR...

    }

    //
  }
  public void panic() {

    setState(0);
    FloorHolderAdvanced fh2 = (FloorHolderAdvanced) fh;
    fh2.resumeNormalOperation();
  }