A helper class for Shell Objects
        /// <summary>
        /// Creates a ShellObject given a native IShellItem interface
        /// </summary>
        /// <param name="nativeShellItem"></param>
        /// <returns>A newly constructed ShellObject object</returns>
        internal static ShellObject Create(IShellItem nativeShellItem)
        {
            // Sanity check
            Debug.Assert(nativeShellItem != null, "nativeShellItem should not be null");

            // Need to make sure we're running on Vista or higher
            if (!CoreHelpers.RunningOnVista)
            {
                throw new PlatformNotSupportedException(LocalizedMessages.ShellObjectFactoryPlatformNotSupported);
            }

            // A lot of APIs need IShellItem2, so just keep a copy of it here
            IShellItem2 nativeShellItem2 = nativeShellItem as IShellItem2;

            // Get the System.ItemType property
            string itemType = ShellHelper.GetItemType(nativeShellItem2);

            if (!string.IsNullOrEmpty(itemType))
            {
                itemType = itemType.ToLowerInvariant();
            }

            // Get some IShellItem attributes
            ShellNativeMethods.ShellFileGetAttributesOptions sfgao;
            nativeShellItem2.GetAttributes(ShellNativeMethods.ShellFileGetAttributesOptions.FileSystem | ShellNativeMethods.ShellFileGetAttributesOptions.Folder, out sfgao);

            // Is this item a FileSystem item?
            bool isFileSystem = (sfgao & ShellNativeMethods.ShellFileGetAttributesOptions.FileSystem) != 0;

            // Is this item a Folder?
            bool isFolder = (sfgao & ShellNativeMethods.ShellFileGetAttributesOptions.Folder) != 0;

            // Shell Library
            ShellLibrary shellLibrary = null;

            // Create the right type of ShellObject based on the above information

            // 1. First check if this is a Shell Link
            if (StringComparer.OrdinalIgnoreCase.Equals(itemType, ".lnk"))
            {
                return(new ShellLink(nativeShellItem2));
            }
            // 2. Check if this is a container or a single item (entity)
            else if (isFolder)
            {
                // 3. If this is a folder, check for types: Shell Library, Shell Folder or Search Container
                if (itemType == ".library-ms" && (shellLibrary = ShellLibrary.FromShellItem(nativeShellItem2, true)) != null)
                {
                    return(shellLibrary); // we already created this above while checking for Library
                }
                else if (itemType == ".searchconnector-ms")
                {
                    return(new ShellSearchConnector(nativeShellItem2));
                }
                else if (itemType == ".search-ms")
                {
                    return(new ShellSavedSearchCollection(nativeShellItem2));
                }

                // 4. It's a ShellFolder
                if (isFileSystem)
                {
                    // 5. Is it a (File-System / Non-Virtual) Known Folder
                    if (!IsVirtualKnownFolder(nativeShellItem2))
                    { //needs to check if it is a known folder and not virtual
                        FileSystemKnownFolder kf = new FileSystemKnownFolder(nativeShellItem2);
                        return(kf);
                    }

                    return(new ShellFileSystemFolder(nativeShellItem2));
                }

                // 5. Is it a (Non File-System / Virtual) Known Folder
                if (IsVirtualKnownFolder(nativeShellItem2))
                { //needs to check if known folder is virtual
                    NonFileSystemKnownFolder kf = new NonFileSystemKnownFolder(nativeShellItem2);
                    return(kf);
                }

                return(new ShellNonFileSystemFolder(nativeShellItem2));
            }

            // 6. If this is an entity (single item), check if its filesystem or not
            if (isFileSystem)
            {
                return(new ShellFile(nativeShellItem2));
            }

            return(new ShellNonFileSystemItem(nativeShellItem2));
        }