public IPathValue MoveItem(IProviderContext providerContext, string path, string movePath, IPathValue destinationContainer)
        {
            if (providerContext == null)
            {
                throw new ArgumentNullException(nameof(providerContext));
            }
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (destinationContainer == null)
            {
                throw new ArgumentNullException(nameof(destinationContainer));
            }

            var drive = providerContext.Drive as ICloudDrive;

            if (drive != null)
            {
                var moveItem = new CloudPathNode(drive.MoveItem((FileSystemInfoContract)nodeValue.Item, movePath, (DirectoryInfoContract)destinationContainer.Item));
                var destinationContainerNode = providerContext.ResolvePath(((DirectoryInfoContract)destinationContainer.Item).Id.Value) as CloudPathNode;
                destinationContainerNode.children.Add(moveItem);
                moveItem.SetParent(destinationContainerNode);
                parent.children.Remove(this);
                SetParent(null);
                return(moveItem.nodeValue);
            }

            throw new InvalidOperationException();
        }
        private void SetParent(CloudPathNode parent)
        {
            this.parent = parent;
            var directory = ((DirectoryInfoContract)parent?.nodeValue.Item);

            var fileItem = nodeValue.Item as FileInfoContract;

            if (fileItem != null)
            {
                fileItem.Directory = directory;
                return;
            }

            var directoryItem = nodeValue.Item as DirectoryInfoContract;

            if (directoryItem != null)
            {
                directoryItem.Parent = directory;
                return;
            }
        }
        public IPathValue NewItem(IProviderContext providerContext, string path, string itemTypeName, object newItemValue)
        {
            if (providerContext == null)
            {
                throw new ArgumentNullException(nameof(providerContext));
            }
            if (path == null)
            {
                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.ItemAlreadyPresent, providerContext.Path));
            }
            if (itemMode != Mode.Directory)
            {
                throw new NotSupportedException($"{nameof(ItemMode)} = {ItemMode}");
            }
            Mode mode;

            if (!Enum.TryParse(itemTypeName, out mode))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.UnknownItemType, itemTypeName), nameof(providerContext));
            }

            var drive = providerContext.Drive as ICloudDrive;

            if (drive != null)
            {
                var           baseDirectory = (DirectoryInfoContract)nodeValue.Item;
                CloudPathNode newItem       = null;
                switch (mode)
                {
                case Mode.Directory:
                    newItem          = new CloudPathNode(drive.NewDirectoryItem(baseDirectory, path));
                    newItem.children = new List <CloudPathNode>();
                    break;

                case Mode.File:
                    Stream stream = null;

                    if ((stream = newItemValue as Stream) != null)
                    {
                        // nothing else to to
                    }
                    else
                    {
                        var newItemByteArray = newItemValue as byte[];
                        if (newItemByteArray != null)
                        {
                            stream = new MemoryStream(newItemByteArray);
                        }
                        else
                        {
                            var newItemString = newItemValue as string;
                            if (newItemString != null)
                            {
                                stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(newItemString));
                            }
                            else if (newItemValue != null)
                            {
                                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.UnsupportedContentType, newItemValue.GetType().Name));
                            }
                        }
                    }

                    newItem = new CloudPathNode(drive.NewFileItem(baseDirectory, path, stream, new ProgressProxy(providerContext, "New-Item", path)));
                    break;
                }
                children.Add(newItem);
                newItem.SetParent(this);
                return(newItem.nodeValue);
            }

            throw new InvalidOperationException();
        }
        public IPathValue NewItem(IProviderContext providerContext, string path, string itemTypeName, object newItemValue)
        {
            if (providerContext == null)
                throw new ArgumentNullException(nameof(providerContext));
            if (path == null)
                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.ItemAlreadyPresent, providerContext.Path));
            if (itemMode != Mode.Directory)
                throw new NotSupportedException($"{nameof(ItemMode)} = {ItemMode}");
            Mode mode;
            if (!Enum.TryParse(itemTypeName, out mode))
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.UnknownItemType, itemTypeName), nameof(providerContext));

            var drive = providerContext.Drive as ICloudDrive;
            if (drive != null) {
                var baseDirectory = (DirectoryInfoContract)nodeValue.Item;
                CloudPathNode newItem = null;
                switch (mode) {
                    case Mode.Directory:
                        newItem = new CloudPathNode(drive.NewDirectoryItem(baseDirectory, path));
                        newItem.children = new List<CloudPathNode>();
                        break;
                    case Mode.File:
                        Stream stream = null;

                        if ((stream = newItemValue as Stream) != null) {
                            // nothing else to to
                        } else {
                            var newItemByteArray = newItemValue as byte[];
                            if (newItemByteArray != null) {
                                stream = new MemoryStream(newItemByteArray);
                            } else {
                                var newItemString = newItemValue as string;
                                if (newItemString != null) {
                                    stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(newItemString));
                                } else if (newItemValue != null) {
                                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.UnsupportedContentType, newItemValue.GetType().Name));
                                }
                            }
                        }

                        newItem = new CloudPathNode(drive.NewFileItem(baseDirectory, path, stream, new ProgressProxy(providerContext, "New-Item", path)));
                        break;
                }
                children.Add(newItem);
                newItem.SetParent(this);
                return newItem.nodeValue;
            }

            throw new InvalidOperationException();
        }
        public IPathValue MoveItem(IProviderContext providerContext, string path, string movePath, IPathValue destinationContainer)
        {
            if (providerContext == null)
                throw new ArgumentNullException(nameof(providerContext));
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException(nameof(path));
            if (destinationContainer == null)
                throw new ArgumentNullException(nameof(destinationContainer));

            var drive = providerContext.Drive as ICloudDrive;
            if (drive != null) {
                var moveItem = new CloudPathNode(drive.MoveItem((FileSystemInfoContract)nodeValue.Item, movePath, (DirectoryInfoContract)destinationContainer.Item));
                var destinationContainerNode = providerContext.ResolvePath(((DirectoryInfoContract)destinationContainer.Item).Id.Value) as CloudPathNode;
                destinationContainerNode.children.Add(moveItem);
                moveItem.SetParent(destinationContainerNode);
                parent.children.Remove(this);
                SetParent(null);
                return moveItem.nodeValue;
            }

            throw new InvalidOperationException();
        }
        private void SetParent(CloudPathNode parent)
        {
            this.parent = parent;
            var directory = ((DirectoryInfoContract)parent?.nodeValue.Item);

            var fileItem = nodeValue.Item as FileInfoContract;
            if (fileItem != null) {
                fileItem.Directory = directory;
                return;
            }

            var directoryItem = nodeValue.Item as DirectoryInfoContract;
            if (directoryItem != null) {
                directoryItem.Parent = directory;
                return;
            }
        }