private ByteBuffer merge(
      ContextState mergedState, ContextState leftState, ContextState rightState) {
    while (leftState.hasRemaining() && rightState.hasRemaining()) {
      int cmp = leftState.compareIdTo(rightState);
      if (cmp == 0) {
        Relationship rel = compare(leftState, rightState);
        if (rel == Relationship.DISJOINT) // two local shards
        mergedState.writeLocal(
              leftState.getCounterId(),
              leftState.getClock() + rightState.getClock(),
              leftState.getCount() + rightState.getCount());
        else if (rel == Relationship.GREATER_THAN) leftState.copyTo(mergedState);
        else // EQUAL or LESS_THAN
        rightState.copyTo(mergedState);

        rightState.moveToNext();
        leftState.moveToNext();
      } else if (cmp > 0) {
        rightState.copyTo(mergedState);
        rightState.moveToNext();
      } else // cmp < 0
      {
        leftState.copyTo(mergedState);
        leftState.moveToNext();
      }
    }

    while (leftState.hasRemaining()) {
      leftState.copyTo(mergedState);
      leftState.moveToNext();
    }

    while (rightState.hasRemaining()) {
      rightState.copyTo(mergedState);
      rightState.moveToNext();
    }

    return mergedState.context;
  }