docs: protected final MtasDataCollector add(String key,
        boolean increaseSourceNumber) throws IOException {
      if (!closed) {
        if (collectorType.equals(DataCollector.COLLECTOR_TYPE_DATA)) {
          throw new IOException(
              "collector should be " + DataCollector.COLLECTOR_TYPE_LIST);
        } else if (key == null) {
          throw new IOException("key shouldn't be null");
        } else {
          // check previous added
          if ((newPosition > 0)
              && newKeyList[(newPosition - 1)].compareTo(key) >= 0) {
            int i = newPosition;
            do {
              i--;
              if (newKeyList[i].equals(key)) {
                newCurrentPosition = i;
                newCurrentExisting = true;
                if (subDataTypes != null) {
                  return newSubCollectorListNextLevel[newCurrentPosition];
                } else {
                  return null;
                }
              }
            } while ((i > 0) && (newKeyList[i].compareTo(key) > 0));
          }
          // move position in old list
          if (position < getSize()) {
            // just add smaller or equal items
            while (keyList[position].compareTo(key) <= 0) {
              if (newPosition == newSize) {
                increaseNewListSize();
              }
              // copy
              newKeyList[newPosition] = keyList[position];
              newSourceNumberList[newPosition] = sourceNumberList[position];
              newErrorNumber[newPosition] = errorNumber[position];
              newErrorList[newPosition] = errorList[position];
              if (hasSub) {
                newSubCollectorListNextLevel[newPosition] = subCollectorListNextLevel[position];
              }
              copyToNew(position, newPosition);
              newPosition++;
              position++;
              // check if added key from list is right key
              if (newKeyList[(newPosition - 1)].equals(key)) {
                if (increaseSourceNumber) {
                  newSourceNumberList[(newPosition - 1)]++;
                }
                newCurrentPosition = newPosition - 1;
                newCurrentExisting = true;
                // register known key found again in segment
                newKnownKeyFoundInSegment.add(key);
                // ready
                if (hasSub) {
                  return newSubCollectorListNextLevel[newCurrentPosition];
                } else {
                  return null;
                }
                // stop if position exceeds size
              } else if (position == getSize()) {
                break;
              }
            }
          }
          // check size
          if (newPosition == newSize) {
            increaseNewListSize();
          }
          // add key
          newKeyList[newPosition] = key;
          newSourceNumberList[newPosition] = 1;
          newErrorNumber[newPosition] = 0;
          newErrorList[newPosition] = new HashMap<>();
          newPosition++;
          newCurrentPosition = newPosition - 1;
          newCurrentExisting = false;
          // ready, only handle sub
          if (hasSub) {
            newSubCollectorListNextLevel[newCurrentPosition] = DataCollector
                .getCollector(subCollectorTypes[0], subDataTypes[0],
                    subStatsTypes[0], subStatsItems[0], subSortTypes[0],
                    subSortDirections[0], subStart[0], subNumber[0],
                    newSubCollectorTypes, newSubDataTypes, newSubStatsTypes,
                    newSubStatsItems, newSubSortTypes, newSubSortDirections,
                    newSubStart, newSubNumber, segmentRegistration, null);
            return newSubCollectorListNextLevel[newCurrentPosition];
          } else {
            return null;
          }
        }
      } else {
        throw new IOException("already closed");
      }
    }