/**
   * Consume the serive provided by the service provider.
   *
   * @param service the service that is to be consumed
   * @throws FederationServiceConsumptionFailed if an error occurs
   */
  @Override
  public void consume(FederationRequest service) throws FederationServiceConsumptionFailed {
    try {
      captureThread =
          SoundUtility.createCaptureThread(service.getFederationConnection().getOutputStream());

      soundOutputThread =
          SoundUtility.createSoundOutputThread(service.getFederationConnection().getInputStream());
    } catch (Exception e) {
      System.err.println("Error in Voice talk handler: " + e.toString());
      e.printStackTrace();

      throw new FederationServiceConsumptionFailed("Error in Voice talk handler: " + e.toString());
    } // end of try .. catch block
  }
    /** Overridden run method */
    @Override
    public void run() {
      taskData = getNextTaskData();

      while (taskData != null) {
        try {
          // first initiate a federation request
          ArrayList<Serializable> data = new ArrayList<Serializable>();
          data.add(taskData);

          FederationServiceMapReduceConsumer fsmrc =
              new FederationServiceMapReduceConsumer(workerMap, data);
          FederationRequest req = fsmrc.discover(node.getIpAddress());

          // then start a "heart-beat" thread
          startHeartBeatThread();

          // consume the service
          fsmrc.consume(req);

          // get back the processed data
          ArrayList<Serializable> results = fsmrc.getDataList();
          for (Serializable result : results) resultList.add(result);

          // stop the "heart-beat" thread
          stopHeartBeatThread();

          // and close the connections
          req.closeIt();
        } catch (FederationServiceDiscoveryFailed fe) {
          System.err.println(
              "Exception in Worker thread: " + fe.toString() + ", for node: " + node.toString());
          fe.printStackTrace();
          System.err.println("Will now try to use other free nodes...");

          synchronized (MapReduceControllerFederationImpl.this.freeNodeList) {
            // add to the end of the list
            MapReduceControllerFederationImpl.this.freeNodeList.add(node);

            System.out.println(MapReduceControllerFederationImpl.this.freeNodeList.size());

            // and change to a new node from beginning of the list
            // that is not the same as the current node, if none is
            // found keep trying the same node
            FederationNode newNode = null;
            for (FederationNode fn : MapReduceControllerFederationImpl.this.freeNodeList) {
              if (!fn.getIpAddress().equals(node.getIpAddress())) {
                newNode = fn;
                break;
              } // end if
            } // end for

            if (newNode == null) {
              node = MapReduceControllerFederationImpl.this.freeNodeList.get(0);
            } else {
              node = newNode;
            } // end if
          }

          System.err.println("Will be using: " + node);

          // there was some problem with processing
          // this data, so save it for other nodes
          pushBackTaskData(taskData);
        } catch (Exception ex) {
          System.err.println(
              "Exception in Worker thread: " + ex.toString() + ", for node: " + node.toString());
          ex.printStackTrace();

          // there was some problem with processing
          // this data, so save it for other nodes
          pushBackTaskData(taskData);

          try {
            // sleep for quite some time
            sleep(10000);
          } catch (InterruptedException ignored) {
          }
        } // end of try .. catch block

        taskData = getNextTaskData();
      } // end while

      // if we are done we add our selfs in the free node list
      // so as to make us available at a later stage, if some node
      // breaks down
      synchronized (MapReduceControllerFederationImpl.this.freeNodeList) {
        MapReduceControllerFederationImpl.this.freeNodeList.add(node);
      }
    }