void TagComparator::_mergeText(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  const Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    const SchemaVertex& tv = schema.getTagVertex(it1.key());

    // if this is a text field and it exists in both tag sets.
    if (tv.valueType == Text && t2.contains(it1.key()))
    {
      // only keep the unique text fields
      QStringList values = t1.getList(it1.key());
      values.append(t2.getList(it1.key()));

      // append all unique values in the existing order.
      for (int i = 0; i < values.size(); i++)
      {
        if (values[i].isEmpty() == false)
        {
          result.appendValueIfUnique(it1.key(), values[i]);
        }
      }

      t1.remove(it1.key());
      t2.remove(it1.key());
    }
  }
}
QSet<QString> TagComparator::_toSet(const Tags& t, const QString& k)
{
  Tags::const_iterator it = t.find(k);
  if (OsmSchema::getInstance().isList(k, *it))
  {
    return QSet<QString>::fromList(t.getList(k));
  }
  else
  {
    QSet<QString> result;
    result.insert(*it);
    return result;
  }
}
void TagComparator::_mergeExactMatches(Tags& t1, Tags& t2, Tags& result)
{
  OsmSchema& schema = OsmSchema::getInstance();

  Tags t1Copy = t1;
  for (Tags::ConstIterator it1 = t1Copy.begin(); it1 != t1Copy.end(); ++it1)
  {
    bool keepIt = false;
    Tags::const_iterator it2 = t2.find(it1.key());
    if (it2 != t2.end())
    {
      if (schema.isList(it1.key(), it1.value()))
      {
        // treat the inputs as unordered lists
        QSet<QString> values1 = QSet<QString>::fromList(t1.getList(it1.key()));
        QSet<QString> values2 = QSet<QString>::fromList(t2.getList(it2.key()));
        values1.intersect(values2);
        if (values1.size() == values2.size())
        {
          keepIt = true;
        }
      }
      else if (it2.value() == it1.value())
      {
        keepIt = true;
      }

      if (keepIt)
      {
        result[it1.key()] = it1.value();
        t1.remove(it1.key());
        t2.remove(it1.key());
      }
    }
  }
}