Pārlūkot izejas kodu

Remove Encoding from SubsystemSession and NetConfSession, and move it to SftpSession (as it is only used there).
Refactor creation of SFTP response messages to a SftpResponseFactory.
Implement SaveData for a few SFTP response messages.

Gert Driesen 8 gadi atpakaļ
vecāks
revīzija
e2cf28a28d
61 mainītis faili ar 1616 papildinājumiem un 509 dzēšanām
  1. 4 0
      src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj
  2. 38 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpDataResponseBuilder.cs
  3. 42 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpHandleResponseBuilder.cs
  4. 20 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpInitRequestBuilder.cs
  5. 61 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpNameResponseBuilder.cs
  6. 71 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpOpenRequestBuilder.cs
  7. 67 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpReadRequestBuilder.cs
  8. 61 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpRealPathRequestBuilder.cs
  9. 96 71
      src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs
  10. 85 186
      src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs
  11. 200 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs
  12. 207 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs
  13. 165 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs
  14. 61 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsRequestBuilder.cs
  15. 135 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs
  16. 16 31
      src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs
  17. 15 4
      src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs
  18. 15 8
      src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs
  19. 14 3
      src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs
  20. 7 8
      src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs
  21. 2 2
      src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs
  22. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs
  23. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs
  24. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs
  25. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs
  26. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs
  27. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs
  28. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs
  29. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs
  30. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs
  31. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs
  32. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
  33. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs
  34. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
  35. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs
  36. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs
  37. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs
  38. 1 4
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs
  39. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs
  40. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs
  41. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs
  42. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs
  43. 1 5
      src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs
  44. 12 0
      src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
  45. 4 1
      src/Renci.SshNet/IServiceFactory.cs
  46. 1 1
      src/Renci.SshNet/Netconf/NetConfSession.cs
  47. 3 0
      src/Renci.SshNet/Renci.SshNet.csproj
  48. 8 2
      src/Renci.SshNet/ServiceFactory.cs
  49. 9 0
      src/Renci.SshNet/Sftp/ISftpMessageFactory.cs
  50. 8 1
      src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs
  51. 8 1
      src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs
  52. 36 7
      src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs
  53. 5 5
      src/Renci.SshNet/Sftp/Responses/SftpResponse.cs
  54. 2 2
      src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs
  55. 22 9
      src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs
  56. 18 1
      src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs
  57. 1 47
      src/Renci.SshNet/Sftp/SftpMessage.cs
  58. 48 0
      src/Renci.SshNet/Sftp/SftpMessageFactory.cs
  59. 22 6
      src/Renci.SshNet/Sftp/SftpSession.cs
  60. 3 4
      src/Renci.SshNet/SftpClient.cs
  61. 2 12
      src/Renci.SshNet/SubsystemSession.cs

+ 4 - 0
src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj

@@ -97,6 +97,10 @@
       <Version>4.0.1</Version>
     </PackageReference>
   </ItemGroup>
+  <ItemGroup>
+    <Compile Update="..\Renci.SshNet\Sftp\ISftpMessageFactory.cs" Link="Sftp\ISftpResponseFactory.cs" />
+    <Compile Update="..\Renci.SshNet\Sftp\SftpMessageFactory.cs" Link="Sftp\SftpResponseFactory.cs" />
+  </ItemGroup>
   <PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
     <DefineConstants>TRACE;DEBUG;FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_DNS_TAP;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512</DefineConstants>
   </PropertyGroup>

+ 38 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpDataResponseBuilder.cs

@@ -0,0 +1,38 @@
+using Renci.SshNet.Sftp.Responses;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpDataResponseBuilder
+    {
+        private uint _protocolVersion;
+        private uint _responseId;
+        private byte[] _data;
+
+        public SftpDataResponseBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpDataResponseBuilder WithResponseId(uint responseId)
+        {
+            _responseId = responseId;
+            return this;
+        }
+
+        public SftpDataResponseBuilder WithData(byte[] data)
+        {
+            _data = data;
+            return this;
+        }
+
+        public SftpDataResponse Build()
+        {
+            return new SftpDataResponse(_protocolVersion)
+                {
+                    ResponseId = _responseId,
+                    Data = _data
+                };
+        }
+    }
+}

+ 42 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpHandleResponseBuilder.cs

@@ -0,0 +1,42 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpHandleResponseBuilder
+    {
+        private uint _protocolVersion;
+        private uint _responseId;
+        private byte[] _handle;
+
+        public SftpHandleResponseBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpHandleResponseBuilder WithResponseId(uint responseId)
+        {
+            _responseId = responseId;
+            return this;
+        }
+
+        public SftpHandleResponseBuilder WithHandle(byte[] handle)
+        {
+            _handle = handle;
+            return this;
+        }
+
+        public SftpHandleResponse Build()
+        {
+            var sftpHandleResponse = new SftpHandleResponse(_protocolVersion)
+            {
+                ResponseId = _responseId,
+                Handle = _handle
+            };
+            return sftpHandleResponse;
+        }
+    }
+}

+ 20 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpInitRequestBuilder.cs

@@ -0,0 +1,20 @@
+using Renci.SshNet.Sftp.Requests;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpInitRequestBuilder
+    {
+        private uint _version;
+
+        public SftpInitRequestBuilder WithVersion(uint version)
+        {
+            _version = version;
+            return this;
+        }
+
+        public SftpInitRequest Build()
+        {
+            return new SftpInitRequest(_version);
+        }
+    }
+}

+ 61 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpNameResponseBuilder.cs

@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpNameResponseBuilder
+    {
+        private uint _responseId;
+        private uint _protocolVersion;
+        private Encoding _encoding;
+        private List<KeyValuePair<string, SftpFileAttributes>> _files;
+
+        public SftpNameResponseBuilder()
+        {
+            _files = new List<KeyValuePair<string, SftpFileAttributes>>();
+        }
+
+        public SftpNameResponseBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpNameResponseBuilder WithResponseId(uint responseId)
+        {
+            _responseId = responseId;
+            return this;
+        }
+
+        public SftpNameResponseBuilder WithFiles(params KeyValuePair<string, SftpFileAttributes>[] files)
+        {
+            for (var i = 0; i < files.Length; i++)
+                _files.Add(files[i]);
+            return this;
+        }
+
+        public SftpNameResponseBuilder WithFile(string filename, SftpFileAttributes attributes)
+        {
+            _files.Add(new KeyValuePair<string, SftpFileAttributes>(filename, attributes));
+            return this;
+        }
+
+        public SftpNameResponseBuilder WithEncoding(Encoding encoding)
+        {
+            _encoding = encoding;
+            return this;
+        }
+
+        public SftpNameResponse Build()
+        {
+            var sftpNameResponse = new SftpNameResponse(_protocolVersion, _encoding)
+                {
+                    ResponseId = _responseId,
+                    Files = _files.ToArray()
+                };
+            return sftpNameResponse;
+        }
+    }
+}

+ 71 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpOpenRequestBuilder.cs

