@Override
    public void run() {
        try {
            directoryQueue.addLast(rootDirectory);

            final FileFilter fileTraversalFilter = new FileFilter() {
                @Override
                public boolean accept(File pathName) {
                    if (pathName.isDirectory()) {
                        directoryQueue.add(pathName);
                    } else if (pathName.isFile()) {
                        try {
                            taskQueue.push(new FileSearchBean(pathName));
                        } catch (InterruptedException e) {
                            logger.warn("File listing interrupted", e);
                            Thread.currentThread().interrupt();
                        }
                    }
                    return false;
                }
            };
            while (directoryQueue.size() > 0) {
                final File rootNode = directoryQueue.removeFirst();
                //noinspection ResultOfMethodCallIgnored
                rootNode.listFiles(fileTraversalFilter);
            }
        } finally {
            logger.info("Listing finished.");
            taskQueue.signalEndOfData();
        }
    }