code: private static WorkUnitState mergeSplits(FileSystem fs, CopyableFile file, Collection<WorkUnitState> workUnits,
        Path parentPath) throws IOException {
  
      log.info(String.format("File %s was written in %d parts. Merging.", file.getDestination(), workUnits.size()));
      Path[] parts = new Path[workUnits.size()];
      for (WorkUnitState workUnit : workUnits) {
        if (!isSplitWorkUnit(workUnit)) {
          throw new IOException("Not a split work unit.");
        }
        Split split = getSplit(workUnit).get();
        parts[split.getSplitNumber()] = new Path(parentPath, split.getPartName());
      }
  
      Path target = new Path(parentPath, file.getDestination().getName());
  
      fs.rename(parts[0], target);
      fs.concat(target, Arrays.copyOfRange(parts, 1, parts.length));
  
      WorkUnitState finalWorkUnit = workUnits.iterator().next();
      finalWorkUnit.removeProp(SPLIT_KEY);
      return finalWorkUnit;
    }
docs: Merges all the splits for a given file.
  Should be called on the target/destination file system (after blocks have been copied to targetFs).
  @param fs {@link FileSystem} where file parts exist.
  @param file {@link CopyableFile} to merge.
  @param workUnits {@link WorkUnitState}s for all parts of this file.
  @param parentPath {@link Path} where the parts of the file are located.
  @return a {@link WorkUnit} equivalent to the distcp work unit if the file had not been split.
  @throws IOException