/**
   * This method is responsible for the calculation of the position of the SkyNet-node in the
   * SkyNet-tree. Additionally, it determines the key of the Parent-Coordinator, which can be looked
   * up.<br>
   * This method starts the recursive calculation, where first the determination of the Coordinator
   * for every new interval is executed. Then it is checked, if the SkyNet-node is responsible for
   * that Coordinator. In case of a positive outcome, the Parent-Coordinator is looked up,
   * otherwise, the interval at the next level is calculated, to which the SkyNet-node must descend.
   *
   * @param ownID the ID of this SkyNet-node
   * @param left the left bound of the interval
   * @param right the right bound of the interval
   * @param iter the current level
   */
  private void processNextLevel(SkyNetID ownID, BigDecimal left, BigDecimal right, int iter) {

    BigDecimal temp = left.add(right);
    temp = temp.divide(new BigDecimal(String.valueOf(2)));
    // BigDecimal temp = new BigDecimal((left + right) / 2);
    SkyNetID skyNetCoKey = new SkyNetID(temp);

    // call the process-method for the corresponding overlay
    treeHandlerDelegator.processNextLevel(
        ownID,
        skyNetCoKey,
        left,
        right,
        iter,
        new OperationCallback<Object>() {

          @Override
          public void calledOperationFailed(Operation<Object> op) {
            processNextLevelOperationFailed(op);
          }

          @Override
          public void calledOperationSucceeded(Operation<Object> op) {
            processNextLevelOperationSucceeded(op);
          }
        });
  }
  private void lookupParentCoordinator() {
    if (((AbstractOverlayNode<?, ?>) skyNetNode.getOverlayNode())
        .getPeerStatus()
        .equals(PeerStatus.PRESENT)) {
      log.debug(
          SkyNetUtilities.getTimeAndNetID(skyNetNode)
              + "starts a lookup for the key "
              + coordinatorKey.getPlainSkyNetID());
      treeHandlerDelegator.lookupParentCoordinator(
          coordinatorKey,
          new OperationCallback<OverlayContact<OverlayID<?>>>() {

            @Override
            public void calledOperationFailed(Operation<OverlayContact<OverlayID<?>>> op) {
              lookupOperationFailed(op);
            }

            @Override
            public void calledOperationSucceeded(Operation<OverlayContact<OverlayID<?>>> op) {
              lookupOperationSucceeded(op);
            }
          });
    } else {
      log.warn("SkyNetNode cannot lookup ParentCoordinator" + ", because he is not PRESENT");
    }
  }
 void calculateResponsibilityIntervalOperationSucceeded(
     Operation<OverlayContact<OverlayID<?>>> op, SkyNetID ownID) {
   treeHandlerDelegator.calculateResponsibilityIntervalOperationSucceeded(op);
   int iter = 0;
   BigDecimal left = new BigDecimal(0);
   BigDecimal right = new BigDecimal(1);
   level = 0;
   processNextLevel(ownID, left, right, iter);
 }
  void lookupOperationSucceeded(Operation<OverlayContact<OverlayID<?>>> op) {
    LookupResult result = treeHandlerDelegator.lookupOperationSucceeded(op);
    parentCoordinator =
        new SkyNetNodeInfoImpl(
            result.getSkyNetID(),
            coordinatorKey,
            DefaultTransInfo.getTransInfo(
                result.getContact().getTransInfo().getNetId(), skyNetNode.getPort()),
            level);
    log.info(
        parentCoordinator.toString()
            + " is parentCoordinator of "
            + skyNetNode.getSkyNetNodeInfo().toString());

    skyNetNode.getMetricUpdateStrategy().sendNextDataUpdate();
  }
 void processNextLevelOperationSucceeded(Operation<?> op) {
   ProcessNextLevelResult result = treeHandlerDelegator.processNextLevelOperationSucceeded(op);
   if (result.isKeyResponsibility()) {
     checkResponsibility(
         result.getOwnID(),
         result.getSkyNetCoKey(),
         result.getLeft(),
         result.getRight(),
         result.getIter());
   } else {
     calculateNextLevel(
         result.getOwnID(),
         result.getSkyNetCoKey(),
         result.getLeft(),
         result.getRight(),
         result.getIter());
   }
 }
  /**
   * If it is possible to calculate the responsibility interval of a peer on the current overlay,
   * this method calculates the corresponding responsibility interval of the node in the ID-space of
   * SkyNet. In this context, the responsibility interval is used to test, if a SkyNet-node is
   * responsible for a Coordinator.
   *
   * @param id contains the ID of this SkyNet-node
   */
  public void calculateResponsibilityInterval(SkyNetID id) {
    if (((AbstractOverlayNode<?, ?>) skyNetNode.getOverlayNode())
        .getPeerStatus()
        .equals(PeerStatus.PRESENT)) {
      // execute getPredecessor-method
      final SkyNetID ownID = id;
      treeHandlerDelegator.calculateResponsibilityInterval(
          ownID,
          new OperationCallback<OverlayContact<OverlayID<?>>>() {

            @Override
            public void calledOperationFailed(Operation<OverlayContact<OverlayID<?>>> op) {
              calculateResponsibilityIntervalOperationFailed(op);
            }

            @Override
            public void calledOperationSucceeded(Operation<OverlayContact<OverlayID<?>>> op) {
              calculateResponsibilityIntervalOperationSucceeded(op, ownID);
            }
          });
    } else {
      log.warn("SkyNetNode cannot get Predecessor" + ", because he is not PRESENT");
    }
  }
 void lookupOperationFailed(Operation<OverlayContact<OverlayID<?>>> op) {
   treeHandlerDelegator.lookupOperationFailed(op);
   skyNetNode.getMetricUpdateStrategy().scheduleNextUpdateEvent();
 }
 void processNextLevelOperationFailed(Operation<?> op) {
   treeHandlerDelegator.processNextLevelOperationFailed(op);
   skyNetNode.getMetricUpdateStrategy().scheduleNextUpdateEvent();
 }
 void calculateResponsibilityIntervalOperationFailed(Operation<OverlayContact<OverlayID<?>>> op) {
   treeHandlerDelegator.calculateResponsibilityIntervalOperationFailed(op);
   skyNetNode.getMetricUpdateStrategy().scheduleNextUpdateEvent();
 }