docs: protected void remapData(int[][] mapping) throws IOException {
      if (!closed) {
        // remap and merge keys
        String[] newKeyList = new String[mapping.length];
        // process mapping for functions?
        HashMap<MtasDataCollector<?, ?>, MtasDataCollector<?, ?>> map = new HashMap<>();
        int[] newSourceNumberList = new int[mapping.length];
        int[] newErrorNumber = new int[mapping.length];
        @SuppressWarnings("unchecked")
        HashMap<String, Integer>[] newErrorList = (HashMap<String, Integer>[]) new HashMap<?, ?>[mapping.length];
        for (int i = 0; i < mapping.length; i++) {
          newKeyList[i] = keyList[mapping[i][0]];
          newSourceNumberList[i] = sourceNumberList[mapping[i][0]];
          for (int j = 0; j < mapping[i].length; j++) {
            if (j == 0) {
              newErrorNumber[i] = errorNumber[mapping[i][j]];
              newErrorList[i] = errorList[mapping[i][j]];
            } else {
              newErrorNumber[i] += errorNumber[mapping[i][j]];
              for (Entry<String, Integer> entry : errorList[mapping[i][j]]
                  .entrySet()) {
                if (newErrorList[i].containsKey(entry.getKey())) {
                  newErrorList[i].put(entry.getKey(),
                      newErrorList[i].get(entry.getKey()) + entry.getValue());
                } else {
                  newErrorList[i].put(entry.getKey(), entry.getValue());
                }
              }
            }
          }
        }
        if (hasSub) {
          newSubCollectorListNextLevel = new MtasDataCollector<?, ?>[mapping.length];
          for (int i = 0; i < mapping.length; i++) {
            for (int j = 0; j < mapping[i].length; j++) {
              if (j == 0 || newSubCollectorListNextLevel[i] == null) {
                newSubCollectorListNextLevel[i] = subCollectorListNextLevel[mapping[i][j]];
              } else {
                newSubCollectorListNextLevel[i]
                    .merge(subCollectorListNextLevel[mapping[i][j]], map, false);
              }
            }
          }
          subCollectorListNextLevel = newSubCollectorListNextLevel;
        }
        keyList = newKeyList;
        sourceNumberList = newSourceNumberList;
        errorNumber = newErrorNumber;
        errorList = newErrorList;
        size = keyList.length;
        position = 0;
      } else {
        throw new IOException("already closed");
      }
    }