@Test(timeout = 100000)
public void testCustomShuffleTransfer() throws IOException {

  File absLogDir = new File("target", 
      TestFadvisedFileRegion.class.getSimpleName() + 
      "LocDir").getAbsoluteFile();
  
  String testDirPath =
      StringUtils.join(Path.SEPARATOR,
          new String[] { absLogDir.getAbsolutePath(),
              "testCustomShuffleTransfer"});
  File testDir = new File(testDirPath);
  testDir.mkdirs();
  
  System.out.println(testDir.getAbsolutePath());
  
  File inFile = new File(testDir, "fileIn.out");
  File outFile = new File(testDir, "fileOut.out");
  
  
  //Initialize input file
  byte [] initBuff = new byte[FILE_SIZE];
  Random rand = new Random();
  rand.nextBytes(initBuff);
  
  FileOutputStream out = new FileOutputStream(inFile);
  try{
    out.write(initBuff);  
  } finally {
    IOUtils.cleanupWithLogger(LOG, out);
  }
  
  
  //define position and count to read from a file region.
  int position = 2*1024*1024;
  int count = 4*1024*1024 - 1;
  
  RandomAccessFile inputFile = null;
  RandomAccessFile targetFile = null;
  WritableByteChannel target = null;
  FadvisedFileRegion fileRegion = null;
  
  try {
    inputFile = new RandomAccessFile(inFile.getAbsolutePath(), "r");
    targetFile = new RandomAccessFile(outFile.getAbsolutePath(), "rw");
    target = targetFile.getChannel();
    
    Assert.assertEquals(FILE_SIZE, inputFile.length());
    
    //create FadvisedFileRegion
    fileRegion = new FadvisedFileRegion(
        inputFile, position, count, false, 0, null, null, 1024, false);
    
    //test corner cases
    customShuffleTransferCornerCases(fileRegion, target, count);
          
    long pos = 0;
    long size;
    while((size = fileRegion.customShuffleTransfer(target, pos)) > 0) {
      pos += size; 
    }
  
    //assert size
    Assert.assertEquals(count, (int)pos);
    Assert.assertEquals(count, targetFile.length());
  } finally {
    if (fileRegion != null) {
      fileRegion.releaseExternalResources();
    }
    IOUtils.cleanupWithLogger(LOG, target);
    IOUtils.cleanupWithLogger(LOG, targetFile);
    IOUtils.cleanupWithLogger(LOG, inputFile);
  }
  
  //Read the target file and verify that copy is done correctly
  byte [] buff = new byte[FILE_SIZE];
  FileInputStream in = new FileInputStream(outFile);
  try {
    int total = in.read(buff, 0, count);
  
    Assert.assertEquals(count, total);
  
    for(int i = 0; i < count; i++) {
      Assert.assertEquals(initBuff[position+i], buff[i]);
    }
  } finally {
    IOUtils.cleanupWithLogger(LOG, in);
  }
  
  //delete files and folders
  inFile.delete();
  outFile.delete();
  testDir.delete();
  absLogDir.delete();
}