@InterfaceAudience.Private
  protected void bulkLoadPhase(AsyncClusterConnection conn, TableName tableName,
    Deque<LoadQueueItem> queue, Multimap<ByteBuffer, LoadQueueItem> regionGroups, boolean copyFiles,
    Map<LoadQueueItem, ByteBuffer> item2RegionMap) throws IOException {
    // atomically bulk load the groups.
    List<Future<Collection<LoadQueueItem>>> loadingFutures = new ArrayList<>();
    for (Entry<ByteBuffer, ? extends Collection<LoadQueueItem>> entry : regionGroups.asMap()
      .entrySet()) {
      byte[] first = entry.getKey().array();
      final Collection<LoadQueueItem> lqis = entry.getValue();
      if (bulkLoadByFamily) {
        groupByFamilies(lqis).values().forEach(familyQueue -> loadingFutures
          .add(tryAtomicRegionLoad(conn, tableName, copyFiles, first, familyQueue)));
      } else {
        loadingFutures.add(tryAtomicRegionLoad(conn, tableName, copyFiles, first, lqis));
      }
      if (item2RegionMap != null) {
        for (LoadQueueItem lqi : lqis) {
          item2RegionMap.put(lqi, entry.getKey());
        }
      }
    }

    // get all the results.
    for (Future<Collection<LoadQueueItem>> future : loadingFutures) {
      try {
        Collection<LoadQueueItem> toRetry = future.get();

        if (item2RegionMap != null) {
          for (LoadQueueItem lqi : toRetry) {
            item2RegionMap.remove(lqi);
          }
        }
        // LQIs that are requeued to be regrouped.
        queue.addAll(toRetry);
      } catch (ExecutionException e1) {
        Throwable t = e1.getCause();
        if (t instanceof IOException) {
          // At this point something unrecoverable has happened.
          // TODO Implement bulk load recovery
          throw new IOException("BulkLoad encountered an unrecoverable problem", t);
        }
        LOG.error("Unexpected execution exception during bulk load", e1);
        throw new IllegalStateException(t);
      } catch (InterruptedException e1) {
        LOG.error("Unexpected interrupted exception during bulk load", e1);
        throw (InterruptedIOException) new InterruptedIOException().initCause(e1);
      }
    }
  }
This takes the LQI's grouped by likely regions and attempts to bulk load them. Any failures are
re-queued for another pass with the groupOrSplitPhase.
<p/>
protected for testing.
hbase-server/src/main/java/org/apache/hadoop/hbase/tool/BulkLoadHFilesTool.java