In the code for traverseSubdirectory, for the FileTypeDirectory case, file is passed to haveSeenDirectory, addDirectoryToSeen, and traverseSubdirectory, but canonicalPath should be passed in for this to handle the symbolic link loops.
In the code for traverseSubdirectory, for the FileTypeDirectory case, file is passed to haveSeenDirectory, addDirectoryToSeen, and traverseSubdirectory, but canonicalPath should be passed in for this to handle the symbolic link loops.