public VirtualDirectory CreateDirectory(VirtualDirectory directory, string name)
        {
            name = VirtualPath.GetFileName(name);
            VirtualPath.CheckRestrictedSymbols(name);
            var retv = createVirtualEntity <VirtualDirectory>(directory, name);

            _directoryWatcherSource.RaiseCreated(directory, retv);
            return(retv);
        }
        public void RenameFile(VirtualFile file, string newName)
        {
            var fileEntry       = getFileEntry(file);
            var parentDirectory = getVirtualDirectory(fileEntry.DirectoryId);

            if (!_locker.CanWrite(fileEntry))
            {
                throw new AccessViolationException("Unable to rename file: file is locked");
            }

            var name = VirtualPath.GetFileNameWithoutExtension(newName);

            VirtualPath.CheckRestrictedSymbols(name);

            if (fileEntry.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            Indexer.TryGetParentDirectory(fileEntry, out var parentDirectoryEntry);
            if (getDirectoryFiles(parentDirectoryEntry, false, makeRegexPattern(name)).Any())
            {
                throw new InvalidOperationException($"Item with the same name exists in the directory {GetDirectoryName(parentDirectoryEntry.Id)}");
            }

            using (_locker.LockWriting(fileEntry))
                using (_locker.LockReading(fileEntry))
                {
                    var newExtension = VirtualPath.GetFileExtension(newName);
                    fileEntry.ModificationTime = DateTime.Now;
                    fileEntry.Name             = name;
                    fileEntry.Extension        = newExtension;
                    Cache.FileNames.Remove(fileEntry.Id);
                    _rawDataManager.Write(fileEntry);
                }

            _directoryWatcherSource.RaiseUpdated(parentDirectory, file);
        }
        public void RenameDirectory(VirtualDirectory directory, string newName)
        {
            var directoryEntry  = getDirectoryEntry(directory);
            var parentDirectory = getVirtualDirectory(directoryEntry.DirectoryId);

            if (directory.Id == 0)
            {
                throw new InvalidOperationException("Root directory cannot be renamed");
            }

            var name = VirtualPath.GetFileName(newName);

            VirtualPath.CheckRestrictedSymbols(name);

            if (directoryEntry.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            Indexer.TryGetParentDirectory(directoryEntry, out var parentDirectoryEntry);
            if (getNestedDirecories(parentDirectoryEntry, false, makeRegexPattern(name)).Any())
            {
                throw new InvalidOperationException($"Item with the same name exists in the directory {GetDirectoryName(parentDirectoryEntry.Id)}");
            }

            if (!_locker.TryLockWriting(directoryEntry, out var operation))
            {
                throw new AccessViolationException("Unable to rename directory: directory is locked");
            }

            using (operation)
                using (_locker.LockReading(directoryEntry))
                {
                    directoryEntry.Name = name;

                    Cache.DirectoryNames.Remove(directoryEntry.Id);
                    var nestedDirectories = getNestedDirecories(directoryEntry, true, null);
                    var directoryFiles    = getDirectoryFiles(directoryEntry, true, null);
                    var nestedEntries     = nestedDirectories.Cast <BaseEntry>()
                                            .Union(directoryFiles);

                    foreach (var nestedEntry in nestedEntries)
                    {
                        switch (nestedEntry)
                        {
                        case FileEntry directoryFile:
                            Cache.FileNames.Remove(directoryFile.Id);
                            break;

                        case DirectoryEntry nestedDirectory:
                            Cache.DirectoryNames.Remove(nestedDirectory.Id);
                            break;
                        }
                    }

                    _rawDataManager.Write(directoryEntry);
                }


            _directoryWatcherSource.RaiseNameChanged(directory);
            _directoryWatcherSource.RaiseUpdated(parentDirectory, directory);
        }