Exemple #1
0
 internal Collection<string> ExpandGlobPath(string path, bool allowNonexistingPaths, ContainerCmdletProvider provider, CmdletProviderContext context)
 {
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     if (provider == null)
     {
         throw PSTraceSource.NewArgumentNullException("provider");
     }
     string updatedPath = null;
     string updatedFilter = null;
     string filter = context.Filter;
     bool flag = provider.ConvertPath(path, context.Filter, ref updatedPath, ref updatedFilter, context);
     if (flag)
     {
         tracer.WriteLine("Provider converted path and filter.", new object[0]);
         tracer.WriteLine("Original path: " + path, new object[0]);
         tracer.WriteLine("Converted path: " + updatedPath, new object[0]);
         tracer.WriteLine("Original filter: " + context.Filter, new object[0]);
         tracer.WriteLine("Converted filter: " + updatedFilter, new object[0]);
         path = updatedPath;
         filter = context.Filter;
     }
     NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
     tracer.WriteLine("path = {0}", new object[] { path });
     Collection<string> collection = new Collection<string>();
     using (pathResolutionTracer.TraceScope("EXPANDING WILDCARDS", new object[0]))
     {
         if (ShouldPerformGlobbing(path, context))
         {
             StringCollection currentDirs = new StringCollection();
             Stack<string> stack = new Stack<string>();
             using (pathResolutionTracer.TraceScope("Tokenizing path", new object[0]))
             {
                 while (StringContainsGlobCharacters(path))
                 {
                     if (context.Stopping)
                     {
                         throw new PipelineStoppedException();
                     }
                     string childName = path;
                     if (provider2 != null)
                     {
                         childName = provider2.GetChildName(path, context);
                     }
                     if (string.IsNullOrEmpty(childName))
                     {
                         break;
                     }
                     tracer.WriteLine("Pushing leaf element: {0}", new object[] { childName });
                     pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { childName });
                     stack.Push(childName);
                     if (provider2 != null)
                     {
                         string root = string.Empty;
                         if (context != null)
                         {
                             PSDriveInfo drive = context.Drive;
                             if (drive != null)
                             {
                                 root = drive.Root;
                             }
                         }
                         string a = provider2.GetParentPath(path, root, context);
                         if (string.Equals(a, path, StringComparison.OrdinalIgnoreCase))
                         {
                             throw PSTraceSource.NewInvalidOperationException("SessionStateStrings", "ProviderImplementationInconsistent", new object[] { provider.ProviderInfo.Name, path });
                         }
                         path = a;
                     }
                     else
                     {
                         path = string.Empty;
                     }
                     tracer.WriteLine("New path: {0}", new object[] { path });
                     pathResolutionTracer.WriteLine("Parent path: {0}", new object[] { path });
                 }
                 tracer.WriteLine("Base container path: {0}", new object[] { path });
                 if (stack.Count == 0)
                 {
                     string str7 = path;
                     if (provider2 != null)
                     {
                         str7 = provider2.GetChildName(path, context);
                         if (!string.IsNullOrEmpty(str7))
                         {
                             path = provider2.GetParentPath(path, null, context);
                         }
                     }
                     else
                     {
                         path = string.Empty;
                     }
                     stack.Push(str7);
                     pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { str7 });
                 }
                 pathResolutionTracer.WriteLine("Root path of resolution: {0}", new object[] { path });
             }
             currentDirs.Add(path);
             while (stack.Count > 0)
             {
                 if (context.Stopping)
                 {
                     throw new PipelineStoppedException();
                 }
                 string leafElement = stack.Pop();
                 currentDirs = this.GenerateNewPathsWithGlobLeaf(currentDirs, leafElement, stack.Count == 0, provider, context);
                 if (stack.Count > 0)
                 {
                     using (pathResolutionTracer.TraceScope("Checking matches to ensure they are containers", new object[0]))
                     {
                         int index = 0;
                         while (index < currentDirs.Count)
                         {
                             if (context.Stopping)
                             {
                                 throw new PipelineStoppedException();
                             }
                             if ((provider2 != null) && !provider2.IsItemContainer(currentDirs[index], context))
                             {
                                 tracer.WriteLine("Removing {0} because it is not a container", new object[] { currentDirs[index] });
                                 pathResolutionTracer.WriteLine("{0} is not a container", new object[] { currentDirs[index] });
                                 currentDirs.RemoveAt(index);
                             }
                             else if (provider2 != null)
                             {
                                 pathResolutionTracer.WriteLine("{0} is a container", new object[] { currentDirs[index] });
                                 index++;
                             }
                         }
                         continue;
                     }
                 }
             }
             foreach (string str9 in currentDirs)
             {
                 pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str9 });
                 collection.Add(str9);
             }
         }
         else
         {
             string str10 = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);
             if (allowNonexistingPaths || provider.ItemExists(str10, context))
             {
                 pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str10 });
                 collection.Add(str10);
             }
             else
             {
                 ItemNotFoundException exception2 = new ItemNotFoundException(path, "PathNotFound", SessionStateStrings.PathNotFound);
                 pathResolutionTracer.TraceError("Item does not exist: {0}", new object[] { path });
                 throw exception2;
             }
         }
     }
     if (flag)
     {
         context.Filter = filter;
     }
     return collection;
 }
