/** Inserts a tuple into the tuple space. */
  public boolean rout(Tuple t, int dest) {
    AgillaTSReqMsgJ request = new AgillaTSReqMsgJ(dest, TOS_UART_ADDRESS, BasicOpcodes.OProut, t);
    try {
      sni.send(request);
    } catch (IOException e) {
      e.printStackTrace();
      return false;
    }
    log("rout: Request sent, no reply expected.");

    /*log("rout: Request sent, awaiting reply.");
    synchronized(waiting) {
    	if (results == null){
    		timer = new TimeoutTimer(waiting, AGILLA_RTS_TIMEOUT);
    		try {
    			waiting.wait();
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    if (results != null)
    	log("rout: Reply received, success = " + results.isSuccess());
    else
    	log("rout: The operation timed out");
    if (results != null)
    	return results.isSuccess();
    else
    	return false;*/
    return true;
  }
  /**
   * Performs a remote tuple space operation.
   *
   * @param template
   * @param dest
   * @param type
   * @return The matching tuple or null if none was found.
   */
  private Tuple doMonoOp(Tuple template, int dest, int type) {
    AgillaTSReqMsgJ request;
    if (type == REMOVE)
      request = new AgillaTSReqMsgJ(dest, TOS_UART_ADDRESS, BasicOpcodes.OPrinp, template);
    else request = new AgillaTSReqMsgJ(dest, TOS_UART_ADDRESS, BasicOpcodes.OPrrdp, template);

    log("doMonoOp: request = " + request + ", dest = " + dest);

    response.clear();

    try {
      log("doMonoOp: Sent inp or rdp request.");
      // results = null;
      sni.send(request);
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }

    TimeoutTimer timer = new TimeoutTimer(response, AGILLA_RTS_TIMEOUT, timerid++);
    MessageJ rMsg = waitForResponse();

    if (rMsg instanceof TimeoutMsgJ && ((TimeoutMsgJ) rMsg).id() == timer.id()) {
      log("doMonoOp: Remote TS operation timed out.");
      return null;
    } else if (rMsg instanceof AgillaTSResMsgJ) {
      AgillaTSResMsgJ results = (AgillaTSResMsgJ) rMsg;
      log("doMonoOp: Got results, " + (results.isSuccess() ? "SUCCESS" : "FAIL"));
      if (results.isSuccess()) return results.getTuple();
      else return null;
    }
    return null;
  }
  private void processRequest(AgillaTSReqMsgJ reqMsg) {
    switch (reqMsg.getOp()) {
      case BasicOpcodes.OProut:
        Tuple t = reqMsg.getTemplate();
        log("processRequest(): OUTing tuple: " + t);
        out(t);

        /*try {
        	sni.send(new AgillaTSResMsgJ(reqMsg.getReply(), reqMsg.getOp(), SUCCESS, reqMsg.getTemplate()));
        } catch (IOException ioe) {
        	ioe.printStackTrace();
        }*/
        break;
      case BasicOpcodes.OPrrdp:
      case BasicOpcodes.OPrinp:
        Tuple template = reqMsg.getTemplate();
        Tuple result = null;
        if (reqMsg.getOp() == BasicOpcodes.OPrinp) result = inp(template);
        else result = rdp(template);
        AgillaTSResMsgJ resMsg = null;
        if (result == null)
          resMsg = new AgillaTSResMsgJ(reqMsg.getReply(), reqMsg.getOp(), FAIL, template);
        else resMsg = new AgillaTSResMsgJ(reqMsg.getReply(), reqMsg.getOp(), SUCCESS, result);
        log("processRequest(): Sending results: " + resMsg);

        //				*** Added this for benchmarking Agillimone agents *** //
        //				edu.wustl.mobilab.agillimone.microbenchmarks.TimeKeeper.start();
        try {
          // Do not send to the reply address because the mote may be multiple hops away
          // Instead, send it to the bcast address
          // sni.send(resMsg, reqMsg.getReply());  // send the results back
          sni.send(resMsg, TOS_BCAST_ADDRESS);
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
        //				*** Added this for benchmarking Agillimone agents *** //
        //				edu.wustl.mobilab.agillimone.microbenchmarks.TimeKeeper.end();
        break;
      default:
        log("processRequest(): Invalid Request " + reqMsg);
        resMsg = new AgillaTSResMsgJ(reqMsg.getReply(), reqMsg.getOp(), FAIL, null);
        try {
          sni.send(resMsg);
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
    }
  }