//#define SelectorTrace

// FileSelector.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2008-2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved: <2011-August-05 11:03:11>
//
// ------------------------------------------------------------------
//
// This module implements a "file selector" that finds files based on a
// set of inclusion criteria, including filename, size, file time, and
// potentially file attributes.  The criteria are given in a string with
// a simple expression language. Examples:
//
// find all .txt files:
//     name = *.txt
//
// shorthand for the above
//     *.txt
//
// all files modified after January 1st, 2009
//     mtime > 2009-01-01
//
// All .txt files modified after the first of the year
//     name = *.txt  AND  mtime > 2009-01-01
//
// All .txt files modified after the first of the year, or any file with the archive bit set
//     (name = *.txt  AND  mtime > 2009-01-01) or (attribtues = A)
//
// All .txt files or any file greater than 1mb in size
//     (name = *.txt  or  size > 1mb)
//
// and so on.
// ------------------------------------------------------------------


using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Collections.Generic;
#if SILVERLIGHT
using System.Linq;
#endif

namespace OfficeOpenXml.Packaging.Ionic
{

    /// <summary>
    /// Enumerates the options for a logical conjunction. This enum is intended for use
    /// internally by the FileSelector class.
    /// </summary>
    internal enum LogicalConjunction
    {
        NONE,
        AND,
        OR,
        XOR,
    }

    internal enum WhichTime
    {
        atime,
        mtime,
        ctime,
    }


    internal enum ComparisonOperator
    {
        [Description(">")]
        GreaterThan,
        [Description(">=")]
        GreaterThanOrEqualTo,
        [Description("<")]
        LesserThan,
        [Description("<=")]
        LesserThanOrEqualTo,
        [Description("=")]
        EqualTo,
        [Description("!=")]
        NotEqualTo
    }


    internal abstract partial class SelectionCriterion
    {
        internal virtual bool Verbose
        {
            get;set;
        }
        internal abstract bool Evaluate(string filename);

        [System.Diagnostics.Conditional("SelectorTrace")]
        protected static void CriterionTrace(string format, params object[] args)
        {
            //System.Console.WriteLine("  " + format, args);
        }
    }


    internal partial class SizeCriterion : SelectionCriterion
    {
        internal ComparisonOperator Operator;
        internal Int64 Size;

        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("size ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Size.ToString());
            return sb.ToString();
        }

        internal override bool Evaluate(string filename)
        {
            System.IO.FileInfo fi = new System.IO.FileInfo(filename);
            CriterionTrace("SizeCriterion::Evaluate('{0}' [{1}])",
                           filename, this.ToString());
            return _Evaluate(fi.Length);
        }

        private bool _Evaluate(Int64 Length)
        {
            bool result = false;
            switch (Operator)
            {
                case ComparisonOperator.GreaterThanOrEqualTo:
                    result = Length >= Size;
                    break;
                case ComparisonOperator.GreaterThan:
                    result = Length > Size;
                    break;
                case ComparisonOperator.LesserThanOrEqualTo:
                    result = Length <= Size;
                    break;
                case ComparisonOperator.LesserThan:
                    result = Length < Size;
                    break;
                case ComparisonOperator.EqualTo:
                    result = Length == Size;
                    break;
                case ComparisonOperator.NotEqualTo:
                    result = Length != Size;
                    break;
                default:
                    throw new ArgumentException("Operator");
            }
            return result;
        }

    }



    internal partial class TimeCriterion : SelectionCriterion
    {
        internal ComparisonOperator Operator;
        internal WhichTime Which;
        internal DateTime Time;

        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Which.ToString()).Append(" ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Time.ToString("yyyy-MM-dd-HH:mm:ss"));
            return sb.ToString();
        }

        internal override bool Evaluate(string filename)
        {
            DateTime x;
            switch (Which)
            {
                case WhichTime.atime:
                    x = System.IO.File.GetLastAccessTime(filename).ToUniversalTime();
                    break;
                case WhichTime.mtime:
                    x = System.IO.File.GetLastWriteTime(filename).ToUniversalTime();
                    break;
                case WhichTime.ctime:
                    x = System.IO.File.GetCreationTime(filename).ToUniversalTime();
                    break;
                default:
                    throw new ArgumentException("Operator");
            }
            CriterionTrace("TimeCriterion({0},{1})= {2}", filename, Which.ToString(), x);
            return _Evaluate(x);
        }


