docs: private String parseWithMetric(final String metric) {
      // TODO: Try to reduce code duplication with Tags.parseWithMetric().
      final int curly = metric.indexOf('{');
      if (curly < 0) {
        clearTags();
        return metric;
      }
      final int len = metric.length();
      if (metric.charAt(len - 1) != '}') {  // "foo{"
        clearTags();
        return null;  // Missing '}' at the end.
      } else if (curly == len - 2) {  // "foo{}"
        clearTags();
        return metric.substring(0, len - 2);
      }
      final int num_tags_before = getNumTags();
      
      final List<Filter> filters = new ArrayList<Filter>();
      final int close = metric.indexOf('}');
      int i = 0;
      if (close != metric.length() - 1) { // "foo{...}{tagk=filter}" 
        final int filter_bracket = metric.lastIndexOf('{');
        for (final String filter : metric.substring(filter_bracket + 1, 
            metric.length() - 1).split(",")) {
          if (filter.isEmpty()) {
            break;
          }
          final String[] kv = filter.split("=");
          if (kv.length != 2 || kv[0].isEmpty() || kv[1].isEmpty()) {
            continue;  // Invalid tag.
          }
          final Filter f = new Filter();
          f.tagk = kv[0];
          f.tagv = kv[1];
          f.is_groupby = false;
          filters.add(f);
          i++;  
        }
      }
      
      i = 0;
      for (final String tag : metric.substring(curly + 1, close).split(",")) {
        if (tag.isEmpty() && close != metric.length() - 1){
          break;
        }
        final String[] kv = tag.split("=");
        if (kv.length != 2 || kv[0].isEmpty() || kv[1].isEmpty()) {
          continue;  // Invalid tag.
        }
        final Filter f = new Filter();
        f.tagk = kv[0];
        f.tagv = kv[1];
        f.is_groupby = true;
        filters.add(f);
        i++;
      }
      if (!filters.isEmpty()) {
        Collections.sort(filters);
      }
      
      i = 0;
      for (int x = filters.size() - 1; x >= 0; x--) {
        final Filter filter = filters.get(x);
        if (i < num_tags_before) {
          setTag(i++, filter.tagk, filter.tagv, filter.is_groupby);
        } else {
          addTag(filter.tagk, filter.tagv, filter.is_groupby);
        }
      }
      
      if (i < num_tags_before) {
        setTag(i, "", "", true);
      } else {
        addTag();
      }
      // Remove extra tags.
      for (i++; i < num_tags_before; i++) {
        tagtable.removeRow(i + 1);
      }
      // Return the "foo" part of "foo{a=b,...,x=y}"
      return metric.substring(0, curly);
      
      /*
      // substring the tags out of "foo{a=b,...,x=y}" and parse them.
      int i = 0;  // Tag index.
      final int num_tags_before = getNumTags();
      for (final String tag : metric.substring(curly + 1, len - 1).split(",")) {
        final String[] kv = tag.split("=");
        if (kv.length != 2 || kv[0].isEmpty() || kv[1].isEmpty()) {
          setTag(i, "", "", true);
          continue;  // Invalid tag.
        }
        if (i < num_tags_before) {
          setTag(i, kv[0], kv[1], true);
        } else {
          addTag(kv[0], kv[1]);
        }
        i++;
      }
      // Leave an empty line at the end.
      if (i < num_tags_before) {
        setTag(i, "", "", true);
      } else {
        addTag();
      }
      // Remove extra tags.
      for (i++; i < num_tags_before; i++) {
        tagtable.removeRow(i + 1);
      }
      // Return the "foo" part of "foo{a=b,...,x=y}"
      return metric.substring(0, curly); */
    }