@Override
 protected void setup(Reducer.Context context) throws IOException, InterruptedException {
   super.setup(context);
   Configuration conf = context.getConfiguration();
   iteration = conf.getInt("iteration", -1);
   System.out.println("Setting up Reducer " + iteration);
   centroids = KMeansUtil.readCentroids(conf);
   System.out.println("Reducer " + iteration + " Received " + centroids.size() + " centroids as");
   KMeansUtil.showOutput(centroids);
 }
 @Override
 protected void reduce(IntWritable key, Iterable<LongWritable> values, Context context)
     throws IOException, InterruptedException {
   Double currentCentroid = centroids.get(key.get());
   System.out.println("Reducer " + iteration + " Current Centroid: " + currentCentroid);
   Double newCentroid = getNewCentroid(values);
   System.out.println(
       "Reducer "
           + iteration
           + " Reducer for centroid "
           + key.get()
           + " which is "
           + centroids.get(key.get()));
   if (newCentroid != null) {
     System.out.println(
         "Reducer "
             + iteration
             + " New centroid calculated for "
             + key.get()
             + " is "
             + newCentroid);
     if (belowThreshold(currentCentroid, newCentroid)) {
       context.getCounter(Convergence.CONVERGENT).increment(1);
       System.out.println(
           "Reducer "
               + iteration
               + " REDUCER CONVERGED!"
               + context.getCounter(Convergence.CONVERGENT).getValue()
               + " times");
     }
     context = KMeansUtil.writeCentroid(context, key.get(), newCentroid);
     DoubleWritable op = new DoubleWritable(newCentroid);
     context.write(key, op);
   } else {
     System.out.println("Reducer " + iteration + " New Centroid calculated is NULL!");
   }
 }