        private bool _Evaluate(DateTime x)
        {
            bool result = false;
            switch (Operator)
            {
                case ComparisonOperator.GreaterThanOrEqualTo:
                    result = (x >= Time);
                    break;
                case ComparisonOperator.GreaterThan:
                    result = (x > Time);
                    break;
                case ComparisonOperator.LesserThanOrEqualTo:
                    result = (x <= Time);
                    break;
                case ComparisonOperator.LesserThan:
                    result = (x < Time);
                    break;
                case ComparisonOperator.EqualTo:
                    result = (x == Time);
                    break;
                case ComparisonOperator.NotEqualTo:
                    result = (x != Time);
                    break;
                default:
                    throw new ArgumentException("Operator");
            }

            CriterionTrace("TimeCriterion: {0}", result);
            return result;
        }
    }



    internal partial class NameCriterion : SelectionCriterion
    {
        private Regex _re;
        private String _regexString;
        internal ComparisonOperator Operator;
        private string _MatchingFileSpec;
        internal virtual string MatchingFileSpec
        {
            set
            {
                // workitem 8245
                if (Directory.Exists(value))
                {
                    _MatchingFileSpec = ".\\" + value + "\\*.*";
                }
                else
                {
                    _MatchingFileSpec = value;
                }

                _regexString = "^" +
                Regex.Escape(_MatchingFileSpec)
                    .Replace(@"\\\*\.\*", @"\\([^\.]+|.*\.[^\\\.]*)")
                    .Replace(@"\.\*", @"\.[^\\\.]*")
                    .Replace(@"\*", @".*")
                    //.Replace(@"\*", @"[^\\\.]*") // ill-conceived
                    .Replace(@"\?", @"[^\\\.]")
                    + "$";

                CriterionTrace("NameCriterion regexString({0})", _regexString);

                _re = new Regex(_regexString, RegexOptions.IgnoreCase);
            }
        }


        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("name ").Append(EnumUtil.GetDescription(Operator))
                .Append(" '")
                .Append(_MatchingFileSpec)
                .Append("'");
            return sb.ToString();
        }


        internal override bool Evaluate(string filename)
        {
            CriterionTrace("NameCriterion::Evaluate('{0}' pattern[{1}])",
                           filename, _MatchingFileSpec);
            return _Evaluate(filename);
        }

        private bool _Evaluate(string fullpath)
        {
            CriterionTrace("NameCriterion::Evaluate({0})", fullpath);
            // No slash in the pattern implicitly means recurse, which means compare to
            // filename only, not full path.
            String f = (_MatchingFileSpec.IndexOf('\\') == -1)
                ? System.IO.Path.GetFileName(fullpath)
                : fullpath; // compare to fullpath

            bool result = _re.IsMatch(f);

            if (Operator != ComparisonOperator.EqualTo)
                result = !result;
            return result;
        }
    }


    internal partial class TypeCriterion : SelectionCriterion
    {
        private char ObjectType;  // 'D' = Directory, 'F' = File
        internal ComparisonOperator Operator;
        internal string AttributeString
        {
            get
            {
                return ObjectType.ToString();
            }
            set
            {
                if (value.Length != 1 ||
                    (value[0]!='D' && value[0]!='F'))
                    throw new ArgumentException("Specify a single character: either D or F");
                ObjectType = value[0];
            }
        }

        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("type ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
            return sb.ToString();
        }

        internal override bool Evaluate(string filename)
        {
            CriterionTrace("TypeCriterion::Evaluate({0})", filename);

            bool result = (ObjectType == 'D')
                ? Directory.Exists(filename)
                : File.Exists(filename);

            if (Operator != ComparisonOperator.EqualTo)
                result = !result;
            return result;
        }
    }


