public void actionPerformed(ObjectOutputStream oos, Message msg) throws EventHandleException {
    Message result = null;
    Head thead = new Head();

    try {
      /* get the handler of the ServerPeer */
      ServerPeer serverpeer = (ServerPeer) gui.peer();

      /* get the message body */
      SPLeaveFindReplacementNodeBody body = (SPLeaveFindReplacementNodeBody) msg.getBody();

      TreeNode treeNode = serverpeer.getTreeNode(body.getLogicalDestination());
      if (treeNode == null) {
        System.out.println("Tree node is null, do not process the message");
        return;
      }

      RoutingTableInfo leftRoutingTable = treeNode.getLeftRoutingTable();
      RoutingTableInfo rightRoutingTable = treeNode.getRightRoutingTable();
      RoutingItemInfo temptInfo, transferInfo = null;

      int i;

      if (treeNode.getLeftChild() != null) {
        // if it has left child
        body.setPhysicalSender(serverpeer.getPhysicalInfo());
        body.setLogicalSender(treeNode.getLogicalInfo());
        body.setLogicalDestination(treeNode.getLeftChild().getLogicalInfo());

        thead.setMsgType(MsgType.SP_LEAVE_FIND_REPLACEMENT_NODE.getValue());
        result = new Message(thead, body);
        serverpeer.sendMessage(treeNode.getLeftChild().getPhysicalInfo(), result);
      } else if (treeNode.getRightChild() != null) {
        // if it has right child
        body.setPhysicalSender(serverpeer.getPhysicalInfo());
        body.setLogicalSender(treeNode.getLogicalInfo());
        body.setLogicalDestination(treeNode.getRightChild().getLogicalInfo());

        thead.setMsgType(MsgType.SP_LEAVE_FIND_REPLACEMENT_NODE.getValue());
        result = new Message(thead, body);
        serverpeer.sendMessage(treeNode.getRightChild().getPhysicalInfo(), result);
      } else {
        // if it has no child, check routing table
        i = 0;
        while ((i < leftRoutingTable.getTableSize()) && (transferInfo == null)) {
          temptInfo = leftRoutingTable.getRoutingTableNode(i);
          if (temptInfo != null) {
            if ((temptInfo.getLeftChild() != null) || (temptInfo.getRightChild() != null)) {
              transferInfo = temptInfo;
            }
          }
          i++;
        }

        i = 0;
        while ((i < rightRoutingTable.getTableSize()) && (transferInfo == null)) {
          temptInfo = rightRoutingTable.getRoutingTableNode(i);
          if (temptInfo != null) {
            if ((temptInfo.getLeftChild() != null) || (temptInfo.getRightChild() != null)) {
              transferInfo = temptInfo;
            }
          }
          i++;
        }

        if (transferInfo != null) {
          body.setPhysicalSender(serverpeer.getPhysicalInfo());
          body.setLogicalSender(treeNode.getLogicalInfo());
          if (transferInfo.getLeftChild() != null) {
            body.setLogicalDestination(transferInfo.getLeftChild().getLogicalInfo());

            thead.setMsgType(MsgType.SP_LEAVE_FIND_REPLACEMENT_NODE.getValue());
            result = new Message(thead, body);
            serverpeer.sendMessage(transferInfo.getLeftChild().getPhysicalInfo(), result);
          } else {
            body.setLogicalDestination(transferInfo.getRightChild().getLogicalInfo());

            thead.setMsgType(MsgType.SP_LEAVE_FIND_REPLACEMENT_NODE.getValue());
            result = new Message(thead, body);
            serverpeer.sendMessage(transferInfo.getRightChild().getPhysicalInfo(), result);
          }
        } else {
          doLeaveAndReplace(serverpeer, treeNode, body);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new EventHandleException(
          "Super peer finds a replacement peer failure when it leaves network", e);
    }
  }
 public boolean isConsumed(Message msg) throws EventHandleException {
   if (msg.getHead().getMsgType() == MsgType.SP_LEAVE_FIND_REPLACEMENT_NODE.getValue())
     return true;
   return false;
 }