Abstract enhanced solver for Private Working Copy Usage and Support.
Inheritance: AbstractEnhancedSolver
        private void RunSolverToChangeRemoteBeforeContinue(
            AbstractEnhancedSolverWithPWC solver,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE) {
            this.remoteDocument.Setup(d => d.ChangeToken).Returns(this.changeTokenOld + ".change");

            Assert.Throws<ArgumentException>(() => solver.Solve(this.localFile.Object, this.remoteDocument.Object, localContent, remoteContent));
            Assert.That(this.transmissionManager.ActiveTransmissions, Is.Empty);

            this.remotePWCDocument.Verify(d => d.DeleteContentStream(), Times.Exactly(1));
            this.remotePWCDocument.Verify(d => d.AppendContentStream(It.IsAny<IContentStream>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Exactly(3)); // 1 for one AppendContentStream is aborted, and 2 for the last upload having two AppendContentStream
            this.remotePWCDocument.Verify(d => d.CheckIn(It.IsAny<bool>(), It.IsAny<IDictionary<string, object>>(), null, It.IsAny<string>()), Times.Never());
        }
        private void RunSolverToContinueUpload(
            AbstractEnhancedSolverWithPWC solver,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE) {
            long readLength = 0;
            var stream = new Mock<MemoryStream>();
            stream.SetupAllProperties();
            stream.Setup(s => s.CanRead).Returns(true);
            stream.Setup(s => s.Length).Returns(this.fileLength);
            stream.Setup(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())).Returns((byte[] buffer, int offset, int count) => {
                if (readLength + count > this.fileLength) {
                    count = (int)(this.fileLength - readLength);
                }

                Array.Copy(this.fileContent, readLength, buffer, offset, count);
                readLength += count;
                return count;
            });
            stream.Setup(f => f.Seek(It.IsAny<long>(), It.IsAny<SeekOrigin>())).Callback((long offset, SeekOrigin loc) => readLength = offset);
            stream.Setup(s => s.Position).Returns(() => { return readLength; });

            this.localFile.Setup(f => f.Length).Returns(this.fileLength);
            this.localFile.Setup(f => f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(stream.Object);

            solver.Solve(this.localFile.Object, this.remoteDocument.Object, localContent, remoteContent);
            Assert.That(this.transmissionManager.ActiveTransmissions, Is.Empty);

            this.remotePWCDocument.Verify(d => d.AppendContentStream(It.IsAny<IContentStream>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Exactly(this.chunkCount + 1)); // plus 1 for one AppendContentStream is aborted
            this.remotePWCDocument.Verify(d => d.CheckIn(It.IsAny<bool>(), It.Is<IDictionary<string, object>>(p => p.ContainsKey(PropertyIds.LastModificationDate)), null, It.IsAny<string>()), Times.Once());
        }
        private void RunSolverToChangeLocalBeforeContinue(
            AbstractEnhancedSolverWithPWC solver,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE) {
            this.SetupToChangeLocal();

            solver.Solve(this.localFile.Object, this.remoteDocument.Object, localContent, remoteContent);
            Assert.That(this.transmissionManager.ActiveTransmissions, Is.Empty);

            this.remotePWCDocument.Verify(d => d.DeleteContentStream(), Times.Exactly(2));
            this.remotePWCDocument.Verify(d => d.AppendContentStream(It.IsAny<IContentStream>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Exactly(this.chunkCount + 3)); // plus 1 for one AppendContentStream is aborted, plus 2 for the last upload having two AppendContentStream
            this.remotePWCDocument.Verify(d => d.CheckIn(It.IsAny<bool>(), It.Is<IDictionary<string, object>>(p => p.ContainsKey(PropertyIds.LastModificationDate)), null, It.IsAny<string>()), Times.Once());
        }
        private void RunSolverToAbortUpload(
            AbstractEnhancedSolverWithPWC solver,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE) {
            var stream = new Mock<MemoryStream>();
            stream.SetupAllProperties();
            stream.Setup(s => s.CanRead).Returns(true);
            stream.Setup(s => s.Length).Returns(this.fileLength);
            long readLength = 0;
            stream.Setup(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())).Returns((byte[] buffer, int offset, int count) => {
                if (readLength > 0) {
                    foreach (var transmission in this.transmissionManager.ActiveTransmissions) {
                        transmission.Abort();
                    }
                }

                if (readLength + count > this.fileLength) {
                    count = (int)(this.fileLength - readLength);
                }

                Array.Copy(this.fileContent, readLength, buffer, offset, count);
                readLength += count;
                return count;
            });
            stream.Setup(s => s.Position).Returns(() => { return readLength; });

            this.localFile.Setup(f => f.Length).Returns(this.fileLength);
            this.localFile.Setup(f => f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(stream.Object);

            Assert.Throws<AbortException>(() => solver.Solve(this.localFile.Object, this.remoteDocument.Object, localContent, remoteContent));
            Assert.That(this.transmissionManager.ActiveTransmissions, Is.Empty);
        }