@@ -0,0 +1,71 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpOpenRequestBuilder
+    {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _fileName;
+        private Encoding _encoding;
+        private Flags _flags;
+        private Action<SftpHandleResponse> _handleAction;
+        private Action<SftpStatusResponse> _statusAction;
+
+        public SftpOpenRequestBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithRequestId(uint requestId)
+        {
+            _requestId = requestId;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithFileName(string fileName)
+        {
+            _fileName = fileName;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithEncoding(Encoding encoding)
+        {
+            _encoding = encoding;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithFlags(Flags flags)
+        {
+            _flags = flags;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithDataAction(Action<SftpHandleResponse> handleAction)
+        {
+            _handleAction = handleAction;
+            return this;
+        }
+
+        public SftpOpenRequestBuilder WithStatusAction(Action<SftpStatusResponse> statusAction)
+        {
+            _statusAction = statusAction;
+            return this;
+        }
+
+        public SftpOpenRequest Build()
+        {
+            var handleAction = _handleAction ?? ((handleResponse) => { });
+            var statusAction = _statusAction ?? ((statusResponse) => { });
+
+            return new SftpOpenRequest(_protocolVersion, _requestId, _fileName, _encoding, _flags, handleAction, statusAction);
+        }
+    }
+}

+ 67 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpReadRequestBuilder.cs

@@ -0,0 +1,67 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpReadRequestBuilder
+    {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private uint _offset;
+        private uint _length;
+        private Action<SftpDataResponse> _dataAction;
+        private Action<SftpStatusResponse> _statusAction;
+
+        public SftpReadRequestBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithRequestId(uint requestId)
+        {
+            _requestId = requestId;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithHandle(byte[] handle)
+        {
+            _handle = handle;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithOffset(uint offset)
+        {
+            _offset = offset;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithLength(uint length)
+        {
+            _length = length;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithDataAction(Action<SftpDataResponse> dataAction)
+        {
+            _dataAction = dataAction;
+            return this;
+        }
+
+        public SftpReadRequestBuilder WithStatusAction(Action<SftpStatusResponse> statusAction)
+        {
+            _statusAction = statusAction;
+            return this;
+        }
+
+        public SftpReadRequest Build()
+        {
+            var dataAction = _dataAction ?? ((dataResponse) => { });
+            var statusAction = _statusAction ?? ((statusResponse) => { });
+
+            return new SftpReadRequest(_protocolVersion, _requestId, _handle, _offset, _length, dataAction, statusAction);
+        }
+    }
+}

+ 61 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpRealPathRequestBuilder.cs

@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpRealPathRequestBuilder
+    {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _path;
+        private Encoding _encoding;
+        private Action<SftpNameResponse> _nameAction;
+        private Action<SftpStatusResponse> _statusAction;
+
+        public SftpRealPathRequestBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpRealPathRequestBuilder WithRequestId(uint requestId)
+        {
+            _requestId = requestId;
+            return this;
+        }
+
+        public SftpRealPathRequestBuilder WithPath(string path)
+        {
+            _path = path;
+            return this;
+        }
+
+        public SftpRealPathRequestBuilder WithEncoding(Encoding encoding)
+        {
+            _encoding = encoding;
+            return this;
+        }
+
+        public SftpRealPathRequestBuilder WithNameAction(Action<SftpNameResponse> nameAction)
+        {
+            _nameAction = nameAction;
+            return this;
+        }
+
+        public SftpRealPathRequestBuilder WithStatusAction(Action<SftpStatusResponse> statusAction)
+        {
+            _statusAction = statusAction;
+            return this;
+        }
+
+        public SftpRealPathRequest Build()
+        {
+            var nameAction = _nameAction ?? ((nameResponse) => { });
+            var statusAction = _statusAction ?? ((statusResponse) => { });
+
+            return new SftpRealPathRequest(_protocolVersion, _requestId, _path, _encoding, nameAction, statusAction);
+        }
+    }
+}

+ 96 - 71
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -7,19 +6,37 @@ using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Sftp;
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp
 {
     [TestClass]
     public class SftpSessionTest_Connected_RequestRead
     {
+        #region SftpSession.Connect()
+
         private Mock<ISession> _sessionMock;
         private Mock<IChannelSession> _channelSessionMock;
+        private ISftpResponseFactory _sftpMessageFactory;
         private SftpSession _sftpSession;
         private int _operationTimeout;
-        private byte[] _actual;
-        private byte[] _expected;
         private Encoding _encoding;
+        private uint _protocolVersion;
+        private byte[] _sftpInitRequestBytes;
+        private SftpVersionResponse _sftpVersionResponse;
+        private byte[] _sftpRealPathRequestBytes;
+        private SftpNameResponse _sftpNameResponse;
+
+        #endregion SftpSession.Connect()
+
+        private byte[] _sftpReadRequestBytes;
+        private byte[] _sftpDataResponseBytes;
+        private byte[] _handle;
+        private uint _offset;
+        private uint _length;
+        private byte[] _data;
+        private byte[] _actual;
 
         [TestInitialize]
         public void Setup()
@@ -28,111 +45,119 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             Act();
         }
 
-        protected void Arrange()
+        private void SetupData()
         {
             var random = new Random();
 
+            #region SftpSession.Connect()
+
             _operationTimeout = random.Next(100, 500);
-            _expected = new byte[random.Next(30, 50)];
+            _protocolVersion = (uint) random.Next(0, 3);
             _encoding = Encoding.UTF8;
-            random.NextBytes(_expected);
+            _sftpMessageFactory = new SftpResponseFactory();
+            _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+                                                                   .Build();
+            _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                        .WithRequestId(1)
+                                                                        .WithPath(".")
+                                                                        .WithEncoding(_encoding)
+                                                                        .Build()
+                                                                        .GetBytes();
+            _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                             .WithResponseId(1)
+                                                             .WithEncoding(_encoding)
+                                                             .WithFile("XYZ", SftpFileAttributes.Empty)
+                                                             .Build();
+
+            #endregion SftpSession.Connect()
+
+            _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10));
+            _offset = (uint) random.Next(1, 5);
+            _length = (uint) random.Next(30, 50);
+            _data = CryptoAbstraction.GenerateRandom((int) _length);
+            _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(2)
+                                                                .WithHandle(_handle)
+                                                                .WithOffset(_offset)
+                                                                .WithLength(_length)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                  .WithResponseId(2)
+                                                                  .WithData(_data)
+                                                                  .Build()
+                                                                  .GetBytes();
+        }
 
+        private void CreateMocks()
+        {
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
             _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+        }
 
+        private void SetupMocks()
+        {
             var sequence = new MockSequence();
 
+            #region SftpSession.Connect()
+
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
             _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
             _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
-                () =>
-                    {
-                        // generate response for SftpInitRequest
-                        var versionInfoResponse = SftpVersionResponseBuilder.Create(3)
-                                                                            .Build();
-                        _channelSessionMock.Raise(
-                            c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, versionInfoResponse));
-                    });
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+                                                    });
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
-                () =>
-                    {
-                        var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+                                                    });
+
+            #endregion SftpSession.Connect()
 
-                        _channelSessionMock.Raise(
-                            c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, sftpNameResponse));
-                    }
-                );
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
-                () =>
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes))
+                                                    .Callback(() =>
                     {
-                        var sftpDataResponse = CreateSftpDataResponse(2, _expected);
-
                         _channelSessionMock.Raise(
                             c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, sftpDataResponse.Take(0, 20)));
+                            new ChannelDataEventArgs(0, _sftpDataResponseBytes.Take(0, 20)));
                         _channelSessionMock.Raise(
                             c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, sftpDataResponse.Take(20, sftpDataResponse.Length - 20)));
+                            new ChannelDataEventArgs(0, _sftpDataResponseBytes.Take(20, _sftpDataResponseBytes.Length - 20)));
                     }
                 );
+        }
+
+        private void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
 
-            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactory);
             _sftpSession.Connect();
         }
 
         protected void Act()
         {
-            _actual = _sftpSession.RequestRead(new byte[0], 0, 200);
+            _actual = _sftpSession.RequestRead(_handle, _offset, _length);
         }
 
         [TestMethod]
         public void ReturnedValueShouldBeDataOfSftpDataResponse()
         {
             Assert.IsNotNull(_actual);
-            Assert.IsTrue(_expected.SequenceEqual(_actual));
-        }
-
-        private static byte[] CreateSftpDataResponse(uint responseId, byte[] data)
-        {
-            var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + data.Length + 1);
-            sshDataStream.Write((uint) sshDataStream.Capacity - 4);
-            sshDataStream.WriteByte((byte) SftpMessageTypes.Data);
-            sshDataStream.Write(responseId);
-            sshDataStream.Write((uint) data.Length);
-            sshDataStream.Write(data, 0, data.Length);
-            sshDataStream.WriteByte(1); // EOF
-            return sshDataStream.ToArray();
-        }
-
-        private static byte[] CreateSftpNameResponse(uint responseId, Encoding encoding, params string[] names)
-        {
-            var namesAndAttributes = new List<byte>();
-            foreach (var name in names)
-            {
-                var nameBytes = encoding.GetBytes(name);
-                var attributesBytes = SftpFileAttributes.Empty.GetBytes();
-
-                namesAndAttributes.AddRange(Pack.UInt32ToBigEndian((uint) nameBytes.Length)); // filename length
-                namesAndAttributes.AddRange(nameBytes); // filename
-                namesAndAttributes.AddRange(Pack.UInt32ToBigEndian(0U)); // longname length
-                namesAndAttributes.AddRange(attributesBytes); // attributes
-            }
-
-            var namesAndAttributesBytes = namesAndAttributes.ToArray();
-
-            var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + namesAndAttributesBytes.Length);
-            sshDataStream.Write((uint) sshDataStream.Capacity - 4);
-            sshDataStream.WriteByte((byte) SftpMessageTypes.Name);
-            sshDataStream.Write(responseId);
-            sshDataStream.Write((uint) names.Length);
-            sshDataStream.Write(namesAndAttributesBytes, 0, namesAndAttributesBytes.Length);
-            return sshDataStream.ToArray();
+            Assert.IsTrue(_data.SequenceEqual(_actual));
         }
     }
 }

+ 85 - 186
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs

@@ -1,25 +1,38 @@
 using System;
-using System.Collections.Generic;
 using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp
 {
     [TestClass]
     public class SftpSessionTest_Connected_RequestStatVfs
     {
+        #region SftpSession.Connect()
+
         private Mock<ISession> _sessionMock;
         private Mock<IChannelSession> _channelSessionMock;
+        private ISftpResponseFactory _sftpMessageFactory;
         private SftpSession _sftpSession;
         private int _operationTimeout;
-        private SftpFileSytemInformation _actual;
         private Encoding _encoding;
+        private uint _protocolVersion;
+        private SftpVersionResponse _sftpVersionResponse;
+        private SftpNameResponse _sftpNameResponse;
+        private byte[] _sftpInitRequestBytes;
+        private byte[] _sftpRealPathRequestBytes;
+
+        #endregion SftpSession.Connect()
 
+        private byte[] _sftpStatVfsRequestBytes;
+        private StatVfsResponse _sftpStatVfsResponse;
         private ulong _bAvail;
+        private string _path;
+        private SftpFileSytemInformation _actual;
 
         [TestInitialize]
         public void Setup()
@@ -28,67 +41,104 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             Act();
         }
 
-        protected void Arrange()
+        private void SetupData()
         {
             var random = new Random();
 
+            #region SftpSession.Connect()
+
             _operationTimeout = random.Next(100, 500);
             _encoding = Encoding.UTF8;
-
+            _protocolVersion = 3;
+            _sftpMessageFactory = new SftpResponseFactory();
+            _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+                                                                   .WithExtension("statvfs@openssh.com", "")
+                                                                   .Build();
+            _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                        .WithRequestId(1)
+                                                                        .WithPath(".")
+                                                                        .WithEncoding(_encoding)
+                                                                        .Build()
+                                                                        .GetBytes();
+            _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                             .WithResponseId(1U)
+                                                             .WithEncoding(_encoding)
+                                                             .WithFile("ABC", SftpFileAttributes.Empty)
+                                                             .Build();
+
+            #endregion SftpSession.Connect()
+
+            _path = random.Next().ToString();
             _bAvail = (ulong) random.Next(0, int.MaxValue);
+            _sftpStatVfsRequestBytes = new SftpStatVfsRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                      .WithRequestId(2)
+                                                                      .WithPath(_path)
+                                                                      .WithEncoding(_encoding)
+                                                                      .Build()
+                                                                      .GetBytes();
+            _sftpStatVfsResponse = new SftpStatVfsResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                   .WithResponseId(2U)
+                                                                   .WithBAvail(_bAvail)
+                                                                   .Build();
+        }
 
+        private void CreateMocks()
+        {
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
             _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+        }
 
+        private void SetupMocks()
+        {
             var sequence = new MockSequence();
 
+            #region SftpSession.Connect()
+
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
             _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
             _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes)).Callback(
                 () =>
-                    {
-                        // generate response for SftpInitRequest
-                        var versionInfoResponse = SftpVersionResponseBuilder.Create(3)
-                                                                            .AddExtension("statvfs@openssh.com", "")
-                                                                            .Build();
-                        _channelSessionMock.Raise(
-                            c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, versionInfoResponse));
-                    });
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+                });
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes)).Callback(
                 () =>
-                    {
-                        var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+                });
+
+            #endregion SftpSession.Connect()
 
