@Override
    public void reduce(Text key, Iterator<Node> values,
        OutputCollector<Text, Node> output, Reporter reporter)
            throws IOException {
      int min = Integer.MAX_VALUE;
      Node node = null;
      while (values.hasNext()) {
        Node distance = values.next();
        if(LOGGER.isDebugEnabled()) {
          LOGGER.debug("Reduce1 " + key + "\t" + distance.toString());
        }
        min = Math.min(distance.getDistance(), min);
        if (distance.getFriends() != null) {
          if (node != null) {
            throw new IOException("Node " + node.toString() + " already found for "
                + key.toString() + ": " + distance.toString());
          }
          node = new Node(distance.getDistance(), distance.getFriends());
          if(LOGGER.isDebugEnabled()) {
            LOGGER.debug("Reduce2 " + key + "\t" + node.toString());
          }

        }
      }
      if (min < 0) {
        throw new IOException("min " + min + " less than zero "
            + key.toString());
      }
      if (node == null) {
        throw new IOException("Did not find structure for "
            + key.toString());
      }
      if (min != node.getDistance()) {
        reporter.incrCounter(Counters.NUMBER_OF_SHORTER_PATHS_FOUND, 1);
        node.setDistance(min);
      }
      if(LOGGER.isDebugEnabled()) {
        LOGGER.debug("Reduce3 " + key + "\t" + node.toString());
      }
      output.collect(key, node);
    }