/**
   * 入力されたメッセージを元に、宛先とコマンドを変更したものを返す
   *
   * @deprecated 0.7.4 親子関係を組み込むと、callの部分がmanualに成る為、使用不可とする。
   * @param receiverName
   * @param command
   * @param eventString
   * @return
   */
  public String copyOut(
      int messageCategoly, String newReceiverName, String newCommand, String eventString) {
    // 内容チェックを行い、receiverとcommandを書き換える
    debug.assertTrue(newReceiverName != null, "newReceiverName = null");
    debug.assertTrue(newCommand != null, "newCommand = null");
    debug.assertTrue(eventString != null, "eventString = null");

    JSONObject eventObj = JSONParser.parseStrict(eventString).isObject();
    debug.assertTrue(
        eventObj.containsKey(KEY_MESSAGE_CATEGOLY), "not contain KEY_MESSAGE_CATEGOLY");
    debug.assertTrue(eventObj.containsKey(KEY_MESSENGER_NAME), "not contain KEY_MESSENGER_NAME");
    debug.assertTrue(eventObj.containsKey(KEY_MESSENGER_ID), "not contain KEY_MESSENGER_ID");
    debug.assertTrue(eventObj.containsKey(KEY_MESSENGER_EXEC), "not contain KEY_MESSENGER_EXEC");
    debug.assertTrue(eventObj.containsKey(KEY_TO_NAME), "not contain KEY_TO_NAME");
    debug.assertTrue(eventObj.containsKey(KEY_TO_ID), "not contain KEY_TO_ID");
    debug.assertTrue(
        eventObj.containsKey(KEY_MESSENGER_TAGVALUE_GROUP),
        "not contain KEY_MESSENGER_TAGVALUE_GROUP");

    // categolyの書き換えを行う

    return replaceSenderInformation(
            messageCategoly, getName(), getID(), newReceiverName, newCommand, eventObj)
        .toString();
  }
  /**
   * 親子関係の構築を行う
   *
   * @param input
   */
  public void inputParent(String inputName) {
    debug.assertTrue(parentName.equals(""), "already have parentName	すでに先約があるようです");
    debug.assertTrue(parentID.equals(""), "already have parentID	すでに先約があるようです");

    debug.assertTrue(!inputName.equals(""), "空文字は親の名称として指定できません");

    parentName = inputName;

    String messageID = UUID.uuid(8, 16);
    JSONObject messageMap =
        getMessageStructure(
            MS_CATEGOLY_PARENTSEARCH, messageID, getName(), getID(), inputName, "", "");
    sendAsyncMessage(messageMap);
  }
  /**
   * コンストラクタ メッセージの受信ハンドラを設定する
   *
   * @param string
   */
  public MessengerGWTImplement(String messengerName, Object invokeObject) {
    debug = new Debug(this);

    this.messengerName = messengerName;
    this.messengerID = UUID.uuid(8, 16);
    this.invokeObject = invokeObject;

    parentName = "";
    parentID = "";

    sendList = new ArrayList<JSONObject>();
    receiveList = new ArrayList<JSONObject>();

    childList = new ArrayList<JSONObject>();

    postMessageAPIMethod = get(this);

    if (MessageMasterHub.getMaster().getMessengerGlobalStatus()
        == MESSENGER_STATUS_READY_FOR_INITIALIZE) {
      int status = setUp(postMessageAPIMethod); // Java-method to JavaScriptObject(as function)

      debug.assertTrue(
          MessageMasterHub.getMaster().getMessengerGlobalStatus()
              == MESSENGER_STATUS_READY_FOR_INITIALIZE,
          "already initialized");
      MessageMasterHub.getMaster().setMessengerGlobalStatus(status);
    }

    MessageMasterHub.getMaster().setInvokeObject(this);
  }
  /**
   * EventBus実装での同期メッセージング 同期メッセージを親へと送信するメソッド 親へのメッセージング
   *
   * @param command
   * @param tagValue
   */
  public void sCallParent(String command, JSONObject... tagValue) {
    debug.assertTrue(parentName != "", "SYNC	parentName not applied yet");
    debug.assertTrue(parentID != "", "SYNC	parentID not applied yet");

    JSONObject messageMap =
        getMessageStructure(
            MS_CATEGOLY_CALLPARENT,
            UUID.uuid(8, 16),
            getName(),
            getID(),
            getParentName(),
            getParentID(),
            command,
            tagValue);
    MessageMasterHub.getMaster().syncMessage(messageMap.toString());
    addSendLog(messageMap);
  }
  /**
   * 非同期メッセージを親へと送信するメソッド 親へのメッセージング
   *
   * @param command
   * @param tagValue
   */
  public String callParent(String command, JSONObject... tagValue) {
    debug.assertTrue(parentName != "", "ASYNC parentName not applied yet");
    debug.assertTrue(parentID != "", "ASYNC	parentID not applied yet");

    String messageID = UUID.uuid(8, 16);
    JSONObject messageMap =
        getMessageStructure(
            MS_CATEGOLY_CALLPARENT,
            messageID,
            getName(),
            getID(),
            getParentName(),
            getParentID(),
            command,
            tagValue);
    debug.trace("true	messageMap	" + messageMap.toString());
    sendAsyncMessage(messageMap);
    return messageID;
  }
  /** 同期メッセージング(試作) */
  private void sendSyncMessage(JSONObject message) {
    debug.timeAssert("11/07/23 8:40:07", 0, "yieldが正式に全ブラウザに実装されるまでは使えない。");

    String href = Window.Location.getHref();
    postMessage(message.toString(), href);

    // この辺にyieldでメッセージ受信の受付を行えば良い

    addSendLog(message);
  }
 /**
  * 受け取りログを差し出す
  *
  * @param i
  * @return
  */
 public String getReceiveLog(int i) {
   debug.assertTrue(receiveList != null, "receiveList not yet initialize");
   return receiveList.get(i).toString();
 }
 /**
  * 送信ログを差し出す
  *
  * @return
  */
 public String getSendLog(int i) {
   debug.assertTrue(sendList != null, "sendList == null");
   debug.assertTrue(i < sendList.size(), "oversize of sendList");
   return sendList.get(i).toString();
 }
  /**
   * 送信メッセージ構造を構築する
   *
   * <p>KEY_MESSENGER_NAME:送信者名 KEY_MESSENGER_ID:送信者ID KEY_TO_NAME:送信先 KEY_MESSENGER_EXEC:実行コマンド
   * KEY_MESSENGER_TAGVALUE_GROUP:タグとバリューのグループ
   *
   * @param receiverName
   * @param command
   * @param tagValue
   * @return
   */
  public JSONObject getMessageStructure(
      int messageCategoly,
      String messageID,
      String senderName,
      String senderID,
      String receiverName,
      String receiverID,
      String command,
      JSONObject... tagValue) { // JSONObject[] tagValue
    JSONObject messageMap = new JSONObject();

    messageMap.put(KEY_MESSENGER_NAME, new JSONString(senderName));
    messageMap.put(KEY_MESSENGER_ID, new JSONString(senderID));
    messageMap.put(KEY_MESSAGE_ID, new JSONString(messageID));
    messageMap.put(KEY_MESSAGE_CATEGOLY, new JSONNumber(messageCategoly));

    switch (messageCategoly) {
      case MS_CATEGOLY_LOCAL:
        messageMap.put(KEY_TO_NAME, new JSONString(receiverName));
        messageMap.put(KEY_MESSENGER_EXEC, new JSONString(command));
        messageMap.put(KEY_TO_ID, new JSONString(senderID));

        break;

      case MS_CATEGOLY_CALLCHILD:
        messageMap.put(KEY_TO_NAME, new JSONString(receiverName));
        messageMap.put(KEY_TO_ID, new JSONString(receiverID));

        messageMap.put(KEY_MESSENGER_EXEC, new JSONString(command));
        break;

      case MS_CATEGOLY_CALLPARENT:
        messageMap.put(KEY_TO_NAME, new JSONString(receiverName));
        messageMap.put(KEY_TO_ID, new JSONString(receiverID));

        messageMap.put(KEY_MESSENGER_EXEC, new JSONString(command));

        break;

      case MS_CATEGOLY_PARENTSEARCH:
      case MS_CATEGOLY_PARENTSEARCH_S:
        messageMap.put(KEY_TO_NAME, new JSONString(receiverName));
        messageMap.put(KEY_TO_ID, new JSONString(receiverID));

        messageMap.put(KEY_MESSENGER_EXEC, new JSONString(command));

        messageMap.put(KEY_PARENT_NAME, new JSONString(receiverName));
        break;

      case MS_CATEGOLY_PARENTSEARCH_RET:
        messageMap.put(KEY_PARENT_NAME, new JSONString(getName()));
        messageMap.put(KEY_PARENT_ID, new JSONString(getID()));

        messageMap.put(KEY_TO_NAME, new JSONString(receiverName));
        messageMap.put(KEY_TO_ID, new JSONString(receiverID));

        messageMap.put(KEY_MESSENGER_EXEC, new JSONString(command));
        break;

      case MS_CATEGOLY_REMOVE_CHILD:
      case MS_CATEGOLY_REMOVE_PARENT:
      default:
        debug.assertTrue(false, "not ready yet");
        break;
    }

    JSONObject tagValueGroup = new JSONObject();

    for (JSONObject currentObject : tagValue) {
      for (Iterator<String> currentItel = currentObject.keySet().iterator();
          currentItel.hasNext(); ) {
        String currentKey = currentItel.next();
        tagValueGroup.put(currentKey, currentObject.get(currentKey)); // オブジェクトの移し替え
      }
    }

    messageMap.put(KEY_MESSENGER_TAGVALUE_GROUP, tagValueGroup);
    //		debug.trace("messageMap_"+messageMap);//しばらくin-outのテスト用にとっておこう。
    return messageMap;
  }
  /**
   * PostMessageAPI からダイレクトで複数のmessengerが各個に呼ばれる事を想定したメソッド
   *
   * @param rootMessage
   */
  public void onMessagereceivedFromPostMessageAPI(String rootMessage) {
    JSONObject rootObject = null;
    //		Window.alert("受け取った	"+getName());
    try {
      rootObject = JSONParser.parseStrict(rootMessage).isObject();
    } catch (Exception e) {
      debug.trace("receiveMessage_parseError_" + e);
      return;
    }

    if (rootObject == null) {
      debug.trace("rootObject = null");
      return;
    }

    String toName = null;
    {
      /*
       * 宛先チェック
       */
      debug.assertTrue(rootObject.get(KEY_TO_NAME).isString() != null, "invalid KEY_TO_NAME");
      toName = rootObject.get(KEY_TO_NAME).isString().stringValue();

      if (!toName.equals(getName())) { // 送信者の指定した宛先が自分か
        //			NSLog(@"MS_CATEGOLY_CALLPARENT_宛先ではないMessnegerが受け取った");
        return;
      }
    }

    String fromName = null;
    String fromID = null;
    {
      /*
       * 送付元名前チェック
       */
      fromName = rootObject.get(KEY_MESSENGER_NAME).isString().stringValue();
      debug.assertTrue(fromName != null, "invalid KEY_MESSENGER_NAME");

      /*
       * 送付元IDチェック
       */

      fromID = rootObject.get(KEY_MESSENGER_ID).isString().stringValue();
      debug.assertTrue(fromID != null, "invalid KEY_MESSENGER_ID");
    }

    int categoly;
    {
      debug.assertTrue(
          rootObject.get(KEY_MESSAGE_CATEGOLY).isNumber() != null, "no KEY_MESSAGE_CATEGOLY");
      categoly = (int) rootObject.get(KEY_MESSAGE_CATEGOLY).isNumber().doubleValue();
    }

    /*
     * コマンドチェック
     */
    {
      debug.assertTrue(
          rootObject.get(KEY_MESSENGER_EXEC).isString() != null, "KEY_MESSENGER_EXEC = null");
    }

    /*
     * tag-valueチェック
     */
    {
      debug.assertTrue(
          rootObject.get(KEY_MESSENGER_TAGVALUE_GROUP).isObject() != null,
          "KEY_MESSENGER_TAGVALUE_GROUP = null");
    }

    /*
     * 宛先存在チェック
     */
    String toID = null;
    {
      debug.assertTrue(rootObject.get(KEY_TO_ID).isString() != null, "no KEY_TO_ID");
      toID = rootObject.get(KEY_TO_ID).isString().stringValue();
    }
    //		Window.alert("カテゴリチェックまで	メッセージングを受け取りました");

    switch (categoly) {
      case MS_CATEGOLY_LOCAL:
        {
          if (toID.equals(getID())) {
            addReceiveLog(rootObject);
            receiveCenter(rootMessage);
          }
        }
        return;

      case MS_CATEGOLY_CALLCHILD:
        if (toID.equals(getID())) {
          addReceiveLog(rootObject);
          receiveCenter(rootMessage);
        }
        return;

      case MS_CATEGOLY_CALLPARENT:
        // 宛先MIDが自分のIDと一致するか
        if (toID.equals(getID())) {
          //				Window.alert("親として呼ばれた	メッセージングを受け取りました	");
          addReceiveLog(rootObject);
          receiveCenter(rootMessage);
          //				Window.alert("親として呼ばれた2	メッセージングを受け取りました");
        }

        return;

      case MS_CATEGOLY_PARENTSEARCH:
        debug.assertTrue(rootObject.get(KEY_PARENT_NAME).isString() != null, "no KEY_PARENT_NAME");
        String childSearchingName = rootObject.get(KEY_PARENT_NAME).isString().stringValue();
        if (childSearchingName.equals(getName())) {

          JSONObject childInfo = new JSONObject();
          childInfo.put(CHILDLIST_KEY_CHILD_ID, new JSONString(fromID));
          childInfo.put(CHILDLIST_KEY_CHILD_NAME, new JSONString(fromName));

          childList.add(childInfo);
          //				Window.alert("子供っす	"+childList+"	で、名前が	"+childInfo);
          JSONObject messageMap =
              getMessageStructure(
                  MS_CATEGOLY_PARENTSEARCH_RET,
                  UUID.uuid(8, 16),
                  getName(),
                  getID(),
                  fromName,
                  fromID,
                  TRIGGER_PARENTCONNECTED);
          sendAsyncMessage(messageMap);
          addReceiveLog(rootObject);
        }

        return;

      case MS_CATEGOLY_PARENTSEARCH_S:
        debug.assertTrue(rootObject.get(KEY_PARENT_NAME).isString() != null, "no KEY_PARENT_NAME");
        String childSearchingName2 = rootObject.get(KEY_PARENT_NAME).isString().stringValue();
        if (childSearchingName2.equals(getName())) {
          addReceiveLog(rootObject);
          JSONObject childInfo = new JSONObject();
          childInfo.put(CHILDLIST_KEY_CHILD_ID, new JSONString(fromID));
          childInfo.put(CHILDLIST_KEY_CHILD_NAME, new JSONString(fromName));

          childList.add(childInfo);

          JSONObject messageMap =
              getMessageStructure(
                  MS_CATEGOLY_PARENTSEARCH_RET,
                  UUID.uuid(8, 16),
                  getName(),
                  getID(),
                  fromName,
                  fromID,
                  TRIGGER_PARENTCONNECTED);
          MessageMasterHub.getMaster().syncMessage(messageMap.toString());
          addSendLog(messageMap);
        }
        break;

      case MS_CATEGOLY_PARENTSEARCH_RET:
        if (!parentName.equals(fromName)) {
          return;
        }

        if (toID.equals(getID())) {
          if (parentID.equals("")) {
            parentID = fromID;
            addReceiveLog(rootObject);
          } else {
            //					debug.trace("もう別の親が居ます"+ "/fromID	"+fromID);
          }
        }

        return;

      case MS_CATEGOLY_REMOVE_CHILD:
      case MS_CATEGOLY_REMOVE_PARENT:
      default:
        debug.assertTrue(false, "not ready yet or UNKNOWN CATEGOLY");
        return;
    }
  }
 /** 現在のEventBusからこのMessengerのレジスタだけを削除する */
 public void removeFromCurrentMessageAspect() {
   //		debug.timeAssert("11/09/29 17:17:21", 3600, "未完成の切断");//24F8A5DC-A35B-4981-A206-B5AB86690992
   tearDown(postMessageAPIMethod);
   debug.trace("this	" + this + "/postMessageAPIMethod	tearDown	" + postMessageAPIMethod);
 }
 /**
  * 入力されている親のIDを取得する
  *
  * @return
  */
 public String getParentID() {
   debug.assertTrue(!parentName.equals(""), "まだ親のIDのinputが行われていません");
   return parentID;
 }
  /**
   * バリューをタグから取得する 存在しない場合アサーションエラー
   *
   * @param message
   * @param tag
   * @return
   */
  public JSONValue getValueForTag(String tag, String message) {
    JSONObject obj = getJSONObjetFromMessage(message);
    debug.assertTrue(obj.containsKey(tag), "no-	" + tag + "	-contains");

    return obj.get(tag);
  }