-                        _channelSessionMock.Raise(
-                            c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, sftpNameResponse));
-                    }
-                );
             _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpStatVfsRequestBytes)).Callback(
                 () =>
-                    {
-                        var statVfsReplyBuilder = StatVfsReplyBuilder.Create(2);
-                        statVfsReplyBuilder.WithBAvail(_bAvail);
-                        var statVfsReply = statVfsReplyBuilder.Build();
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpStatVfsResponse.GetBytes()));
+                });
+        }
 
-                        _channelSessionMock.Raise(
-                            c => c.DataReceived += null,
-                            new ChannelDataEventArgs(0, statVfsReply));
-                    }
-                );
+        protected void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
 
-            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactory);
             _sftpSession.Connect();
         }
 
         protected void Act()
         {
-            _actual = _sftpSession.RequestStatVfs("path");
+            _actual = _sftpSession.RequestStatVfs(_path);
         }
 
         [TestMethod]
@@ -102,156 +152,5 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             Assert.AreEqual(_bAvail, _actual.AvailableBlocks);
         }
-
-        private static byte[] CreateSftpNameResponse(uint responseId, Encoding encoding, params string[] names)
-        {
-            var namesAndAttributes = new List<byte>();
-            foreach (var name in names)
-            {
-                var nameBytes = encoding.GetBytes(name);
-                var attributesBytes = SftpFileAttributes.Empty.GetBytes();
-
-                namesAndAttributes.AddRange(Pack.UInt32ToBigEndian((uint) nameBytes.Length)); // filename length
-                namesAndAttributes.AddRange(nameBytes); // filename
-                namesAndAttributes.AddRange(Pack.UInt32ToBigEndian(0U)); // longname length
-                namesAndAttributes.AddRange(attributesBytes); // attributes
-            }
-
-            var namesAndAttributesBytes = namesAndAttributes.ToArray();
-
-            var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + namesAndAttributesBytes.Length);
-            sshDataStream.Write((uint) sshDataStream.Capacity - 4);
-            sshDataStream.WriteByte((byte) SftpMessageTypes.Name);
-            sshDataStream.Write(responseId);
-            sshDataStream.Write((uint) names.Length);
-            sshDataStream.Write(namesAndAttributesBytes, 0, namesAndAttributesBytes.Length);
-            return sshDataStream.ToArray();
-        }
-
-        public class StatVfsReplyBuilder
-        {
-            private readonly uint _responseId;
-            private ulong _bsize;
-            private ulong _frsize;
-            private ulong _blocks;
-            private ulong _bfree;
-            private ulong _bavail;
-            private ulong _files;
-            private ulong _ffree;
-            private ulong _favail;
-            private ulong _sid;
-            private ulong _flag;
-            private ulong _namemax;
-
-            private StatVfsReplyBuilder(uint responseId)
-            {
-                _responseId = responseId;
-            }
-
-            public static StatVfsReplyBuilder Create(uint responseId)
-            {
-                return new StatVfsReplyBuilder(responseId);
-            }
-
-            public StatVfsReplyBuilder WithBSize(ulong bsize)
-            {
-                _bsize = bsize;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithFrSize(ulong frsize)
-            {
-                _frsize = frsize;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithBlocks(ulong blocks)
-            {
-                _blocks = blocks;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithBFree(ulong bfree)
-            {
-                _bfree = bfree;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithBAvail(ulong bavail)
-            {
-                _bavail = bavail;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithFiles(ulong files)
-            {
-                _files = files;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithFFree(ulong ffree)
-            {
-                _ffree = ffree;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithFAvail(ulong favail)
-            {
-                _favail = favail;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithSid(ulong sid)
-            {
-                _sid = sid;
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithIsReadOnly(bool isReadOnly)
-            {
-                if (isReadOnly)
-                    _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
-                else
-                    _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
-
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithSupportsSetUid(bool supportsSetUid)
-            {
-                if (supportsSetUid)
-                    _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
-                else
-                    _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
-
-                return this;
-            }
-
-            public StatVfsReplyBuilder WithNameMax(ulong nameMax)
-            {
-                _namemax = nameMax;
-                return this;
-            }
-
-            public byte[] Build()
-            {
-                var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
-                sshDataStream.Write((uint) sshDataStream.Capacity - 4);
-                sshDataStream.WriteByte((byte) SftpMessageTypes.ExtendedReply);
-                sshDataStream.Write(_responseId);
-                sshDataStream.Write(_bsize);
-                sshDataStream.Write(_frsize);
-                sshDataStream.Write(_blocks);
-                sshDataStream.Write(_bfree);
-                sshDataStream.Write(_bavail);
-                sshDataStream.Write(_files);
-                sshDataStream.Write(_ffree);
-                sshDataStream.Write(_favail);
-                sshDataStream.Write(_sid);
-                sshDataStream.Write(_flag);
-                sshDataStream.Write(_namemax);
-                return sshDataStream.ToArray();
-            }
-        }
-    }
+   }
 }

+ 200 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs

@@ -0,0 +1,200 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage
+    {
+        #region SftpSession.Connect()
+
+        private Mock<ISession> _sessionMock;
+        private Mock<IChannelSession> _channelSessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private SftpSession _sftpSession;
+        private int _operationTimeout;
+        private Encoding _encoding;
+        private uint _protocolVersion;
+        private byte[] _sftpInitRequestBytes;
+        private SftpVersionResponse _sftpVersionResponse;
+        private byte[] _sftpRealPathRequestBytes;
+        private SftpNameResponse _sftpNameResponse;
+        private byte[] _sftpOpenRequestBytes;
+        private byte[] _sftpHandleResponseBytes;
+        private byte[] _sftpReadRequestBytes;
+        private byte[] _sftpDataResponseBytes;
+        private byte[] _handle;
+        private uint _offset;
+        private uint _length;
+        private byte[] _data;
+        private string _path;
+        private byte[] _actualHandle;
+        private byte[] _actualData;
+
+        #endregion SftpSession.Connect()
+
+        [TestInitialize]
+        public void Setup()
+        {
+            Arrange();
+            Act();
+        }
+
+        private void SetupData()
+        {
+            var random = new Random();
+
+            #region SftpSession.Connect()
+
+            _operationTimeout = random.Next(100, 500);
+            _protocolVersion = (uint)random.Next(0, 3);
+            _encoding = Encoding.UTF8;
+
+            _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+                                                                   .Build();
+            _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                        .WithRequestId(1)
+                                                                        .WithPath(".")
+                                                                        .WithEncoding(_encoding)
+                                                                        .Build()
+                                                                        .GetBytes();
+            _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                             .WithResponseId(1)
+                                                             .WithEncoding(_encoding)
+                                                             .WithFile("/ABC", SftpFileAttributes.Empty)
+                                                             .Build();
+
+            #endregion SftpSession.Connect()
+
+            _path = random.Next().ToString();
+            _handle = CryptoAbstraction.GenerateRandom(4);
+            _offset = (uint) random.Next(1, 5);
+            _length = (uint) random.Next(30, 50);
+            _data = CryptoAbstraction.GenerateRandom(200);
+            _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(2)
+                                                                .WithFileName(_path)
+                                                                .WithFlags(Flags.Read)
+                                                                .WithEncoding(_encoding)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpHandleResponseBytes = new SftpHandleResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                      .WithResponseId(2)
+                                                                      .WithHandle(_handle)
+                                                                      .Build()
+                                                                      .GetBytes();
+            _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(3)
+                                                                .WithHandle(_handle)
+                                                                .WithOffset(_offset)
+                                                                .WithLength(_length)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                  .WithResponseId(3)
+                                                                  .WithData(_data)
+                                                                  .Build()
+                                                                  .GetBytes();
+        }
+
+        private void CreateMocks()
+        {
+            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
+        }
+
+        private void SetupMocks()
+        {
+            var sequence = new MockSequence();
+
+            #region SftpSession.Connect()
+
+            _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+                                                    });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(0U, (byte)SftpMessageTypes.Version, _encoding))
+                                   .Returns(_sftpVersionResponse);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+                                                    });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte)SftpMessageTypes.Name, _encoding))
+                                   .Returns(_sftpNameResponse);
+
+            #endregion SftpSession.Connect()
+
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpOpenRequestBytes));
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes)).Callback(() =>
+                {
+                    var sshMessagePayload = new byte[_sftpHandleResponseBytes.Length + _sftpDataResponseBytes.Length];
+                    Buffer.BlockCopy(_sftpHandleResponseBytes, 0, sshMessagePayload, 0, _sftpHandleResponseBytes.Length);
+                    Buffer.BlockCopy(_sftpDataResponseBytes, 0, sshMessagePayload, _sftpHandleResponseBytes.Length, _sftpDataResponseBytes.Length);
+
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, sshMessagePayload));
+                });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Handle, _encoding))
+                                   .Returns(new SftpHandleResponse(_protocolVersion));
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+                                   .Returns(new SftpDataResponse(_protocolVersion));
+        }
+
+        protected void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
+
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+            _sftpSession.Connect();
+        }
+
+        protected void Act()
+        {
+            var openAsyncResult = _sftpSession.BeginOpen(_path, Flags.Read, null, null);
+            var readAsyncResult = _sftpSession.BeginRead(_handle, _offset, _length, null, null);
+
+            _actualHandle = _sftpSession.EndOpen(openAsyncResult);
+            _actualData = _sftpSession.EndRead(readAsyncResult);
+        }
+
+        [TestMethod]
+        public void ReturnedValueShouldBeDataOfSftpDataResponse()
+        {
+            Assert.IsTrue(_data.IsEqualTo(_actualData));
+        }
+
+        [TestMethod]
+        public void ReturnedHandleShouldBeHandleOfSftpHandleResponse()
+        {
+            Assert.IsTrue(_handle.IsEqualTo(_actualHandle));
+        }
+    }
+}

