/// <summary>
        ///		Not thread safe
        /// </summary>
        private DirectSingleFolderWriter GetExistingWriterByFolderKey(string folderKey)
        {
            DirectSingleFolderWriter retval = null;

            _directWritersByFolderKey.TryGetValue(folderKey, out retval);
            return(retval);
        }
        /// <summary>
        ///		Not thread safe
        /// </summary>
        private DirectSingleFolderWriter GetExistingWriterByRelativePath(string relativePath)
        {
            DirectSingleFolderWriter retval = null;

            _directWritersByRelativePath.TryGetValue(relativePath, out retval);
            return(retval);
        }
        /// <summary>
        ///		Check whether the writer is accessing data in the <paramref name="folder"/> or any of its descendants.
        ///		Descandants include <paramref name="folder" /> itself.
        /// </summary>
        /// <param name="folder">
        ///		<see cref="IRepositoryFolder"/> instance representing the subtree (the folder and all its descendants) root
        /// </param>
        /// <param name="subtree">
        ///		<code>bool</code> indicating whether to check access to any of the descendants of <paramref name="folder"/> (<see langword="true"/>)
        ///		or just <paramref name="folder"/> itself.
        /// </param>
        /// <returns>
        ///		<see langword="true"/> if the accessor is accessing data in the specified folder or folders
        ///		<see langword="false"/> otherwise
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///		<paramref name="folder"/> is <see langword="null"/>
        /// </exception>
        /// <exception cref="ArgumentException">
        ///		<paramref name="folder"/> is not attached to the same <see cref="IRepositoryManager"/> instance (<see cref="Repository"/>)
        /// </exception>
        /// <remarks>
        ///		If <paramref name="folder"/> is the same as <see cref="Folder"/> the method returns <see langword="true"/>, even before acceppting
        ///		any data.
        /// </remarks>
        public bool IsAccessing(IRepositoryFolder folder, bool subtree)
        {
            Check.DoRequireArgumentNotNull(folder, "folder");

            if (!IsOpen)
            {
                return(false);
            }

            Exceptions.DifferentRepositoriesExceptionHelper.Check(folder.Repository, _repoFolder.Repository);

            bool retval = object.ReferenceEquals(folder, this.Folder);

            if (!retval)
            {
                lock (_directWritersByRelativePath)
                {
                    if (subtree)
                    {
                        for (
                            var e = _directWritersByRelativePath.Values.GetEnumerator();
                            !retval && e.MoveNext();
                            retval = e.Current.Folder.IsDescendantOf(folder))
                        {
                        }
                    }
                    else
                    {
                        DirectSingleFolderWriter writer = GetExistingWriterByFolderKey(folder.FolderKey);
                        retval = writer != null && object.ReferenceEquals(folder, writer.Folder);
                    }
                }
            }

            return(retval);
        }
        /// <summary>
        ///		Create single folder writer and add it to the collection of writers.
        /// </summary>
        /// <param name="targetFolder">
        ///		Target folder for writer
        /// </param>
        /// <returns>
        ///		New initialised instance. If the method succeeds (does not throw exception)
        /// </returns>
        /// <remarks>
        ///		Locking sequence: target folder lock start, then repo manager's registry lock/release, then direct writers collection lock/release,
        ///		then target folder released.
        /// </remarks>
        private DirectSingleFolderWriter CreateWriter(IRepositoryFolder targetFolder, string normalisedRelativePath)
        {
            Check.RequireArgumentNotNull(targetFolder, "targetFolder");
            RepositoryFolder.CheckNotDetached(targetFolder);

            IFolder folder = RepositoryFolder.CastFolder(targetFolder);

            Exceptions.DifferentRepositoriesExceptionHelper.Check(Folder.Repository, targetFolder.Repository);

            DirectSingleFolderWriter writer = null;

            ICoder compressor = GetCompressor(targetFolder: targetFolder);
            ICoder encryptor  = GetEncryptor(targetFolder: targetFolder);

            lock (targetFolder)
            {
                Check.DoAssertLambda(
                    object.ReferenceEquals(targetFolder, _repoFolder) ||                                                        // this writer has already seized this folder as target
                    !Folder.Repository.IsDataBeingWrittenTo(targetFolder, false),
                    () => new InvalidOperationException(string.Format(StorageResources.WriterAlreadyExistsForFolder, targetFolder.LogicalPath)));

                writer = new DirectSingleFolderWriter(folder, compressor, encryptor);
                writer.EqualTimestampedItemsComparer = this.EqualTimestampedItemsComparer;

                lock (_directWritersByRelativePath)
                {
                    _directWritersByRelativePath.Add(normalisedRelativePath, writer);
                    _directWritersByFolderKey.Add(targetFolder.FolderKey, writer);
                }
            }

            writer.TrackUnsavedItems = TrackUnsavedItems;

            Check.Ensure(Repository.IsDataBeingWrittenTo(targetFolder, false));
            return(writer);
        }