/// <summary>
 /// Retrieve entries from the zipfile by specified criteria.
 /// </summary>
 ///
 /// <remarks>
 /// <para>
 /// This method allows callers to retrieve the collection of entries from the zipfile
 /// that fit the specified criteria.  The criteria are described in a string format, and
 /// can include patterns for the filename; constraints on the size of the entry;
 /// constraints on the last modified, created, or last accessed time for the file
 /// described by the entry; or the attributes of the entry.
 /// </para>
 ///
 /// <para>
 /// For details on the syntax for the selectionCriteria parameter, see <see
 /// cref="AddSelectedFiles(String)"/>.
 /// </para>
 ///
 /// <para>
 /// This method is intended for use with a ZipFile that has been read from storage.
 /// When creating a new ZipFile, this method will work only after the ZipArchive has
 /// been Saved to the disk (the ZipFile class subsequently and implicitly reads the Zip
 /// archive from storage.)  Calling SelectEntries on a ZipFile that has not yet been
 /// saved will deliver undefined results.
 /// </para>
 /// </remarks>
 ///
 /// <exception cref="System.Exception">
 /// Thrown if selectionCriteria has an invalid syntax.
 /// </exception>
 ///
 /// <example>
 /// <code>
 /// using (ZipFile zip1 = ZipFile.Read(ZipFileName))
 /// {
 ///     var UpdatedPhotoShopFiles = zip1.SelectEntries("*.psd", "UpdatedFiles");
 ///     foreach (ZipEntry e in UpdatedPhotoShopFiles)
 ///     {
 ///         // prompt for extract here
 ///         if (WantExtract(e.FileName))
 ///             e.Extract();
 ///     }
 /// }
 /// </code>
 /// <code lang="VB">
 /// Using zip1 As ZipFile = ZipFile.Read(ZipFileName)
 ///     Dim UpdatedPhotoShopFiles As ICollection(Of ZipEntry) = zip1.SelectEntries("*.psd", "UpdatedFiles")
 ///     Dim e As ZipEntry
 ///     For Each e In UpdatedPhotoShopFiles
 ///         ' prompt for extract here
 ///         If Me.WantExtract(e.FileName) Then
 ///             e.Extract
 ///         End If
 ///     Next
 /// End Using
 /// </code>
 /// </example>
 /// <param name="selectionCriteria">the string that specifies which entries to select</param>
 ///
 /// <param name="directoryPathInArchive">
 /// the directory in the archive from which to select entries. If null, then
 /// all directories in the archive are used.
 /// </param>
 ///
 /// <returns>a collection of ZipEntry objects that conform to the inclusion spec</returns>
 public ICollection<ZipEntry> SelectEntries(String selectionCriteria, string directoryPathInArchive)
 {
     Alienlab.FileSelector ff = new Alienlab.FileSelector(selectionCriteria,
                                                    AddDirectoryWillTraverseReparsePoints);
     return ff.SelectEntries(this, directoryPathInArchive);
 }
        private void _AddOrUpdateSelectedFiles(String selectionCriteria,
                                               String directoryOnDisk,
                                               String directoryPathInArchive,
                                               bool recurseDirectories,
                                               bool wantUpdate)
        {
            if (directoryOnDisk == null && (Directory.Exists(selectionCriteria)))
            {
                directoryOnDisk = selectionCriteria;
                selectionCriteria = "*.*";
            }
            else if (String.IsNullOrEmpty(directoryOnDisk))
            {
                directoryOnDisk = ".";
            }

            // workitem 9176
            while (directoryOnDisk.EndsWith("\\")) directoryOnDisk = directoryOnDisk.Substring(0, directoryOnDisk.Length - 1);
            if (Verbose) StatusMessageTextWriter.WriteLine("adding selection '{0}' from dir '{1}'...",
                                                               selectionCriteria, directoryOnDisk);
            Alienlab.FileSelector ff = new Alienlab.FileSelector(selectionCriteria,
                                                           AddDirectoryWillTraverseReparsePoints);
            var itemsToAdd = ff.SelectFiles(directoryOnDisk, recurseDirectories);

            if (Verbose) StatusMessageTextWriter.WriteLine("found {0} files...", itemsToAdd.Count);

            OnAddStarted();

            AddOrUpdateAction action = (wantUpdate) ? AddOrUpdateAction.AddOrUpdate : AddOrUpdateAction.AddOnly;
            foreach (var item in itemsToAdd)
            {
                // workitem 10153
                string dirInArchive = (directoryPathInArchive == null)
                    ? null
                    // workitem 12260
                    : ReplaceLeadingDirectory(Path.GetDirectoryName(item),
                                              directoryOnDisk,
                                              directoryPathInArchive);

                if (File.Exists(item))
                {
                    if (wantUpdate)
                        this.UpdateFile(item, dirInArchive);
                    else
                        this.AddFile(item, dirInArchive);
                }
                else
                {
                    // this adds "just" the directory, without recursing to the contained files
                    AddOrUpdateDirectoryImpl(item, dirInArchive, action, false, 0);
                }
            }

            OnAddCompleted();
        }