#if !SILVERLIGHT
    internal partial class AttributesCriterion : SelectionCriterion
    {
        private FileAttributes _Attributes;
        internal ComparisonOperator Operator;
        internal string AttributeString
        {
            get
            {
                string result = "";
                if ((_Attributes & FileAttributes.Hidden) != 0)
                    result += "H";
                if ((_Attributes & FileAttributes.System) != 0)
                    result += "S";
                if ((_Attributes & FileAttributes.ReadOnly) != 0)
                    result += "R";
                if ((_Attributes & FileAttributes.Archive) != 0)
                    result += "A";
                if ((_Attributes & FileAttributes.ReparsePoint) != 0)
                    result += "L";
                if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
                    result += "I";
                return result;
            }

            set
            {
                _Attributes = FileAttributes.Normal;
                foreach (char c in value.ToUpper(CultureInfo.InvariantCulture))
                {
                    switch (c)
                    {
                        case 'H':
                            if ((_Attributes & FileAttributes.Hidden) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.Hidden;
                            break;

                        case 'R':
                            if ((_Attributes & FileAttributes.ReadOnly) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.ReadOnly;
                            break;

                        case 'S':
                            if ((_Attributes & FileAttributes.System) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.System;
                            break;

                        case 'A':
                            if ((_Attributes & FileAttributes.Archive) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.Archive;
                            break;

                        case 'I':
                            if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.NotContentIndexed;
                            break;

                        case 'L':
                            if ((_Attributes & FileAttributes.ReparsePoint) != 0)
                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
                            _Attributes |= FileAttributes.ReparsePoint;
                            break;

                        default:
                            throw new ArgumentException(value);
                    }
                }
            }
        }


        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("attributes ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
            return sb.ToString();
        }

        private bool _EvaluateOne(FileAttributes fileAttrs, FileAttributes criterionAttrs)
        {
            bool result = false;
            if ((_Attributes & criterionAttrs) == criterionAttrs)
                result = ((fileAttrs & criterionAttrs) == criterionAttrs);
            else
                result = true;
            return result;
        }



        internal override bool Evaluate(string filename)
        {
            // workitem 10191
            if (Directory.Exists(filename))
            {
                // Directories don't have file attributes, so the result
                // of an evaluation is always NO. This gets negated if
                // the operator is NotEqualTo.
                return (Operator != ComparisonOperator.EqualTo);
            }
#if NETCF
            FileAttributes fileAttrs = NetCfFile.GetAttributes(filename);
#else
            FileAttributes fileAttrs = System.IO.File.GetAttributes(filename);
#endif

            return _Evaluate(fileAttrs);
        }

        private bool _Evaluate(FileAttributes fileAttrs)
        {
            bool result = _EvaluateOne(fileAttrs, FileAttributes.Hidden);
            if (result)
                result = _EvaluateOne(fileAttrs, FileAttributes.System);
            if (result)
                result = _EvaluateOne(fileAttrs, FileAttributes.ReadOnly);
            if (result)
                result = _EvaluateOne(fileAttrs, FileAttributes.Archive);
            if (result)
                result = _EvaluateOne(fileAttrs, FileAttributes.NotContentIndexed);
            if (result)
                result = _EvaluateOne(fileAttrs, FileAttributes.ReparsePoint);

            if (Operator != ComparisonOperator.EqualTo)
                result = !result;

            return result;
        }
    }
#endif


    internal partial class CompoundCriterion : SelectionCriterion
    {
        internal LogicalConjunction Conjunction;
        internal SelectionCriterion Left;

        private SelectionCriterion _Right;
        internal SelectionCriterion Right
        {
            get { return _Right; }
            set
            {
                _Right = value;
                if (value == null)
                    Conjunction = LogicalConjunction.NONE;
                else if (Conjunction == LogicalConjunction.NONE)
                    Conjunction = LogicalConjunction.AND;
            }
        }


        internal override bool Evaluate(string filename)
        {
            bool result = Left.Evaluate(filename);
            switch (Conjunction)
            {
                case LogicalConjunction.AND:
                    if (result)
                        result = Right.Evaluate(filename);
                    break;
                case LogicalConjunction.OR:
                    if (!result)
                        result = Right.Evaluate(filename);
                    break;
                case LogicalConjunction.XOR:
                    result ^= Right.Evaluate(filename);
                    break;
                default:
                    throw new ArgumentException("Conjunction");
            }
            return result;
        }


        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("(")
            .Append((Left != null) ? Left.ToString() : "null")
            .Append(" ")
            .Append(Conjunction.ToString())
            .Append(" ")
            .Append((Right != null) ? Right.ToString() : "null")
            .Append(")");
            return sb.ToString();
        }
    }



    /// <summary>
    ///   FileSelector encapsulates logic that selects files from a source - a zip file
    ///   or the filesystem - based on a set of criteria.  This class is used internally
    ///   by the DotNetZip library, in particular for the AddSelectedFiles() methods.
    ///   This class can also be used independently of the zip capability in DotNetZip.
    /// </summary>
    ///
    /// <remarks>
    ///
    /// <para>
    ///   The FileSelector class is used internally by the ZipFile class for selecting
    ///   files for inclusion into the ZipFile, when the <see
    ///   cref="Ionic.Zip.ZipFile.AddSelectedFiles(String,String)"/> method, or one of
    ///   its overloads, is called.  It's also used for the <see
    ///   cref="Ionic.Zip.ZipFile.ExtractSelectedEntries(String)"/> methods.  Typically, an
    ///   application that creates or manipulates Zip archives will not directly
    ///   interact with the FileSelector class.
    /// </para>
    ///
    /// <para>
    ///   Some applications may wish to use the FileSelector class directly, to
    ///   select files from disk volumes based on a set of criteria, without creating or
    ///   querying Zip archives.  The file selection criteria include: a pattern to
    ///   match the filename; the last modified, created, or last accessed time of the
    ///   file; the size of the file; and the attributes of the file.
    /// </para>
    ///
    /// <para>
    ///   Consult the documentation for <see cref="SelectionCriteria"/>
    ///   for more information on specifying the selection criteria.
    /// </para>
    ///
    /// </remarks>
    internal partial class FileSelector
    {
        internal SelectionCriterion _Criterion;

#if NOTUSED
        /// <summary>
        ///   The default constructor.
        /// </summary>
        /// <remarks>
        ///   Typically, applications won't use this constructor.  Instead they'll
        ///   call the constructor that accepts a selectionCriteria string.  If you
        ///   use this constructor, you'll want to set the SelectionCriteria
        ///   property on the instance before calling SelectFiles().
        /// </remarks>
        protected FileSelector() { }
#endif
        /// <summary>
        ///   Constructor that allows the caller to specify file selection criteria.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This constructor allows the caller to specify a set of criteria for
        ///   selection of files.
        /// </para>
        ///
        /// <para>
        ///   See <see cref="FileSelector.SelectionCriteria"/> for a description of
        ///   the syntax of the selectionCriteria string.
        /// </para>
        ///
        /// <para>
        ///   By default the FileSelector will traverse NTFS Reparse Points.  To
        ///   change this, use <see cref="FileSelector(String,
        ///   bool)">FileSelector(String, bool)</see>.
        /// </para>
        /// </remarks>
        ///
        /// <param name="selectionCriteria">The criteria for file selection.</param>
        public FileSelector(String selectionCriteria)
        : this(selectionCriteria, true)
        {
        }

        /// <summary>
        ///   Constructor that allows the caller to specify file selection criteria.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This constructor allows the caller to specify a set of criteria for
        ///   selection of files.
        /// </para>
        ///
        /// <para>
        ///   See <see cref="FileSelector.SelectionCriteria"/> for a description of
        ///   the syntax of the selectionCriteria string.
        /// </para>
        /// </remarks>
        ///
        /// <param name="selectionCriteria">The criteria for file selection.</param>
        /// <param name="traverseDirectoryReparsePoints">
        /// whether to traverse NTFS reparse points (junctions).
        /// </param>
        public FileSelector(String selectionCriteria, bool traverseDirectoryReparsePoints)
        {
            if (!String.IsNullOrEmpty(selectionCriteria))
                _Criterion = _ParseCriterion(selectionCriteria);
            TraverseReparsePoints = traverseDirectoryReparsePoints;
        }



        /// <summary>
        ///   The string specifying which files to include when retrieving.
        /// </summary>
        /// <remarks>
        ///
        /// <para>
        ///   Specify the criteria in statements of 3 elements: a noun, an operator,
        ///   and a value.  Consider the string "name != *.doc" .  The noun is
        ///   "name".  The operator is "!=", implying "Not Equal".  The value is
        ///   "*.doc".  That criterion, in English, says "all files with a name that
        ///   does not end in the .doc extension."
        /// </para>
        ///
        /// <para>
        ///   Supported nouns include "name" (or "filename") for the filename;
        ///   "atime", "mtime", and "ctime" for last access time, last modfied time,
        ///   and created time of the file, respectively; "attributes" (or "attrs")
        ///   for the file attributes; "size" (or "length") for the file length
        ///   (uncompressed); and "type" for the type of object, either a file or a
        ///   directory.  The "attributes", "type", and "name" nouns all support =
        ///   and != as operators.  The "size", "atime", "mtime", and "ctime" nouns
        ///   support = and !=, and &gt;, &gt;=, &lt;, &lt;= as well.  The times are
        ///   taken to be expressed in local time.
        /// </para>
        ///
        /// <para>
        ///   Specify values for the file attributes as a string with one or more of
        ///   the characters H,R,S,A,I,L in any order, implying file attributes of
        ///   Hidden, ReadOnly, System, Archive, NotContextIndexed, and ReparsePoint
        ///   (symbolic link) respectively.
        /// </para>
        ///
        /// <para>
        ///   To specify a time, use YYYY-MM-DD-HH:mm:ss or YYYY/MM/DD-HH:mm:ss as
        ///   the format.  If you omit the HH:mm:ss portion, it is assumed to be
        ///   00:00:00 (midnight).
        /// </para>
        ///
        /// <para>
        ///   The value for a size criterion is expressed in integer quantities of
        ///   bytes, kilobytes (use k or kb after the number), megabytes (m or mb),
        ///   or gigabytes (g or gb).
        /// </para>
        ///
        /// <para>
        ///   The value for a name is a pattern to match against the filename,
        ///   potentially including wildcards.  The pattern follows CMD.exe glob
        ///   rules: * implies one or more of any character, while ?  implies one
        ///   character.  If the name pattern contains any slashes, it is matched to
        ///   the entire filename, including the path; otherwise, it is matched
        ///   against only the filename without the path.  This means a pattern of
        ///   "*\*.*" matches all files one directory level deep, while a pattern of
        ///   "*.*" matches all files in all directories.
        /// </para>
        ///
        /// <para>
        ///   To specify a name pattern that includes spaces, use single quotes
        ///   around the pattern.  A pattern of "'* *.*'" will match all files that
        ///   have spaces in the filename.  The full criteria string for that would
        ///   be "name = '* *.*'" .
        /// </para>
        ///
        /// <para>
        ///   The value for a type criterion is either F (implying a file) or D
        ///   (implying a directory).
        /// </para>
        ///
        /// <para>
        ///   Some examples:
        /// </para>
        ///
        /// <list type="table">
        ///   <listheader>
        ///     <term>criteria</term>
        ///     <description>Files retrieved</description>
        ///   </listheader>
        ///
        ///   <item>
        ///     <term>name != *.xls </term>
        ///     <description>any file with an extension that is not .xls
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>name = *.mp3 </term>
        ///     <description>any file with a .mp3 extension.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>*.mp3</term>
        ///     <description>(same as above) any file with a .mp3 extension.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>attributes = A </term>
        ///     <description>all files whose attributes include the Archive bit.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>attributes != H </term>
        ///     <description>all files whose attributes do not include the Hidden bit.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>mtime > 2009-01-01</term>
        ///     <description>all files with a last modified time after January 1st, 2009.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>ctime > 2009/01/01-03:00:00</term>
        ///     <description>all files with a created time after 3am (local time),
        ///     on January 1st, 2009.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>size > 2gb</term>
        ///     <description>all files whose uncompressed size is greater than 2gb.
        ///     </description>
        ///   </item>
        ///
        ///   <item>
        ///     <term>type = D</term>
        ///     <description>all directories in the filesystem. </description>
        ///   </item>
        ///
        /// </list>
        ///
        /// <para>
        ///   You can combine criteria with the conjunctions AND, OR, and XOR. Using
        ///   a string like "name = *.txt AND size &gt;= 100k" for the
        ///   selectionCriteria retrieves entries whose names end in .txt, and whose
        ///   uncompressed size is greater than or equal to 100 kilobytes.
        /// </para>
        ///
        /// <para>
        ///   For more complex combinations of criteria, you can use parenthesis to
        ///   group clauses in the boolean logic.  Absent parenthesis, the
        ///   precedence of the criterion atoms is determined by order of
        ///   appearance.  Unlike the C# language, the AND conjunction does not take
        ///   precendence over the logical OR.  This is important only in strings
        ///   that contain 3 or more criterion atoms.  In other words, "name = *.txt
        ///   and size &gt; 1000 or attributes = H" implies "((name = *.txt AND size
        ///   &gt; 1000) OR attributes = H)" while "attributes = H OR name = *.txt
        ///   and size &gt; 1000" evaluates to "((attributes = H OR name = *.txt)
        ///   AND size &gt; 1000)".  When in doubt, use parenthesis.
        /// </para>
        ///
        /// <para>
        ///   Using time properties requires some extra care. If you want to
        ///   retrieve all entries that were last updated on 2009 February 14,
        ///   specify "mtime &gt;= 2009-02-14 AND mtime &lt; 2009-02-15".  Read this
        ///   to say: all files updated after 12:00am on February 14th, until
        ///   12:00am on February 15th.  You can use the same bracketing approach to
        ///   specify any time period - a year, a month, a week, and so on.
        /// </para>
        ///
        /// <para>
        ///   The syntax allows one special case: if you provide a string with no
        ///   spaces, it is treated as a pattern to match for the filename.
        ///   Therefore a string like "*.xls" will be equivalent to specifying "name
        ///   = *.xls".  This "shorthand" notation does not work with compound
        ///   criteria.
        /// </para>
        ///
        /// <para>
        ///   There is no logic in this class that insures that the inclusion
        ///   criteria are internally consistent.  For example, it's possible to
        ///   specify criteria that says the file must have a size of less than 100
        ///   bytes, as well as a size that is greater than 1000 bytes.  Obviously
        ///   no file will ever satisfy such criteria, but this class does not check
        ///   for or detect such inconsistencies.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <exception cref="System.Exception">
        ///   Thrown in the setter if the value has an invalid syntax.
        /// </exception>
        public String SelectionCriteria
        {
            get
            {
                if (_Criterion == null) return null;
                return _Criterion.ToString();
            }
            set
            {
                if (value == null) _Criterion = null;
                else if (value.Trim() == "") _Criterion = null;
                else
                    _Criterion = _ParseCriterion(value);
            }
        }

        /// <summary>
        ///  Indicates whether searches will traverse NTFS reparse points, like Junctions.
        /// </summary>
        public bool TraverseReparsePoints
        {
            get; set;
        }


        private enum ParseState
        {
            Start,
            OpenParen,
            CriterionDone,
            ConjunctionPending,
            Whitespace,
        }


        private static class RegexAssertions
        {
            public static readonly String PrecededByOddNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*'[^']*)";
            public static readonly String FollowedByOddNumberOfSingleQuotesAndLineEnd = "(?=[^']*'(?:[^']*'[^']*')*[^']*$)";

            public static readonly String PrecededByEvenNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*[^']*)";
            public static readonly String FollowedByEvenNumberOfSingleQuotesAndLineEnd = "(?=(?:[^']*'[^']*')*[^']*$)";
        }


        private static string NormalizeCriteriaExpression(string source)
        {
            // The goal here is to normalize the criterion expression. At output, in
            // the transformed criterion string, every significant syntactic element
            // - a property element, grouping paren for the boolean logic, operator
            // ( = < > != ), conjunction, or property value - will be separated from
            // its neighbors by at least one space. Thus,
            //
            // before                         after
            // -------------------------------------------------------------------
            // name=*.txt                     name = *.txt
            // (size>100)AND(name=*.txt)      ( size > 100 ) AND ( name = *.txt )
            //
            // This is relatively straightforward using regular expression
            // replacement. This method applies a distinct regex pattern and
            // corresponding replacement string for each one of a number of cases:
            // an open paren followed by a word; a word followed by a close-paren; a
            // pair of open parens; a close paren followed by a word (which should
            // then be followed by an open paren). And so on. These patterns and
            // replacements are all stored in prPairs. By applying each of these
            // regex replacements in turn, we get the transformed string. Easy.
            //
            // The resulting "normalized" criterion string, is then used as the
            // subject that gets parsed, by splitting the string into tokens that
            // are separated by spaces.  Here, there's a twist. The spaces within
            // single-quote delimiters do not delimit distinct tokens.  So, this
            // normalization method temporarily replaces those spaces with
            // ASCII 6 (0x06), a control character which is not a legal
            // character in a filename. The parsing logic that happens later will
            // revert that change, restoring the original value of the filename
            // specification.
            //
            // To illustrate, for a "before" string of [(size>100)AND(name='Name
            // (with Parens).txt')] , the "after" string is [( size > 100 ) AND
            // ( name = 'Name\u0006(with\u0006Parens).txt' )].
            //

            string[][] prPairs =
                {
                    // A. opening double parens - insert a space between them
                    new string[] { @"([^']*)\(\(([^']+)", "$1( ($2" },

                    // B. closing double parens - insert a space between
                    new string[] { @"(.)\)\)", "$1) )" },

                    // C. single open paren with a following word - insert a space between
                    new string[] { @"\((\S)", "( $1" },

                    // D. single close paren with a preceding word - insert a space between the two
                    new string[] { @"(\S)\)", "$1 )" },

                    // E. close paren at line start?, insert a space before the close paren
                    // this seems like a degenerate case.  I don't recall why it's here.
                    new string[] { @"^\)", " )" },

                    // F. a word (likely a conjunction) followed by an open paren - insert a space between
                    new string[] { @"(\S)\(", "$1 (" },

                    // G. single close paren followed by word - insert a paren after close paren
                    new string[] { @"\)(\S)", ") $1" },

                    // H. insert space between = and a following single quote
                    //new string[] { @"(=|!=)('[^']*')", "$1 $2" },
                    new string[] { @"(=)('[^']*')", "$1 $2" },

                    // I. insert space between property names and the following operator
                    //new string[] { @"([^ ])([><(?:!=)=])", "$1 $2" },
                    new string[] { @"([^ !><])(>|<|!=|=)", "$1 $2" },

                    // J. insert spaces between operators and the following values
                    //new string[] { @"([><(?:!=)=])([^ ])", "$1 $2" },
                    new string[] { @"(>|<|!=|=)([^ =])", "$1 $2" },

                    // K. replace fwd slash with backslash
                    new string[] { @"/", "\\" },
                };

            string interim = source;

            for (int i=0; i < prPairs.Length; i++)
            {
                //char caseIdx = (char)('A' + i);
                string pattern = RegexAssertions.PrecededByEvenNumberOfSingleQuotes +
                    prPairs[i][0] +
                    RegexAssertions.FollowedByEvenNumberOfSingleQuotesAndLineEnd;

                interim = Regex.Replace(interim, pattern, prPairs[i][1]);
            }

            // match a fwd slash, followed by an odd number of single quotes.
            // This matches fwd slashes only inside a pair of single quote delimiters,
            // eg, a filename.  This must be done as well as the case above, to handle
            // filenames specified inside quotes as well as filenames without quotes.
            var regexPattern = @"/" +
                                RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;
            // replace with backslash
            interim = Regex.Replace(interim, regexPattern, "\\");

            // match a space, followed by an odd number of single quotes.
            // This matches spaces only inside a pair of single quote delimiters.
            regexPattern = " " +
                RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;

            // Replace all spaces that appear inside single quotes, with
            // ascii 6.  This allows a split on spaces to get tokens in
            // the expression. The split will not split any filename or
            // wildcard that appears within single quotes. After tokenizing, we
            // need to replace ascii 6 with ascii 32 to revert the
            // spaces within quotes.
            return Regex.Replace(interim, regexPattern, "\u0006");
        }


        private static SelectionCriterion _ParseCriterion(String s)
        {
            if (s == null) return null;

            // inject spaces after open paren and before close paren, etc
            s = NormalizeCriteriaExpression(s);

            // no spaces in the criteria is shorthand for filename glob
            if (s.IndexOf(" ") == -1)
                s = "name = " + s;

            // split the expression into tokens
            string[] tokens = s.Trim().Split(' ', '\t');

            if (tokens.Length < 3) throw new ArgumentException(s);

            SelectionCriterion current = null;

            LogicalConjunction pendingConjunction = LogicalConjunction.NONE;

            ParseState state;
            var stateStack = new System.Collections.Generic.Stack<ParseState>();
            var critStack = new System.Collections.Generic.Stack<SelectionCriterion>();
            stateStack.Push(ParseState.Start);

            for (int i = 0; i < tokens.Length; i++)
            {
                string tok1 = tokens[i].ToLower(CultureInfo.InvariantCulture);
                switch (tok1)
                {
                    case "and":
                    case "xor":
                    case "or":
                        state = stateStack.Peek();
                        if (state != ParseState.CriterionDone)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        if (tokens.Length <= i + 3)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        pendingConjunction = (LogicalConjunction)Enum.Parse(typeof(LogicalConjunction), tokens[i].ToUpper(CultureInfo.InvariantCulture), true);
                        current = new CompoundCriterion { Left = current, Right = null, Conjunction = pendingConjunction };
                        stateStack.Push(state);
                        stateStack.Push(ParseState.ConjunctionPending);
                        critStack.Push(current);
                        break;

                    case "(":
                        state = stateStack.Peek();
                        if (state != ParseState.Start && state != ParseState.ConjunctionPending && state != ParseState.OpenParen)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        if (tokens.Length <= i + 4)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        stateStack.Push(ParseState.OpenParen);
                        break;

                    case ")":
                        state = stateStack.Pop();
                        if (stateStack.Peek() != ParseState.OpenParen)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        stateStack.Pop();
                        stateStack.Push(ParseState.CriterionDone);
                        break;

                    case "atime":
                    case "ctime":
                    case "mtime":
                        if (tokens.Length <= i + 2)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        DateTime t;
                        try
                        {
                            t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd-HH:mm:ss", null);
                        }
                        catch (FormatException)
                        {
                            try
                            {
                                t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd-HH:mm:ss", null);
                            }
                            catch (FormatException)
                            {
                                try
                                {
                                    t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd", null);
                                }
                                catch (FormatException)
                                {
                                    try
                                    {
                                        t = DateTime.ParseExact(tokens[i + 2], "MM/dd/yyyy", null);
                                    }
                                    catch (FormatException)
                                    {
                                        t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd", null);
                                    }
                                }
                            }
                        }
                        t= DateTime.SpecifyKind(t, DateTimeKind.Local).ToUniversalTime();
                        current = new TimeCriterion
                        {
                            Which = (WhichTime)Enum.Parse(typeof(WhichTime), tokens[i], true),
                            Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]),
                            Time = t
                        };
                        i += 2;
                        stateStack.Push(ParseState.CriterionDone);
                        break;


                    case "length":
                    case "size":
                        if (tokens.Length <= i + 2)
                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                        Int64 sz = 0;
                        string v = tokens[i + 2];
                        if (v.EndsWith("K", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024;
                        else if (v.EndsWith("KB", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024;
                        else if (v.EndsWith("M", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024;
                        else if (v.EndsWith("MB", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024;
                        else if (v.EndsWith("G", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024 * 1024;
                        else if (v.EndsWith("GB", StringComparison.InvariantCultureIgnoreCase))
                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024 * 1024;
                        else sz = Int64.Parse(tokens[i + 2]);

                        current = new SizeCriterion
                        {
                            Size = sz,
                            Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1])
                        };
                        i += 2;
                        stateStack.Push(ParseState.CriterionDone);
                        break;

                    case "filename":
                    case "name":
                        {
                            if (tokens.Length <= i + 2)
                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                            ComparisonOperator c =
                                (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);

                            if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                            string m = tokens[i + 2];

                            // handle single-quoted filespecs (used to include
                            // spaces in filename patterns)
                            if (m.StartsWith("'") && m.EndsWith("'"))
                            {
                                // trim off leading and trailing single quotes and
                                // revert the control characters to spaces.
                                m = m.Substring(1, m.Length - 2)
                                    .Replace("\u0006", " ");
                            }

                            // if (m.StartsWith("'"))
                            //     m = m.Replace("\u0006", " ");

                            current = new NameCriterion
                            {
                                MatchingFileSpec = m,
                                Operator = c
                            };
                            i += 2;
                            stateStack.Push(ParseState.CriterionDone);
                        }
                        break;

#if !SILVERLIGHT
                    case "attrs":
                    case "attributes":
#endif
                    case "type":
                        {
                            if (tokens.Length <= i + 2)
                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

                            ComparisonOperator c =
                                (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);

                            if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));

#if SILVERLIGHT
                            current = (SelectionCriterion) new TypeCriterion
                                    {
                                        AttributeString = tokens[i + 2],
                                        Operator = c
                                    };
#else
                            current = (tok1 == "type")
                                ? (SelectionCriterion) new TypeCriterion
                                    {
                                        AttributeString = tokens[i + 2],
                                        Operator = c
                                    }
                                : (SelectionCriterion) new AttributesCriterion
                                    {
                                        AttributeString = tokens[i + 2],
                                        Operator = c
                                    };
#endif
                            i += 2;
                            stateStack.Push(ParseState.CriterionDone);
                        }
                        break;

                    case "":
                        // NOP
                        stateStack.Push(ParseState.Whitespace);
                        break;

                    default:
                        throw new ArgumentException("'" + tokens[i] + "'");
                }

                state = stateStack.Peek();
                if (state == ParseState.CriterionDone)
                {
                    stateStack.Pop();
                    if (stateStack.Peek() == ParseState.ConjunctionPending)
                    {
                        while (stateStack.Peek() == ParseState.ConjunctionPending)
                        {
                            var cc = critStack.Pop() as CompoundCriterion;
                            cc.Right = current;
                            current = cc; // mark the parent as current (walk up the tree)
                            stateStack.Pop();   // the conjunction is no longer pending

                            state = stateStack.Pop();
                            if (state != ParseState.CriterionDone)
                                throw new ArgumentException("??");
                        }
                    }
                    else stateStack.Push(ParseState.CriterionDone);  // not sure?
                }

                if (state == ParseState.Whitespace)
                    stateStack.Pop();
            }

            return current;
        }


        /// <summary>
        /// Returns a string representation of the FileSelector object.
        /// </summary>
        /// <returns>The string representation of the boolean logic statement of the file
        /// selection criteria for this instance. </returns>
        public override String ToString()
        {
            return "FileSelector("+_Criterion.ToString()+")";
        }


        private bool Evaluate(string filename)
        {
            // dinoch - Thu, 11 Feb 2010  18:34
            SelectorTrace("Evaluate({0})", filename);
            bool result = _Criterion.Evaluate(filename);
            return result;
        }

        [System.Diagnostics.Conditional("SelectorTrace")]
        private void SelectorTrace(string format, params object[] args)
        {
            if (_Criterion != null && _Criterion.Verbose)
                System.Console.WriteLine(format, args);
        }

        /// <summary>
        ///   Returns the names of the files in the specified directory
        ///   that fit the selection criteria specified in the FileSelector.
        /// </summary>
        ///
        /// <remarks>
        ///   This is equivalent to calling <see cref="SelectFiles(String, bool)"/>
        ///   with recurseDirectories = false.
        /// </remarks>
        ///
        /// <param name="directory">
        ///   The name of the directory over which to apply the FileSelector
        ///   criteria.
        /// </param>
        ///
        /// <returns>
        ///   A collection of strings containing fully-qualified pathnames of files
        ///   that match the criteria specified in the FileSelector instance.
        /// </returns>
        public System.Collections.Generic.ICollection<String> SelectFiles(String directory)
        {
            return SelectFiles(directory, false);
        }


        /// <summary>
        ///   Returns the names of the files in the specified directory that fit the
        ///   selection criteria specified in the FileSelector, optionally recursing
        ///   through subdirectories.
        /// </summary>
        ///
        /// <remarks>
        ///   This method applies the file selection criteria contained in the
        ///   FileSelector to the files contained in the given directory, and
        ///   returns the names of files that conform to the criteria.
        /// </remarks>
        ///
        /// <param name="directory">
        ///   The name of the directory over which to apply the FileSelector
        ///   criteria.
        /// </param>
        ///
        /// <param name="recurseDirectories">
        ///   Whether to recurse through subdirectories when applying the file
        ///   selection criteria.
        /// </param>
        ///
        /// <returns>
        ///   A collection of strings containing fully-qualified pathnames of files
        ///   that match the criteria specified in the FileSelector instance.
        /// </returns>
        public System.Collections.ObjectModel.ReadOnlyCollection<String>
            SelectFiles(String directory,
                        bool recurseDirectories)
        {
            if (_Criterion == null)
                throw new ArgumentException("SelectionCriteria has not been set");

            var list = new List<String>();
            try
            {
                if (Directory.Exists(directory))
                {
                    String[] filenames = Directory.GetFiles(directory);

                    // add the files:
                    foreach (String filename in filenames)
                    {
                        if (Evaluate(filename))
                            list.Add(filename);
                    }

                    if (recurseDirectories)
                    {
                        // add the subdirectories:
                        String[] dirnames = Directory.GetDirectories(directory);
                        foreach (String dir in dirnames)
                        {
                            if (this.TraverseReparsePoints
#if !SILVERLIGHT
                                || ((File.GetAttributes(dir) & FileAttributes.ReparsePoint) == 0)
#endif
                                )
                            {
                                // workitem 10191
                                if (Evaluate(dir)) list.Add(dir);
                                list.AddRange(this.SelectFiles(dir, recurseDirectories));
                            }
                        }
                    }
                }
            }
            // can get System.UnauthorizedAccessException here
            catch (System.UnauthorizedAccessException)
            {
            }
            catch (System.IO.IOException)
            {
            }

            return list.AsReadOnly();
        }
    }



    /// <summary>
    /// Summary description for EnumUtil.
    /// </summary>
    internal sealed class EnumUtil
    {
        private EnumUtil() { }
        /// <summary>
        ///   Returns the value of the DescriptionAttribute if the specified Enum
        ///   value has one.  If not, returns the ToString() representation of the
        ///   Enum value.
        /// </summary>
        /// <param name="value">The Enum to get the description for</param>
        /// <returns></returns>
        internal static string GetDescription(System.Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attributes.Length > 0)
                return attributes[0].Description;
            else
                return value.ToString();
        }

        /// <summary>
        ///   Converts the string representation of the name or numeric value of one
        ///   or more enumerated constants to an equivalent enumerated object.
        ///   Note: use the DescriptionAttribute on enum values to enable this.
        /// </summary>
        /// <param name="enumType">The System.Type of the enumeration.</param>
        /// <param name="stringRepresentation">
        ///   A string containing the name or value to convert.
        /// </param>
        /// <returns></returns>
        internal static object Parse(Type enumType, string stringRepresentation)
        {
            return Parse(enumType, stringRepresentation, false);
        }


#if SILVERLIGHT
       public static System.Enum[] GetEnumValues(Type type)
        {
            if (!type.IsEnum)
                throw new ArgumentException("not an enum");

            return (
              from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
              where field.IsLiteral
              select (System.Enum)field.GetValue(null)
            ).ToArray();
        }

        public static string[] GetEnumStrings<T>()
        {
            var type = typeof(T);
            if (!type.IsEnum)
                throw new ArgumentException("not an enum");

            return (
              from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
              where field.IsLiteral
              select field.Name
            ).ToArray();
        }
#endif

        /// <summary>
        ///   Converts the string representation of the name or numeric value of one
        ///   or more enumerated constants to an equivalent enumerated object.  A
        ///   parameter specified whether the operation is case-sensitive.  Note:
        ///   use the DescriptionAttribute on enum values to enable this.
        /// </summary>
        /// <param name="enumType">The System.Type of the enumeration.</param>
        /// <param name="stringRepresentation">
        ///   A string containing the name or value to convert.
        /// </param>
        /// <param name="ignoreCase">
        ///   Whether the operation is case-sensitive or not.</param>
        /// <returns></returns>
        internal static object Parse(Type enumType, string stringRepresentation, bool ignoreCase)
        {
            if (ignoreCase)
                stringRepresentation = stringRepresentation.ToLower(CultureInfo.InvariantCulture);

#if SILVERLIGHT
            foreach (System.Enum enumVal in GetEnumValues(enumType))
#else
            foreach (System.Enum enumVal in System.Enum.GetValues(enumType))
#endif
            {
                string description = GetDescription(enumVal);
                if (ignoreCase)
                    description = description.ToLower(CultureInfo.InvariantCulture);
                if (description == stringRepresentation)
                    return enumVal;
            }

            return System.Enum.Parse(enumType, stringRepresentation, ignoreCase);
        }
    }


#if DEMO
    internal class DemonstrateFileSelector
    {
        private string _directory;
        private bool _recurse;
        private bool _traverse;
        private bool _verbose;
        private string _selectionCriteria;
        private FileSelector f;

        public DemonstrateFileSelector()
        {
            this._directory = ".";
            this._recurse = true;
        }

        public DemonstrateFileSelector(string[] args) : this()
        {
            for (int i = 0; i < args.Length; i++)
            {
                switch(args[i])
                {
                case"-?":
                    Usage();
                    Environment.Exit(0);
                    break;
                case "-d":
                    i++;
                    if (args.Length <= i)
                        throw new ArgumentException("-directory");
                    this._directory = args[i];
                    break;
                case "-norecurse":
                    this._recurse = false;
                    break;

                case "-j-":
                    this._traverse = false;
                    break;

                case "-j+":
                    this._traverse = true;
                    break;

                case "-v":
                    this._verbose = true;
                    break;

                default:
                    if (this._selectionCriteria != null)
                        throw new ArgumentException(args[i]);
                    this._selectionCriteria = args[i];
                    break;
                }

                if (this._selectionCriteria != null)
                    this.f = new FileSelector(this._selectionCriteria);
            }
        }


        public static void Main(string[] args)
        {
            try
            {
                Console.WriteLine();
                new DemonstrateFileSelector(args).Run();
            }
            catch (Exception exc1)
            {
                Console.WriteLine("Exception: {0}", exc1.ToString());
                Usage();
            }
        }


        public void Run()
        {
            if (this.f == null)
                this.f = new FileSelector("name = *.jpg AND (size > 1000 OR atime < 2009-02-14-01:00:00)");

            this.f.TraverseReparsePoints = _traverse;
            this.f.Verbose = this._verbose;
            Console.WriteLine();
            Console.WriteLine(new String(':', 88));
            Console.WriteLine("Selecting files:\n" + this.f.ToString());
            var files = this.f.SelectFiles(this._directory, this._recurse);
            if (files.Count == 0)
            {
                Console.WriteLine("no files.");
            }
            else
            {
                Console.WriteLine("files: {0}", files.Count);
                foreach (string file in files)
                {
                    Console.WriteLine("  " + file);
                }
            }
        }

        public static void Usage()
        {
            Console.WriteLine("FileSelector: select files based on selection criteria.\n");
            Console.WriteLine("Usage:\n  FileSelector <selectionCriteria>  [options]\n" +
                              "\n" +
                              "  -d <dir>   directory to select from (Default .)\n" +
                              " -norecurse  don't recurse into subdirs\n" +
                              " -j-         don't traverse junctions\n" +
                              " -v          verbose output\n");
        }
    }

#endif



}


