package cc.twittertools.util;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;

/**
 * Iterates over the downloaded tweet files. Recall we have a folder full of folders
 * (and unrelated files), and in each of these folders are files, *ALL* of which are
 * tweet files	
 */
public final class FilesInFoldersIterator implements Iterator<Path>, AutoCloseable
{
	private DirectoryStream<Path> folders;
	private DirectoryStream<Path> filesInCurrentFolder;
	
	private Iterator<Path> foldersIter;
	private Iterator<Path> filesInCurrentFolderIter;
	
	private Exception error;

	public FilesInFoldersIterator(Path folderOfFolders) throws IOException
	{	folders = Files.newDirectoryStream(folderOfFolders, new DirectoryStream.Filter<Path>()
		{ @Override public boolean accept(Path path) throws IOException
			{	return Files.isDirectory(path);
			}
		});
		foldersIter = folders.iterator();
		filesInCurrentFolderIter = nextFolder();
	}
	
	public boolean hasNext()
	{	try
		{	while (filesInCurrentFolderIter != null && ! filesInCurrentFolderIter.hasNext())
			{	filesInCurrentFolderIter = nextFolder();
			}
		
			return filesInCurrentFolderIter != null; // the lopp above implies hasNext = true
		}
		catch (Exception e)
		{	error = e;
			return true; // we want the exception to be thrown on the call to next
		}
	}

	public Path next()
	{	if (error != null)
		{	RuntimeException runError = new RuntimeException ("Error occurred while determining the next file to read : " + error.getMessage(), error);
			error = null;
			throw runError;
		}
		return filesInCurrentFolderIter.next();
	}

	public void remove()
	{	throw new UnsupportedOperationException();
	}
  
	private Iterator<Path> nextFolder() throws IOException
	{	if (! foldersIter.hasNext())
			return null;
	
		Path folder = foldersIter.next();
		if (filesInCurrentFolder != null)
			filesInCurrentFolder.close();
		
		filesInCurrentFolder = Files.newDirectoryStream(folder, new DirectoryStream.Filter<Path>()
		{	@Override public boolean accept(Path path) throws IOException
			{	return ! Files.isDirectory(path);
			}
		});
		return filesInCurrentFolder.iterator();
	}
	
	public void close() throws Exception
	{	folders.close();
		if (filesInCurrentFolder != null)
			filesInCurrentFolder.close();
	}
}
@@ -490,16 +490,22 @@
  folders
+Stream
 ;%0A%09priva
@@ -530,35 +530,32 @@
 %3CPath%3E f
-ilesInCurrentFolder
+olderFilesStream
 ;%0A%09%0A%09pri
@@ -612,35 +612,26 @@
 %3CPath%3E f
-ilesInCurrentF
 older
+Files
 Iter;%0A%09%0A
@@ -689,25 +689,31 @@
 erator(Path 
-f
+pathToF
 olderOfFolde
@@ -745,16 +745,22 @@
 %09folders
+Stream
  = Files
@@ -775,25 +775,35 @@
 ctoryStream(
-f
+%0A%09%09%09pathToF
 olderOfFolde
@@ -806,16 +806,20 @@
 olders, 
+%0A%09%09%09
 new Dire
@@ -845,16 +845,17 @@
 Path%3E()%0A
+%09
 %09%09%7B @Ove
@@ -907,32 +907,33 @@
  IOException%0A%09%09%09
+%09
 %7B%09return Files.i
@@ -949,29 +949,34 @@
 y(path);%0A%09%09%09
+%09
 %7D%0A
+%09
 %09%09%7D
+%0A%09%09
 );%0A%09%09folders
@@ -989,16 +989,22 @@
  folders
+Stream
 .iterato
@@ -1011,35 +1011,26 @@
 r();%0A%09%09f
-ilesInCurrentF
 older
+Files
 Iter = n
@@ -1034,24 +1034,33 @@
 = nextFolder
+FilesIter
 ();%0A%09%7D%0A%09%0A%09pu
@@ -1105,65 +1105,47 @@
 e (f
-ilesInCurrentFolderIter != null && ! filesInCurrentFolder
+olderFilesIter != null && ! folderFiles
 Iter
@@ -1162,35 +1162,26 @@
 )%0A%09%09%09%7B%09f
-ilesInCurrentF
 older
+Files
 Iter = n
@@ -1189,16 +1189,25 @@
 xtFolder
+FilesIter
 ();%0A%09%09%09%7D
@@ -1221,35 +1221,26 @@
 return f
-ilesInCurrentF
 older
+Files
 Iter != 
@@ -1254,17 +1254,17 @@
 / the lo
-p
+o
 p above 
@@ -1645,35 +1645,26 @@
 return f
-ilesInCurrentF
 older
+Files
 Iter.nex
@@ -1746,16 +1746,187 @@
 ;%0A%09%7D%0A  %0A
+%09/**%0A%09 * Returns an iterator over the files in the next folder (according to%0A%09 * its iterator), or null if there are no more folders whose contents%0A%09 * need listing.%0A%09 */%0A
 %09private
@@ -1951,16 +1951,25 @@
 xtFolder
+FilesIter
 () throw
@@ -2079,95 +2079,86 @@
 f (f
-ilesInCurrentFolder != null)%0A%09%09%09filesInCurrentFolder.close();%0A%09%09%0A%09%09filesInCurrentFolder
+olderFilesStream != null)%0A%09%09%09folderFilesStream.close();%0A%09%09%0A%09%09folderFilesStream
  = F
@@ -2350,35 +2350,32 @@
 return f
-ilesInCurrentFolder
+olderFilesStream
 .iterato
@@ -2432,16 +2432,22 @@
 %09folders
+Stream
 .close()
@@ -2459,60 +2459,54 @@
 f (f
-ilesInCurrentFolder != null)%0A%09%09%09filesInCurrentFolder
+olderFilesStream != null)%0A%09%09%09folderFilesStream
 .clo

Simplify variale names to make easier to understand code