Exemple #2
0
        } // GenerateNewPathsWithGlobLeaf

        /// <summary>
        /// Gets the child names in the specified path by using the provider
        /// </summary>
        /// 
        /// <param name="dir">
        /// The path of the directory to get the child names from. If this is an Msh Path,
        /// dirIsProviderPath must be false, If this is a provider-internal path,
        /// dirIsProviderPath must be true.
        /// </param>
        /// 
        /// <param name="leafElement">
        /// The element that we are ultimately looking for. Used to set filters on the context
        /// if desired.
        /// </param>
        /// 
        /// <param name="getAllContainers">
        /// Determines if the GetChildNames call should get all containers even if they don't
        /// match the filter.
        /// </param>
        /// 
        /// <param name="context">
        /// The context to be used for the command. The context is copied to a new context, the
        /// results are accumulated and then returned.
        /// </param>
        /// 
        /// <param name="dirIsProviderPath">
        /// Specifies whether the dir parameter is a provider-internal path (true) or Msh Path (false).
        /// </param>
        /// 
        /// <param name="drive">
        /// The drive to use to qualify the Msh path if dirIsProviderPath is false.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider to use to get the child names.
        /// </param>
        /// 
        /// <param name="modifiedDirPath">
        /// Returns the modified dir path. If dirIsProviderPath is true, this is the unescaped dir path.
        /// If dirIsProviderPath is false, this is the unescaped resolved provider path.
        /// </param>
        /// 
        /// <returns>
        /// A collection of PSObjects whose BaseObject is a string that contains the name of the child.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="dir"/> or <paramref name="drive"/> is null.
        /// </exception>
        /// 
        /// <exception cref="ProviderNotFoundException">
        /// If the path is a provider-qualified path for a provider that is
        /// not loaded into the system.
        /// </exception>
        /// 
        /// <exception cref="DriveNotFoundException">
        /// If the <paramref name="path"/> refers to a drive that could not be found.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="NotSupportedException">
        /// If the provider that the <paramref name="path"/> represents is not a NavigationCmdletProvider
        /// or ContainerCmdletProvider.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with the <paramref name="path"/> threw an
        /// exception when its GetParentPath or MakePath was called while
        /// processing the <paramref name="path"/>.
        /// </exception>
        /// 
        /// <exception cref="PipelineStoppedException">
        /// If <paramref name="context"/> has been signaled for
        /// StopProcessing.
        /// </exception>
        /// 
        /// <exception>
        /// Any exception can be thrown by the provider that is called to build
        /// the provider path.
        /// </exception>
        /// 
        private Collection<PSObject> GetChildNamesInDir(
            string dir,
            string leafElement,
            bool getAllContainers,
            CmdletProviderContext context,
            bool dirIsProviderPath,
            PSDriveInfo drive,
            ContainerCmdletProvider provider,
            out string modifiedDirPath)
        {
            // See if the provider wants to convert the path and filter
            string convertedPath = null;
            string convertedFilter = null;
            string originalFilter = context.Filter;
            bool changedPathOrFilter = provider.ConvertPath(leafElement, context.Filter, ref convertedPath, ref convertedFilter, context);

            if (changedPathOrFilter)
            {
                if (s_tracer.IsEnabled)
                {
                    s_tracer.WriteLine("Provider converted path and filter.");
                    s_tracer.WriteLine("Original path: {0}", leafElement);
                    s_tracer.WriteLine("Converted path: {0}", convertedPath);
                    s_tracer.WriteLine("Original filter: {0}", context.Filter);
                    s_tracer.WriteLine("Converted filter: {0}", convertedFilter);
                }

                leafElement = convertedPath;
                context.Filter = convertedFilter;
            }

            ReturnContainers returnContainers = ReturnContainers.ReturnAllContainers;
            if (!getAllContainers)
            {
                returnContainers = ReturnContainers.ReturnMatchingContainers;
            }

            CmdletProviderContext getChildNamesContext =
                new CmdletProviderContext(context);

            // Remove the include/exclude filters from the new context
            getChildNamesContext.SetFilters(
                new Collection<string>(),
                new Collection<string>(),
                context.Filter);

            try
            {
                // Use the provider to get the children
                string unescapedDir = null;
                modifiedDirPath = null;

                if (dirIsProviderPath)
                {
                    modifiedDirPath = unescapedDir = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);
                }
                else
                {
                    Dbg.Diagnostics.Assert(
                        drive != null,
                        "Caller should verify that drive is not null when dirIsProviderPath is false");

                    // If the directory is an MSH path we must resolve it before calling GetChildNames()
                    // -- If the path is passed in by LiteralPath (context.SuppressWildcardExpansion == false), we surely should use 'dir' unchanged.
                    // -- If the path is passed in by Path (context.SuppressWildcardExpansion == true), we still should use 'dir' unchanged, in case that the special character
                    //    in 'dir' is escaped
                    modifiedDirPath = GetMshQualifiedPath(dir, drive);

                    ProviderInfo providerIgnored = null;
                    CmdletProvider providerInstanceIgnored = null;
                    Collection<string> resolvedPaths =
                        GetGlobbedProviderPathsFromMonadPath(
                            modifiedDirPath,
                            false,
                            getChildNamesContext,
                            out providerIgnored,
                            out providerInstanceIgnored);

                    // After resolving the path, we unescape the modifiedDirPath if necessary.
                    modifiedDirPath = context.SuppressWildcardExpansion
                                          ? modifiedDirPath
                                          : RemoveGlobEscaping(modifiedDirPath);
                    if (resolvedPaths.Count > 0)
                    {
                        unescapedDir = resolvedPaths[0];
                    }
                    else
                    {
                        // If there were no results from globbing but no
                        // exception was thrown, that means there was filtering.
                        // So return an empty collection and let the caller deal
                        // with it.

                        if (changedPathOrFilter)
                        {
                            context.Filter = originalFilter;
                        }

                        return new Collection<PSObject>();
                    }
                }

                if (provider.HasChildItems(unescapedDir, getChildNamesContext))
                {
                    provider.GetChildNames(
                        unescapedDir,
                        returnContainers,
                        getChildNamesContext);
                }

                // First check to see if there were any errors, and write them
                // to the real context if there are.

                if (getChildNamesContext.HasErrors())
                {
                    Collection<ErrorRecord> errors = getChildNamesContext.GetAccumulatedErrorObjects();

                    if (errors != null &&
                        errors.Count > 0)
                    {
                        foreach (ErrorRecord errorRecord in errors)
                        {
                            context.WriteError(errorRecord);
                        }
                    }
                }

                Collection<PSObject> childNamesObjectArray = getChildNamesContext.GetAccumulatedObjects();

                if (changedPathOrFilter)
                {
                    context.Filter = originalFilter;
                }

                return childNamesObjectArray;
            }
            finally
            {
                getChildNamesContext.RemoveStopReferral();
            }
        } // GetChildNamesInDir
