private void doSql(String contents) {
    if (getSql() == null) {
      LOG.info("send: optional sql argument is null.");
      return;
    }

    if (contents == null) {
      LOG.info("doSql: HTTP reply is null");
      return;
    }

    LOG.debug("send: compiling expression: {}", getSwitchValue("result-match"));
    Pattern p = Pattern.compile(getSwitchValue("result-match"));
    Matcher m = p.matcher(contents);
    if (m.matches()) {
      LOG.debug("send: compiled expression ready to run sql: {}", getSql());
      MatchTable matches = new MatchTable(m);
      String sqlString = PropertiesUtils.substitute(getSql(), matches);
      LOG.debug("send: running sql: {}", sqlString);
      JdbcTemplate template = new JdbcTemplate(DataSourceFactory.getInstance());
      template.execute(sqlString);
    } else {
      LOG.info("send: result didn't match, not running sql");
    }
  }
  /**
   * getResourceByIndex
   *
   * @param set a Set<OnmsAttribute> object.
   * @param index a {@link java.lang.String} object.
   * @return a {@link org.opennms.netmgt.model.OnmsResource} object.
   */
  public OnmsResource getResourceByIndex(final Set<OnmsAttribute> set, final String index) {

    String label;
    if (m_resourceLabelExpression == null) {
      label = index;
    } else {
      SymbolTable symbolTable =
          new SymbolTable() {
            private int lastN;
            private boolean lastNSet = false;

            @Override
            public String getSymbolValue(String symbol) {
              if (symbol.equals("index")) {
                return index;
              }

              Matcher subIndexMatcher = SUB_INDEX_PATTERN.matcher(symbol);
              if (subIndexMatcher.matches()) {
                Matcher subIndexArgumentsMatcher =
                    SUB_INDEX_ARGUMENTS_PATTERN.matcher(subIndexMatcher.group(1));
                if (!subIndexArgumentsMatcher.matches()) {
                  // Invalid arguments
                  return null;
                }

                List<String> indexElements = tokenizeIndex(index);

                int start;
                int offset;
                if ("n".equals(subIndexArgumentsMatcher.group(1)) && lastNSet) {
                  start = lastN;
                  lastNSet = false;
                } else if ("n".equals(subIndexArgumentsMatcher.group(1))) {
                  // Invalid use of "n" when lastN is not set
                  return null;
                } else {
                  offset = Integer.parseInt(subIndexArgumentsMatcher.group(1));
                  if (offset < 0) {
                    start = indexElements.size() + offset;
                  } else {
                    start = offset;
                  }
                }

                int end;
                if ("n".equals(subIndexArgumentsMatcher.group(2))) {
                  end = start + Integer.parseInt(indexElements.get(start)) + 1;
                  start++;
                  lastN = end;
                  lastNSet = true;
                } else {
                  if (subIndexArgumentsMatcher.group(2) == null) {
                    end = indexElements.size();
                  } else {
                    end = start + Integer.parseInt(subIndexArgumentsMatcher.group(2));
                  }
                }

                if (start < 0 || start >= indexElements.size()) {
                  // Bogus index start
                  return null;
                }

                if (end < 0 || end > indexElements.size()) {
                  // Bogus index end
                  return null;
                }

                StringBuffer indexSubString = new StringBuffer();
                for (int i = start; i < end; i++) {
                  if (indexSubString.length() != 0) {
                    indexSubString.append(".");
                  }

                  indexSubString.append(indexElements.get(i));
                }

                return indexSubString.toString();
              }

              Matcher hexMatcher = HEX_PATTERN.matcher(symbol);
              if (hexMatcher.matches()) {
                String subSymbol = getSymbolValue(hexMatcher.group(1));
                List<String> indexElements = tokenizeIndex(subSymbol);

                StringBuffer hexString = new StringBuffer();
                for (String indexElement : indexElements) {
                  if (hexString.length() > 0) {
                    hexString.append(":");
                  }
                  try {
                    hexString.append(String.format("%02X", Integer.parseInt(indexElement)));
                  } catch (NumberFormatException e) {
                    return null;
                  }
                }

                return hexString.toString();
              }

              Matcher stringMatcher = STRING_PATTERN.matcher(symbol);
              if (stringMatcher.matches()) {
                String subSymbol = getSymbolValue(stringMatcher.group(1));
                List<String> indexElements = tokenizeIndex(subSymbol);

                StringBuffer stringString = new StringBuffer();
                for (String indexElement : indexElements) {
                  stringString.append(String.format("%c", Integer.parseInt(indexElement)));
                }

                return stringString.toString();
              }

              for (OnmsAttribute attr : set) {
                if (symbol.equals(attr.getName())) {
                  if (StringPropertyAttribute.class.isAssignableFrom(attr.getClass())) {
                    StringPropertyAttribute stringAttr = (StringPropertyAttribute) attr;
                    return stringAttr.getValue();
                  }
                  if (ExternalValueAttribute.class.isAssignableFrom(attr.getClass())) {
                    ExternalValueAttribute extAttr = (ExternalValueAttribute) attr;
                    return extAttr.getValue();
                  }
                }
              }

              return null;
            }

            private List<String> tokenizeIndex(final String index) {
              List<String> indexElements = new ArrayList<String>();
              StringTokenizer t = new StringTokenizer(index, ".");
              while (t.hasMoreTokens()) {
                indexElements.add(t.nextToken());
              }
              return indexElements;
            }
          };

      label = PropertiesUtils.substitute(m_resourceLabelExpression, symbolTable);
    }

    return new OnmsResource(index, label, this, set);
  }
  private static String fetchSnmpAssetString(
      final SnmpAgentConfig agentConfig, final MibObjs mibObjs, final String formatString)
      throws MissingFormatArgumentException {

    final List<String> aliases = new ArrayList<String>();
    final List<SnmpObjId> objs = new ArrayList<SnmpObjId>();
    for (final MibObj mibobj : mibObjs.getMibObj()) {
      aliases.add(mibobj.getAlias());
      objs.add(SnmpObjId.get(mibobj.getOid()));
    }
    // Fetch the values from the SNMP agent
    final SnmpValue[] values = SnmpUtils.get(agentConfig, objs.toArray(new SnmpObjId[0]));
    if (values.length == aliases.size()) {
      final Properties substitutions = new Properties();
      boolean foundAValue = false;
      for (int i = 0; i < values.length; i++) {
        // If the value is a NO_SUCH_OBJECT or NO_SUCH_INSTANCE error, then skip it
        if (values[i] == null || values[i].isError()) {
          // No value for this OID
          continue;
        }
        foundAValue = true;
        // Use trapd's SyntaxToEvent parser so that we format base64
        // and MAC address values appropriately
        Parm parm = SyntaxToEvent.processSyntax(aliases.get(i), values[i]);
        substitutions.setProperty(aliases.get(i), parm.getValue().getContent());
      }

      if (!foundAValue) {
        if (log().isDebugEnabled()) {
          log()
              .debug(
                  "fetchSnmpAssetString: Failed to fetch any SNMP values for system "
                      + agentConfig.toString());
        }
        throw new MissingFormatArgumentException(
            "fetchSnmpAssetString: Failed to fetch any SNMP values for system "
                + agentConfig.toString());
      } else {
        log()
            .debug(
                "fetchSnmpAssetString: Fetched asset properties from SNMP agent:\n"
                    + formatPropertiesAsString(substitutions));
      }

      if (objs.size() != substitutions.size()) {
        log()
            .warn(
                "fetchSnmpAssetString: Unexpected number of properties returned from SNMP GET:\n"
                    + formatPropertiesAsString(substitutions));
      }

      return PropertiesUtils.substitute(formatString, substitutions);
    } else {
      log()
          .warn(
              "fetchSnmpAssetString: Invalid number of SNMP parameters returned: "
                  + values.length
                  + " != "
                  + aliases.size());
      throw new MissingFormatArgumentException(
          "fetchSnmpAssetString: Invalid number of SNMP parameters returned: "
              + values.length
              + " != "
              + aliases.size());
    }
  }