protected void reconfigureSegmentGroup(
      SegmentGroup affectedGroup,
      DataNodeIdentifier oldNode,
      DataNodeIdentifier replacementNode,
      boolean oldNodeIsUp) {
    System.out.println("Reconfiguring");
    /* what do we do? this is what we do...
        note: we do NOT worry about the status of the node here; we assume that is set by the coordinator

        for each segment in the segment group:
            if (oldNodeIsUp):
                send an unset-segment request
            perform a read on the segment group
            send a write request to the new node

        swap the new node into the segment group
    */

    int volumeId = affectedGroup.getVolumeId();
    long startingOffset = affectedGroup.getStartingBlock();
    long stoppingOffset = affectedGroup.getStoppingBlock();

    if (oldNodeIsUp) {
      List<DataNodeIdentifier> targets = new ArrayList<DataNodeIdentifier>();
      targets.add(oldNode);
      int unsetId =
          coordinator
              .getServer()
              .issueUnsetSegmentRequest(targets, volumeId, startingOffset, stoppingOffset);

      boolean waiting = true;

      while (waiting) {
        List<UnsetSegmentRequestResult> results =
            coordinator.getServer().getUnsetSegmentRequestResults(unsetId);
        if (results.get(0).wasSuccessful()) {
          waiting = false;
        }
      }
    }

    List<DataNodeIdentifier> replacementMembers =
        new ArrayList<DataNodeIdentifier>(affectedGroup.getMembers());
    int oldNodeIndex = replacementMembers.indexOf(oldNode);
    replacementMembers.set(oldNodeIndex, replacementNode);
    SegmentGroup replacementGroup =
        new SegmentGroup(replacementMembers, volumeId, startingOffset, stoppingOffset);

    for (long offset = startingOffset; offset <= stoppingOffset; ++offset)
    // TODO FIXME eventual improvement: make this whole loop asynchronous
    // that is, issue each read request, then as the results come in, issue the write requests
    {
      int readId = coordinator.read(volumeId, logicalOffset);
      while (!coordinator.requestFinished(readId)) {
        // spin!!!
      }

      ReadRequestResult readResult = coordinator.readResult(readId);
      byte[] block = readResult.getBlock();

      int writeId = coordinator.writeWithTarget(replacementGroup, volumeId, offset, block);
      while (!coordinator.requestFinished(writeId)) {
        // spin!!!
      }

      // TODO FIXME check for success of the read (above) and the write (here)
    }

    affectedGroup.replace(oldNode, replacementNode);
  }