示例#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;
 }
示例#2
0
 internal StringCollection GenerateNewPathsWithGlobLeaf(StringCollection currentDirs, string leafElement, bool isLastLeaf, ContainerCmdletProvider provider, CmdletProviderContext context)
 {
     if (currentDirs == null)
     {
         throw PSTraceSource.NewArgumentNullException("currentDirs");
     }
     if (provider == null)
     {
         throw PSTraceSource.NewArgumentNullException("provider");
     }
     NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
     StringCollection strings = new StringCollection();
     if (((leafElement != null) && (leafElement.Length > 0)) && (StringContainsGlobCharacters(leafElement) || isLastLeaf))
     {
         WildcardPattern stringMatcher = new WildcardPattern(ConvertMshEscapeToRegexEscape(leafElement), WildcardOptions.IgnoreCase);
         Collection<WildcardPattern> includeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Include, WildcardOptions.IgnoreCase);
         Collection<WildcardPattern> excludeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Exclude, WildcardOptions.IgnoreCase);
         foreach (string str2 in currentDirs)
         {
             using (pathResolutionTracer.TraceScope("Expanding wildcards for items under '{0}'", new object[] { str2 }))
             {
                 if (context.Stopping)
                 {
                     throw new PipelineStoppedException();
                 }
                 string modifiedDirPath = null;
                 Collection<PSObject> collection3 = this.GetChildNamesInDir(str2, leafElement, !isLastLeaf, context, true, null, provider, out modifiedDirPath);
                 if (collection3 == null)
                 {
                     tracer.TraceError("GetChildNames returned a null array", new object[0]);
                     pathResolutionTracer.WriteLine("No child names returned for '{0}'", new object[] { str2 });
                 }
                 else
                 {
                     foreach (PSObject obj2 in collection3)
                     {
                         if (context.Stopping)
                         {
                             throw new PipelineStoppedException();
                         }
                         string childName = string.Empty;
                         if (IsChildNameAMatch(obj2, stringMatcher, includeMatcher, excludeMatcher, out childName))
                         {
                             string str5 = childName;
                             if (provider2 != null)
                             {
                                 str5 = provider2.MakePath(modifiedDirPath, childName, context);
                             }
                             tracer.WriteLine("Adding child path to dirs {0}", new object[] { str5 });
                             strings.Add(str5);
                         }
                     }
                 }
             }
         }
         return strings;
     }
     tracer.WriteLine("LeafElement does not contain any glob characters so do a MakePath", new object[0]);
     foreach (string str6 in currentDirs)
     {
         using (pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", new object[] { str6 }))
         {
             if (context.Stopping)
             {
                 throw new PipelineStoppedException();
             }
             string child = ConvertMshEscapeToRegexEscape(leafElement);
             string parent = context.SuppressWildcardExpansion ? str6 : RemoveGlobEscaping(str6);
             string path = child;
             if (provider2 != null)
             {
                 path = provider2.MakePath(parent, child, context);
             }
             if (provider.ItemExists(path, context))
             {
                 tracer.WriteLine("Adding child path to dirs {0}", new object[] { path });
                 strings.Add(path);
                 pathResolutionTracer.WriteLine("Valid intermediate container: {0}", new object[] { path });
             }
         }
     }
     return strings;
 }
