/**
   * @param inTag
   * @param inVariable
   * @param inData
   * @return
   */
  public static Message createRequestMessage(
      int inTag,
      long inType,
      String inService,
      String inVariable,
      IPersistentMap<String, DataType<?>> inData) {

    RequestMessage.Builder builder = RequestMessage.newBuilder();
    builder.setTag(inTag);
    builder.setService(inService);

    if (inVariable != null) builder.setVariable(inVariable);

    if (inData != null) {
      DataMap.Builder dataMapBuilder = DataMap.newBuilder();
      parseMapValues(inData, dataMapBuilder);

      builder.setData(dataMapBuilder.build());
      builder.setType(inType);
    }

    Message.Builder messBuilder = Message.newBuilder();
    messBuilder.setType(Message.Type.RequestMessage);
    messBuilder.setRequestMessage(builder.build());

    return messBuilder.build();
  }
  /**
   * @param inTag
   * @param inRef
   * @param inStatus
   * @param inEntry
   * @return
   */
  public static Message createSubResponse(
      Long inTag, int inRef, Status inStatus, ISTMEntryKey inKey, ISTMEntry inEntry) {

    SubQueryResponseMessage.Builder builder = SubQueryResponseMessage.newBuilder();
    builder.setReference(inRef);
    builder.setTag(inTag.intValue());
    builder.setStatus(inStatus.ordinal());

    if (inEntry != null) {
      DataMap.Builder dataBuilder = DataMap.newBuilder();
      parseMapValues(inEntry.getDataMap(), dataBuilder);
      builder.setData(dataBuilder.build());
    }

    if (inKey != null) {
      DataKey dKey = createDataKey(inKey);

      builder.setKey(dKey);
    }

    Message.Builder messBuilder = Message.newBuilder();
    messBuilder.setSubQueryResponseMessage(builder.build());
    messBuilder.setType(Message.Type.SubQueryResponseMessage);

    return messBuilder.build();
  }
  /**
   * @param inRef
   * @param inDataMap
   * @return
   */
  public static Message createUpdateMessage(
      int inRef, ISTMEntry inEntry, boolean inFullUpdate, ISTMEntryKey inKey) {
    IPersistentMap<String, DataType<?>> dataMap = inEntry.getDataMap();

    UpdateMessage.Builder builder = UpdateMessage.newBuilder();
    builder.setReference(inRef);
    builder.setFullupdate(inFullUpdate);

    DataMap.Builder dataMapBuilder = DataMap.newBuilder();

    if (inFullUpdate) {
      parseMapValues(dataMap, dataMapBuilder);
    } else {
      parseDeltaMapValues(dataMap, inEntry.getDeltaSet(), dataMapBuilder);
    }

    builder.setData(dataMapBuilder.build());

    if (inKey != null) {
      DataKey dKey = createDataKey(inKey);
    }

    Message.Builder messBuilder = Message.newBuilder();
    try {
      messBuilder.setUpdateMessage(builder.build());
    } catch (Throwable t) {
      t.printStackTrace();
    }
    messBuilder.setType(Message.Type.UpdateMessage);

    return messBuilder.build();
  }
  /**
   * @param inReference
   * @return
   */
  public static Message createSubscriptionMessage(int inReference) {
    SubscribeMessage.Builder subMessB = SubscribeMessage.newBuilder();
    subMessB.setReference(inReference);

    Message.Builder messB = Message.newBuilder();
    messB.setSubscribeMessage(subMessB);
    messB.setType(Message.Type.SubscribeMessage);

    return messB.build();
  }
  /**
   * @param inTag
   * @param inRef
   * @return
   */
  public static Message createSubResponse(Long inTag, int inRef, Status inStatus) {
    SubQueryResponseMessage.Builder builder = SubQueryResponseMessage.newBuilder();
    builder.setReference(inRef);
    builder.setTag(inTag.intValue());
    builder.setStatus(inStatus.ordinal());

    Message.Builder messBuilder = Message.newBuilder();
    messBuilder.setSubQueryResponseMessage(builder.build());
    messBuilder.setType(Message.Type.SubQueryResponseMessage);

    return messBuilder.build();
  }
  public static Message createSubscriptionMessage(int inReference, ISTMEntryKey inKey) {
    SubscribeMessage.Builder subMessB = SubscribeMessage.newBuilder();

    DataKey key = createDataKey(inKey);
    subMessB.setKey(key);
    subMessB.setReference(inReference);

    Message.Builder messB = Message.newBuilder();
    messB.setSubscribeMessage(subMessB);
    messB.setType(Message.Type.SubscribeMessage);

    return messB.build();
  }
  /**
   * @param inService
   * @param inQuery
   * @return
   */
  public static Message createSubQuery(String inService, int inTag, Map<String, String> inQuery) {
    SubQueryMessage.Builder builder = SubQueryMessage.newBuilder();
    builder.setService(inService);
    builder.setTag(inTag);

    StringMap.Builder dataBuilder = StringMap.newBuilder();

    for (Map.Entry<String, String> keyVal : inQuery.entrySet()) {
      addStringValue(dataBuilder, keyVal.getKey(), keyVal.getValue());
    }

    builder.setQueryMap(dataBuilder.build());

    Message.Builder messBuilder = Message.newBuilder();
    messBuilder.setSubQueryMessage(builder.build());
    messBuilder.setType(Message.Type.SubQueryMessage);

    return messBuilder.build();
  }