public void action() {
    this.prepateTemplate();

    if (template == null) msg = myAgent.receive();
    else msg = myAgent.receive(template);

    if (msg != null) {
      finished = true;
      handle(msg);
      return;
    }
    long dt = wakeupTime - System.currentTimeMillis();

    if (dt > 0) block(dt);
    else {
      finished = true;
      if (msg != null) handle(msg);
    }
  }
    public int onEnd() {
      int ret = super.onEnd();
      SSResponder parent = (SSResponder) getParent();

      // If a reply was sent back, adjust the template and deadline of the
      // RECEIVE_NEXT state
      ACLMessage reply = (ACLMessage) getDataStore().get(parent.REPLY_KEY);
      if (reply != null) {
        MsgReceiver mr = (MsgReceiver) parent.getState(RECEIVE_NEXT);
        mr.setTemplate(createNextMsgTemplate(reply));

        Date d = reply.getReplyByDate();
        if (d != null && d.getTime() > System.currentTimeMillis()) {
          mr.setDeadline(d.getTime());
        } else {
          mr.setDeadline(MsgReceiver.INFINITE);
        }
      }

      parent.afterReply(reply);
      return ret;
    }
 @Override
 public void onStart() {
   wakeupTime = (timeOut < 0 ? Long.MAX_VALUE : System.currentTimeMillis() + timeOut);
 }