示例#3
0
        } // ExpandGlobPath


        /// <summary>
        /// Generates a collection of containers and/or leaves that are children of the containers
        /// in the currentDirs parameter and match the glob expression in the 
        /// <paramref name="leafElement" /> parameter.
        /// </summary>
        /// 
        /// <param name="currentDirs">
        /// A collection of paths that should be searched for leaves that match the 
        /// <paramref name="leafElement" /> expression.
        /// </param>
        /// 
        /// <param name="leafElement">
        /// A single element of a path that may or may not contain a glob expression. This parameter
        /// is used to search the containers in <paramref name="currentDirs" /> for children that 
        /// match the glob expression.
        /// </param>
        /// 
        /// <param name="isLastLeaf">
        /// True if the <paramref name="leafElement" /> is the last element to glob over. If false, we 
        /// need to get all container names from the provider even if they don't match the filter.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider associated with the paths that are being passed in the 
        /// <paramref name="currentDirs" /> and <paramref name="leafElement" /> parameters.
        /// The provider must derive from ContainerCmdletProvider or NavigationCmdletProvider 
        /// in order to get globbing.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// A collection of fully qualified namespace paths whose leaf element matches the 
        /// <paramref name="leafElement" /> expression.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="currentDirs" /> 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.
        /// </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 List<string> GenerateNewPathsWithGlobLeaf(
            List<string> currentDirs,
            string leafElement,
            bool isLastLeaf,
            ContainerCmdletProvider provider,
            CmdletProviderContext context)
        {
            if (currentDirs == null)
            {
                throw PSTraceSource.NewArgumentNullException("currentDirs");
            }

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

            NavigationCmdletProvider navigationProvider = provider as NavigationCmdletProvider;

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

            // Only loop through the child names if the leafElement contains a glob character

            if (!string.IsNullOrEmpty(leafElement) &&
                (StringContainsGlobCharacters(leafElement) ||
                 isLastLeaf))
            {
                string regexEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                // Construct the glob filter

                WildcardPattern stringMatcher =
                    WildcardPattern.Get(
                        regexEscapedLeafElement,
                        WildcardOptions.IgnoreCase);

                // Construct the include filter

                Collection<WildcardPattern> includeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Include,
                        WildcardOptions.IgnoreCase);


                // Construct the exclude filter

                Collection<WildcardPattern> excludeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Exclude,
                        WildcardOptions.IgnoreCase);

                // Loop through the current dirs and add the appropriate children

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding wildcards for items under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string unescapedDir = null;

                        Collection<PSObject> childNamesObjectArray =
                            GetChildNamesInDir(dir, leafElement, !isLastLeaf, context, true, null, provider, out unescapedDir);

                        if (childNamesObjectArray == null)
                        {
                            s_tracer.TraceError("GetChildNames returned a null array");

                            s_pathResolutionTracer.WriteLine("No child names returned for '{0}'", dir);
                            continue;
                        }

                        // Loop through each child to see if they match the glob expression

                        foreach (PSObject childObject in childNamesObjectArray)
                        {
                            // Make sure to obey StopProcessing
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }

                            string child = String.Empty;
                            if (IsChildNameAMatch(childObject, stringMatcher, includeMatcher, excludeMatcher, out child))
                            {
                                string childPath = child;

                                if (navigationProvider != null)
                                {
                                    childPath =
                                        navigationProvider.
                                        MakePath(
                                            unescapedDir,
                                            child,
                                            context);
                                }

                                s_tracer.WriteLine("Adding child path to dirs {0}", childPath);

                                newDirs.Add(childPath);
                            }
                        } // foreach (child in childNames)
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))
            else
            {
                s_tracer.WriteLine(
                    "LeafElement does not contain any glob characters so do a MakePath");

                // Loop through the current dirs and add the leafElement to each of 
                // the dirs

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string backslashEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                        string unescapedDir = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);

                        string childPath = backslashEscapedLeafElement;

                        if (navigationProvider != null)
                        {
                            childPath =
                                navigationProvider.
                                    MakePath(
                                        unescapedDir,
                                        backslashEscapedLeafElement,
                                        context);
                        }


                        if (provider.ItemExists(childPath, context))
                        {
                            s_tracer.WriteLine("Adding child path to dirs {0}", childPath);

                            newDirs.Add(childPath);

                            s_pathResolutionTracer.WriteLine("Valid intermediate container: {0}", childPath);
                        }
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))


            return newDirs;
        } // GenerateNewPathsWithGlobLeaf
示例#4
0
        private Collection<string> ExpandMshGlobPath(string path, bool allowNonexistingPaths, PSDriveInfo drive, ContainerCmdletProvider provider, CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }
            if (provider == null)
            {
                throw PSTraceSource.NewArgumentNullException("provider");
            }
            if (drive == null)
            {
                throw PSTraceSource.NewArgumentNullException("drive");
            }
            tracer.WriteLine("path = {0}", new object[] { path });
            NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
            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 a = provider2.GetParentPath(path, drive.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 str3 = path;
                            if (provider2 != null)
                            {
                                str3 = provider2.GetChildName(path, context);
                                if (!string.IsNullOrEmpty(str3))
                                {
                                    path = provider2.GetParentPath(path, null, context);
                                }
                            }
                            else
                            {
                                path = string.Empty;
                            }
                            stack.Push(str3);
                            pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { str3 });
                        }
                        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.GenerateNewPSPathsWithGlobLeaf(currentDirs, drive, 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();
                                    }
                                    string mshQualifiedPath = GetMshQualifiedPath(currentDirs[index], drive);
                                    if ((provider2 != null) && !this.sessionState.Internal.IsItemContainer(mshQualifiedPath, 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 str6 in currentDirs)
                    {
                        pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str6 });
                        collection.Add(str6);
                    }
                    return collection;
                }
                string str7 = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);
				string format = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? (str7.StartsWith ("/") ? "{1}" : "{0}/{1}") : "{0}:" + '\\' + "{1}";
                if (drive.Hidden)
                {
                    if (IsProviderDirectPath(str7))
                    {
                        format = "{1}";
                    }
                    else
                    {
                        format = "{0}::{1}";
                    }
                }
                else
                {
					char ch = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? '/' : '\\';
                    if (path.StartsWith(ch.ToString(), StringComparison.Ordinal))
                    {
						format = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? "{1}" : "{0}:{1}";
                    }
                }
                string str9 = string.Format(CultureInfo.InvariantCulture, format, new object[] { drive.Name, str7 });
                if (allowNonexistingPaths || provider.ItemExists(this.GetProviderPath(str9, context), context))
                {
                    pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str9 });
                    collection.Add(str9);
                    return collection;
                }
                ItemNotFoundException exception2 = new ItemNotFoundException(str9, "PathNotFound", SessionStateStrings.PathNotFound);
                pathResolutionTracer.TraceError("Item does not exist: {0}", new object[] { path });
                throw exception2;
            }
        }
示例#5
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