/**
   * Used to transform the GPstatus into HMessage <br>
   *
   * @param gpActivity
   * @return HMessage
   */
  public HMessage tranformeGPActivityToHMessage(GPActivity gpActivity) {
    HMessage msg = new HMessage();
    msg.setType("GPActivity");
    msg.setPayload(gpActivity);

    return msg;
  }
  /**
   * Used to build an HMessage, with payload conatain JSONObject received from instagram
   *
   * @param instagramResult JSONObject received from Instagram
   * @return HMessage
   */
  public HMessage transformInstagramToHMessage(JSONObject instagramResult) {

    HMessage message = new HMessage();
    message.setAuthor(this.actor);
    message.setType("HInstagramRT");
    message.setPublished(new DateTime());
    message.setPayload(instagramResult);
    return message;
  }
  public HMessage transformItem(JSONObject item) throws JSONException {
    HMessage msg = new HMessage();
    msg.setType("GPActivity");

    GPItem gpItem = new GPItem();

    if (!item.isNull("published")) {
      gpItem.setPublished(item.getString("published"));
    }

    if (!item.isNull("title")) {
      gpItem.setTitle(item.getString("title"));
    }

    if (!item.isNull("updated")) {
      gpItem.setUpdated(item.getString("updated"));
    }
    if (!item.isNull("id")) {
      gpItem.setId(item.getString("id"));
    }
    if (!item.isNull("url")) {
      gpItem.setUrl(item.getString("url"));
    }

    if (!item.isNull("actor")) {

      if (!item.getJSONObject("actor").isNull("id")) {
        gpItem.setActorId(item.getJSONObject("actor").getString("id"));
      }
      if (!item.getJSONObject("actor").isNull("displayName")) {
        gpItem.setDisplayName(item.getJSONObject("actor").getString("displayName"));
      }
      if (!item.getJSONObject("actor").isNull("image")) {
        gpItem.setImage(item.getJSONObject("actor").getString("image"));
      }
      if (!item.getJSONObject("actor").isNull("url")) {
        gpItem.setActorUrl(item.getJSONObject("actor").getString("url"));
      }
    }

    if (!item.isNull("object")) {
      if (!item.getJSONObject("object").isNull("attachments")) {
        gpItem.setAttachments(item.getJSONObject("object").getJSONArray("attachments"));
      }
    }

    msg.setPayload(gpItem);
    return (msg);
  }
  public void dispatcher(HMessage msg, HMessageDelegate callback) {
    if (msg != null) {
      HubotMessageStructure hubotStruct = new HubotMessageStructure(msg, callback);
      String msgActor = msg.getActor();

      if (!adapterOutboxActors.contains(msgActor)) {
        // if the actor's domain is twitter.com
        // we have to use a twitter outbox adapter
        // search the first outbox adapter where the domain is "twitter.com"
        // and send the hMessage to this adapter
        if (msgActor.endsWith("@twitter.com")) {
          msgActor = getFirstTwitterOutboxAdapter();
          if (msgActor != null) {
            put(msgActor, hubotStruct);
            return;
          }
        }
        // in other cases we try to send the hMessage through the hubiquitus
        // legacy adapter
        put(HUBOT_ADAPTER_OUTBOX, hubotStruct);
      } else {
        put(msgActor, hubotStruct);
      }
    }
  }
  @Override
  public void process(Exchange exchange) throws Exception {
    Message in = exchange.getIn();
    HttpServletRequest request = in.getBody(HttpServletRequest.class);
    // Get Exchange body
    byte[] rawBody = in.getBody(byte[].class);

    if (request.getParameter("hub.verify_token") != null) {
      if (this.verifyToken.equalsIgnoreCase(request.getParameter("hub.verify_token"))) {
        if (request.getParameter("hub.challenge") != null) {
          Object body = request.getParameter("hub.challenge");
          exchange.getOut().setBody(body);
          log.trace(" Challenge is posted,  his value  :" + request.getParameter("hub.challenge"));
        }
      }
    }
    if (in.getBody() != null) {
      String instagramBody = new String(rawBody);
      log.debug("Received body value is  :  " + instagramBody);

      if (instagramBody.startsWith("{")) {
        log.info("Instagram response  :" + new JSONObject(instagramBody));

      } else if (instagramBody.startsWith("[{")) {
        // Get the first pagination order by the recent element
        JSONArray instagramJSArray = new JSONArray(instagramBody);
        long subscriptionID = instagramJSArray.getJSONObject(0).getLong("subscription_id");
        String tag = instagramJSArray.getJSONObject(0).getString("object_id");

        JSONArray data = getInstagramTag(tag);
        if (data != null) {
          JSONArray pileTags = empileTag(data);

          if (pileTags != null) {
            for (int i = (pileTags.length() - 1); i >= 0; i--) {
              HMessage msg = new HMessage();
              msg = transformInstagramToHMessage(pileTags.getJSONObject(i));
              JSONObject header = new JSONObject();
              header.put("subscription_id", subscriptionID);
              msg.setHeaders(header);
              put(msg);
            }
          }
        }
      }
    }
  }
  @Override
  public void inProcessMessage(HMessage incomingMessage) {
    logger.info("received message from " + incomingMessage.getAuthor() + " : ");
    logger.info("---------------------------------------------------------");
    logger.info(incomingMessage.toString());
    logger.info("---------------------------------------------------------\n");

    if (incomingMessage != null && incomingMessage.getType().equals("hHttpData")) {
      HHttpData httpData = null;
      try {
        httpData = new HHttpData(incomingMessage.getPayloadAsJSONObject());
      } catch (Exception e) {
        logger.info("message: ", e);
      }
      logger.info("the httpdata : ");
      logger.info("---------------------------------------------------------");
      logger.info(httpData.toString());
      logger.info("---------------------------------------------------------");

      /** ***test out box**** */
      // try to use out box to send the message to http://localhost:8082
      try {
        incomingMessage.setActor("*****@*****.**");
        if (httpData.getServerPort() != 8082) {
          httpData.setServerPort(8082);

          incomingMessage.setPayload(httpData);
          logger.info(
              "send message to http://"
                  + httpData.getServerName()
                  + ":"
                  + httpData.getServerPort()
                  + httpData.getQueryPath());
          send(incomingMessage);
        }
      } catch (MissingAttrException e) {
        logger.info("", e);
      }
      /** *********************** */
    }
  }