+ 207 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs

@@ -0,0 +1,207 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages
+    {
+        #region SftpSession.Connect()
+
+        private Mock<ISession> _sessionMock;
+        private Mock<IChannelSession> _channelSessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private SftpSession _sftpSession;
+        private int _operationTimeout;
+        private Encoding _encoding;
+        private uint _protocolVersion;
+        private byte[] _sftpInitRequestBytes;
+        private SftpVersionResponse _sftpVersionResponse;
+        private byte[] _sftpRealPathRequestBytes;
+        private SftpNameResponse _sftpNameResponse;
+        private byte[] _sftpOpenRequestBytes;
+        private byte[] _sftpHandleResponseBytes;
+        private byte[] _sftpReadRequestBytes;
+        private byte[] _sftpDataResponseBytes;
+        private byte[] _handle;
+        private uint _offset;
+        private uint _length;
+        private byte[] _data;
+        private string _path;
+        private byte[] _actualHandle;
+        private byte[] _actualData;
+
+        #endregion SftpSession.Connect()
+
+        [TestInitialize]
+        public void Setup()
+        {
+            Arrange();
+            Act();
+        }
+
+        private void SetupData()
+        {
+            var random = new Random();
+
+            #region SftpSession.Connect()
+
+            _operationTimeout = random.Next(100, 500);
+            _protocolVersion = (uint)random.Next(0, 3);
+            _encoding = Encoding.UTF8;
+
+            _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+                                                                   .Build();
+            _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                        .WithRequestId(1)
+                                                                        .WithPath(".")
+                                                                        .WithEncoding(_encoding)
+                                                                        .Build()
+                                                                        .GetBytes();
+            _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                             .WithResponseId(1)
+                                                             .WithEncoding(_encoding)
+                                                             .WithFile("/ABC", SftpFileAttributes.Empty)
+                                                             .Build();
+
+            #endregion SftpSession.Connect()
+
+            _path = random.Next().ToString();
+            _handle = CryptoAbstraction.GenerateRandom(4);
+            _offset = (uint) random.Next(1, 5);
+            _length = (uint) random.Next(30, 50);
+            _data = CryptoAbstraction.GenerateRandom(200);
+            _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(2)
+                                                                .WithFileName(_path)
+                                                                .WithFlags(Flags.Read)
+                                                                .WithEncoding(_encoding)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpHandleResponseBytes = new SftpHandleResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                      .WithResponseId(2)
+                                                                      .WithHandle(_handle)
+                                                                      .Build()
+                                                                      .GetBytes();
+            _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(3)
+                                                                .WithHandle(_handle)
+                                                                .WithOffset(_offset)
+                                                                .WithLength(_length)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                  .WithResponseId(3)
+                                                                  .WithData(_data)
+                                                                  .Build()
+                                                                  .GetBytes();
+        }
+
+        private void CreateMocks()
+        {
+            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
+        }
+
+        private void SetupMocks()
+        {
+            var sequence = new MockSequence();
+
+            #region SftpSession.Connect()
+
+            _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+                                                    });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(0U, (byte)SftpMessageTypes.Version, _encoding))
+                                   .Returns(_sftpVersionResponse);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+                                                    .Callback(() =>
+                                                    {
+                                                        _channelSessionMock.Raise(c => c.DataReceived += null,
+                                                                                  new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+                                                    });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte)SftpMessageTypes.Name, _encoding))
+                                   .Returns(_sftpNameResponse);
+
+            #endregion SftpSession.Connect()
+
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpOpenRequestBytes)).Callback(() =>
+                {
+                    var sshMessagePayload = new byte[_sftpHandleResponseBytes.Length + 40];
+                    Buffer.BlockCopy(_sftpHandleResponseBytes, 0, sshMessagePayload, 0, _sftpHandleResponseBytes.Length);
+                    Buffer.BlockCopy(_sftpDataResponseBytes, 0, sshMessagePayload, _sftpHandleResponseBytes.Length, 40);
+
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, sshMessagePayload));
+                });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Handle, _encoding))
+                                   .Returns(new SftpHandleResponse(_protocolVersion));
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes)).Callback(() =>
+            {
+                var sshMessagePayload = new byte[_sftpDataResponseBytes.Length - 40];
+                Buffer.BlockCopy(_sftpDataResponseBytes, 40, sshMessagePayload, 0, _sftpDataResponseBytes.Length - 40);
+
+                _channelSessionMock.Raise(c => c.DataReceived += null,
+                                          new ChannelDataEventArgs(0, sshMessagePayload));
+            });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+                                   .Returns(new SftpDataResponse(_protocolVersion));
+        }
+
+        protected void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
+
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+            _sftpSession.Connect();
+        }
+
+        protected void Act()
+        {
+            var openAsyncResult = _sftpSession.BeginOpen(_path, Flags.Read, null, null);
+            var readAsyncResult = _sftpSession.BeginRead(_handle, _offset, _length, null, null);
+
+            _actualHandle = _sftpSession.EndOpen(openAsyncResult);
+            _actualData = _sftpSession.EndRead(readAsyncResult);
+        }
+
+        [TestMethod]
+        public void ReturnedValueShouldBeDataOfSftpDataResponse()
+        {
+            Assert.IsTrue(_data.IsEqualTo(_actualData));
+        }
+
+        [TestMethod]
+        public void ReturnedHandleShouldBeHandleOfSftpHandleResponse()
+        {
+            Assert.IsTrue(_handle.IsEqualTo(_actualHandle));
+        }
+    }
+}

+ 165 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs

@@ -0,0 +1,165 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage
+    {
+        #region SftpSession.Connect()
+
+        private Mock<ISession> _sessionMock;
+        private Mock<IChannelSession> _channelSessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private SftpSession _sftpSession;
+        private int _operationTimeout;
+        private Encoding _encoding;
+        private uint _protocolVersion;
+        private byte[] _sftpInitRequestBytes;
+        private SftpVersionResponse _sftpVersionResponse;
+        private byte[] _sftpRealPathRequestBytes;
+        private SftpNameResponse _sftpNameResponse;
+        private byte[] _sftpReadRequestBytes;
+        private byte[] _sftpDataResponseBytes;
+        private byte[] _handle;
+        private uint _offset;
+        private uint _length;
+        private byte[] _data;
+        private byte[] _actual;
+
+        #endregion SftpSession.Connect()
+
+        [TestInitialize]
+        public void Setup()
+        {
+            Arrange();
+            Act();
+        }
+
+        private void SetupData()
+        {
+            var random = new Random();
+
+            #region SftpSession.Connect()
+
+            _operationTimeout = random.Next(100, 500);
+            _protocolVersion = (uint) random.Next(0, 3);
+            _encoding = Encoding.UTF8;
+
+            _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+                                                                   .Build();
+            _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                        .WithRequestId(1)
+                                                                        .WithPath(".")
+                                                                        .WithEncoding(_encoding)
+                                                                        .Build()
+                                                                        .GetBytes();
+            _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                             .WithResponseId(1)
+                                                             .WithEncoding(_encoding)
+                                                             .WithFile("/ABC", SftpFileAttributes.Empty)
+                                                             .Build();
+
+            #endregion SftpSession.Connect()
+
+            _handle = CryptoAbstraction.GenerateRandom(4);
+            _offset = (uint) random.Next(1, 5);
+            _length = (uint) random.Next(30, 50);
+            _data = CryptoAbstraction.GenerateRandom(200);
+            _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+                                                                .WithRequestId(2)
+                                                                .WithHandle(_handle)
+                                                                .WithOffset(_offset)
+                                                                .WithLength(_length)
+                                                                .Build()
+                                                                .GetBytes();
+            _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+                                                                  .WithResponseId(2)
+                                                                  .WithData(_data)
+                                                                  .Build()
+                                                                  .GetBytes();
+        }
+
+        private void CreateMocks()
+        {
+            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
+        }
+
+        private void SetupMocks()
+        {
+            var sequence = new MockSequence();
+
+            #region SftpSession.Connect()
+
+            _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+                                                    .Callback(() =>
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+                });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(0U, (byte) SftpMessageTypes.Version, _encoding))
+                                   .Returns(_sftpVersionResponse);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+                                                    .Callback(() =>
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+                });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Name, _encoding))
+                                   .Returns(_sftpNameResponse);
+
+            #endregion SftpSession.Connect()
+
+            _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes))
+                                                    .Callback(() =>
+                {
+                    _channelSessionMock.Raise(c => c.DataReceived += null,
+                                              new ChannelDataEventArgs(0, _sftpDataResponseBytes));
+                });
+            _sftpMessageFactoryMock.InSequence(sequence)
+                                   .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+                                   .Returns(new SftpDataResponse(_protocolVersion));
+        }
+
+        protected void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
+
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+            _sftpSession.Connect();
+        }
+
+        protected void Act()
+        {
+            _actual = _sftpSession.RequestRead(_handle, _offset, _length);
+        }
+
+        [TestMethod]
+        public void ReturnedValueShouldBeDataOfSftpDataResponse()
+        {
+            Assert.IsTrue(_data.IsEqualTo(_actual));
+        }
+    }
+}

