/// <exception cref="System.IO.IOException"/>
        /// <exception cref="Com.Drew.Imaging.Jpeg.JpegProcessingException"/>
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                System.Console.Error.Println("Expects one or more directories as arguments.");
                System.Environment.Exit(1);
            }
            IList <string> directories = new AList <string>();

            ProcessAllImagesInFolderUtility.FileHandler handler = null;
            foreach (string arg in args)
            {
                if (Sharpen.Runtime.EqualsIgnoreCase(arg, "-text"))
                {
                    // If "-text" is specified, write the discovered metadata into a sub-folder relative to the image
                    handler = new ProcessAllImagesInFolderUtility.TextFileOutputHandler();
                }
                else
                {
                    if (Sharpen.Runtime.EqualsIgnoreCase(arg, "-markdown"))
                    {
                        // If "-markdown" is specified, write a summary table in markdown format to standard out
                        handler = new ProcessAllImagesInFolderUtility.MarkdownTableOutputHandler();
                    }
                    else
                    {
                        if (Sharpen.Runtime.EqualsIgnoreCase(arg, "-unknown"))
                        {
                            // If "-unknown" is specified, write CSV tallying unknown tag counts
                            handler = new ProcessAllImagesInFolderUtility.UnknownTagHandler();
                        }
                        else
                        {
                            // Treat this argument as a directory
                            directories.Add(arg);
                        }
                    }
                }
            }
            if (handler == null)
            {
                handler = new ProcessAllImagesInFolderUtility.BasicFileHandler();
            }
            long start = Runtime.NanoTime();

            // Order alphabetically so that output is stable across invocations
            directories.Sort();
            foreach (string directory in directories)
            {
                ProcessDirectory(new FilePath(directory), handler, string.Empty);
            }
            handler.OnCompleted();
            System.Console.Out.Println(Sharpen.Extensions.StringFormat("Completed in %d ms", (Runtime.NanoTime() - start) / 1000000));
        }
 private static void ProcessDirectory(FilePath path, ProcessAllImagesInFolderUtility.FileHandler handler)
 {
     string[] pathItems = path.List();
     if (pathItems == null)
     {
         return;
     }
     // Order alphabetically so that output is stable across invocations
     Arrays.Sort(pathItems);
     foreach (string pathItem in pathItems)
     {
         FilePath file = new FilePath(path, pathItem);
         if (file.IsDirectory())
         {
             ProcessDirectory(file, handler);
         }
         else
         {
             if (handler.ShouldProcess(file))
             {
                 handler.OnProcessingStarting(file);
                 // Read metadata
                 Com.Drew.Metadata.Metadata metadata;
                 try
                 {
                     metadata = ImageMetadataReader.ReadMetadata(file);
                 }
                 catch (Exception t)
                 {
                     handler.OnException(file, t);
                     continue;
                 }
                 handler.OnExtracted(file, metadata);
             }
         }
     }
 }