public void actionPerformed(ObjectOutputStream oos, Message msg) throws EventHandleException {
    try {
      /* get the handler of the ServerPeer */
      ServerPeer serverpeer = (ServerPeer) gui.peer();

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

      TreeNode treeNode = body.getTreeNode();
      treeNode.setContent(body.getContent());
      SPGeneralAction.saveData(body.getContent().getData());
      treeNode.setStatus(TreeNode.ACTIVE);
      treeNode.setRole(TreeNode.MASTER);
      treeNode.addCoOwnerList(body.getPhysicalSender());
      serverpeer.addListItem(treeNode);
      SPGeneralAction.updateRotateRoutingTable(serverpeer, treeNode);

      serverpeer.setActivateStablePosition(
          new ActivateStablePosition(serverpeer, treeNode, ServerPeer.TIME_TO_STABLE_POSITION));

      ((ServerGUI) gui).updatePane(treeNode);
    } catch (Exception e) {
      e.printStackTrace();
      throw new EventHandleException(
          "Replace a super peer's position failure when it leaves network", e);
    }
  }
  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);
    }
  }