+ 61 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsRequestBuilder.cs

@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpStatVfsRequestBuilder
+    {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _path;
+        private Encoding _encoding;
+        private Action<SftpExtendedReplyResponse> _extendedAction;
+        private Action<SftpStatusResponse> _statusAction;
+
+        public SftpStatVfsRequestBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpStatVfsRequestBuilder WithRequestId(uint requestId)
+        {
+            _requestId = requestId;
+            return this;
+        }
+
+        public SftpStatVfsRequestBuilder WithPath(string path)
+        {
+            _path = path;
+            return this;
+        }
+
+        public SftpStatVfsRequestBuilder WithEncoding(Encoding encoding)
+        {
+            _encoding = encoding;
+            return this;
+        }
+
+        public SftpStatVfsRequestBuilder WithExtendedAction(Action<SftpExtendedReplyResponse> extendedAction)
+        {
+            _extendedAction = extendedAction;
+            return this;
+        }
+        
+        public SftpStatVfsRequestBuilder WithStatusAction(Action<SftpStatusResponse> statusAction)
+        {
+            _statusAction = statusAction;
+            return this;
+        }
+
+        public StatVfsRequest Build()
+        {
+            var extendedAction = _extendedAction ?? ((extendedReplyResponse) => { });
+            var statusAction = _statusAction ?? ((statusResponse) => { });
+
+            return new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, extendedAction, statusAction);
+        }
+    }
+}

+ 135 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs

