private List<ByteArrayId> internalGetInsertionIds(
     final MultiDimensionalNumericData indexedData, final BigInteger maxDuplicateInsertionIds) {
   final BinnedNumericDataset[] ranges =
       BinnedNumericDataset.applyBins(indexedData, baseDefinitions);
   // place each of these indices into a single row ID at a tier that will
   // fit its min and max
   final List<ByteArrayId> rowIds = new ArrayList<ByteArrayId>(ranges.length);
   for (final BinnedNumericDataset range : ranges) {
     rowIds.addAll(getRowIds(range, maxDuplicateInsertionIds));
   }
   return rowIds;
 }
  @Override
  public List<ByteArrayRange> getQueryRanges(
      final MultiDimensionalNumericData indexedRange, final int maxRangeDecomposition) {
    // TODO don't just pass max ranges along to the SFC, take tiering and
    // binning into account to limit the number of ranges correctly

    final List<ByteArrayRange> queryRanges = new ArrayList<ByteArrayRange>();
    final BinnedNumericDataset[] binnedQueries =
        BinnedNumericDataset.applyBins(indexedRange, baseDefinitions);
    int maxRangeDecompositionPerSfc = maxRangeDecomposition;
    if ((maxRangeDecomposition > 1) && (orderedSfcs.length > 1)) {
      maxRangeDecompositionPerSfc =
          (int) Math.ceil((double) maxRangeDecomposition / (double) orderedSfcs.length);
    }
    for (int sfcIndex = orderedSfcs.length - 1; sfcIndex >= 0; sfcIndex--) {
      final SpaceFillingCurve sfc = orderedSfcs[sfcIndex];
      final Byte tier = orderedSfcIndexToTierId.get(sfcIndex);
      queryRanges.addAll(getQueryRanges(binnedQueries, sfc, maxRangeDecompositionPerSfc, tier));
    }
    return queryRanges;
  }