/*
(non-Javadoc)

@see mtas.codec.util.DataCollector.MtasDataCollector#merge(mtas.codec.util.
DataCollector.MtasDataCollector)
516146
@Override
  public void merge(MtasDataCollector<?, ?> newDataCollector,
      Map<MtasDataCollector<?, ?>, MtasDataCollector<?, ?>> map,
      boolean increaseSourceNumber) throws IOException {
    closeNewList();
    if (!collectorType.equals(newDataCollector.getCollectorType())
        || !dataType.equals(newDataCollector.getDataType())
        || !statsType.equals(newDataCollector.getStatsType())
        || !(newDataCollector instanceof MtasDataFull)) {
      throw new IOException("cannot merge different dataCollectors");
    } else {
      segmentRegistration = null;
      @SuppressWarnings("unchecked")
      MtasDataFull<T1, T2> newMtasDataFull = (MtasDataFull<T1, T2>) newDataCollector;
      closeNewList();
      initNewList(newMtasDataFull.getSize());
      if (collectorType.equals(DataCollector.COLLECTOR_TYPE_LIST)) {
        map.put(newDataCollector, this);
        for (int i = 0; i < newMtasDataFull.getSize(); i++) {
          if (newMtasDataFull.fullValueList[i].length > 0) {
            MtasDataCollector<?, ?>[] subCollectors = new MtasDataCollector<?, ?>[1];
            subCollectors[0] = add(newMtasDataFull.keyList[i],
                increaseSourceNumber);
            setError(newCurrentPosition, newMtasDataFull.errorNumber[i],
                newMtasDataFull.errorList[i], newCurrentExisting);
            setValue(newCurrentPosition, newMtasDataFull.fullValueList[i],
                newMtasDataFull.fullValueList[i].length, newCurrentExisting);
            if (hasSub() && newMtasDataFull.hasSub()) {
              // single key implies exactly one subCollector if hasSub
              subCollectors[0].merge(
                  newMtasDataFull.subCollectorListNextLevel[i], map,
                  increaseSourceNumber);
            }
          }
        }
      } else if (collectorType.equals(DataCollector.COLLECTOR_TYPE_DATA)) {
        map.put(newDataCollector, this);
        if (newMtasDataFull.getSize() > 0) {
          MtasDataCollector<?, ?> subCollector = add(increaseSourceNumber);
          setError(newCurrentPosition, newMtasDataFull.errorNumber[0],
              newMtasDataFull.errorList[0], newCurrentExisting);
          setValue(newCurrentPosition, newMtasDataFull.fullValueList[0],
              newMtasDataFull.fullValueList[0].length, newCurrentExisting);
          if (hasSub() && newMtasDataFull.hasSub()) {
            subCollector.merge(newMtasDataFull.subCollectorNextLevel, map,
                increaseSourceNumber);
          }
        }
      } else {
        throw new IOException("cannot merge " + collectorType);
      }
      closeNewList();
    }
  }
1195458
public void merge(Metadata other) {
    if (other.isEmpty()) {
      return;
    }
    int remaining = cap() - len();
    if (isEmpty() || remaining < other.len()) {
      expand(len() + other.len());
    }
    System.arraycopy(other.namesAndValues, 0, namesAndValues, len(), other.len());
    size += other.size;
  }
497508
public void merge(GVRSkeleton newSkel)
    {
        int numBones = getNumBones();
        List<Integer> parentBoneIds = new ArrayList<Integer>(numBones + newSkel.getNumBones());
        List<String> newBoneNames = new ArrayList<String>(newSkel.getNumBones());
        List<Matrix4f> newMatrices = new ArrayList<Matrix4f>(newSkel.getNumBones());
        GVRPose oldBindPose = getBindPose();
        GVRPose curPose = getPose();

        for (int i = 0; i < numBones; ++i)
        {
            parentBoneIds.add(mParentBones[i]);
        }
        for (int j = 0; j < newSkel.getNumBones(); ++j)
        {
            String boneName = newSkel.getBoneName(j);
            int boneId = getBoneIndex(boneName);
            if (boneId < 0)
            {
                int parentId = newSkel.getParentBoneIndex(j);
                Matrix4f m = new Matrix4f();

                newSkel.getBindPose().getLocalMatrix(j, m);
                newMatrices.add(m);
                newBoneNames.add(boneName);
                if (parentId >= 0)
                {
                    boneName = newSkel.getBoneName(parentId);
                    parentId = getBoneIndex(boneName);
                }
                parentBoneIds.add(parentId);
            }
        }
        if (parentBoneIds.size() == numBones)
        {
            return;
        }
        int n = numBones +  parentBoneIds.size();
        int[] parentIds = Arrays.copyOf(mParentBones, n);
        int[] boneOptions = Arrays.copyOf(mBoneOptions, n);
        String[] boneNames = Arrays.copyOf(mBoneNames, n);

        mBones = Arrays.copyOf(mBones, n);
        mPoseMatrices =  new float[n * 16];
        for (int i = 0; i < parentBoneIds.size(); ++i)
        {
            n = numBones + i;
            parentIds[n] = parentBoneIds.get(i);
            boneNames[n] = newBoneNames.get(i);
            boneOptions[n] = BONE_ANIMATE;
        }
        mBoneOptions = boneOptions;
        mBoneNames = boneNames;
        mParentBones = parentIds;
        mPose = new GVRPose(this);
        mBindPose = new GVRPose(this);
        mBindPose.copy(oldBindPose);
        mPose.copy(curPose);
        mBindPose.sync();
        for (int j = 0; j < newSkel.getNumBones(); ++j)
        {
            mBindPose.setLocalMatrix(numBones + j, newMatrices.get(j));
            mPose.setLocalMatrix(numBones + j, newMatrices.get(j));
        }
        setBindPose(mBindPose);
        mPose.sync();
        updateBonePose();
    }
640762
public JMCountMap<V> merge(JMCountMap<V> jmCountMap) {
        synchronized (countMap) {
            jmCountMap.forEach((value, count) -> countMap
                    .put(value, getCount(value) + count));
            return this;
        }
    }
966302
@Override
    public T merge(Archive<?> source, Filter<ArchivePath> filter) throws IllegalArgumentException {
        return merge(source, new BasicPath(), filter);
    }
1094217
@SuppressWarnings("unchecked")
	private void mergeResponsesArrayList(ArrayList<Object> originalList, ArrayList<Object> shardList)
			throws IOException {
		// get keys from original
		HashMap<String, Object> originalKeyList = new HashMap<>();
		for (Object item : originalList) {
			if (item instanceof NamedList<?>) {
				NamedList<Object> itemList = (NamedList<Object>) item;
				Object key = itemList.get("key");
				if ((key != null) && (key instanceof String)) {
					originalKeyList.put((String) key, item);
				}
			}
		}
		for (Object item : shardList) {
			if (item instanceof NamedList<?>) {
				NamedList<Object> itemList = (NamedList<Object>) item;
				Object key = itemList.get("key");
				// item with key
				if ((key != null) && (key instanceof String)) {
					// merge
					if (originalKeyList.containsKey(key)) {
						Object originalItem = originalKeyList.get(key);
						if (originalItem.getClass().equals(item.getClass())) {
							mergeResponsesNamedList((NamedList<Object>) originalItem, (NamedList<Object>) item);
						} else {
							// ignore?
						}
						// add
					} else {
						Object clonedItem = adjustablePartsCloned(item);
						originalList.add(clonedItem);
						originalKeyList.put((String) key, clonedItem);
					}
				} else {
					originalList.add(item);
				}
			} else {
				originalList.add(item);
			}
		}
	}
610060
public boolean merge(ResourceMetadata other) {
        boolean modified = m_metrics.addAll(other.m_metrics);
        if (!modified) {
            modified = !m_attributes.equals(other.m_attributes);
        }
        m_attributes.putAll(other.m_attributes);
        return modified;
    }
125210
public static void merge(List<PathDetail> pathDetails, List<PathDetail> otherDetails) {
        // Make sure that the PathDetail list is merged correctly at via points
        if (!pathDetails.isEmpty() && !otherDetails.isEmpty()) {
            PathDetail lastDetail = pathDetails.get(pathDetails.size() - 1);
            if (lastDetail.getValue().equals(otherDetails.get(0).getValue())) {
                lastDetail.setLast(otherDetails.get(0).getLast());
                otherDetails.remove(0);
            }
        }

        pathDetails.addAll(otherDetails);
    }
813222
public static MtasSpanSequenceItem merge(MtasSpanSequenceItem item1,
      MtasSpanSequenceItem item2, MtasSpanQuery ignoreQuery,
      Integer maximumIgnoreLength) {
    if (item1 == null || item2 == null) {
      return null;
    } else {
      MtasSpanQuery q1 = item1.getQuery();
      MtasSpanQuery q2 = item2.getQuery();
      boolean optional = item1.optional && item2.optional;
      // first spanRecurrenceQuery
      if (q1 instanceof MtasSpanRecurrenceQuery) {
        MtasSpanRecurrenceQuery rq1 = (MtasSpanRecurrenceQuery) q1;
        // both spanRecurrenceQuery
        if (q2 instanceof MtasSpanRecurrenceQuery) {
          MtasSpanRecurrenceQuery rq2 = (MtasSpanRecurrenceQuery) q2;
          // equal query
          if (rq1.getQuery().equals(rq2.getQuery())) {
            // equal ignoreQuery settings
            boolean checkCondition;
            checkCondition = ignoreQuery != null
                && rq1.getIgnoreQuery() != null;
            checkCondition = checkCondition
                ? ignoreQuery.equals(rq1.getIgnoreQuery()) : false;
            checkCondition = checkCondition
                ? maximumIgnoreLength.equals(rq1.getMaximumIgnoreLength())
                : false;
            checkCondition = checkCondition ? rq2.getIgnoreQuery() != null
                : false;
            checkCondition = checkCondition
                ? ignoreQuery.equals(rq2.getIgnoreQuery()) : false;
            checkCondition = checkCondition
                ? maximumIgnoreLength.equals(rq2.getMaximumIgnoreLength())
                : false;
            if (checkCondition) {
              // at least one optional
              if (item1.optional || item2.optional) {
                int minimum = Math.min(rq1.getMinimumRecurrence(),
                    rq2.getMinimumRecurrence());
                int maximum = rq1.getMaximumRecurrence()
                    + rq2.getMaximumRecurrence();
                // only if ranges match
                if ((rq1.getMaximumRecurrence() + 1) >= rq2
                    .getMinimumRecurrence()
                    && (rq2.getMaximumRecurrence() + 1) >= rq1
                        .getMinimumRecurrence()) {
                  return new MtasSpanSequenceItem(
                      new MtasSpanRecurrenceQuery(rq1.getQuery(), minimum,
                          maximum, ignoreQuery, maximumIgnoreLength),
                      optional);
                }
                // not optional
              } else {
                int minimum = rq1.getMinimumRecurrence()
                    + rq2.getMinimumRecurrence();
                int maximum = rq1.getMaximumRecurrence()
                    + rq2.getMaximumRecurrence();
                // only if ranges match
                if ((rq1.getMaximumRecurrence() + 1) >= rq2
                    .getMinimumRecurrence()
                    && (rq2.getMaximumRecurrence() + 1) >= rq1
                        .getMinimumRecurrence()) {
                  return new MtasSpanSequenceItem(
                      new MtasSpanRecurrenceQuery(rq1.getQuery(), minimum,
                          maximum, ignoreQuery, maximumIgnoreLength),
                      optional);
                }
              }
            }
          }
        } else {
          if (rq1.getQuery().equals(q2)) {
            boolean checkCondition;
            checkCondition = ignoreQuery != null;
            checkCondition &= rq1.getIgnoreQuery() != null;
            checkCondition &= ignoreQuery.equals(rq1.getIgnoreQuery());
            checkCondition &= rq1.getMaximumIgnoreLength() != null;
            checkCondition &= maximumIgnoreLength
                .equals(rq1.getMaximumIgnoreLength());
            if (checkCondition) {
              if (!optional) {
                if (item1.optional) {
                  if (rq1.getMinimumRecurrence() == 1) {
                    return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(
                        q2, 1, rq1.getMaximumRecurrence() + 1, ignoreQuery,
                        maximumIgnoreLength), false);
                  }
                } else if (item2.optional) {
                  return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(
                      q2, rq1.getMinimumRecurrence(),
                      rq1.getMaximumRecurrence() + 1, ignoreQuery,
                      maximumIgnoreLength), false);
                } else {
                  return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(
                      q2, rq1.getMinimumRecurrence() + 1,
                      rq1.getMaximumRecurrence() + 1, ignoreQuery,
                      maximumIgnoreLength), false);
                }
              } else {
                if (rq1.getMinimumRecurrence() == 1) {
                  return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(
                      q2, 1, rq1.getMaximumRecurrence() + 1, ignoreQuery,
                      maximumIgnoreLength), true);
                }
              }
            }
          }
        }
        // second spanRecurrenceQuery
      } else if (q2 instanceof MtasSpanRecurrenceQuery) {
        MtasSpanRecurrenceQuery rq2 = (MtasSpanRecurrenceQuery) q2;
        if (rq2.getQuery().equals(q1)) {
          boolean checkCondition;
          checkCondition = ignoreQuery != null;
          checkCondition &= rq2.getIgnoreQuery() != null;
          checkCondition &= ignoreQuery.equals(rq2.getIgnoreQuery());
          checkCondition &= maximumIgnoreLength
              .equals(rq2.getMaximumIgnoreLength());
          if (checkCondition) {
            if (!optional) {
              if (item1.optional) {
                return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(q1,
                    rq2.getMinimumRecurrence(), rq2.getMaximumRecurrence() + 1,
                    ignoreQuery, maximumIgnoreLength), false);
              } else if (item2.optional) {
                if (rq2.getMinimumRecurrence() == 1) {
                  return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(
                      q1, 1, rq2.getMaximumRecurrence() + 1, ignoreQuery,
                      maximumIgnoreLength), false);
                }
              } else {
                return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(q1,
                    rq2.getMinimumRecurrence() + 1,
                    rq2.getMaximumRecurrence() + 1, ignoreQuery,
                    maximumIgnoreLength), false);
              }
            } else {
              if (rq2.getMinimumRecurrence() == 1) {
                return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(q1,
                    1, rq2.getMaximumRecurrence() + 1, ignoreQuery,
                    maximumIgnoreLength), true);
              }
            }
          }
        }
        // both no spanRecurrenceQuery
      } else if (q1.equals(q2)) {
        // at least one optional
        if (item1.optional || item2.optional) {
          return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(q1, 1, 2,
              ignoreQuery, maximumIgnoreLength), optional);
        } else {
          return new MtasSpanSequenceItem(new MtasSpanRecurrenceQuery(q1, 2, 2,
              ignoreQuery, maximumIgnoreLength), optional);
        }
      }
      return null;
    }
  }
1219580
void merge(MtasSolrMtasResult newItem) throws IOException {
    HashMap<MtasDataCollector<?, ?>, MtasDataCollector<?, ?>> map = new HashMap<>();
    if (newItem.dataCollector.withTotal()) {
      dataCollector.setWithTotal();
    }
    dataCollector.merge(newItem.dataCollector, map, true);
    if (newItem.functionData != null) {
      if (functionData == null) {
        functionData = new HashMap<>();
      }
      for (MtasDataCollector<?, ?> keyCollector : newItem.functionData
          .keySet()) {
        if (map.containsKey(keyCollector)) {
          // compute mapped key
          MtasDataCollector<?, ?> newKeyCollector = keyCollector;
          while (map.containsKey(newKeyCollector)) {
            newKeyCollector = map.get(keyCollector);
          }
          if (functionData.containsKey(newKeyCollector)) {
            HashMap<String, MtasSolrMtasResult> tmpList = functionData
                .get(newKeyCollector);
            for (String functionKey : newItem.functionData.get(keyCollector)
                .keySet()) {
              if (tmpList.containsKey(functionKey)) {
                tmpList.get(functionKey).merge(
                    newItem.functionData.get(keyCollector).get(functionKey));
              } else {
                tmpList.put(functionKey,
                    newItem.functionData.get(keyCollector).get(functionKey));
              }
            }
          } else {
            functionData.put(newKeyCollector,
                newItem.functionData.get(keyCollector));
          }
        }
      }
    }
  }
852906
public void merge(BloomKFilter that)
  {
    if (this != that && this.m == that.m && this.k == that.k) {
      this.bitSet.putAll(that.bitSet);
    } else {
      throw new IllegalArgumentException("BloomKFilters are not compatible for merging." +
                                         " this - " + this + " that - " + that);
    }
  }
1319322
static <T> void mergeFrom(InputStream in, byte[] buf, T message, Schema<T> schema,
            boolean decodeNestedMessageAsGroup) throws IOException
    {
        final CodedInput input = new CodedInput(in, buf, decodeNestedMessageAsGroup);
        schema.mergeFrom(input, message);
        input.checkLastTagWas(0);
    }
1197419
@Override
  public void merge(MtasDataCollector<?, ?> newDataCollector,
      Map<MtasDataCollector<?, ?>, MtasDataCollector<?, ?>> map,
      boolean increaseSourceNumber) throws IOException {
    closeNewList();
    if (!collectorType.equals(newDataCollector.getCollectorType())
        || !dataType.equals(newDataCollector.getDataType())
        || !statsType.equals(newDataCollector.getStatsType())
        || !(newDataCollector instanceof MtasDataBasic)) {
      throw new IOException("cannot merge different dataCollectors");
    } else {
      segmentRegistration = null;
      @SuppressWarnings("unchecked")
      MtasDataBasic<T1, T2> newMtasDataBasic = (MtasDataBasic<T1, T2>) newDataCollector;
      newMtasDataBasic.closeNewList();
      initNewList(newMtasDataBasic.getSize());
      if (collectorType.equals(DataCollector.COLLECTOR_TYPE_LIST)) {
        map.put(newDataCollector, this);
        for (int i = 0; i < newMtasDataBasic.getSize(); i++) {
          MtasDataCollector<?, ?>[] subCollectors = new MtasDataCollector[1];
          subCollectors[0] = add(newMtasDataBasic.keyList[i],
              increaseSourceNumber);
          setError(newCurrentPosition, newMtasDataBasic.errorNumber[i],
              newMtasDataBasic.errorList[i], newCurrentExisting);
          setValue(newCurrentPosition, newMtasDataBasic.basicValueSumList[i],
              newMtasDataBasic.basicValueNList[i], newCurrentExisting);
          if (hasSub() && newMtasDataBasic.hasSub()) {
            // single key implies exactly one subCollector if hasSub
            subCollectors[0].merge(
                newMtasDataBasic.subCollectorListNextLevel[i], map,
                increaseSourceNumber);
          }
        }
        closeNewList();
      } else if (collectorType.equals(DataCollector.COLLECTOR_TYPE_DATA)) {
        map.put(newDataCollector, this);
        if (newMtasDataBasic.getSize() > 0) {
          MtasDataCollector<?, ?> subCollector = add(increaseSourceNumber);
          setError(newCurrentPosition, newMtasDataBasic.errorNumber[0],
              newMtasDataBasic.errorList[0], newCurrentExisting);
          setValue(newCurrentPosition, newMtasDataBasic.basicValueSumList[0],
              newMtasDataBasic.basicValueNList[0], newCurrentExisting);
          if (hasSub() && newMtasDataBasic.hasSub()) {
            subCollector.merge(newMtasDataBasic.subCollectorNextLevel, map,
                increaseSourceNumber);
          }
        }
        closeNewList();
      } else {
        throw new IOException("cannot merge " + collectorType);
      }
    }
  }
304736
@Override
    public void merge(JMSConnectionFactoryDefinition annotation, Class<?> instanceClass, Member member) throws InjectionException {

        if (member != null) {
            // ConnectionFactoryDefinition is a class-level annotation only.
            throw new IllegalArgumentException(member.toString());
        }

        interfaceName = mergeAnnotationValue(interfaceName, isXmlInterfaceNameSet, annotation.interfaceName(), JMSConnectionFactoryProperties.INTERFACE_NAME.getAnnotationKey(),
                                             JMSResourceDefinitionConstants.JMS_CONNECTION_FACTORY_INTERFACE);
        className = mergeAnnotationValue(className, isXmlClassNameSet, annotation.className(), JMSConnectionFactoryProperties.CLASS_NAME.getAnnotationKey(), "");
        resourceAdapter = mergeAnnotationValue(resourceAdapter, isXmlResourceAdapterSet, annotation.resourceAdapter(),
                                               JMSConnectionFactoryProperties.RESOURCE_ADAPTER.getAnnotationKey(),
                                               JMSResourceDefinitionConstants.DEFAULT_JMS_RESOURCE_ADAPTER);
        user = mergeAnnotationValue(user, isXMLUserSet, annotation.user(), JMSConnectionFactoryProperties.USER.getAnnotationKey(), "");
        password = mergeAnnotationValue(password, isXmlPasswordSet, annotation.password(), JMSConnectionFactoryProperties.PASSWORD.getAnnotationKey(), "");
        clientId = mergeAnnotationValue(clientId, isXmlClientIdSet, annotation.clientId(), JMSConnectionFactoryProperties.CLIENT_ID.getAnnotationKey(), "");
        properties = mergeAnnotationProperties(properties, xmlProperties, annotation.properties());
        transactional = mergeAnnotationBoolean(transactional, isXmlTransactionalSet, annotation.transactional(), JMSConnectionFactoryProperties.TRANSACTIONAL.getAnnotationKey(),
                                               JMSResourceDefinitionConstants.DEFAULT_TRANSACTIONAL_VALUE);
        description = mergeAnnotationValue(description, isXmlDescriptionSet, annotation.description(), JMSConnectionFactoryProperties.DESCRIPTION.getAnnotationKey(), ""); // d662109
        maxPoolSize = mergeAnnotationInteger(maxPoolSize, isXmlMaxPoolSizeSet, annotation.maxPoolSize(), JMSConnectionFactoryProperties.MAX_POOL_SIZE.getAnnotationKey(), -1, null);
        minPoolSize = mergeAnnotationInteger(minPoolSize, isXmlMinPoolSizeSet, annotation.minPoolSize(), JMSConnectionFactoryProperties.MIN_POOL_SIZE.getAnnotationKey(), -1, null);

    }
377164
@Override
    protected LofDataSet mergeState(LofDataSet baseDataSet, LofDataSet targetDataSet,
            Map<String, Object> mergeConfig)
    {
        int kn = Integer.parseInt(mergeConfig.get(LofConfKey.KN).toString());
        int maxDataCount = Integer.parseInt(mergeConfig.get(LofConfKey.MAX_DATA_COUNT).toString());

        // 学習データの保持する対象点を新しい方から最大保持数個だけ取得
        LofDataSet mergedDataSet = LofCalculator.mergeDataSet(baseDataSet, targetDataSet,
                maxDataCount);

        // 中間データ保持設定が存在しない場合は中間データの生成は行わない。
        if (mergeConfig.containsKey(LofConfKey.HAS_INTERMEDIATE) == false)
        {
            return mergedDataSet;
        }

        // 中間データ保持設定が存在し、かつ「true」の場合のみ中間データの生成を行う。
        if (Boolean.getBoolean(mergeConfig.get(LofConfKey.HAS_INTERMEDIATE).toString()) == true)
        {
            LofCalculator.initDataSet(kn, mergedDataSet);
        }

        return mergedDataSet;
    }
30612
private void mergeRows(ExcelRows excelRowsAnn, Cell templateCell, int itemSize) {
        val tmplCellRowIndex = templateCell.getRowIndex();

        for (val ann : excelRowsAnn.mergeRows()) {
            val fr = ann.fromRef();
            val cellRef = PoiUtil.isFullCellReference(fr) ? fr : fr + (tmplCellRowIndex + 1);
            val fromCell = PoiUtil.findCell(sheet, cellRef);

            val lastRow = tmplCellRowIndex + itemSize - 1;
            if (ann.type() == MergeType.Direct) {
                val fromRow = fromCell.getRow().getRowNum();
                directMergeRows(ann, fromRow, lastRow, fromCell.getColumnIndex());
            } else if (ann.type() == MergeType.SameValue) {
                sameValueMergeRows(ann, itemSize, fromCell);
            }
        }
    }
838098
public LCMSDataSubset merge(LCMSDataSubset other) {
    LCMSDataSubset merged = new LCMSDataSubset();

    Set<Integer> msLvlsThis = getMsLvls();
    Set<Integer> msLvlsThat = other.getMsLvls();
    // only merge if both are not null, otherwise null signifies the whole
    // run, so we can keep it null in the merged version
    if (msLvlsThis != null && msLvlsThat != null) {
      HashSet<Integer> mergedMsLvls = new HashSet<>(msLvlsThis);
      mergedMsLvls.addAll(msLvlsThat);
      merged.setMsLvls(mergedMsLvls);
    }

    // merge mz ranges
    List<DoubleRange> mzRangesThis = getMzRanges();
    List<DoubleRange> mzRangesThat = other.getMzRanges();
    if (mzRangesThis != null && mzRangesThat != null) {
      ArrayList<DoubleRange> mergedMzRanges = new ArrayList<>(mzRangesThis);
      mergedMzRanges.addAll(mzRangesThat);
      merged.setMzRanges(mergedMzRanges);
    }

    // compare scan number ranges
    Integer scanNumLoThis = getScanNumLo();
    Integer scanNumLoThat = other.getScanNumLo();
    if (scanNumLoThis != null && scanNumLoThat != null) {
      merged.setScanNumLo(Math.min(scanNumLoThis, scanNumLoThat));
    }
    Integer scanNumHiThis = getScanNumHi();
    Integer scanNumHiThat = other.getScanNumHi();
    if (scanNumHiThis != null && scanNumHiThat != null) {
      merged.setScanNumHi(Math.max(scanNumHiThis, scanNumHiThat));
    }

    return merged;
  }