@@ -0,0 +1,135 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    internal class SftpStatVfsResponseBuilder
+    {
+        private uint _protocolVersion;
+        private uint _responseId;
+        private ulong _bsize;
+        private ulong _frsize;
+        private ulong _blocks;
+        private ulong _bfree;
+        private ulong _bavail;
+        private ulong _files;
+        private ulong _ffree;
+        private ulong _favail;
+        private ulong _sid;
+        private ulong _flag;
+        private ulong _namemax;
+
+        public SftpStatVfsResponseBuilder WithProtocolVersion(uint protocolVersion)
+        {
+            _protocolVersion = protocolVersion;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithResponseId(uint responseId)
+        {
+            _responseId = responseId;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithBSize(ulong bsize)
+        {
+            _bsize = bsize;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithFrSize(ulong frsize)
+        {
+            _frsize = frsize;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithBlocks(ulong blocks)
+        {
+            _blocks = blocks;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithBFree(ulong bfree)
+        {
+            _bfree = bfree;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithBAvail(ulong bavail)
+        {
+            _bavail = bavail;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithFiles(ulong files)
+        {
+            _files = files;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithFFree(ulong ffree)
+        {
+            _ffree = ffree;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithFAvail(ulong favail)
+        {
+            _favail = favail;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithSid(ulong sid)
+        {
+            _sid = sid;
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithIsReadOnly(bool isReadOnly)
+        {
+            if (isReadOnly)
+                _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
+            else
+                _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
+
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithSupportsSetUid(bool supportsSetUid)
+        {
+            if (supportsSetUid)
+                _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
+            else
+                _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
+
+            return this;
+        }
+
+        public SftpStatVfsResponseBuilder WithNameMax(ulong nameMax)
+        {
+            _namemax = nameMax;
+            return this;
+        }
+
+        public StatVfsResponse Build()
+        {
+            var fileSystemInfo = new SftpFileSytemInformation(_bsize,
+                                                              _frsize,
+                                                              _blocks,
+                                                              _bfree,
+                                                              _bavail,
+                                                              _files,
+                                                              _ffree,
+                                                              _favail,
+                                                              _sid,
+                                                              _flag,
+                                                              _namemax);
+
+            return new StatVfsResponse(_protocolVersion)
+            {
+                ResponseId = _responseId,
+                Information = fileSystemInfo
+            };
+        }
+    }
+}

+ 16 - 31
src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs

@@ -1,53 +1,38 @@
 using System.Collections.Generic;
-using System.Text;
-using Renci.SshNet.Common;
-using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp
 {
-    public class SftpVersionResponseBuilder
+    internal class SftpVersionResponseBuilder
     {
-        private readonly uint _version;
-        private readonly IDictionary<string, string> _extensions;
+        private uint _version;
+        private IDictionary<string, string> _extensions;
 
-        private SftpVersionResponseBuilder(uint version)
+        public SftpVersionResponseBuilder()
         {
-            _version = version;
             _extensions = new Dictionary<string, string>();
         }
 
-        public static SftpVersionResponseBuilder Create(uint version)
+        public SftpVersionResponseBuilder WithVersion(uint version)
         {
-            return new SftpVersionResponseBuilder(version);
+            _version = version;
+            return this;
         }
 
-        public SftpVersionResponseBuilder AddExtension(string name, string data)
+        public SftpVersionResponseBuilder WithExtension(string name, string data)
         {
             _extensions.Add(name, data);
             return this;
         }
 
-        public byte[] Build()
-        {
-            var extensions = BuildExtensions();
-
-            var sshDataStream = new SshDataStream(4 + 1 + 4 + extensions.Length);
-            sshDataStream.Write((uint)sshDataStream.Capacity - 4);
-            sshDataStream.WriteByte((byte)SftpMessageTypes.Version);
-            sshDataStream.Write(_version);
-            sshDataStream.Write(extensions, 0, extensions.Length);
-            return sshDataStream.ToArray();
-        }
-
-        private byte[] BuildExtensions()
+        public SftpVersionResponse Build()
         {
-            var sshDataStream = new SshDataStream(0);
-            foreach (var extensionPair in _extensions)
-            {
-                sshDataStream.Write(extensionPair.Key, Encoding.ASCII);
-                sshDataStream.Write(extensionPair.Value, Encoding.ASCII);
-            }
-            return sshDataStream.ToArray();
+            var sftpVersionResponse = new SftpVersionResponse()
+                {
+                    Version = _version,
+                    Extentions = _extensions
+                };
+            return sftpVersionResponse;
         }
     }
 }

+ 15 - 4
src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs

@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
     {
         private Mock<IServiceFactory> _serviceFactoryMock;
         private Mock<ISession> _sessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private Mock<ISftpSession> _sftpSessionMock;
         private SftpClient _sftpClient;
         private ConnectionInfo _connectionInfo;
-        private Mock<ISftpSession> _sftpSessionMock;
         private int _operationTimeout;
 
         [TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
         {
             _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,8 +46,11 @@ namespace Renci.SshNet.Tests.Classes
                 .Returns(_sessionMock.Object);
             _sessionMock.InSequence(sequence).Setup(p => p.Connect());
             _serviceFactoryMock.InSequence(sequence)
-                .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
-                .Returns(_sftpSessionMock.Object);
+                               .Setup(p => p.CreateSftpMessageFactory())
+                               .Returns(_sftpMessageFactoryMock.Object);
+            _serviceFactoryMock.InSequence(sequence)
+                               .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
+                               .Returns(_sftpSessionMock.Object);
             _sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
             _sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
             _sftpSessionMock.InSequence(sequence).Setup(p => p.Dispose());
@@ -59,11 +64,17 @@ namespace Renci.SshNet.Tests.Classes
             _sftpClient.Dispose();
         }
 
+        [TestMethod]
+        public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+        {
+            _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+        }
+
         [TestMethod]
         public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
         {
             _serviceFactoryMock.Verify(
-                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
                 Times.Once);
         }
 

+ 15 - 8
src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs

@@ -10,9 +10,11 @@ namespace Renci.SshNet.Tests.Classes
     {
         private Mock<IServiceFactory> _serviceFactoryMock;
         private Mock<ISession> _sessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private Mock<ISftpSession> _sftpSessionMock;
         private SftpClient _sftpClient;
         private ConnectionInfo _connectionInfo;
-        private Mock<ISftpSession> _sftpSessionMock;
+
         private int _operationTimeout;
 
         [TestInitialize]
@@ -22,15 +24,11 @@ namespace Renci.SshNet.Tests.Classes
             Act();
         }
 
-        [TestCleanup]
-        public void Cleanup()
-        {
-        }
-
         protected void Arrange()
         {
             _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,7 +42,10 @@ namespace Renci.SshNet.Tests.Classes
                 .Returns(_sessionMock.Object);
             _sessionMock.InSequence(sequence).Setup(p => p.Connect());
             _serviceFactoryMock.InSequence(sequence)
-                .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
+                               .Setup(p => p.CreateSftpMessageFactory())
+                               .Returns(_sftpMessageFactoryMock.Object);
+            _serviceFactoryMock.InSequence(sequence)
+                .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
                 .Returns(_sftpSessionMock.Object);
             _sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
             _sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
@@ -60,11 +61,17 @@ namespace Renci.SshNet.Tests.Classes
             _sftpClient.Dispose();
         }
 
+        [TestMethod]
+        public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+        {
+            _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+        }
+
         [TestMethod]
         public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
         {
             _serviceFactoryMock.Verify(
-                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
                 Times.Once);
         }
 

+ 14 - 3
src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs

@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
     {
         private Mock<IServiceFactory> _serviceFactoryMock;
         private Mock<ISession> _sessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private Mock<ISftpSession> _sftpSessionMock;
         private SftpClient _sftpClient;
         private ConnectionInfo _connectionInfo;
-        private Mock<ISftpSession> _sftpSessionMock;
         private int _operationTimeout;
 
         [TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
         {
             _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,7 +46,10 @@ namespace Renci.SshNet.Tests.Classes
                 .Returns(_sessionMock.Object);
             _sessionMock.InSequence(sequence).Setup(p => p.Connect());
             _serviceFactoryMock.InSequence(sequence)
-                .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
+                               .Setup(p => p.CreateSftpMessageFactory())
+                               .Returns(_sftpMessageFactoryMock.Object);
+            _serviceFactoryMock.InSequence(sequence)
+                .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
                 .Returns(_sftpSessionMock.Object);
             _sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
             _sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
@@ -60,11 +65,17 @@ namespace Renci.SshNet.Tests.Classes
             _sftpClient.Dispose();
         }
 
+        [TestMethod]
+        public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+        {
+            _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+        }
+
         [TestMethod]
         public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
         {
             _serviceFactoryMock.Verify(
-                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+                p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
                 Times.Once);
         }
 

+ 7 - 8
src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Sftp;
@@ -11,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
     {
         private Mock<IServiceFactory> _serviceFactoryMock;
         private Mock<ISession> _sessionMock;
+        private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
+        private Mock<ISftpSession> _sftpSessionMock;
         private SftpClient _sftpClient;
         private ConnectionInfo _connectionInfo;
-        private Mock<ISftpSession> _sftpSessionMock;
         private int _operationTimeout;
 
         [TestInitialize]
@@ -27,6 +27,7 @@ namespace Renci.SshNet.Tests.Classes
         {
             _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Loose);
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -37,17 +38,15 @@ namespace Renci.SshNet.Tests.Classes
             _serviceFactoryMock.Setup(p => p.CreateSession(_connectionInfo))
                 .Returns(_sessionMock.Object);
             _sessionMock.Setup(p => p.Connect());
-            _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
-                .Returns(_sftpSessionMock.Object);
+            _serviceFactoryMock.Setup(p => p.CreateSftpMessageFactory())
+                               .Returns(_sftpMessageFactoryMock.Object);
+            _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
+                               .Returns(_sftpSessionMock.Object);
             _sftpSessionMock.Setup(p => p.Connect());
 
             _sftpClient.Connect();
             _sftpClient = null;
 
-            _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
-                .Returns((ISftpSession)  null);
-            _serviceFactoryMock.ResetCalls();
-
             // we need to dereference all other mocks as they might otherwise hold the target alive
             _sessionMock = null;
             _connectionInfo = null;

+ 2 - 2
src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs

@@ -10,8 +10,8 @@ namespace Renci.SshNet.Tests.Classes
     {
         private int _onChannelOpenInvocationCount;
 
-        public SubsystemSessionStub(ISession session, string subsystemName, int operationTimeout, Encoding encoding)
-            : base(session, subsystemName, operationTimeout, encoding)
+        public SubsystemSessionStub(ISession session, string subsystemName, int operationTimeout)
+            : base(session, subsystemName, operationTimeout)
         {
             OnDataReceivedInvocations = new List<ChannelDataEventArgs>();
         }

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private InvalidOperationException _actualException;
@@ -35,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -51,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs

@@ -18,7 +18,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private MockSequence _sequence;
@@ -35,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -55,8 +53,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ObjectDisposedException _actualException;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Dispose();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private MockSequence _sequence;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -50,8 +48,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs

@@ -15,7 +15,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -31,7 +30,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -40,8 +38,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
         }

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs

@@ -16,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
 
@@ -32,7 +31,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -41,8 +39,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
         }

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ChannelDataEventArgs _channelDataEventArgs;
@@ -35,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _channelDataEventArgs = new ChannelDataEventArgs(
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ChannelDataEventArgs _channelDataEventArgs;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _channelDataEventArgs = new ChannelDataEventArgs(
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ChannelDataEventArgs _channelDataEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _channelDataEventArgs = new ChannelDataEventArgs(
@@ -55,8 +52,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.OnDataReceivedException = _onDataReceivedException;

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ExceptionEventArgs _channelExceptionEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _channelExceptionEventArgs = new ExceptionEventArgs(new SystemException());
@@ -52,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ExceptionEventArgs _channelExceptionEventArgs;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _channelExceptionEventArgs = new ExceptionEventArgs(new SystemException());
@@ -51,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private MockSequence _sequence;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs

@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
             
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ExceptionEventArgs _errorOccurredEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _errorOccurredEventArgs = new ExceptionEventArgs(new SystemException());
@@ -52,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ExceptionEventArgs _errorOccurredEventArgs;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _errorOccurredEventArgs = new ExceptionEventArgs(new SystemException());
@@ -51,8 +48,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private byte[] _data;
@@ -35,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _data = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private ObjectDisposedException _actualException;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
 
@@ -50,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
             _subsystemSession.Connect();

+ 1 - 5
src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
         private string _subsystemName;
         private SubsystemSessionStub _subsystemSession;
         private int _operationTimeout;
-        private Encoding _encoding;
         private IList<EventArgs> _disconnectedRegister;
         private IList<ExceptionEventArgs> _errorOccurredRegister;
         private InvalidOperationException _actualException;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
             var random = new Random();
             _subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
             _operationTimeout = 30000;
-            _encoding = Encoding.UTF8;
             _disconnectedRegister = new List<EventArgs>();
             _errorOccurredRegister = new List<ExceptionEventArgs>();
             _data = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
             _subsystemSession = new SubsystemSessionStub(
                 _sessionMock.Object,
                 _subsystemName,
-                _operationTimeout,
-                _encoding);
+                _operationTimeout);
             _subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
             _subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
         }

+ 12 - 0
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -343,6 +343,7 @@
     <Compile Include="Classes\SftpClientTest_Dispose_Disconnected.cs" />
     <Compile Include="Classes\SftpClientTest_Dispose_Disposed.cs" />
     <Compile Include="Classes\SftpClientTest_Finalize_Connected.cs" />
+    <Compile Include="Classes\Sftp\SftpDataResponseBuilder.cs" />
     <Compile Include="Classes\Sftp\SftpFileReaderTestBase.cs" />
     <Compile Include="Classes\Sftp\SftpFileReaderTest_DisposeShouldUnblockReadAndReadAhead.cs" />
     <Compile Include="Classes\Sftp\SftpFileReaderTest_LastChunkBeforeEofIsComplete.cs" />
@@ -453,8 +454,19 @@
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileTest.cs" />
+    <Compile Include="Classes\Sftp\SftpHandleResponseBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpInitRequestBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpNameResponseBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpOpenRequestBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpReadRequestBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpRealPathRequestBuilder.cs" />
     <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestRead.cs" />
     <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestStatVfs.cs" />
+    <Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs" />
+    <Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs" />
+    <Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs" />
+    <Compile Include="Classes\Sftp\SftpStatVfsRequestBuilder.cs" />
+    <Compile Include="Classes\Sftp\SftpStatVfsResponseBuilder.cs" />
     <Compile Include="Classes\Sftp\SftpVersionResponseBuilder.cs" />
     <Compile Include="Classes\ShellTestTest.cs" />
     <Compile Include="Classes\ShellStreamTest.cs" />

+ 4 - 1
src/Renci.SshNet/IServiceFactory.cs

@@ -31,10 +31,11 @@ namespace Renci.SshNet
         /// <param name="session">The <see cref="ISession"/> to create the <see cref="ISftpSession"/> in.</param>
         /// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
         /// <param name="encoding">The encoding.</param>
+        /// <param name="sftpMessageFactory">The factory to use for creating SFTP messages.</param>
         /// <returns>
         /// An <see cref="ISftpSession"/>.
         /// </returns>
-        ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding);
+        ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory);
 
         /// <summary>
         /// Create a new <see cref="PipeStream"/>.
@@ -59,5 +60,7 @@ namespace Renci.SshNet
         IKeyExchange CreateKeyExchange(IDictionary<string, Type> clientAlgorithms, string[] serverAlgorithms);
 
         ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSession, uint bufferSize);
+
+        ISftpResponseFactory CreateSftpMessageFactory();
     }
 }

+ 1 - 1
src/Renci.SshNet/Netconf/NetConfSession.cs

@@ -35,7 +35,7 @@ namespace Renci.SshNet.NetConf
         /// <param name="session">The session.</param>
         /// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
         public NetConfSession(ISession session, int operationTimeout)
-            : base(session, "netconf", operationTimeout, Encoding.UTF8)
+            : base(session, "netconf", operationTimeout)
         {
             ClientCapabilities = new XmlDocument();
             ClientCapabilities.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+ 3 - 0
src/Renci.SshNet/Renci.SshNet.csproj

@@ -172,6 +172,7 @@
     <Compile Include="ServiceFactory.cs" />
     <Compile Include="ServiceFactory.NET.cs" />
     <Compile Include="Sftp\ISftpFileReader.cs" />
+    <Compile Include="Sftp\ISftpMessageFactory.cs" />
     <Compile Include="Sftp\ISftpSession.cs" />
     <Compile Include="Common\SshDataStream.cs" />
     <Compile Include="ExpectAsyncResult.cs" />
@@ -416,6 +417,7 @@
     <Compile Include="Sftp\Responses\SftpResponse.cs" />
     <Compile Include="Sftp\Responses\SftpStatusResponse.cs" />
     <Compile Include="Sftp\Responses\SftpVersionResponse.cs" />
+    <Compile Include="Sftp\Responses\StatVfsResponse.cs" />
     <Compile Include="Sftp\SftpCloseAsyncResult.cs" />
     <Compile Include="Sftp\SftpDownloadAsyncResult.cs" />
     <Compile Include="Sftp\SftpFile.cs" />
@@ -427,6 +429,7 @@
     </Compile>
     <Compile Include="Sftp\SftpListDirectoryAsyncResult.cs" />
     <Compile Include="Sftp\SftpMessage.cs" />
+    <Compile Include="Sftp\SftpMessageFactory.cs" />
     <Compile Include="Sftp\SftpMessageTypes.cs">
       <SubType>Code</SubType>
     </Compile>

+ 8 - 2
src/Renci.SshNet/ServiceFactory.cs

@@ -46,12 +46,13 @@ namespace Renci.SshNet
         /// <param name="session">The <see cref="ISession"/> to create the <see cref="ISftpSession"/> in.</param>
         /// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
         /// <param name="encoding">The encoding.</param>
+        /// <param name="sftpMessageFactory">The factory to use for creating SFTP messages.</param>
         /// <returns>
         /// An <see cref="ISftpSession"/>.
         /// </returns>
-        public ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding)
+        public ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory)
         {
-            return new SftpSession(session, operationTimeout, encoding);
+            return new SftpSession(session, operationTimeout, encoding, sftpMessageFactory);
         }
 
         /// <summary>
@@ -130,5 +131,10 @@ namespace Renci.SshNet
 
             return sftpSession.CreateFileReader(handle, sftpSession, chunkSize, maxPendingReads, fileSize);
         }
+
+        public ISftpResponseFactory CreateSftpMessageFactory()
+        {
+            return new SftpResponseFactory();
+        }
     }
 }

+ 9 - 0
src/Renci.SshNet/Sftp/ISftpMessageFactory.cs

@@ -0,0 +1,9 @@
+using System.Text;
+
+namespace Renci.SshNet.Sftp
+{
+    internal interface ISftpResponseFactory
+    {
+        SftpMessage Create(uint protocolVersion, byte messageType, Encoding encoding);
+    }
+}

+ 8 - 1
src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs

@@ -7,7 +7,7 @@
             get { return SftpMessageTypes.Data; }
         }
 
-        public byte[] Data { get; private set; }
+        public byte[] Data { get; set; }
 
         public SftpDataResponse(uint protocolVersion)
             : base(protocolVersion)
@@ -20,5 +20,12 @@
             
             Data = ReadBinary();
         }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+
+            WriteBinary(Data, 0, Data.Length);
+        }
     }
 }

+ 8 - 1
src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs

@@ -7,7 +7,7 @@
             get { return SftpMessageTypes.Handle; }
         }
 
-        public byte[] Handle { get; private set; }
+        public byte[] Handle { get; set; }
 
         public SftpHandleResponse(uint protocolVersion)
             : base(protocolVersion)
@@ -20,5 +20,12 @@
             
             Handle = ReadBinary();
         }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+
