@Override
 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
   final Channel channel = ctx.getChannel();
   Message m = (Message) e.getMessage();
   Tuple t = cb.receive(m);
   if (m.type() == Type.DEREG) {
     channel.close();
   }
   if (t != null) {
     if (m.type() == Type.REG) {
       PhysicalLocation pl = new PhysicalLocation(m.source().logId(), (Integer) t.get(0));
       plMap.put(pl, channel);
       ctx.setAttachment(pl);
     }
     Message rsp = new Message(m.type(), m.getAck(), m.destination(), m.source(), t);
     channel.write(rsp);
   }
 }
  private void handleTaintMessage(Message m) throws ExecException {
    if (m.body().get(0).equals("cross")) { // cross-task (accumulates)
      String sourceAlias = m.source().logId();
      Map<Tuple, Set<String>> oneCTTT = crossTaskTaintTags.get(sourceAlias);

      Tuple keys = (Tuple) m.body().get(1);
      if (!oneCTTT.containsKey(keys)) {
        oneCTTT.put(keys, new HashSet<String>());
      }
      Set<String> tags = oneCTTT.get(keys);
      for (int i = 2; i < m.body().size(); i++) {
        tags.add((String) m.body().get(i));
      }
    } else { // within-task (replaces)
      currentWithinTaskTaintTag = new HashSet<String>();
      for (int i = 1; i < m.body().size(); i++) {
        currentWithinTaskTaintTag.add((String) m.body().get(i));
      }
    }
  }
  public void initialize() throws Exception {
    this.communicator =
        new Communicator() {

          @Override
          public Location myLocation() {
            return location;
          }

          @Override
          public void sendToCoordinator(Tuple message) {
            senderReceiver.sendAsync(
                new Message(location, PhysicalLocation.coordinatorLocation(), message));
          }

          @Override
          public void sendDownstream(Tuple message) throws NoSuchLocationException {
            if (withinTaskDownstreamNeighbors.isEmpty() && crossTaskDownstreamNeighbors.isEmpty())
              throw new NoSuchLocationException(
                  "Line " + logicalLocation.logId() + " has no downstream neighbor.");
            for (String neighbor : withinTaskDownstreamNeighbors) {
              sendWithinTaskMessage(
                  neighbor, new Message(location, new LogicalLocation(neighbor), message));
            }
            for (String neighbor : crossTaskDownstreamNeighbors) {
              senderReceiver.sendAsync(
                  new Message(location, new LogicalLocation(neighbor), message));
            }
          }

          @Override
          public void sendUpstream(Tuple message) throws NoSuchLocationException {
            if (withinTaskUpstreamNeighbors.isEmpty())
              throw new NoSuchLocationException(
                  "Line " + logicalLocation.logId() + " has no within-task upstream neighbor.");
            for (String neighbor : withinTaskUpstreamNeighbors) {
              sendWithinTaskMessage(
                  neighbor, new Message(location, new LogicalLocation(neighbor), message));
            }
          }

          @Override
          public void sendToAgents(LogicalLocation destination, Tuple tuple)
              throws NoSuchLocationException {
            if (!logicalIds.contains(destination.logId()))
              throw new NoSuchLocationException(
                  "Logical location " + destination + " does not exist.");
            senderReceiver.sendAsync(new Message(location, destination, tuple));
          }
        };

    this.messageReceiptCallback =
        new MessageReceiptCallback() {
          public Tuple receive(Message m) {
            if (m.type() == Message.Type.TAINT) {
              try {
                handleTaintMessage(m);
              } catch (ExecException e) {
                throw new RuntimeException("Error in taint logic.", e);
              }
            } else {
              synchronized (monitorAgent) { // avoid concurrent calls to
                // monitorAgent, and also
                // wait for initialization
                // to finish
                monitorAgent.receiveMessage(m.source(), m.body());
              }
            }
            return null; // default ack
          }

          @Override
          public void ioError(PhysicalLocation addr, Exception e) {}
        };

    synchronized (monitorAgent) { // block tuple-processing and message
      // receipt activity until initialization
      // finishes
      this.senderReceiver = new MessagingClient(masterAddr, messageReceiptCallback);
      this.senderReceiver.connect();

      monitorAgent.initialize(communicator);

      // send registration message to master
      Tuple regResponse = senderReceiver.sendSync(createRegistrationMessage());

      // first part of registration response contains assigned physical
      // location id
      this.location = new PhysicalLocation(logicalLocation, (Integer) regResponse.get(0));

      // next part of registration response contains pending incoming
      // async messages
      for (Iterator<Tuple> it = ((DataBag) regResponse.get(1)).iterator(); it.hasNext(); ) {
        messageReceiptCallback.receive(Message.fromTuple(it.next()));
      }
    }
  }