/**
   * Returns the result of replacing each column reference c in the inverse expression with : - the
   * quoted and escaped data value of column c in r, if c is a referenced column in the term map -
   * the column name of column c, otherwise
   *
   * @param stringTemplate
   * @param dbValues
   * @param columnReferences
   * @param dbTypes
   * @return
   * @throws R2RMLDataError
   * @throws SQLException
   * @throws UnsupportedEncodingException
   * @throws MalformedURLException
   */
  public static String extractColumnValueFromInverseExpression(
      String inverseExpression,
      Map<ColumnIdentifier, byte[]> dbValues,
      Set<ColumnIdentifier> columnReferences)
      throws R2RMLDataError, SQLException, UnsupportedEncodingException {
    // Let result be the template string
    String result = inverseExpression;
    if (dbValues == null) return null;

    for (ColumnIdentifier column : dbValues.keySet()) {
      // A quoted and escaped data value is any SQL
      // string that matches the <literal> or <null specification>
      // productions of [SQL2].
      // This string can be used in a SQL query to specify a SQL data
      // value.
      String value = null;
      if (dbValues.get(column) == null) value = "NULL";
      else {
        // Extract db value
        byte[] byteValue = dbValues.get(column);
        // Apply cast to string to the SQL data value
        value = new String(byteValue, "UTF-8");
      }
      result = column.replaceAll(result, "'" + value + "'");
      // Test backslashes result =
      /*
       * result.replaceAll("\\{\\\"" + column + "\\\"\\}", "'" + result +
       * "'"); result = result.replaceAll("\\{\\'" + column + "\\'\\}",
       * "'" + result + "'"); result = result.replaceAll("\\{\\`" + column
       * + "\\`\\}", "'" + result + "'");
       */
    }
    // Replace curly braces of not referenced column references
    for (ColumnIdentifier column : columnReferences) {
      if (!dbValues.keySet().contains(column)) {
        result = column.replaceAll(result, column.toString());
        //				result = result.replaceAll("\\{\\'" + columnStr + "\\'\\}", columnStr);
        //				result = result.replaceAll("\\{\\`" + columnStr + "\\`\\}", columnStr);
      }
    }
    // Curly braces that do not enclose column names MUST be
    // escaped by a backslash character (“\”).
    result = result.replaceAll("\\\\\\{", "{");
    result = result.replaceAll("\\\\\\}", "}");
    return result;
  }