+            WriteBinary(Handle, 0, Handle.Length);
+        }
     }
 }

+ 36 - 7
src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs

@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using Renci.SshNet.Common;
+using System.Collections.Generic;
 using System.Text;
 
 namespace Renci.SshNet.Sftp.Responses
@@ -14,12 +15,12 @@ namespace Renci.SshNet.Sftp.Responses
 
         public Encoding Encoding { get; private set; }
 
-        public KeyValuePair<string, SftpFileAttributes>[] Files { get; private set; }
+        public KeyValuePair<string, SftpFileAttributes>[] Files { get; set; }
 
         public SftpNameResponse(uint protocolVersion, Encoding encoding)
             : base(protocolVersion)
         {
-            Files = new KeyValuePair<string, SftpFileAttributes>[0];
+            Files = Array<KeyValuePair<string, SftpFileAttributes>>.Empty;
             Encoding = encoding;
         }
 
@@ -29,14 +30,42 @@ namespace Renci.SshNet.Sftp.Responses
             
             Count = ReadUInt32();
             Files = new KeyValuePair<string, SftpFileAttributes>[Count];
-            
+
             for (var i = 0; i < Count; i++)
             {
                 var fileName = ReadString(Encoding);
-                ReadString(Encoding);   //  skip longname
-                var attributes = ReadAttributes();
-                Files[i] = new KeyValuePair<string, SftpFileAttributes>(fileName, attributes);
+                if (SupportsLongName(ProtocolVersion))
+                {
+                    ReadString(Encoding); // skip longname
+                }
+                Files[i] = new KeyValuePair<string, SftpFileAttributes>(fileName, ReadAttributes());
             }
         }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+
+            Write((uint) Files.Length); // count
+
+            for (var i = 0; i < Files.Length; i++)
+            {
+                var file = Files[i];
+
+                Write(file.Key, Encoding); // filename
+
+                if (SupportsLongName(ProtocolVersion))
+                {
+                    Write(0U); // longname
+                }
+
+                Write(file.Value.GetBytes()); // attrs
+            }
+        }
+
+        private static bool SupportsLongName(uint protocolVersion)
+        {
+            return protocolVersion <= 3U;
+        }
     }
 }

+ 5 - 5
src/Renci.SshNet/Sftp/Responses/SftpResponse.cs

@@ -1,10 +1,8 @@
-using System;
-
-namespace Renci.SshNet.Sftp.Responses
+namespace Renci.SshNet.Sftp.Responses
 {
     internal abstract class SftpResponse : SftpMessage
     {
-        public uint ResponseId { get; private set; }
+        public uint ResponseId { get; set; }
 
         public uint ProtocolVersion { get; private set; }
 
@@ -22,7 +20,9 @@ namespace Renci.SshNet.Sftp.Responses
 
         protected override void SaveData()
         {
-            throw new InvalidOperationException("Response cannot be saved.");
+            base.SaveData();
+
+            Write(ResponseId);
         }
     }
 }

+ 2 - 2
src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs

@@ -9,9 +9,9 @@ namespace Renci.SshNet.Sftp.Responses
             get { return SftpMessageTypes.Version; }
         }
 
-        public uint Version { get; private set; }
+        public uint Version { get; set; }
 
-        public IDictionary<string, string> Extentions { get; private set; }
+        public IDictionary<string, string> Extentions { get; set; }
 
         protected override void LoadData()
         {

+ 22 - 9
src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs

@@ -2,10 +2,10 @@
 {
     internal class StatVfsResponse : SftpExtendedReplyResponse
     {
-        public SftpFileSytemInformation Information { get; private set; }
+        public SftpFileSytemInformation Information { get; set; }
 
-        public StatVfsResponse()
-            : base(0)
+        public StatVfsResponse(uint protocolVersion)
+            : base(protocolVersion)
         {
         }
 
@@ -13,12 +13,25 @@
         {
             base.LoadData();
 
-            this.Information = new SftpFileSytemInformation(this.ReadUInt64(), this.ReadUInt64(),
-                                                                     this.ReadUInt64(), this.ReadUInt64(),
-                                                                     this.ReadUInt64(), this.ReadUInt64(),
-                                                                     this.ReadUInt64(), this.ReadUInt64(),
-                                                                     this.ReadUInt64(), this.ReadUInt64(),
-                                                                     this.ReadUInt64());
+            Information = new SftpFileSytemInformation(ReadUInt64(), // FileSystemBlockSize
+                                                       ReadUInt64(), // BlockSize
+                                                       ReadUInt64(), // TotalBlocks
+                                                       ReadUInt64(), // FreeBlocks
+                                                       ReadUInt64(), // AvailableBlocks
+                                                       ReadUInt64(), // TotalNodes
+                                                       ReadUInt64(), // FreeNodes
+                                                       ReadUInt64(), // AvailableNodes
+                                                       ReadUInt64(), // Sid
+                                                       ReadUInt64(), // Flags
+                                                       ReadUInt64()  // MaxNameLenght
+                                                       );
+        }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+
+            Information.SaveData(DataStream);
         }
     }
 }

+ 18 - 1
src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs

@@ -1,4 +1,6 @@
-namespace Renci.SshNet.Sftp
+using Renci.SshNet.Common;
+
+namespace Renci.SshNet.Sftp
 {
     /// <summary>
     /// Contains File system information exposed by statvfs@openssh.com request.
@@ -140,5 +142,20 @@
             _flag = flag;
             MaxNameLenght = namemax;
         }
+
+        internal void SaveData(SshDataStream stream)
+        {
+            stream.Write(FileSystemBlockSize);
+            stream.Write(BlockSize);
+            stream.Write(TotalBlocks);
+            stream.Write(FreeBlocks);
+            stream.Write(AvailableBlocks);
+            stream.Write(TotalNodes);
+            stream.Write(FreeNodes);
+            stream.Write(AvailableNodes);
+            stream.Write(Sid);
+            stream.Write(_flag);
+            stream.Write(MaxNameLenght);
+        }
     }
 }

+ 1 - 47
src/Renci.SshNet/Sftp/SftpMessage.cs

