@Override
  public List<FilterType> merge(List<Wrapper<FilterType>> items) {
    Map<String /*businessKey*/, List<Wrapper<FilterType>>> keyMap =
        new HashMap<String, List<Wrapper<FilterType>>>();
    logger.trace("Merge for " + klass.getSimpleName());

    final List<FilterType> result = new ArrayList<FilterType>();

    // Groupping
    for (Wrapper<FilterType> item : items) {
      String businessKey = getBusinessKey(item);

      if (!keyMap.containsKey(businessKey)) {
        keyMap.put(businessKey, new ArrayList<Wrapper<FilterType>>());
      }

      keyMap.get(businessKey).add(item);
    }

    // Joining
    int counter = 0;
    for (Map.Entry<String, List<Wrapper<FilterType>>> item : keyMap.entrySet()) {
      counter++;
      if (counter % 100 == 0)
        logger.debug("Processing " + klass + " " + counter + " of " + keyMap.size());

      String businessKey = item.getKey();
      List<Wrapper<FilterType>> itemsToJoin = item.getValue();

      FilterType newItem = join(itemsToJoin);
      finalTemplate.save(newItem);
      for (Wrapper<FilterType> itemToJoin : itemsToJoin) {
        addToContext(itemToJoin.source(), itemToJoin.item().getCode(), newItem.getCode());
      }

      mergeChildren(itemsToJoin);
      result.add(newItem);
    }

    return result;
  }
  @Override
  public FilterType join(List<Wrapper<FilterType>> items) {
    Wrapper<FilterType> filterTypeWrapper = findFistFromMannOtherwiseFirst(items);
    FilterType filterType = filterTypeWrapper.item();

    id++;
    FilterType newFilterType = new FilterType();
    newFilterType.setId(id);
    newFilterType.setCode(filterType.getCode());
    newFilterType.setName(filterType.getName());

    return newFilterType;
  }