void removeParentsAndFixSplits(Collection<HbckRegionInfo> overlap) throws IOException {
      Pair<byte[], byte[]> range = null;
      HbckRegionInfo parent = null;
      HbckRegionInfo daughterA = null;
      HbckRegionInfo daughterB = null;
      Collection<HbckRegionInfo> daughters = new ArrayList<HbckRegionInfo>(overlap);

      String thread = Thread.currentThread().getName();
      LOG.info("== [" + thread + "] Attempting fix splits in overlap state.");

      // we only can handle a single split per group at the time
      if (overlap.size() > 3) {
        LOG.info("Too many overlaps were found on this group, falling back to regular merge.");
        return;
      }

      for (HbckRegionInfo hi : overlap) {
        if (range == null) {
          range = new Pair<byte[], byte[]>(hi.getStartKey(), hi.getEndKey());
        } else {
          if (
            RegionSplitCalculator.BYTES_COMPARATOR.compare(hi.getStartKey(), range.getFirst()) < 0
          ) {
            range.setFirst(hi.getStartKey());
          }
          if (
            RegionSplitCalculator.BYTES_COMPARATOR.compare(hi.getEndKey(), range.getSecond()) > 0
          ) {
            range.setSecond(hi.getEndKey());
          }
        }
      }

      LOG.info("This group range is [" + Bytes.toStringBinary(range.getFirst()) + ", "
        + Bytes.toStringBinary(range.getSecond()) + "]");

      // attempt to find a possible parent for the edge case of a split
      for (HbckRegionInfo hi : overlap) {
        if (
          Bytes.compareTo(hi.getHdfsHRI().getStartKey(), range.getFirst()) == 0
            && Bytes.compareTo(hi.getHdfsHRI().getEndKey(), range.getSecond()) == 0
        ) {
          LOG.info("This is a parent for this group: " + hi.toString());
          parent = hi;
        }
      }

      // Remove parent regions from daughters collection
      if (parent != null) {
        daughters.remove(parent);
      }

      // Lets verify that daughters share the regionID at split time and they
      // were created after the parent
      for (HbckRegionInfo hi : daughters) {
        if (Bytes.compareTo(hi.getHdfsHRI().getStartKey(), range.getFirst()) == 0) {
          if (parent.getHdfsHRI().getRegionId() < hi.getHdfsHRI().getRegionId()) {
            daughterA = hi;
          }
        }
        if (Bytes.compareTo(hi.getHdfsHRI().getEndKey(), range.getSecond()) == 0) {
          if (parent.getHdfsHRI().getRegionId() < hi.getHdfsHRI().getRegionId()) {
            daughterB = hi;
          }
        }
      }

      // daughters must share the same regionID and we should have a parent too
      if (
        daughterA.getHdfsHRI().getRegionId() != daughterB.getHdfsHRI().getRegionId()
          || parent == null
      ) {
        return;
      }

      FileSystem fs = FileSystem.get(conf);
      LOG.info("Found parent: " + parent.getRegionNameAsString());
      LOG.info("Found potential daughter a: " + daughterA.getRegionNameAsString());
      LOG.info("Found potential daughter b: " + daughterB.getRegionNameAsString());
      LOG.info("Trying to fix parent in overlap by removing the parent.");
      try {
        hbck.closeRegion(parent);
      } catch (IOException ioe) {
        LOG.warn("Parent region could not be closed, continuing with regular merge...", ioe);
        return;
      } catch (InterruptedException ie) {
        LOG.warn("Parent region could not be closed, continuing with regular merge...", ie);
        return;
      }

      try {
        hbck.offline(parent.getRegionName());
      } catch (IOException ioe) {
        LOG.warn("Unable to offline parent region: " + parent.getRegionNameAsString()
          + ".  Just continuing with regular merge... ", ioe);
        return;
      }

      try {
        HBaseFsckRepair.removeParentInMeta(conf, parent.getHdfsHRI());
      } catch (IOException ioe) {
        LOG.warn("Unable to remove parent region in META: " + parent.getRegionNameAsString()
          + ".  Just continuing with regular merge... ", ioe);
        return;
      }

      hbck.sidelineRegionDir(fs, parent);
      LOG.info("[" + thread + "] Sidelined parent region dir " + parent.getHdfsRegionDir()
        + " into " + hbck.getSidelineDir());
      hbck.debugLsr(parent.getHdfsRegionDir());

      // Make sure we don't have the parents and daughters around
      overlap.remove(parent);
      overlap.remove(daughterA);
      overlap.remove(daughterB);

      LOG.info("Done fixing split.");

    }
This takes set of overlapping regions and merges them into a single region. This covers cases
like degenerate regions, shared start key, general overlaps, duplicate ranges, and partial
overlapping regions. Cases: - Clean regions that overlap - Only .oldlogs regions (can't find
start/stop range, or figure out) This is basically threadsafe, except for the fixer increment
in mergeOverlaps.
hbase-server/src/main/java/org/apache/hadoop/hbase/util/HbckTableInfo.java