Exemple #3
0
 private Collection<PSObject> GetChildNamesInDir(string dir, string leafElement, bool getAllContainers, CmdletProviderContext context, bool dirIsProviderPath, PSDriveInfo drive, ContainerCmdletProvider provider, out string modifiedDirPath)
 {
     string updatedPath = null;
     string updatedFilter = null;
     Collection<PSObject> collection4;
     string filter = context.Filter;
     bool flag = provider.ConvertPath(leafElement, context.Filter, ref updatedPath, ref updatedFilter, context);
     if (flag)
     {
         tracer.WriteLine("Provider converted path and filter.", new object[0]);
         tracer.WriteLine("Original path: " + leafElement, new object[0]);
         tracer.WriteLine("Converted path: " + updatedPath, new object[0]);
         tracer.WriteLine("Original filter: " + context.Filter, new object[0]);
         tracer.WriteLine("Converted filter: " + updatedFilter, new object[0]);
         leafElement = updatedPath;
         context.Filter = updatedFilter;
     }
     ReturnContainers returnAllContainers = ReturnContainers.ReturnAllContainers;
     if (!getAllContainers)
     {
         returnAllContainers = ReturnContainers.ReturnMatchingContainers;
     }
     CmdletProviderContext context2 = new CmdletProviderContext(context);
     context2.SetFilters(new Collection<string>(), new Collection<string>(), context.Filter);
     try
     {
         string path = null;
         modifiedDirPath = null;
         if (dirIsProviderPath)
         {
             modifiedDirPath = path = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);
         }
         else
         {
             modifiedDirPath = GetMshQualifiedPath(dir, drive);
             ProviderInfo info = null;
             CmdletProvider providerInstance = null;
             Collection<string> collection = this.GetGlobbedProviderPathsFromMonadPath(modifiedDirPath, false, context2, out info, out providerInstance);
             modifiedDirPath = context.SuppressWildcardExpansion ? modifiedDirPath : RemoveGlobEscaping(modifiedDirPath);
             if (collection.Count > 0)
             {
                 path = collection[0];
             }
             else
             {
                 if (flag)
                 {
                     context.Filter = filter;
                 }
                 return new Collection<PSObject>();
             }
         }
         if (provider.HasChildItems(path, context2))
         {
             provider.GetChildNames(path, returnAllContainers, context2);
         }
         if (context2.HasErrors())
         {
             Collection<ErrorRecord> accumulatedErrorObjects = context2.GetAccumulatedErrorObjects();
             if ((accumulatedErrorObjects != null) && (accumulatedErrorObjects.Count > 0))
             {
                 foreach (ErrorRecord record in accumulatedErrorObjects)
                 {
                     context.WriteError(record);
                 }
             }
         }
         Collection<PSObject> accumulatedObjects = context2.GetAccumulatedObjects();
         if (flag)
         {
             context.Filter = filter;
         }
         collection4 = accumulatedObjects;
     }
     finally
     {
         context2.RemoveStopReferral();
     }
     return collection4;
 }
