/**
   * Replaces the payload format with property values from messageContext.
   *
   * @param format
   * @param resultCTX
   * @param synCtx
   */
  private void replaceCTX(String format, StringBuffer resultCTX, MessageContext synCtx) {
    Matcher ctxMatcher;

    if (mediaType != null && (mediaType.equals(JSON_TYPE) || mediaType.equals(TEXT_TYPE))) {
      ctxMatcher = ctxPattern.matcher(format);
    } else {
      ctxMatcher = ctxPattern.matcher("<pfPadding>" + format + "</pfPadding>");
    }
    while (ctxMatcher.find()) {
      String ctxMatchSeq = ctxMatcher.group();
      String expressionTxt = ctxMatchSeq.substring(5, ctxMatchSeq.length());

      String replaceValue = synCtx.getProperty(expressionTxt).toString();

      if (mediaType.equals(JSON_TYPE) && inferReplacementType(replaceValue).equals(XML_TYPE)) {
        // XML to JSON conversion here
        try {
          replaceValue = "<jsonObject>" + replaceValue + "</jsonObject>";
          OMElement omXML = AXIOMUtil.stringToOM(replaceValue);
          replaceValue = JsonUtil.toJsonString(omXML).toString();
        } catch (XMLStreamException e) {
          handleException(
              "Error parsing XML for JSON conversion, please check your property values return valid XML: ",
              synCtx);
        } catch (AxisFault e) {
          handleException("Error converting XML to JSON", synCtx);
        }
      } else if (mediaType.equals(XML_TYPE)
          && inferReplacementType(replaceValue).equals(JSON_TYPE)) {
        // JSON to XML conversion here
        try {
          OMElement omXML = JsonUtil.toXml(IOUtils.toInputStream(replaceValue), false);
          if (JsonUtil.isAJsonPayloadElement(omXML)) { // remove <jsonObject/> from result.
            Iterator children = omXML.getChildElements();
            String childrenStr = "";
            while (children.hasNext()) {
              childrenStr += (children.next()).toString().trim();
            }
            replaceValue = childrenStr;
          } else {
            replaceValue = omXML.toString();
          }
        } catch (AxisFault e) {
          handleException(
              "Error converting JSON to XML, please check your property values return valid JSON: ",
              synCtx);
        }
      }
      ctxMatcher.appendReplacement(resultCTX, replaceValue);
    }
    ctxMatcher.appendTail(resultCTX);
  }
  /**
   * Replaces the payload format with SynapsePath arguments which are evaluated using
   * getArgValues().
   *
   * @param format
   * @param result
   * @param synCtx
   */
  private void replace(String format, StringBuffer result, MessageContext synCtx) {
    HashMap<String, String>[] argValues = getArgValues(synCtx);
    HashMap<String, String> replacement;
    Map.Entry<String, String> replacementEntry;
    String replacementValue = null;
    Matcher matcher;

    matcher = pattern.matcher(format);
    try {
      while (matcher.find()) {
        String matchSeq = matcher.group();
        int argIndex;
        try {
          argIndex = Integer.parseInt(matchSeq.substring(1, matchSeq.length()));
        } catch (NumberFormatException e) {
          argIndex = Integer.parseInt(matchSeq.substring(2, matchSeq.length() - 1));
        }
        replacement = argValues[argIndex - 1];
        replacementEntry = replacement.entrySet().iterator().next();
        if (mediaType.equals(JSON_TYPE)
            && inferReplacementType(replacementEntry).equals(XML_TYPE)) {
          // XML to JSON conversion here
          try {
            replacementValue = "<jsonObject>" + replacementEntry.getKey() + "</jsonObject>";
            OMElement omXML = AXIOMUtil.stringToOM(replacementValue);
            replacementValue =
                JsonUtil.toJsonString(omXML)
                    .toString()
                    .replaceAll(
                        ESCAPE_DOUBLE_QUOTE_WITH_FIVE_BACK_SLASHES,
                        ESCAPE_DOUBLE_QUOTE_WITH_NINE_BACK_SLASHES)
                    .replaceAll(
                        ESCAPE_DOLLAR_WITH_TEN_BACK_SLASHES, ESCAPE_DOLLAR_WITH_SIX_BACK_SLASHES);
            replacementValue = JsonUtil.toJsonString(omXML).toString();
          } catch (XMLStreamException e) {
            handleException(
                "Error parsing XML for JSON conversion, please check your xPath expressions return valid XML: ",
                synCtx);
          } catch (AxisFault e) {
            handleException("Error converting XML to JSON", synCtx);
          }
        } else if (mediaType.equals(XML_TYPE)
            && inferReplacementType(replacementEntry).equals(JSON_TYPE)) {
          // JSON to XML conversion here
          try {
            OMElement omXML =
                JsonUtil.toXml(IOUtils.toInputStream(replacementEntry.getKey()), false);
            if (JsonUtil.isAJsonPayloadElement(omXML)) { // remove <jsonObject/> from result.
              Iterator children = omXML.getChildElements();
              String childrenStr = "";
              while (children.hasNext()) {
                childrenStr += (children.next()).toString().trim();
              }
              replacementValue = childrenStr;
            } else { /// ~
              replacementValue = omXML.toString();
            }
            // replacementValue = omXML.toString();
          } catch (AxisFault e) {
            handleException(
                "Error converting JSON to XML, please check your JSON Path expressions return valid JSON: ",
                synCtx);
          }
        } else {
          // No conversion required, as path evaluates to regular String.
          replacementValue = replacementEntry.getKey();
          // This is to replace " with \" and \\ with \\\\
          if (mediaType.equals(JSON_TYPE)
              && inferReplacementType(replacementEntry).equals(STRING_TYPE)
              && (!replacementValue.startsWith("{") && !replacementValue.startsWith("["))) {
            replacementValue =
                replacementValue
                    .replaceAll(
                        Matcher.quoteReplacement("\\\\"),
                        ESCAPE_BACK_SLASH_WITH_SIXTEEN_BACK_SLASHES)
                    .replaceAll("\"", ESCAPE_DOUBLE_QUOTE_WITH_TEN_BACK_SLASHES);
          } else if ((mediaType.equals(JSON_TYPE)
                  && inferReplacementType(replacementEntry).equals(JSON_TYPE))
              && (!replacementValue.startsWith("{") && !replacementValue.startsWith("["))) {
            // This is to handle only the string value
            replacementValue =
                replacementValue.replaceAll("\"", ESCAPE_DOUBLE_QUOTE_WITH_TEN_BACK_SLASHES);
          }
        }
        matcher.appendReplacement(result, replacementValue);
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      log.error("#replace. Mis-match detected between number of formatters and arguments", e);
    }
    matcher.appendTail(result);
  }