@@ -1,21 +1,11 @@
-using System;
-using System.IO;
+using System.IO;
 using Renci.SshNet.Common;
 using System.Globalization;
-using Renci.SshNet.Sftp.Responses;
-using System.Text;
 
 namespace Renci.SshNet.Sftp
 {
     internal abstract class SftpMessage : SshData
     {
-        public static SftpMessage Load(uint protocolVersion, byte[] data, int offset, int count, Encoding encoding)
-        {
-            var messageType = (SftpMessageTypes) data[offset];
-
-            return Load(protocolVersion, messageType, data, offset + 1, count - 1, encoding);
-        }
-
         /// <summary>
         /// Gets the size of the message in bytes.
         /// </summary>
@@ -79,42 +69,6 @@ namespace Renci.SshNet.Sftp
             return SftpFileAttributes.FromBytes(DataStream);
         }
 
-        private static SftpMessage Load(uint protocolVersion, SftpMessageTypes messageType, byte[] data, int offset, int count, Encoding encoding)
-        {
-            SftpMessage message;
-
-            switch (messageType)
-            {
-                case SftpMessageTypes.Version:
-                    message = new SftpVersionResponse();
-                    break;
-                case SftpMessageTypes.Status:
-                    message = new SftpStatusResponse(protocolVersion);
-                    break;
-                case SftpMessageTypes.Data:
-                    message = new SftpDataResponse(protocolVersion);
-                    break;
-                case SftpMessageTypes.Handle:
-                    message = new SftpHandleResponse(protocolVersion);
-                    break;
-                case SftpMessageTypes.Name:
-                    message = new SftpNameResponse(protocolVersion, encoding);
-                    break;
-                case SftpMessageTypes.Attrs:
-                    message = new SftpAttrsResponse(protocolVersion);
-                    break;
-                case SftpMessageTypes.ExtendedReply:
-                    message = new SftpExtendedReplyResponse(protocolVersion);
-                    break;
-                default:
-                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", messageType));
-            }
-
-            message.Load(data, offset, count);
-
-            return message;
-        }
-
         public override string ToString()
         {
             return string.Format(CultureInfo.CurrentCulture, "SFTP Message : {0}", SftpMessageType);

+ 48 - 0
src/Renci.SshNet/Sftp/SftpMessageFactory.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Text;
+using Renci.SshNet.Sftp.Responses;
+using System.Globalization;
+
+namespace Renci.SshNet.Sftp
+{
+    internal sealed class SftpResponseFactory : ISftpResponseFactory
+    {
+        public SftpMessage Create(uint protocolVersion, byte messageType, Encoding encoding)
+        {
+            var sftpMessageType = (SftpMessageTypes) messageType;
+
+            SftpMessage message;
+
+            switch (sftpMessageType)
+            {
+                case SftpMessageTypes.Version:
+                    message = new SftpVersionResponse();
+                    break;
+                case SftpMessageTypes.Status:
+                    message = new SftpStatusResponse(protocolVersion);
+                    break;
+                case SftpMessageTypes.Data:
+                    message = new SftpDataResponse(protocolVersion);
+                    break;
+                case SftpMessageTypes.Handle:
+                    message = new SftpHandleResponse(protocolVersion);
+                    break;
+                case SftpMessageTypes.Name:
+                    message = new SftpNameResponse(protocolVersion, encoding);
+                    break;
+                case SftpMessageTypes.Attrs:
+                    message = new SftpAttrsResponse(protocolVersion);
+                    break;
+                case SftpMessageTypes.ExtendedReply:
+                    message = new SftpExtendedReplyResponse(protocolVersion);
+                    break;
+                default:
+                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", sftpMessageType));
+            }
+
+            return message;
+        }
+
+        public 
+    }
+}

+ 22 - 6
src/Renci.SshNet/Sftp/SftpSession.cs

@@ -11,15 +11,21 @@ namespace Renci.SshNet.Sftp
 {
     internal class SftpSession : SubsystemSession, ISftpSession
     {
-        private const int MaximumSupportedVersion = 3;
+        internal const int MaximumSupportedVersion = 3;
         private const int MinimumSupportedVersion = 0;
 
         private readonly Dictionary<uint, SftpRequest> _requests = new Dictionary<uint, SftpRequest>();
+        private readonly ISftpResponseFactory _sftpMessageFactory;
         //FIXME: obtain from SftpClient!
         private readonly List<byte> _data = new List<byte>(32 * 1024);
         private EventWaitHandle _sftpVersionConfirmed = new AutoResetEvent(false);
         private IDictionary<string, string> _supportedExtensions;
 
+        /// <summary>
+        /// Gets the character encoding to use.
+        /// </summary>
+        protected Encoding Encoding { get; private set; }
+
         /// <summary>
         /// Gets the remote working directory.
         /// </summary>
@@ -49,9 +55,11 @@ namespace Renci.SshNet.Sftp
             }
         }
 
-        public SftpSession(ISession session, int operationTimeout, Encoding encoding)
-            : base(session, "sftp", operationTimeout, encoding)
+        public SftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory)
+            : base(session, "sftp", operationTimeout)
         {
+            Encoding = encoding;
+            _sftpMessageFactory = sftpMessageFactory;
         }
 
         /// <summary>
@@ -263,7 +271,7 @@ namespace Renci.SshNet.Sftp
                 // remove loaded data and bytes for length from _data holder
                 if (_data.Count == packetTotalLength)
                 {
-                    // the only buffered data is the data we're processing 
+                    // the only buffered data is the data we're processing
                     _data.Clear();
                 }
                 else
@@ -282,8 +290,10 @@ namespace Renci.SshNet.Sftp
 
         private bool TryLoadSftpMessage(byte[] packetData, int offset, int count)
         {
-            //  Load SFTP Message and handle it
-            var response = SftpMessage.Load(ProtocolVersion, packetData, offset, count, Encoding);
+            // Create SFTP message
+            var response = _sftpMessageFactory.Create(ProtocolVersion, packetData[offset], Encoding);
+            // Load message data into it
+            response.Load(packetData, offset + 1, count - 1);
 
             try
             {
@@ -1513,6 +1523,8 @@ namespace Renci.SshNet.Sftp
             // bytes 6 to 9: response id
             // bytes 10 to 13: length of payload‏
             //
+            // WinSCP uses a payload length of 32755 bytes
+            //
             // most ssh servers limit the size of the payload of a SSH_MSG_CHANNEL_DATA
             // response to 16 KB; if we requested 16 KB of data, then the SSH_FXP_DATA
             // payload of the SSH_MSG_CHANNEL_DATA message would be too big (16 KB + 13 bytes), and
@@ -1544,6 +1556,10 @@ namespace Renci.SshNet.Sftp
             // <handle>
             // 14-21: offset
             // 22-25: data length
+
+            // Putty uses data length of 4096 bytes
+            // WinSCP uses data length of 32739 bytes (total 32768 bytes; 32739 + 25 + 4 bytes for handle)
+
             var lengthOfNonDataProtocolFields = 25u + (uint)handle.Length;
             var maximumPacketSize = Channel.RemotePacketSize;
             return Math.Min(bufferSize, maximumPacketSize) - lengthOfNonDataProtocolFields;

+ 3 - 4
src/Renci.SshNet/SftpClient.cs

@@ -240,7 +240,7 @@ namespace Renci.SshNet
             : base(connectionInfo, ownsConnectionInfo, serviceFactory)
         {
             _operationTimeout = SshNet.Session.Infinite;
-            BufferSize = 1024 * 32;
+            _bufferSize = 1024 * 32;
         }
 
         #endregion Constructors
@@ -1375,8 +1375,7 @@ namespace Renci.SshNet
         {
             CheckDisposed();
 
-            return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write,
-                (int) _bufferSize);
+            return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize);
         }
 
         /// <summary>
@@ -2123,7 +2122,7 @@ namespace Renci.SshNet
         {
             base.OnConnected();
 
-            _sftpSession = ServiceFactory.CreateSftpSession(Session, _operationTimeout, ConnectionInfo.Encoding);
+            _sftpSession = ServiceFactory.CreateSftpSession(Session, _operationTimeout, ConnectionInfo.Encoding, ServiceFactory.CreateSftpMessageFactory());
             _sftpSession.Connect();
         }
 

+ 2 - 12
src/Renci.SshNet/SubsystemSession.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Globalization;
-using System.Text;
 using System.Threading;
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Channels;
@@ -72,32 +71,23 @@ namespace Renci.SshNet
             get { return _channel != null && _channel.IsOpen; }
         }
 
-        /// <summary>
-        /// Gets the character encoding to use.
-        /// </summary>
-        protected Encoding Encoding { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the SubsystemSession class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="subsystemName">Name of the subsystem.</param>
         /// <param name="operationTimeout">The number of milliseconds to wait for a given operation to complete, or -1 to wait indefinitely.</param>
-        /// <param name="encoding">The character encoding to use.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> or <paramref name="encoding"/> is <c>null</c>.</exception>
-        protected SubsystemSession(ISession session, string subsystemName, int operationTimeout, Encoding encoding)
+        /// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> is <c>null</c>.</exception>
+        protected SubsystemSession(ISession session, string subsystemName, int operationTimeout)
         {
             if (session == null)
                 throw new ArgumentNullException("session");
             if (subsystemName == null)
                 throw new ArgumentNullException("subsystemName");
-            if (encoding == null)
-                throw new ArgumentNullException("encoding");
 
             _session = session;
             _subsystemName = subsystemName;
             OperationTimeout = operationTimeout;
-            Encoding = encoding;
         }
 
         /// <summary>