Exemple #4
0
        } // GenerateNewPSPathsWithGlobLeaf

        /// <summary>
        /// Generates an array of provider specific paths from the single provider specific
        /// path using globing rules.
        /// </summary>
        /// 
        /// <param name="path">
        /// A path that may or may not contain globing characters.
        /// </param>
        /// 
        /// <param name="allowNonexistingPaths">
        /// If true, a ItemNotFoundException will not be thrown for non-existing
        /// paths. Instead an appropriate path will be returned as if it did exist.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider that implements the namespace for the path that we are globing over.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// An array of path strings that match the globing rules applied to the path parameter.
        /// </returns>
        /// 
        /// <remarks>
        /// First the path is checked to see if it contains any globing characters ('?' or '*').
        /// If it doesn't then the path is returned as the only element in the array.
        /// If it does, GetParentPath and GetLeafPathName is called on the path and each element
        /// is stored until the path doesn't contain any globing characters. At that point 
        /// GetChildPathNames() is called on the provider with the last parent path that doesn't
        /// contain a globing character. All the results are then matched against leaf element
        /// of that parent path (which did contain a glob character). We then walk out of the
        /// recursion and apply the same procedure to each leaf element that contained globing
        /// characters.
        /// 
        /// The procedure above allows us to match globing strings in multiple sub-containers
        /// in the namespace without having to have knowledge of the namespace paths, or
        /// their syntax.
        /// 
        /// Example:
        /// dir c:\foo\*\bar\*a??.cs
        /// 
        /// Calling this method for the path above would return all files that end in 'a' and
        /// any other two characters followed by ".cs" in all the subdirectories of
        /// foo that have a bar subdirectory.
        /// 
        /// </remarks>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> or <paramref name="provider"/> is null.
        /// </exception>
        /// 
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// or if the provider is implemented in such a way as to cause the globber to go
        /// into an infinite loop.
        /// </exception>
        /// 
        /// <exception cref="PipelineStoppedException">
        /// If <paramref name="context"/> has been signaled for
        /// StopProcessing.
        /// </exception>
        /// 
        /// <exception>
        /// Any exception can be thrown by the provider that is called to build
        /// the provider path.
        /// </exception>
        /// 
        internal Collection<string> ExpandGlobPath(
            string path,
            bool allowNonexistingPaths,
            ContainerCmdletProvider provider,
            CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            if (provider == null)
            {
                throw PSTraceSource.NewArgumentNullException("provider");
            }

            // See if the provider wants to convert the path and filter
            string convertedPath = null;
            string convertedFilter = null;
            string originalFilter = context.Filter;
            bool changedPathOrFilter = provider.ConvertPath(path, context.Filter, ref convertedPath, ref convertedFilter, context);

            if (changedPathOrFilter)
            {
                if (s_tracer.IsEnabled)
                {
                    s_tracer.WriteLine("Provider converted path and filter.");
                    s_tracer.WriteLine("Original path: {0}", path);
                    s_tracer.WriteLine("Converted path: {0}", convertedPath);
                    s_tracer.WriteLine("Original filter: {0}", context.Filter);
                    s_tracer.WriteLine("Converted filter: {0}", convertedFilter);
                }

                path = convertedPath;
                originalFilter = context.Filter;
            }

            NavigationCmdletProvider navigationProvider = provider as NavigationCmdletProvider;

            s_tracer.WriteLine("path = {0}", path);

            Collection<string> result = new Collection<string>();

            using (s_pathResolutionTracer.TraceScope("EXPANDING WILDCARDS"))
            {
                if (ShouldPerformGlobbing(path, context))
                {
                    // This collection contains the directories for which a leaf is being added.
                    // If the directories are being globed over as well, then there will be
                    // many directories in this collection which will have to be iterated over
                    // every time there is a child being added

                    List<string> dirs = new List<string>();

                    // Each leaf element that is pulled off the path is pushed on the stack in
                    // order such that we can generate the path again.

                    Stack<String> leafElements = new Stack<String>();

                    using (s_pathResolutionTracer.TraceScope("Tokenizing path"))
                    {
                        // If the path contains glob characters then iterate through pulling the
                        // leaf elements off and pushing them on to the leafElements stack until
                        // there are no longer any glob characters in the path.

                        while (StringContainsGlobCharacters(path))
                        {
                            // Make sure to obey StopProcessing
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }

                            // Use the provider to get the leaf element string

                            string leafElement = path;

                            if (navigationProvider != null)
                            {
                                leafElement = navigationProvider.GetChildName(path, context);
                            }

                            if (String.IsNullOrEmpty(leafElement))
                            {
                                break;
                            }

                            s_tracer.WriteLine("Pushing leaf element: {0}", leafElement);

                            s_pathResolutionTracer.WriteLine("Leaf element: {0}", leafElement);

                            // Push the leaf element onto the leaf element stack for future use

                            leafElements.Push(leafElement);

                            // Now use the parent path for the next iteration

                            if (navigationProvider != null)
                            {
                                // See if we can get the root from the context

                                string root = String.Empty;

                                if (context != null)
                                {
                                    PSDriveInfo drive = context.Drive;

                                    if (drive != null)
                                    {
                                        root = drive.Root;
                                    }
                                }

                                // Now call GetParentPath with the root

                                string newParentPath = navigationProvider.GetParentPath(path, root, context);

                                if (String.Equals(
                                        newParentPath,
                                        path,
                                        StringComparison.OrdinalIgnoreCase))
                                {
                                    // The provider is implemented in an inconsistent way. 
                                    // GetChildName returned a non-empty/non-null result but
                                    // GetParentPath with the same path returns the same path.
                                    // This would cause the globber to go into an infinite loop,
                                    // so instead an exception is thrown.

                                    PSInvalidOperationException invalidOperation =
                                        PSTraceSource.NewInvalidOperationException(
                                            SessionStateStrings.ProviderImplementationInconsistent,
                                            provider.ProviderInfo.Name,
                                            path);
                                    throw invalidOperation;
                                }
                                path = newParentPath;
                            }
                            else
                            {
                                // If the provider doesn't implement NavigationCmdletProvider then at most
                                // it can have only one segment in its path. So after removing
                                // the leaf all we have left is the empty string.

                                path = String.Empty;
                            }

                            s_tracer.WriteLine("New path: {0}", path);
                            s_pathResolutionTracer.WriteLine("Parent path: {0}", path);
                        }

                        s_tracer.WriteLine("Base container path: {0}", path);

                        // If no glob elements were found there must be an include and/or
                        // exclude specified. Use the parent path to iterate over to 
                        // resolve the include/exclude filters

                        if (leafElements.Count == 0)
                        {
                            string leafElement = path;

                            if (navigationProvider != null)
                            {
                                leafElement = navigationProvider.GetChildName(path, context);

                                if (!String.IsNullOrEmpty(leafElement))
                                {
                                    path = navigationProvider.GetParentPath(path, null, context);
                                }
                            }
                            else
                            {
                                path = String.Empty;
                            }
                            leafElements.Push(leafElement);
                            s_pathResolutionTracer.WriteLine("Leaf element: {0}", leafElement);
                        }

                        s_pathResolutionTracer.WriteLine("Root path of resolution: {0}", path);
                    }
                    // Once the container path with no glob characters are found store it
                    // so that it's children can be iterated over.

                    dirs.Add(path);

                    // Reconstruct the path one leaf element at a time, expanding where-ever
                    // we encounter glob characters

                    while (leafElements.Count > 0)
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string leafElement = leafElements.Pop();

                        Dbg.Diagnostics.Assert(
                            leafElement != null,
                            "I am only pushing strings onto this stack so I should be able " +
                            "to cast any Pop to a string without failure.");

                        dirs =
                            GenerateNewPathsWithGlobLeaf(
                                dirs,
                                leafElement,
                                leafElements.Count == 0,
                                provider,
                                context);

                        // If there are more leaf elements in the stack we need
                        // to make sure that only containers where added to dirs
                        // in GenerateNewPathsWithGlobLeaf

                        if (leafElements.Count > 0)
                        {
                            using (s_pathResolutionTracer.TraceScope("Checking matches to ensure they are containers"))
                            {
                                int index = 0;

                                while (index < dirs.Count)
                                {
                                    // Make sure to obey StopProcessing
                                    if (context.Stopping)
                                    {
                                        throw new PipelineStoppedException();
                                    }

                                    // Check to see if the matching item is a container

                                    if (navigationProvider != null &&
                                        !navigationProvider.IsItemContainer(
                                            dirs[index],
                                            context))
                                    {
                                        // If not, remove it from the collection

                                        s_tracer.WriteLine(
                                            "Removing {0} because it is not a container",
                                            dirs[index]);

                                        s_pathResolutionTracer.WriteLine("{0} is not a container", dirs[index]);
                                        dirs.RemoveAt(index);
                                    }
                                    else if (navigationProvider == null)
                                    {
                                        Dbg.Diagnostics.Assert(
                                            navigationProvider != null,
                                            "The path in the dirs should never be a container unless " +
                                            "the provider implements the NavigationCmdletProvider interface. If it " +
                                            "doesn't, there should be no more leafElements in the stack " +
                                            "when this check is done");
                                    }
                                    else
                                    {
                                        s_pathResolutionTracer.WriteLine("{0} is a container", dirs[index]);

                                        // If so, leave it and move on to the next one

                                        ++index;
                                    }
                                }
                            }
                        }
                    } // while (leafElements.Count > 0)

                    Dbg.Diagnostics.Assert(
                        dirs != null,
                        "GenerateNewPathsWithGlobLeaf() should return the base path as an element " +
                        "even if there are no globing characters");

                    foreach (string dir in dirs)
                    {
                        s_pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", dir);
                        result.Add(dir);
                    }

                    Dbg.Diagnostics.Assert(
                        dirs.Count == result.Count,
                        "The result of copying the globed strings should be the same " +
                        "as from the collection");
                }
                else
                {
                    string unescapedPath = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);

                    if (allowNonexistingPaths ||
                        provider.ItemExists(unescapedPath, context))
                    {
                        s_pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", unescapedPath);
                        result.Add(unescapedPath);
                    }
                    else
                    {
                        ItemNotFoundException pathNotFound =
                            new ItemNotFoundException(
                                path,
                                "PathNotFound",
                                SessionStateStrings.PathNotFound);

                        s_pathResolutionTracer.TraceError("Item does not exist: {0}", path);

                        throw pathNotFound;
                    }
                }
            }
            Dbg.Diagnostics.Assert(
                result != null,
                "This method should at least return the path or more if it has glob characters");

            if (changedPathOrFilter)
            {
                context.Filter = originalFilter;
            }

            return result;
        } // ExpandGlobPath