Przeglądaj źródła

Fix some (lots of) issues reported by analyzers. (#1125)

Fix some (lots of) issues reported by analyzers.
Gert Driesen 2 lat temu
rodzic
commit
3ecbd1071d
100 zmienionych plików z 3193 dodań i 1309 usunięć
  1. 1235 0
      .editorconfig_soon
  2. 48 0
      Directory.Build.props
  3. 25 14
      README.md
  4. 7 5
      src/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs
  5. 0 1
      src/Renci.SshNet.Tests/Classes/MessageEventArgsTest.cs
  6. 0 1
      src/Renci.SshNet.Tests/Classes/Security/Cryptography/HMacTest.cs
  7. 11 11
      src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs
  8. 1 1
      src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs
  9. 11 4
      src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
  10. 22 2
      src/Renci.SshNet.sln
  11. 25 0
      src/Renci.SshNet/.editorconfig
  12. 1 1
      src/Renci.SshNet/Abstractions/CryptoAbstraction.cs
  13. 31 12
      src/Renci.SshNet/Abstractions/SocketAbstraction.cs
  14. 21 19
      src/Renci.SshNet/Abstractions/SocketExtensions.cs
  15. 8 4
      src/Renci.SshNet/Abstractions/ThreadAbstraction.cs
  16. 7 4
      src/Renci.SshNet/AuthenticationMethod.cs
  17. 52 42
      src/Renci.SshNet/BaseClient.cs
  18. 67 80
      src/Renci.SshNet/Channels/Channel.cs
  19. 28 10
      src/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  20. 6 0
      src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs
  21. 31 29
      src/Renci.SshNet/Channels/ChannelSession.cs
  22. 8 9
      src/Renci.SshNet/Channels/ClientChannel.cs
  23. 10 4
      src/Renci.SshNet/Channels/ServerChannel.cs
  24. 1 1
      src/Renci.SshNet/CipherInfo.cs
  25. 21 8
      src/Renci.SshNet/ClientAuthentication.cs
  26. 14 12
      src/Renci.SshNet/CommandAsyncResult.cs
  27. 47 51
      src/Renci.SshNet/Common/AsyncResult.cs
  28. 1 1
      src/Renci.SshNet/Common/AuthenticationBannerEventArgs.cs
  29. 5 5
      src/Renci.SshNet/Common/AuthenticationEventArgs.cs
  30. 9 9
      src/Renci.SshNet/Common/AuthenticationPasswordChangeEventArgs.cs
  31. 18 18
      src/Renci.SshNet/Common/AuthenticationPrompt.cs
  32. 16 16
      src/Renci.SshNet/Common/AuthenticationPromptEventArgs.cs
  33. 282 100
      src/Renci.SshNet/Common/BigInteger.cs
  34. 6 6
      src/Renci.SshNet/Common/ChannelDataEventArgs.cs
  35. 8 5
      src/Renci.SshNet/Common/ChannelEventArgs.cs
  36. 7 3
      src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs
  37. 3 3
      src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs
  38. 16 16
      src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs
  39. 10 6
      src/Renci.SshNet/Common/ChannelRequestEventArgs.cs
  40. 46 39
      src/Renci.SshNet/Common/DerData.cs
  41. 8 5
      src/Renci.SshNet/Common/ExceptionEventArgs.cs
  42. 68 18
      src/Renci.SshNet/Common/Extensions.cs
  43. 1 4
      src/Renci.SshNet/Common/HostKeyEventArgs.cs
  44. 2 2
      src/Renci.SshNet/Common/NetConfServerException.cs
  45. 12 4
      src/Renci.SshNet/Common/ObjectIdentifier.cs
  46. 23 17
      src/Renci.SshNet/Common/PacketDump.cs
  47. 122 84
      src/Renci.SshNet/Common/PipeStream.cs
  48. 17 13
      src/Renci.SshNet/Common/PortForwardEventArgs.cs
  49. 53 5
      src/Renci.SshNet/Common/PosixPath.cs
  50. 5 5
      src/Renci.SshNet/Common/ProxyException.cs
  51. 15 15
      src/Renci.SshNet/Common/ScpDownloadEventArgs.cs
  52. 2 2
      src/Renci.SshNet/Common/ScpException.cs
  53. 15 15
      src/Renci.SshNet/Common/ScpUploadEventArgs.cs
  54. 34 22
      src/Renci.SshNet/Common/SemaphoreLight.cs
  55. 2 2
      src/Renci.SshNet/Common/SftpPathNotFoundException.cs
  56. 2 2
      src/Renci.SshNet/Common/SftpPermissionDeniedException.cs
  57. 11 11
      src/Renci.SshNet/Common/ShellDataEventArgs.cs
  58. 2 4
      src/Renci.SshNet/Common/SshAuthenticationException.cs
  59. 41 19
      src/Renci.SshNet/Common/SshData.cs
  60. 34 26
      src/Renci.SshNet/Common/SshDataStream.cs
  61. 2 2
      src/Renci.SshNet/Common/SshOperationTimeoutException.cs
  62. 3 5
      src/Renci.SshNet/Common/SshPassPhraseNullOrEmptyException.cs
  63. 13 13
      src/Renci.SshNet/Common/TerminalModes.cs
  64. 12 11
      src/Renci.SshNet/Compression/Compressor.cs
  65. 11 7
      src/Renci.SshNet/Connection/ConnectorBase.cs
  66. 2 1
      src/Renci.SshNet/Connection/DirectConnector.cs
  67. 22 16
      src/Renci.SshNet/Connection/HttpConnector.cs
  68. 68 61
      src/Renci.SshNet/Connection/ProtocolVersionExchange.cs
  69. 4 4
      src/Renci.SshNet/Connection/ProxyConnector.cs
  70. 10 8
      src/Renci.SshNet/Connection/Socks4Connector.cs
  71. 31 17
      src/Renci.SshNet/Connection/Socks5Connector.cs
  72. 20 13
      src/Renci.SshNet/Connection/SshIdentification.cs
  73. 97 97
      src/Renci.SshNet/ConnectionInfo.cs
  74. 13 5
      src/Renci.SshNet/ExpectAction.cs
  75. 5 4
      src/Renci.SshNet/ExpectAsyncResult.cs
  76. 11 15
      src/Renci.SshNet/ForwardedPort.cs
  77. 14 18
      src/Renci.SshNet/ForwardedPortDynamic.NET.cs
  78. 28 21
      src/Renci.SshNet/ForwardedPortDynamic.cs
  79. 10 13
      src/Renci.SshNet/ForwardedPortLocal.NET.cs
  80. 32 21
      src/Renci.SshNet/ForwardedPortLocal.cs
  81. 40 32
      src/Renci.SshNet/ForwardedPortRemote.cs
  82. 18 6
      src/Renci.SshNet/ForwardedPortStatus.cs
  83. 4 3
      src/Renci.SshNet/IBaseClient.cs
  84. 4 3
      src/Renci.SshNet/IConnectionInfo.cs
  85. 0 2
      src/Renci.SshNet/IRemotePathTransformation.cs
  86. 2 2
      src/Renci.SshNet/IServiceFactory.cs
  87. 2 1
      src/Renci.SshNet/ISession.cs
  88. 5 4
      src/Renci.SshNet/ISftpClient.cs
  89. 25 23
      src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs
  90. 12 25
      src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs
  91. 5 3
      src/Renci.SshNet/MessageEventArgs.cs
  92. 10 10
      src/Renci.SshNet/Messages/Authentication/RequestMessageHost.cs
  93. 11 5
      src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs
  94. 4 4
      src/Renci.SshNet/Messages/Connection/ChannelMessage.cs
  95. 4 2
      src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs
  96. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelOpen/DirectTcpipChannelInfo.cs
  97. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelOpen/ForwardedTcpipChannelInfo.cs
  98. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelOpen/SessionChannelOpenInfo.cs
  99. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelOpen/X11ChannelOpenInfo.cs
  100. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelRequest/BreakRequestInfo.cs

+ 1235 - 0
.editorconfig_soon

@@ -0,0 +1,1235 @@
+// Avoid looking for .editorconfig files in parent directories
+root=true
+
+[*]
+
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+
+[*.cs]
+
+#### Sonar rules ####
+
+# S101: Types should be named in PascalCase
+# https://rules.sonarsource.com/csharp/RSPEC-101
+#
+# TODO: Remove this when code has been updated!
+dotnet_diagnostic.S101.severity = none
+
+# S112: General exceptions should never be thrown
+# https://rules.sonarsource.com/csharp/RSPEC-112
+#
+# This is a duplicate of CA2201 and MA0012.
+dotnet_diagnostic.S112.severity = none
+
+# S907: Remove use of 'goto'
+# https://rules.sonarsource.com/csharp/RSPEC-907
+#
+# Limited use of 'goto' is accepted when performance is critical.
+dotnet_diagnostic.S907.severity = none
+
+# S1066: Collapsible "if" statements should be merged
+# https://rules.sonarsource.com/csharp/RSPEC-1066
+#
+dotnet_diagnostic.S1066.severity = none
+
+# S1075: URIs should not be hardcoded
+# https://rules.sonarsource.com/csharp/RSPEC-1075
+#
+# The rule reports false positives for XML namespaces.
+dotnet_diagnostic.S1075.severity = none
+
+# S1104: Fields should not have public accessibility
+# https://rules.sonarsource.com/csharp/RSPEC-1104
+#
+# This is a duplicate of SA1401 and CA1051.
+dotnet_diagnostic.S1104.severity = none
+
+# S1125: Boolean literals should not be redundant
+# https://rules.sonarsource.com/csharp/RSPEC-1125
+#
+# This is a duplicate of MA0073.
+dotnet_diagnostic.S1125.severity = none
+
+# S1135: Track uses of "TODO" tags
+#
+# This is a duplicate of MA0026.
+dotnet_diagnostic.S1135.severity = none
+
+# S1168: Empty arrays and collections should be returned instead of null
+# https://rules.sonarsource.com/csharp/RSPEC-1168
+#
+# We sometimes return null to avoid allocating an empty List<T>.
+dotnet_diagnostic.S1168.severity = none
+
+# S1172: Unused method parameters should be removed
+# https://rules.sonarsource.com/csharp/RSPEC-1172
+#
+# This is a duplicate of IDE0060.
+dotnet_diagnostic.S1172.severity = none
+
+# S1481: Unused local variables should be removed
+# https://rules.sonarsource.com/csharp/RSPEC-1481
+#
+# This is a duplicate of IDE0059.
+dotnet_diagnostic.S1481.severity = none
+
+# S2259: Null pointers should not be dereferenced
+# https://rules.sonarsource.com/csharp/RSPEC-2259
+#
+# The analysis is not precise enough, leading to false positives.
+dotnet_diagnostic.S2259.severity = none
+
+# S2445: Blocks should be synchronized on read-only fields
+# https://rules.sonarsource.com/csharp/RSPEC-2445
+#
+# This is a (partial) duplicate of MA0064.
+dotnet_diagnostic.S2445.severity = none
+
+# S2551: Shared resources should not be used for locking
+# https://rules.sonarsource.com/csharp/RSPEC-2551
+#
+# This is a duplicate of CA2002, and partial duplicate of MA0064.
+dotnet_diagnostic.S2551.severity = none
+
+# S2583: Conditionally executed code should be reachable
+# https://rules.sonarsource.com/csharp/RSPEC-2583
+#
+# This rule produces false errors in, for example, for loops.
+#dotnet_diagnostic.S2583.severity = none
+
+# S2699: Tests should include assertions
+# https://rules.sonarsource.com/csharp/RSPEC-2699
+#
+# Sometimes you want a test in which you invoke a method and just want to verify that it does not throw.
+# For example:
+# [TestMethod]
+# public void InvokeDisposeWithoutNotifyObjectShouldNotThrow()
+# {
+#     _timer.Dispose();
+# }
+dotnet_diagnostic.S2699.severity = none
+
+# S2933: Fields that are only assigned in the constructor should be "readonly"
+# https://rules.sonarsource.com/csharp/RSPEC-2933
+#
+# This is a duplicate of IDE0044, but IDE0044 is not reported when targeting .NET Framework 4.8.
+dotnet_diagnostic.S2933.severity = none
+
+# S2971: "IEnumerable" LINQs should be simplified
+# https://rules.sonarsource.com/csharp/RSPEC-2971
+#
+# This is a duplicate of MA0020.
+dotnet_diagnostic.S2971.severity = none
+
+# S3218: Inner class members should not shadow outer class "static" or type members
+# https://rules.sonarsource.com/csharp/RSPEC-3218
+#
+# This is rather harmless.
+dotnet_diagnostic.S3218.severity = none
+
+# S3267: Loops should be simplified with "LINQ" expressions
+# https://rules.sonarsource.com/csharp/RSPEC-3267
+#
+# LINQ is the root of all evil :p
+dotnet_diagnostic.S3267.severity = none
+
+# S3376: Attribute, EventArgs, and Exception type names should end with the type being extended
+# https://rules.sonarsource.com/csharp/RSPEC-3376
+#
+# This is a partial duplicate of MA0058. If we enable the Sonar in all repositories, we should
+# consider enabling S3376 in favor of MA0058.
+dotnet_diagnostic.S3376.severity = none
+
+# S3871: Exception types should be "public"
+# https://rules.sonarsource.com/csharp/RSPEC-3871
+#
+# This is a duplicate of CA1064.
+dotnet_diagnostic.S3871.severity = none
+
+# S3925: "ISerializable" should be implemented correctly
+# https://rules.sonarsource.com/csharp/RSPEC-3925
+#
+# This is a duplicate of CA2229.
+dotnet_diagnostic.S3925.severity = none
+
+# S3928: Parameter names used into ArgumentException constructors should match an existing one
+# https://rules.sonarsource.com/csharp/RSPEC-3928
+#
+# This is a duplicate of MA0015.
+dotnet_diagnostic.S3928.severity = none
+
+# S3998: Threads should not lock on objects with weak identity
+# https://rules.sonarsource.com/csharp/RSPEC-3998
+#
+# This is a duplicate of CA2002, and partial duplicate of MA0064.
+dotnet_diagnostic.S3998.severity = none
+
+# S4456: Parameter validation in yielding methods should be wrapped
+# https://rules.sonarsource.com/csharp/RSPEC-4456
+#
+# This is a duplicate of MA0050.
+dotnet_diagnostic.S4456.severity = none
+
+# S4487: Unread "private" fields should be removed
+# https://rules.sonarsource.com/csharp/RSPEC-4487
+#
+# This is a duplicate of IDE0052.
+dotnet_diagnostic.S4487.severity = none
+
+# S4581: "new Guid()" should not be used
+# https://rules.sonarsource.com/csharp/RSPEC-4581
+#
+# This is a partial duplicate of MA0067, and we do not want to report the use of 'default' for a Guid as error.
+dotnet_diagnostic.S4581.severity = none
+
+#### StyleCop rules ####
+
+# SA1003: Symbols must be spaced correctly
+#
+# When enabled, a diagnostic is produced when there's a space after a cast.
+# For example:
+# var x = (int) z;
+dotnet_diagnostic.SA1003.severity = none
+
+# SA1008: Opening parenthesis should not be preceded by a space
+#
+# When enabled, a diagnostic is produce when a cast precedes braces.
+# For example:
+# (long) (a * b)
+dotnet_diagnostic.SA1008.severity = none
+
+# SA1009: Closing parenthesis should not be followed by a space
+#
+# When enabled, a diagnostic is produced when there's a space after a cast.
+# For example:
+# var x = (int) z;
+dotnet_diagnostic.SA1009.severity = none
+
+# SA1101: Prefix local calls with this
+dotnet_diagnostic.SA1101.severity = none
+
+# SA1116: Split parameters must start on line after declaration
+#
+# When enabled, a diagnostic is produced when the first parameter is on the same line as the method or constructor.
+# For example:
+# arrayBuilder.Add(new StatisticsCallInfo(callsByType.Key,
+#                                         callsForType.Count);
+dotnet_diagnostic.SA1116.severity = none
+
+# SA1200: Using directives must be placed correctly
+#
+# This is already verified by the .NET compiler platform analyzers (csharp_using_directive_placement option and IDE0065 rule).
+dotnet_diagnostic.SA1200.severity = none
+
+# SA1201: Elements must appear in the correct order
+dotnet_diagnostic.SA1201.severity = none
+
+# SA1206: Modifiers are not ordered
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1206.md
+#
+# This is a duplicate of IDE0036, except that it cannot be configured and expects the required modifier to be before the
+# accessibility modifier.
+dotnet_diagnostic.SA1206.severity = none
+
+# SA1309: Field names must not begin with underscore
+dotnet_diagnostic.SA1309.severity = none
+
+# SA1405: Debug.Assert should provide message text
+#
+# To be discussed if we want to enable this.
+dotnet_diagnostic.SA1405.severity = none
+
+# SA1413: Use trailing comma in multi-line initializers
+dotnet_diagnostic.SA1413.severity = none
+
+# SA1503: Braces should not be omitted
+#
+# This is a duplicate of IDE0011.
+dotnet_diagnostic.SA1503.severity = none
+
+# SA1516: Elements must be separated by blank line
+#
+# When enabled, a diagnostic is produced for properties with both a get and set accessor.
+# For example:
+# public bool EnableStatistics
+# {
+#     get
+#     {
+#         return _enableStatistics;
+#     }
+#     set
+#     {
+#         _enableStatistics = value;
+#     }
+# }
+dotnet_diagnostic.SA1516.severity = none
+
+# SA1520: Use braces consistently
+#
+# Since we always require braces (configured via csharp_prefer_braces and reported as IDE0011), it does not make sense to check if braces
+# are used consistently.
+dotnet_diagnostic.SA1520.severity = none
+
+# SA1633: File must have header
+#
+# We do not use file headers.
+dotnet_diagnostic.SA1633.severity = none
+
+# SA1648: <inheritdoc> must be used with inheriting class
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+dotnet_diagnostic.SA1648.severity = error
+
+# SX1101: Do not prefix local members with 'this.'
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+dotnet_diagnostic.SX1101.severity = error
+
+# SX1309: Field names must begin with underscore
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+dotnet_diagnostic.SX1309.severity = error
+
+# SX1309S: Static field names must begin with underscore
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+dotnet_diagnostic.SX1309S.severity = error
+
+#### Meziantou.Analyzer rules ####
+
+# MA0002: Use an overload that has a IEqualityComparer<string> or IComparer<string> parameter
+#
+# In .NET (Core) there have been quite some optimizations for EqualityComparer<T>.Default (eg. https://github.com/dotnet/coreclr/pull/14125)
+# and Comparer<T>.Default (eg. https://github.com/dotnet/runtime/pull/48160).
+#
+# We'll have to verify impact on performance before we decide to use specific comparers (eg. StringComparer.InvariantCultureIgnoreCase).
+dotnet_diagnostic.MA0002.severity = none
+
+# MA0006: Use string.Equals instead of Equals operator
+#
+# We almost always want ordinal comparison, and using the explicit overload adds a little overhead
+# and is more chatty.
+dotnet_diagnostic.MA0006.severity = none
+
+# MA0007: Add a comma after the last value
+#
+# We do not add a comma after the last value in multi-line initializers.
+# For example:
+# public enum Sex
+# {
+#     Male = 1,
+#     Female = 2 // No comma here
+# }
+#
+# Note:
+# This is a duplicate of SA1413.
+dotnet_diagnostic.MA0007.severity = none
+
+# MA0009: Add regex evaluation timeout
+#
+# We do not see a need guard our regex's against a DOS attack.
+dotnet_diagnostic.MA0009.severity = none
+
+# MA0011: IFormatProvider is missing
+#
+# Also report diagnostic in ToString(...) methods
+MA0011.exclude_tostring_methods = false
+
+# MA0012: Do not raise reserved exception type
+#
+# This is a duplicate of CA2201.
+dotnet_diagnostic.MA0012.severity = none
+
+# MA0014: Do not raise System.ApplicationException type
+#
+# This is a duplicate of CA2201.
+dotnet_diagnostic.MA0014.severity = none
+
+# MA0016: Prefer returning collection abstraction instead of implementation
+#
+# This is a duplicate of CA1002.
+dotnet_diagnostic.MA0016.severity = none
+
+# MA0018: Do not declare static members on generic types
+#
+# This is a duplicate of CA1000.
+dotnet_diagnostic.MA0018.severity = none
+
+# MA0021: Use StringComparer.GetHashCode instead of string.GetHashCode
+#
+# No strong need for this, and may negatively affect performance.
+dotnet_diagnostic.MA0021.severity = none
+
+# MA0031: Optimize Enumerable.Count() usage
+# https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0031.md
+#
+# The proposed code is less readable.
+#
+# For example:
+#
+# the following code fragment:
+# enumerable.Count() > 10;
+#
+# would become:
+# enumerable.Skip(10).Any();
+dotnet_diagnostic.MA0031.severity = none
+
+# MA0036: Make class static
+#
+# This is a partial duplicate of CA1052.
+dotnet_diagnostic.MA0036.severity = none
+
+# MA0038: Make method static
+#
+# This is a partial duplicate of, and deprecated in favor of, CA1822.
+dotnet_diagnostic.MA0038.severity = none
+
+# MA0041: Make property static
+#
+# This is a partial duplicate of, and deprecated in favor of, CA1822.
+dotnet_diagnostic.MA0041.severity = none
+
+# MA0048: File name must match type name
+#
+# This is a duplicate of SA1649.
+dotnet_diagnostic.MA0048.severity = none
+
+# MA0049: Type name should not match containing namespace
+#
+# This is a duplicate of CA1724
+dotnet_diagnostic.MA0049.severity = none
+
+# MA0051: Method is too long
+#
+# We do not want to limit the number of lines or statements per method.
+dotnet_diagnostic.MA0051.severity = none
+
+# MA0053: Make class sealed
+#
+# Also report diagnostic for public types.
+MA0053.public_class_should_be_sealed = true
+
+# MA0053: Make class sealed
+#
+# Also report diagnostic for types that derive from System.Exception.
+MA0053.exceptions_should_be_sealed = true
+
+# MA0053: Make class sealed
+#
+# Also report diagnostic for types that define (new) virtual members.
+MA0053.class_with_virtual_member_shoud_be_sealed = true
+
+# MA0112: Use 'Count > 0' instead of 'Any()'
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+dotnet_diagnostic.MA0112.severity = error
+
+#### .NET Compiler Platform code quality rules ####
+
+# CA1002: Do not expose generic lists
+#
+# For performance reasons - to avoid interface dispatch - we expose generic lists
+# instead of a base class or interface.
+dotnet_diagnostic.CA1002.severity = none
+
+# CA1008: Enums should have zero value
+#
+# TODO: To be discussed. Having a zero value offers a performance advantage.
+dotnet_diagnostic.CA1008.severity = none
+
+# CA1014: Mark assemblies with CLSCompliantAttribute
+#
+# This rule is disabled by default, hence we need to explicitly enable it.
+#
+# Even when enabled, this diagnostic does not appear to be reported for assemblies without CLSCompliantAttribute.
+# We reported this issue as https://github.com/dotnet/roslyn-analyzers/issues/6563.
+dotnet_diagnostic.CA1014.severity = error
+
+# CA1051: Do not declare visible instance fields
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1051
+#
+# This is a duplicate of S1104 and SA1401.
+dotnet_diagnostic.CA1051.severity = none
+
+# CA1052: Static holder types should be Static or NotInheritable
+#
+# By default, this diagnostic is only reported for public types.
+dotnet_code_quality.CA1052.api_surface = all
+
+# CA1303: Do not pass literals as localized parameters
+#
+# We don't care about localization.
+dotnet_diagnostic.CA1303.severity = none
+
+# CA1305: Specify IFormatProvider
+#
+# This is a an equivalent of MA0011, except that it does not report a diagnostic for the use of
+# DateTime.TryParse(string s, out DateTime result).
+#
+# Submitted https://github.com/dotnet/roslyn-analyzers/issues/6096 to fix CA1305.
+dotnet_diagnostic.CA1305.severity = none
+
+# CA1510: Use ArgumentNullException throw helper
+#
+# This is only available in .NET 6.0 and higher. We'd need to use conditional compilation to only
+# use these throw helper when targeting a framework that supports it.
+dotnet_diagnostic.CA1510.severity = none
+
+# CA1725: Parameter names should match base declaration
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1725
+#
+# This is a duplicate of S927, but contains at least one bug:
+# https://github.com/dotnet/roslyn-analyzers/issues/6461
+#
+# Since we do not enable any of the Sonar rules by default, we'll leave CA1725 enabled.
+dotnet_diagnostic.CA1725.severity = error
+
+# CA1819: Properties should not return arrays
+#
+# Arrays offer better performance than collections.
+dotnet_diagnostic.CA1819.severity = none
+
+# CA1828: Mark members as static
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
+#
+# Documentation does not mention which API surface(s) this rule runs on, so we explictly configure it.
+dotnet_code_quality.CA1828.api_surface = all
+
+# CA1852: Seal internal types
+#
+# Similar to MA0053, but does not support public types and types that define (new) virtual members.
+dotnet_diagnostic.CA1852.severity = none
+
+# CA1859: Change return type for improved performance
+#
+# By default, this diagnostic is only reported for private members.
+dotnet_code_quality.CA1859.api_surface = all
+
+# CA2208: Instantiate argument exceptions correctly
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2208
+#
+# This is similar to, but less powerful than, MA0015.
+dotnet_diagnostic.CA2208.severity = none
+
+#### Roslyn IDE analyser rules ####
+
+# IDE0032: Use auto-implemented property
+#
+# For performance reasons, we do not always want to enforce the use of
+# auto-implemented properties.
+dotnet_diagnostic.IDE0032.severity = suggestion
+
+# IDE0045: Use conditional expression for assignment
+#
+# This does not always result in cleaner/clearer code.
+dotnet_diagnostic.IDE0045.severity = none
+
+# IDE0046: Use conditional expression for return
+# 
+# Using a conditional expression is not always a clear win for readability.
+#
+# Configured using 'dotnet_style_prefer_conditional_expression_over_return'
+dotnet_diagnostic.IDE0046.severity = suggestion
+
+# IDE0055: Fix formatting
+#
+# When enabled, diagnostics are reported for indented object initializers.
+# For example:
+# _content = new Person
+#     {
+#         Name = "\u13AAlarm"
+#     };
+#
+# There are no settings to configure this correctly, unless https://github.com/dotnet/roslyn/issues/63256 (or similar) is ever implemented.
+dotnet_diagnostic.IDE0055.severity = none
+
+# IDE0270: Null check can be simplified
+# 
+# var inputPath = originalDossierPathList.Find(x => x.id == updatedPath.id);
+# if (inputPath is null)
+# {
+#     throw new PcsException($"Path id ({updatedPath.id}) unknown in PCS for dossier id {dossierFromTs.dossier.id}", updatedPath.id);
+# }
+#
+# We do not want to modify the code using a null coalescing operator:
+#
+# var inputPath = originalDossierPathList.Find(x => x.id == updatedPath.id) ?? throw new PcsException($"Path id ({updatedPath.id}) unknown in PCS for dossier id {dossierFromTs.dossier.id}", updatedPath.id);
+dotnet_diagnostic.IDE0270.severity = none
+
+#### .NET Compiler Platform code style rules ####
+
+### Language rules ###
+
+## Modifier preferences
+
+dotnet_style_require_accessibility_modifiers = true
+dotnet_style_readonly_field = true
+csharp_prefer_static_local_function = true
+
+## Parentheses preferences
+
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+
+# Expression-level preferences
+
+dotnet_style_object_initializer = true
+csharp_style_inlined_variable_declaration = true
+dotnet_style_collection_initializer = true
+dotnet_style_prefer_auto_properties = true
+dotnet_style_explicit_tuple_names = true
+csharp_prefer_simple_default_expression = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_deconstructed_variable_declaration = false
+dotnet_style_prefer_conditional_expression_over_assignment = true
+dotnet_style_prefer_conditional_expression_over_return = true
+dotnet_style_prefer_compound_assignment = true
+csharp_style_prefer_index_operator = false
+csharp_style_prefer_range_operator = false
+dotnet_style_prefer_simplified_interpolation = false
+dotnet_style_prefer_simplified_boolean_expressions = true
+csharp_style_implicit_object_creation_when_type_is_apparent = false
+csharp_style_prefer_tuple_swap = false
+
+# Namespace declaration preferences
+
+csharp_style_namespace_declarations = block_scoped
+
+# Null-checking preferences
+
+csharp_style_throw_expression = false
+dotnet_style_coalesce_expression = true
+dotnet_style_null_propagation = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_conditional_delegate_call = true
+
+# 'var' preferences
+
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
+csharp_style_var_elsewhere = true
+
+# Expression-bodies members
+
+csharp_style_expression_bodied_methods = false
+csharp_style_expression_bodied_constructors = false
+csharp_style_expression_bodied_operators = false
+csharp_style_expression_bodied_properties = false
+csharp_style_expression_bodied_indexers = false
+csharp_style_expression_bodied_accessors = false
+csharp_style_expression_bodied_lambdas = false
+csharp_style_expression_bodied_local_functions = false
+
+# Pattern matching preferences
+
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_switch_expression = false
+csharp_style_prefer_pattern_matching = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_extended_property_pattern = true
+
+# Code block preferences
+
+csharp_prefer_braces = true
+csharp_prefer_simple_using_statement = false
+
+# Using directive preferences
+
+csharp_using_directive_placement = outside_namespace
+
+# Namespace naming preferences
+
+dotnet_style_namespace_match_folder = true
+
+# Undocumented preferences
+
+csharp_style_prefer_method_group_conversion = false
+csharp_style_prefer_top_level_statements = false
+
+### Formatting rules ###
+
+## .NET formatting options ##
+
+# Using directive options
+
+dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = true
+
+## C# formatting options ##
+
+# New-line options
+
+# TNIS-13005: Enabling this setting breaks Resharper indentation for lambdas
+#csharp_new_line_before_open_brace = accessors, anonymous_methods, anonymous_types, control_blocks, events, indexers, lambdas, local_functions, methods, object_collection_array_initializers, properties, types
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+# Enabling this setting breaks Resharper formatting for an enum field reference that is
+# deeply nested in an object initializer.
+# 
+# For an example, see TDataExchangeGeneralEnricher_CernInfrastructureObstruction.
+#csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation options
+
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_block_contents = true
+# TNIS-13005: Enabling this setting breaks Resharper indentation for lambdas
+#csharp_indent_braces = false
+# TNIS-13005: Enabling this setting breaks Resharper indentation for lambdas
+#csharp_indent_case_contents_when_block = true
+
+# Spacing options
+
+csharp_space_after_cast = true
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_parentheses = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_after_comma = true
+csharp_space_before_comma = false
+csharp_space_after_dot = false
+csharp_space_before_dot = false
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_around_declaration_statements = false
+csharp_space_before_open_square_brackets = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_square_brackets = false
+
+# Wrap options
+
+csharp_preserve_single_line_statements = false
+csharp_preserve_single_line_blocks = true
+
+### Naming styles ###
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_fields_camel_case_begins_with_underscore.symbols = private_fields
+dotnet_naming_rule.private_fields_camel_case_begins_with_underscore.style = camel_case_begins_with_underscore
+dotnet_naming_rule.private_fields_camel_case_begins_with_underscore.severity = error
+
+dotnet_naming_rule.private_static_fields_camel_case_begins_with_underscore.symbols = private_static_fields
+dotnet_naming_rule.private_static_fields_camel_case_begins_with_underscore.style = camel_case_begins_with_underscore
+dotnet_naming_rule.private_static_fields_camel_case_begins_with_underscore.severity = error
+
+dotnet_naming_rule.private_static_readonly_fields_pascal_case.symbols = private_static_readonly_fields
+dotnet_naming_rule.private_static_readonly_fields_pascal_case.style = pascal_case
+dotnet_naming_rule.private_static_readonly_fields_pascal_case.severity = error
+
+dotnet_naming_rule.private_const_fields_pascal_case.symbols = private_const_fields
+dotnet_naming_rule.private_const_fields_pascal_case.style = pascal_case
+dotnet_naming_rule.private_const_fields_pascal_case.severity = error
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = *
+dotnet_naming_symbols.interface.required_modifiers = 
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = *
+dotnet_naming_symbols.types.required_modifiers = 
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = *
+dotnet_naming_symbols.non_field_members.required_modifiers = 
+
+dotnet_naming_symbols.private_fields.applicable_kinds = field
+dotnet_naming_symbols.private_fields.applicable_accessibilities = private
+dotnet_naming_symbols.private_fields.required_modifiers = 
+
+dotnet_naming_symbols.private_static_fields.applicable_kinds = field
+dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private
+dotnet_naming_symbols.private_static_fields.required_modifiers = static
+
+dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private
+dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = static, readonly
+
+dotnet_naming_symbols.private_const_fields.applicable_kinds = field
+dotnet_naming_symbols.private_const_fields.applicable_accessibilities = private
+dotnet_naming_symbols.private_const_fields.required_modifiers = const
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix = 
+dotnet_naming_style.begins_with_i.word_separator = 
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix = 
+dotnet_naming_style.pascal_case.required_suffix = 
+dotnet_naming_style.pascal_case.word_separator = 
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.camel_case_begins_with_underscore.required_prefix = _
+dotnet_naming_style.camel_case_begins_with_underscore.required_suffix = 
+dotnet_naming_style.camel_case_begins_with_underscore.word_separator = 
+dotnet_naming_style.camel_case_begins_with_underscore.capitalization = camel_case
+
+#### .NET Compiler Platform general options ####
+
+# Change the default rule severity for all analyzer rules that are enabled by default
+dotnet_analyzer_diagnostic.severity = error
+
+#### .NET Compiler Platform code refactoring rules ####
+
+dotnet_style_operator_placement_when_wrapping = end_of_line
+
+#### ReSharper code style for C# ####
+
+## Blank Lines
+
+resharper_csharp_blank_lines_around_region = 1
+resharper_csharp_blank_lines_inside_region = 1
+resharper_csharp_blank_lines_before_single_line_comment = 1
+resharper_csharp_keep_blank_lines_in_declarations = 1
+resharper_csharp_remove_blank_lines_near_braces_in_declarations = true
+resharper_csharp_blank_lines_after_start_comment = 1
+resharper_csharp_blank_lines_between_using_groups = 1
+resharper_csharp_blank_lines_after_using_list = 1
+resharper_csharp_blank_lines_around_namespace = 1
+resharper_csharp_blank_lines_inside_namespace = 0
+resharper_csharp_blank_lines_after_file_scoped_namespace_directive = 1
+resharper_csharp_blank_lines_around_type = 1
+resharper_csharp_blank_lines_around_single_line_type = 1
+resharper_csharp_blank_lines_inside_type = 0
+resharper_csharp_blank_lines_around_field = 0
+resharper_csharp_blank_lines_around_single_line_field = 0
+resharper_csharp_blank_lines_around_property = 1
+resharper_csharp_blank_lines_around_single_line_property = 1
+resharper_csharp_blank_lines_around_auto_property = 1
+resharper_csharp_blank_lines_around_single_line_auto_property = 1
+resharper_csharp_blank_lines_around_accessor = 0
+resharper_csharp_blank_lines_around_single_line_accessor = 0
+resharper_csharp_blank_lines_around_invocable = 1
+resharper_csharp_blank_lines_around_single_line_invocable = 1
+resharper_csharp_keep_blank_lines_in_code = 1
+resharper_csharp_remove_blank_lines_near_braces_in_code = true
+resharper_csharp_blank_lines_around_local_method = 1
+resharper_csharp_blank_lines_around_single_line_local_method = 1
+resharper_csharp_blank_lines_before_control_transfer_statements = 0
+resharper_csharp_blank_lines_after_control_transfer_statements = 0
+resharper_csharp_blank_lines_before_block_statements = 0
+resharper_csharp_blank_lines_after_block_statements = 1
+resharper_csharp_blank_lines_before_multiline_statements = 0
+resharper_csharp_blank_lines_after_multiline_statements = 0
+resharper_csharp_blank_lines_around_block_case_section = 0
+resharper_csharp_blank_lines_around_multiline_case_section = 0
+resharper_csharp_blank_lines_before_case = 0
+resharper_csharp_blank_lines_after_case = 0
+
+## Braces Layout
+
+resharper_csharp_type_declaration_braces = next_line
+resharper_csharp_indent_inside_namespace = true
+resharper_csharp_invocable_declaration_braces = next_line
+resharper_csharp_anonymous_method_declaration_braces = next_line_shifted_2
+resharper_csharp_accessor_owner_declaration_braces = next_line
+resharper_csharp_accessor_declaration_braces = next_line
+resharper_csharp_case_block_braces = next_line_shifted_2
+resharper_csharp_initializer_braces = next_line_shifted_2
+resharper_csharp_use_continuous_indent_inside_initializer_braces = true
+resharper_csharp_other_braces = next_line
+resharper_csharp_allow_comment_after_lbrace = false
+resharper_csharp_empty_block_style = multiline
+
+## Syntax Style
+
+# 'var' usage in declarations
+
+resharper_csharp_for_built_in_types = use_var
+resharper_csharp_for_simple_types = use_var
+resharper_csharp_for_other_types = use_var
+
+# Instance members qualification
+
+resharper_csharp_instance_members_qualify_members = none
+resharper_csharp_instance_members_qualify_declared_in = base_class
+
+# Static members qualification
+
+resharper_csharp_static_members_qualify_with = declared_type
+resharper_csharp_static_members_qualify_members = none
+
+# Built-in types
+
+resharper_csharp_builtin_type_reference_style = use_keyword
+resharper_csharp_builtin_type_reference_for_member_access_style = use_keyword
+
+# Reference qualification and 'using' directives
+
+resharper_csharp_prefer_qualified_reference = false
+resharper_csharp_add_imports_to_deepest_scope = false
+resharper_csharp_qualified_using_at_nested_scope = false
+resharper_csharp_allow_alias = true
+resharper_csharp_can_use_global_alias = true
+
+# Modifiers
+
+resharper_csharp_default_private_modifier = explicit
+resharper_csharp_default_internal_modifier = explicit
+resharper_csharp_modifiers_order = public private protected internal file static extern new virtual abstract sealed override readonly unsafe required volatile async
+
+# Braces
+
+resharper_csharp_braces_for_ifelse = required
+resharper_csharp_braces_for_for = required
+resharper_csharp_braces_for_foreach = required
+resharper_csharp_braces_for_while = required
+resharper_csharp_braces_for_dowhile = required
+resharper_csharp_braces_for_using = required
+resharper_csharp_braces_for_lock = required
+resharper_csharp_braces_for_fixed = required
+resharper_csharp_braces_redundant = false
+
+# Code body
+
+resharper_csharp_method_or_operator_body = block_body
+resharper_csharp_local_function_body = block_body
+resharper_csharp_constructor_or_destructor_body = block_body
+resharper_csharp_accessor_owner_body = accessors_with_block_body
+resharper_csharp_namespace_body = block_scoped
+resharper_csharp_use_heuristics_for_body_style = false
+
+# Trailing comma
+
+resharper_csharp_trailing_comma_in_multiline_lists = false
+resharper_csharp_trailing_comma_in_singleline_lists = false
+
+# Object creation
+
+resharper_csharp_object_creation_when_type_evident = explicitly_typed
+resharper_csharp_object_creation_when_type_not_evident = explicitly_typed
+
+# Default value
+
+resharper_csharp_default_value_when_type_evident = default_literal
+resharper_csharp_default_value_when_type_not_evident = default_literal
+
+## Tabs, Indents, Alignment
+
+# Nested statements
+
+resharper_csharp_indent_nested_usings_stmt = false
+resharper_csharp_indent_nested_fixed_stmt = false
+resharper_csharp_indent_nested_lock_stmt = false
+resharper_csharp_indent_nested_for_stmt = true
+resharper_csharp_indent_nested_foreach_stmt =  true
+resharper_csharp_indent_nested_while_stmt = true
+
+# Parenthesis
+
+resharper_csharp_use_continuous_indent_inside_parens = true
+resharper_csharp_indent_method_decl_pars = outside_and_inside
+resharper_csharp_indent_invocation_pars = outside_and_inside
+resharper_csharp_indent_statement_pars = outside_and_inside
+resharper_csharp_indent_typeparam_angles = outside_and_inside
+resharper_csharp_indent_typearg_angles = outside_and_inside
+resharper_csharp_indent_pars = outside_and_inside
+
+# Preprocessor directives
+
+resharper_csharp_indent_preprocessor_if = no_indent
+resharper_csharp_indent_preprocessor_region = usual_indent
+resharper_csharp_indent_preprocessor_other = no_indent
+
+# Other indents
+
+resharper_indent_switch_labels = true
+resharper_csharp_outdent_statement_labels = true
+resharper_csharp_indent_type_constraints = true
+resharper_csharp_stick_comment = false
+resharper_csharp_place_comments_at_first_column = false
+resharper_csharp_use_indent_from_previous_element = true
+resharper_csharp_indent_braces_inside_statement_conditions = true
+
+# Align multiline constructs
+
+resharper_csharp_alignment_tab_fill_style = use_spaces
+resharper_csharp_allow_far_alignment = true
+resharper_csharp_align_multiline_parameter = true
+resharper_csharp_align_multiline_extends_list = true
+resharper_csharp_align_linq_query = true
+resharper_csharp_align_multiline_binary_expressions_chain = true
+resharper_csharp_outdent_binary_ops = false
+resharper_csharp_align_multiline_calls_chain = true
+resharper_csharp_outdent_dots = false
+resharper_csharp_align_multiline_array_and_object_initializer = false
+resharper_csharp_align_multiline_switch_expression = false
+resharper_csharp_align_multiline_property_pattern = false
+resharper_csharp_align_multiline_list_pattern = false
+resharper_csharp_align_multiline_binary_patterns = false
+resharper_csharp_outdent_binary_pattern_ops = false
+resharper_csharp_indent_anonymous_method_block = true
+resharper_csharp_align_first_arg_by_paren = false
+resharper_csharp_align_multiline_argument = true
+resharper_csharp_align_tuple_components = true
+resharper_csharp_align_multiline_expression = true
+resharper_csharp_align_multiline_statement_conditions = true
+resharper_csharp_align_multiline_for_stmt = true
+resharper_csharp_align_multiple_declaration = true
+resharper_csharp_align_multline_type_parameter_list = true
+resharper_csharp_align_multline_type_parameter_constrains = true
+resharper_csharp_outdent_commas = false
+
+## Line Breaks
+
+# General
+
+resharper_csharp_keep_user_linebreaks = true
+resharper_csharp_max_line_length = 140
+resharper_csharp_wrap_before_comma = false
+resharper_csharp_wrap_before_eq = false
+resharper_csharp_special_else_if_treatment = true
+resharper_csharp_insert_final_newline = true
+
+# Arrangement of attributes
+
+resharper_csharp_keep_existing_attribute_arrangement = false
+resharper_csharp_place_type_attribute_on_same_line = false
+resharper_csharp_place_method_attribute_on_same_line = false
+resharper_csharp_place_accessorholder_attribute_on_same_line = false
+resharper_csharp_place_accessor_attribute_on_same_line = false
+resharper_csharp_place_field_attribute_on_same_line = false
+resharper_csharp_place_record_field_attribute_on_same_line = true
+
+# Arrangement of method signatures
+
+resharper_csharp_place_constructor_initializer_on_same_line = false
+resharper_csharp_place_expr_method_on_single_line = true
+resharper_csharp_place_expr_property_on_single_line = true
+resharper_csharp_place_expr_accessor_on_single_line = true
+
+# Arrangement of type parameters, constraints, and base types
+
+resharper_csharp_place_type_constraints_on_same_line = false
+resharper_csharp_wrap_before_first_type_parameter_constraint = true
+
+# Arrangement of declaration blocks
+
+resharper_csharp_place_abstract_accessorholder_on_single_line = true
+
+# Arrangement of statements
+
+resharper_new_line_before_else = true
+resharper_new_line_before_while = true
+resharper_new_line_before_catch = true
+resharper_new_line_before_finally = true
+resharper_wrap_for_stmt_header_style = chop_if_long
+resharper_wrap_multiple_declaration_style = chop_always
+
+## Spaces
+
+# Preserve existing formatting
+
+resharper_csharp_extra_spaces = remove_all
+
+# Before parentheses in statements
+
+resharper_csharp_space_before_if_parentheses = true
+resharper_csharp_space_before_while_parentheses = true
+resharper_csharp_space_before_catch_parentheses = true
+resharper_csharp_space_before_switch_parentheses = true
+resharper_csharp_space_before_for_parentheses = true
+resharper_csharp_space_before_foreach_parentheses = true
+resharper_csharp_space_before_using_parentheses = true
+resharper_csharp_space_before_lock_parentheses = true
+resharper_csharp_space_before_fixed_parentheses = true
+
+# Before other parentheses
+
+resharper_csharp_space_before_method_call_parentheses = false
+resharper_csharp_space_before_empty_method_call_parentheses = false
+resharper_csharp_space_before_method_parentheses = false
+resharper_csharp_space_before_empty_method_parentheses = false
+resharper_csharp_space_before_typeof_parentheses = false
+resharper_csharp_space_before_default_parentheses = false
+resharper_csharp_space_before_checked_parentheses = false
+resharper_csharp_space_before_sizeof_parentheses = false
+resharper_csharp_space_before_nameof_parentheses = false
+resharper_csharp_space_before_new_parentheses = false
+resharper_csharp_space_between_keyword_and_expression = true
+resharper_csharp_space_between_keyword_and_type = false
+
+# Within parentheses in statements
+
+resharper_csharp_space_within_if_parentheses = false
+resharper_csharp_space_within_while_parentheses = false
+resharper_csharp_space_within_catch_parentheses = false
+resharper_csharp_space_within_switch_parentheses = false
+resharper_csharp_space_within_for_parentheses = false
+resharper_csharp_space_within_foreach_parentheses = false
+resharper_csharp_space_within_using_parentheses = false
+resharper_csharp_space_within_lock_parentheses = false
+resharper_csharp_space_within_fixed_parentheses = false
+
+# Within other parentheses
+
+resharper_csharp_space_within_parentheses = false
+resharper_csharp_space_between_typecast_parentheses = false
+resharper_csharp_space_between_method_declaration_parameter_list_parentheses = false
+resharper_csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+resharper_csharp_space_between_method_call_parameter_list_parentheses = false
+resharper_csharp_space_between_method_call_empty_parameter_list_parentheses = false
+resharper_csharp_space_within_typeof_parentheses = false
+resharper_csharp_space_within_default_parentheses = false
+resharper_csharp_space_within_checked_parentheses = false
+resharper_csharp_space_within_sizeof_parentheses = false
+resharper_csharp_space_within_nameof_parentheses = false
+resharper_csharp_space_within_new_parentheses = false
+
+# Around array brackets
+
+resharper_csharp_space_before_array_access_brackets = false
+resharper_csharp_space_before_open_square_brackets = false
+resharper_csharp_space_before_array_rank_brackets = false
+resharper_csharp_space_within_array_access_brackets = false
+resharper_csharp_space_between_square_brackets = false
+resharper_csharp_space_within_array_rank_brackets = false
+resharper_csharp_space_within_array_rank_empty_brackets = false
+resharper_csharp_space_between_empty_square_bracket = false
+
+# Around angle brackets
+
+resharper_csharp_space_before_type_parameter_angle = false
+resharper_csharp_space_before_type_argument_angle = false
+resharper_csharp_space_within_type_parameter_angles = false
+resharper_csharp_space_within_type_argument_angles = false
+
+### ReSharper code style for XMLDOC ###
+
+## Tabs and indents
+
+resharper_xmldoc_indent_style = space
+# ReSharper currently ignores this setting. See https://youtrack.jetbrains.com/issue/RSRP-465678/XMLDOC-indent-settings-ignored.
+resharper_xmldoc_indent_size = 2
+resharper_xmldoc_tab_width = 2
+resharper_xmldoc_alignment_tab_fill_style = use_spaces
+resharper_xmldoc_allow_far_alignment = true
+
+## Line wrapping
+
+resharper_xmldoc_max_line_length = 140
+resharper_xmldoc_wrap_tags_and_pi = false
+
+## Processing instructions
+
+resharper_xmldoc_spaces_around_eq_in_pi_attribute = false
+resharper_xmldoc_space_after_last_pi_attribute = false
+resharper_xmldoc_pi_attribute_style = on_single_line
+resharper_xmldoc_pi_attributes_indent = align_by_first_attribute
+resharper_xmldoc_blank_line_after_pi = false
+
+## Inside of tag header
+
+resharper_xmldoc_spaces_around_eq_in_attribute = false
+resharper_xmldoc_space_after_last_attribute = false
+resharper_xmldoc_space_before_self_closing = false
+resharper_xmldoc_attribute_style = do_not_touch
+resharper_xmldoc_attribute_indent = align_by_first_attribute
+
+## Tag content
+
+resharper_xmldoc_keep_user_linebreaks = true
+resharper_xmldoc_linebreaks_inside_tags_for_multiline_elements = true
+resharper_xmldoc_linebreaks_inside_tags_for_elements_with_child_elements = false
+resharper_xmldoc_spaces_inside_tags = false
+resharper_xmldoc_wrap_text = false
+resharper_xmldoc_wrap_around_elements = false
+# ReSharper currently ignores the 'resharper_xmldoc_indent_size' setting. Once https://youtrack.jetbrains.com/issue/RSRP-465678/XMLDOC-indent-settings-ignored
+# is fixed, we should change the value of this setting to 'one_indent'.
+resharper_xmldoc_indent_child_elements = zero_indent
+resharper_xmldoc_indent_text = zero_indent
+
+## Around tags
+
+resharper_xmldoc_max_blank_lines_between_tags = 1
+resharper_xmldoc_linebreak_before_multiline_elements = true
+resharper_xmldoc_linebreak_before_singleline_elements = false
+
+[*.{xml,xsd,csproj,targets,proj,props,runsettings,config}]
+
+#### ReSharper code style for XML ####
+
+## Tabs and indents
+
+resharper_xml_indent_style = space
+resharper_xml_indent_size = 4
+resharper_xml_tab_width = 4
+resharper_xml_alignment_tab_fill_style = use_spaces
+resharper_xml_allow_far_alignment = true
+
+## Line wrapping
+
+resharper_xml_wrap_tags_and_pi = false
+
+## Processing instructions
+
+resharper_xml_spaces_around_eq_in_pi_attribute = false
+resharper_xml_space_after_last_pi_attribute = false
+resharper_xml_pi_attribute_style = on_single_line
+resharper_xml_pi_attributes_indent = align_by_first_attribute
+resharper_xml_blank_line_after_pi = false
+
+## Inside of tag header
+
+resharper_xml_spaces_around_eq_in_attribute = false
+resharper_xml_space_after_last_attribute = false
+resharper_xml_space_before_self_closing = true
+resharper_xml_attribute_style = do_not_touch
+resharper_xml_attribute_indent = align_by_first_attribute
+
+## Tag content
+
+resharper_xml_keep_user_linebreaks = true
+resharper_xml_linebreaks_inside_tags_for_multiline_elements = false
+resharper_xml_linebreaks_inside_tags_for_elements_with_child_elements = false
+resharper_xml_linebreaks_inside_tags_for_elements_longer_than = false
+resharper_xml_spaces_inside_tags = false
+resharper_xml_wrap_text = false
+resharper_xml_wrap_around_elements = false
+resharper_xml_indent_child_elements = one_indent
+resharper_xml_indent_text = zero_indent
+resharper_xml_max_blank_lines_between_tags = 1
+resharper_xml_linebreak_before_multiline_elements = false
+resharper_xml_linebreak_before_singleline_elements = false
+
+## Other
+
+resharper_xml_insert_final_newline = true

+ 48 - 0
Directory.Build.props

@@ -0,0 +1,48 @@
+<Project>
+    <Import Project="$(MSBuildThisFileFullPath).user" Condition="Exists('$(MSBuildThisFileFullPath).user')" />
+    
+    <!--
+        Assembly Info properties that apply to all projects/assemblies.
+    -->
+    <PropertyGroup>
+        <SignAssembly>true</SignAssembly>
+        <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)src\Renci.SshNet.snk</AssemblyOriginatorKeyFile>
+        <GenerateDocumentationFile>true</GenerateDocumentationFile>
+        <LangVersion>latest</LangVersion>
+        <!--
+        <WarningLevel>9999</WarningLevel>
+        <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+        -->
+        <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
+    </PropertyGroup>
+
+    <!--
+        Code analysis properties.
+    -->
+    <PropertyGroup>
+        <EnableNETAnalyzers>false</EnableNETAnalyzers>
+        <AnalysisLevel>preview-All</AnalysisLevel>
+        <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
+    </PropertyGroup>
+
+    <!--
+        Add the stylecop config to each project.
+    -->
+    <ItemGroup>
+        <AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />
+    </ItemGroup>
+
+    <!--
+        Use fixed version of analyzers.
+    -->
+    <ItemGroup>
+        <!--
+        <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0-preview1.23165.1" PrivateAssets="all" />
+        <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="all" />
+        <PackageReference Include="Meziantou.Analyzer" Version="2.0.52" PrivateAssets="all" />
+        -->
+        <!--
+        <PackageReference Include="SonarAnalyzer.CSharp" Version="8.55.0.65544" PrivateAssets="all" />
+        -->
+    </ItemGroup>
+</Project>

+ 25 - 14
README.md

@@ -1,26 +1,37 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Common;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Common
-{   
-    /// <summary>
-    ///This is a test class for ObjectIdentifierTest and is intended
-    ///to contain all ObjectIdentifierTest Unit Tests
-    ///</summary>
+{
     [TestClass]
-    [Ignore] // placeholder for actual test
     public class ObjectIdentifierTest : TestBase
     {
-        /// <summary>
-        ///A test for ObjectIdentifier Constructor
-        ///</summary>
         [TestMethod]
-        public void ObjectIdentifierConstructorTest()
+        public void Constructor_IdentifiersIsNull()
         {
-            ulong[] identifiers = null; // TODO: Initialize to an appropriate value
-            ObjectIdentifier target = new ObjectIdentifier(identifiers);
-            Assert.Inconclusive("TODO: Implement code to verify target");
+            const ulong[] identifiers = null;
+
+            var actualException = Assert.ThrowsException<ArgumentNullException>(() => new ObjectIdentifier(identifiers));
+
+            Assert.AreEqual(typeof(ArgumentNullException), actualException.GetType());
+            Assert.IsNull(actualException.InnerException);
+            Assert.AreEqual(nameof(identifiers), actualException.ParamName);
+        }
+
+        [TestMethod]
+        public void Constructor_LengthOfIdentifiersIsLessThanTwo()
+        {
+            var identifiers = new[] { 5UL };
+
+            var actualException = Assert.ThrowsException<ArgumentException>(() => new ObjectIdentifier(identifiers));
+
+            Assert.AreEqual(typeof(ArgumentException), actualException.GetType());
+            Assert.IsNull(actualException.InnerException);
+            ArgumentExceptionAssert.MessageEquals("Must contain at least two elements.", actualException);
+            Assert.AreEqual(nameof(identifiers), actualException.ParamName);
         }
     }
 }

+ 7 - 5
src/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs

@@ -1,13 +1,15 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Common;
-using Renci.SshNet.Connection;
-using Renci.SshNet.Tests.Common;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Net;
 using System.Net.Sockets;
 using System.Threading;
 
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Renci.SshNet.Common;
+using Renci.SshNet.Connection;
+using Renci.SshNet.Tests.Common;
+
 namespace Renci.SshNet.Tests.Classes.Connection
 {
     [TestClass]

+ 0 - 1
src/Renci.SshNet.Tests/Classes/MessageEventArgsTest.cs

@@ -6,7 +6,6 @@ namespace Renci.SshNet.Tests.Classes
     /// <summary>
     /// Provides data for message events.
     /// </summary>
-    /// <typeparam name="T">Message type</typeparam>
     [TestClass]
     public class MessageEventArgsTest : TestBase
     {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/Security/Cryptography/HMacTest.cs

@@ -8,7 +8,6 @@ namespace Renci.SshNet.Tests.Classes.Security.Cryptography
     /// <summary>
     /// Provides HMAC algorithm implementation.
     /// </summary>
-    /// <typeparam name="T"></typeparam>
     [TestClass]
     public class HMacTest : TestBase
     {

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

@@ -147,17 +147,17 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             base.LoadData();
 
             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
-                                                        );
+                                                       ReadUInt64(), // BlockSize
+                                                       ReadUInt64(), // TotalBlocks
+                                                       ReadUInt64(), // FreeBlocks
+                                                       ReadUInt64(), // AvailableBlocks
+                                                       ReadUInt64(), // TotalNodes
+                                                       ReadUInt64(), // FreeNodes
+                                                       ReadUInt64(), // AvailableNodes
+                                                       ReadUInt64(), // Sid
+                                                       ReadUInt64(), // Flags
+                                                       ReadUInt64()  // MaxNameLenght
+                                                       );
         }
 
         protected override void SaveData()

+ 1 - 1
src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs

@@ -40,7 +40,7 @@ namespace Renci.SshNet.Tests.Common
         /// <value>
         /// <see langword="true"/> to invoke <see cref="Socket.Shutdown(SocketShutdown)"/> on the <see cref="Socket"/> that is used
         /// to handle the communication with the remote host, when the remote host has closed the connection; otherwise,
-        /// <see langword="false""/>. The default is <see langword="true"/>.
+        /// <see langword="false"/>. The default is <see langword="true"/>.
         /// </value>
         public bool ShutdownRemoteCommunicationSocket { get; set; }
 

+ 11 - 4
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -1,9 +1,16 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-	<LangVersion>7.3</LangVersion>
-	<SignAssembly>true</SignAssembly>
-    <AssemblyOriginatorKeyFile>..\Renci.SshNet.snk</AssemblyOriginatorKeyFile>
-	<TargetFrameworks>net462;net6.0;net7.0</TargetFrameworks>
+    <TargetFrameworks>net462;net6.0;net7.0</TargetFrameworks>
+    <!--
+          Even though we're not interested in producing XML docs for test projects, we have to enable this in order to have the .NET Compiler
+          Platform analyzers produce the IDE0005 (Remove unnecessary import) diagnostic.
+            
+          To avoid warnings for missing XML docs, we add CS1591 (Missing XML comment for publicly visible type or member) to the NoWarn property.
+
+          We can stop producing XML docs for test projects (and remove the NoWarn for CS1591) once the following issue is fixed:
+          https://github.com/dotnet/roslyn/issues/41640.
+      -->
+    <NoWarn>$(NoWarn);CS1591</NoWarn>
   </PropertyGroup>
 
   <PropertyGroup>

+ 22 - 2
src/Renci.SshNet.sln

@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29521.150
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33326.253
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2D6CAE62-D053-476F-9BDD-2B1F27FA9C5D}"
 	ProjectSection(SolutionItems) = preProject
@@ -23,6 +23,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Renci.SshNet", "Renci.SshNe
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Renci.SshNet.Tests", "Renci.SshNet.Tests\Renci.SshNet.Tests.csproj", "{C45379B9-17B1-4E89-BC2E-6D41726413E8}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{04E8CC26-116E-4116-9558-7ED542548E70}"
+	ProjectSection(SolutionItems) = preProject
+		..\.editorconfig = ..\.editorconfig
+		..\.gitattributes = ..\.gitattributes
+		..\.gitignore = ..\.gitignore
+		..\appveyor.yml = ..\appveyor.yml
+		..\CODEOWNERS = ..\CODEOWNERS
+		..\Directory.Build.props = ..\Directory.Build.props
+		..\LICENSE = ..\LICENSE
+		..\README.md = ..\README.md
+		..\THIRD-PARTY-NOTICES.TXT = ..\THIRD-PARTY-NOTICES.TXT
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{D21A4D03-0AC2-4613-BB6D-74D2D16A72CC}"
+	ProjectSection(SolutionItems) = preProject
+		..\test\.editorconfig = ..\test\.editorconfig
+		..\test\Directory.Build.props = ..\test\Directory.Build.props
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -72,6 +91,7 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{94EE3919-19FA-4D9B-8DA9-249050B15232} = {2D6CAE62-D053-476F-9BDD-2B1F27FA9C5D}
 		{A6C3FFD3-16A5-44D3-8C1F-3613D6DD17D1} = {2D6CAE62-D053-476F-9BDD-2B1F27FA9C5D}
+		{D21A4D03-0AC2-4613-BB6D-74D2D16A72CC} = {04E8CC26-116E-4116-9558-7ED542548E70}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {BAD6019D-4AF7-4E15-99A0-8036E16FC0E5}

+ 25 - 0
src/Renci.SshNet/.editorconfig

@@ -0,0 +1,25 @@
+[*.cs]
+
+### StyleCop Analyzers rules ###
+
+# SA1202: Elements must be ordered by access
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1202.md
+dotnet_diagnostic.SA1202.severity = none
+
+#### .NET Compiler Platform analysers rules ####
+
+# CA1031: Do not catch general exception types
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1031
+dotnet_diagnostic.CA1031.severity = none
+
+# CA2213: Disposable fields should be disposed
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2213
+dotnet_diagnostic.CA2213.severity = none
+
+# IDE0004: Types that own disposable fields should be disposable
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0004
+dotnet_diagnostic.IDE0004.severity = none
+
+# IDE0048: Add parentheses for clarity
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0047
+dotnet_diagnostic.IDE0048.severity = none

+ 1 - 1
src/Renci.SshNet/Abstractions/CryptoAbstraction.cs

@@ -8,7 +8,7 @@ namespace Renci.SshNet.Abstractions
         private static readonly System.Security.Cryptography.RandomNumberGenerator Randomizer = CreateRandomNumberGenerator();
 
         /// <summary>
-        /// Generates a <see cref="Byte"/> array of the specified length, and fills it with a
+        /// Generates a <see cref="byte"/> array of the specified length, and fills it with a
         /// cryptographically strong random sequence of values.
         /// </summary>
         /// <param name="length">The length of the array generate.</param>

+ 31 - 12
src/Renci.SshNet/Abstractions/SocketAbstraction.cs

@@ -20,7 +20,6 @@ namespace Renci.SshNet.Abstractions
             }
 
             return false;
-
         }
 
         /// <summary>
@@ -80,8 +79,10 @@ namespace Renci.SshNet.Abstractions
                         // dispose Socket
                         socket.Dispose();
                     }
+
                     // dispose ManualResetEvent
                     connectCompleted.Dispose();
+
                     // dispose SocketAsyncEventArgs
                     args.Dispose();
 
@@ -151,8 +152,12 @@ namespace Renci.SshNet.Abstractions
             catch (SocketException ex)
             {
                 if (ex.SocketErrorCode == SocketError.TimedOut)
+                {
                     throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
-                        "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds));
+                                                                         "Socket read operation has timed out after {0:F0} milliseconds.",
+                                                                         timeout.TotalMilliseconds));
+                }
+
                 throw;
             }
         }
@@ -168,14 +173,18 @@ namespace Renci.SshNet.Abstractions
                 {
                     var bytesRead = socket.Receive(buffer, offset, size, SocketFlags.None);
                     if (bytesRead == 0)
+                    {
                         break;
+                    }
 
                     processReceivedBytesAction(buffer, offset, bytesRead);
                 }
                 catch (SocketException ex)
                 {
                     if (IsErrorResumable(ex.SocketErrorCode))
+                    {
                         continue;
+                    }
 
                     switch (ex.SocketErrorCode)
                     {
@@ -208,7 +217,9 @@ namespace Renci.SshNet.Abstractions
         {
             var buffer = new byte[1];
             if (Read(socket, buffer, 0, 1, timeout) == 0)
+            {
                 return -1;
+            }
 
             return buffer[0];
         }
@@ -221,14 +232,14 @@ namespace Renci.SshNet.Abstractions
         /// <exception cref="SocketException">The write failed.</exception>
         public static void SendByte(Socket socket, byte value)
         {
-            var buffer = new[] {value};
+            var buffer = new[] { value };
             Send(socket, buffer, 0, 1);
         }
 
         /// <summary>
         /// Receives data from a bound <see cref="Socket"/>.
         /// </summary>
-        /// <param name="socket"></param>
+        /// <param name="socket">The <see cref="Socket"/> to read from.</param>
         /// <param name="size">The number of bytes to receive.</param>
         /// <param name="timeout">Specifies the amount of time after which the call will time out.</param>
         /// <returns>
@@ -244,7 +255,7 @@ namespace Renci.SshNet.Abstractions
         public static byte[] Read(Socket socket, int size, TimeSpan timeout)
         {
             var buffer = new byte[size];
-            Read(socket, buffer, 0, size, timeout);
+            _ = Read(socket, buffer, 0, size, timeout);
             return buffer;
         }
 
@@ -256,7 +267,7 @@ namespace Renci.SshNet.Abstractions
         /// <summary>
         /// Receives data from a bound <see cref="Socket"/> into a receive buffer.
         /// </summary>
-        /// <param name="socket"></param>
+        /// <param name="socket">The <see cref="Socket"/> to read from.</param>
         /// <param name="buffer">An array of type <see cref="byte"/> that is the storage location for the received data. </param>
         /// <param name="offset">The position in <paramref name="buffer"/> parameter to store the received data.</param>
         /// <param name="size">The number of bytes to receive.</param>
@@ -288,7 +299,9 @@ namespace Renci.SshNet.Abstractions
                 {
                     var bytesRead = socket.Receive(buffer, offset + totalBytesRead, totalBytesToRead - totalBytesRead, SocketFlags.None);
                     if (bytesRead == 0)
+                    {
                         return 0;
+                    }
 
                     totalBytesRead += bytesRead;
                 }
@@ -301,8 +314,11 @@ namespace Renci.SshNet.Abstractions
                     }
 
                     if (ex.SocketErrorCode == SocketError.TimedOut)
+                    {
                         throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
-                            "Socket read operation has timed out after {0:F0} milliseconds.", readTimeout.TotalMilliseconds));
+                                                               "Socket read operation has timed out after {0:F0} milliseconds.",
+                                                               readTimeout.TotalMilliseconds));
+                    }
 
                     throw;
                 }
@@ -328,8 +344,10 @@ namespace Renci.SshNet.Abstractions
                 {
                     var bytesSent = socket.Send(data, offset + totalBytesSent, totalBytesToSend - totalBytesSent, SocketFlags.None);
                     if (bytesSent == 0)
+                    {
                         throw new SshConnectionException("An established connection was aborted by the server.",
                                                          DisconnectReason.ConnectionLost);
+                    }
 
                     totalBytesSent += bytesSent;
                 }
@@ -341,9 +359,12 @@ namespace Renci.SshNet.Abstractions
                         ThreadAbstraction.Sleep(30);
                     }
                     else
-                        throw;  // any serious error occurr
+                    {
+                        throw; // any serious error occurr
+                    }
                 }
-            } while (totalBytesSent < totalBytesToSend);
+            }
+            while (totalBytesSent < totalBytesToSend);
         }
 
         public static bool IsErrorResumable(SocketError socketError)
@@ -363,10 +384,8 @@ namespace Renci.SshNet.Abstractions
         private static void ConnectCompleted(object sender, SocketAsyncEventArgs e)
         {
             var eventWaitHandle = (ManualResetEvent) e.UserToken;
-            if (eventWaitHandle != null)
-                eventWaitHandle.Set();
+            _ = eventWaitHandle?.Set();
         }
 #endif // FEATURE_SOCKET_EAP
-
     }
 }

+ 21 - 19
src/Renci.SshNet/Abstractions/SocketExtensions.cs

@@ -8,15 +8,14 @@ using System.Threading.Tasks;
 namespace Renci.SshNet.Abstractions
 {
     // Async helpers based on https://devblogs.microsoft.com/pfxteam/awaiting-socket-operations/
-
     internal static class SocketExtensions
     {
-        sealed class SocketAsyncEventArgsAwaitable : SocketAsyncEventArgs, INotifyCompletion
+        private sealed class SocketAsyncEventArgsAwaitable : SocketAsyncEventArgs, INotifyCompletion
         {
-            private readonly static Action SENTINEL = () => { };
+            private static readonly Action SENTINEL = () => { };
 
-            private bool isCancelled;
-            private Action continuationAction;
+            private bool _isCancelled;
+            private Action _continuationAction;
 
             public SocketAsyncEventArgsAwaitable()
             {
@@ -35,7 +34,8 @@ namespace Renci.SshNet.Abstractions
             public void SetCompleted()
             {
                 IsCompleted = true;
-                var continuation = continuationAction ?? Interlocked.CompareExchange(ref continuationAction, SENTINEL, null);
+
+                var continuation = _continuationAction ?? Interlocked.CompareExchange(ref _continuationAction, SENTINEL, null);
                 if (continuation != null)
                 {
                     continuation();
@@ -44,41 +44,43 @@ namespace Renci.SshNet.Abstractions
 
             public void SetCancelled()
             {
-                isCancelled = true;
+                _isCancelled = true;
                 SetCompleted();
             }
 
-            public SocketAsyncEventArgsAwaitable GetAwaiter() { return this; }
+            public SocketAsyncEventArgsAwaitable GetAwaiter()
+            {
+                return this;
+            }
 
             public bool IsCompleted { get; private set; }
 
             void INotifyCompletion.OnCompleted(Action continuation)
             {
-                if (continuationAction == SENTINEL || Interlocked.CompareExchange(ref continuationAction, continuation, null) == SENTINEL)
+                if (_continuationAction == SENTINEL || Interlocked.CompareExchange(ref _continuationAction, continuation, null) == SENTINEL)
                 {
                     // We have already completed; run continuation asynchronously
-                    Task.Run(continuation);
+                    _ = Task.Run(continuation);
                 }
             }
 
             public void GetResult()
             {
-                if (isCancelled)
+                if (_isCancelled)
                 {
                     throw new TaskCanceledException();
                 }
-                else if (IsCompleted)
-                {
-                    if (SocketError != SocketError.Success)
-                    {
-                        throw new SocketException((int)SocketError);
-                    }
-                }
-                else
+
+                if (!IsCompleted)
                 {
                     // We don't support sync/async
                     throw new InvalidOperationException("The asynchronous operation has not yet completed.");
                 }
+
+                if (SocketError != SocketError.Success)
+                {
+                    throw new SocketException((int)SocketError);
+                }
             }
         }
 

+ 8 - 4
src/Renci.SshNet/Abstractions/ThreadAbstraction.cs

@@ -16,10 +16,12 @@ namespace Renci.SshNet.Abstractions
         public static void ExecuteThreadLongRunning(Action action)
         {
             if (action == null)
-                throw new ArgumentNullException("action");
+            {
+                throw new ArgumentNullException(nameof(action));
+            }
 
             var taskCreationOptions = System.Threading.Tasks.TaskCreationOptions.LongRunning;
-            System.Threading.Tasks.Task.Factory.StartNew(action, taskCreationOptions);
+            _ = System.Threading.Tasks.Task.Factory.StartNew(action, taskCreationOptions);
         }
 
         /// <summary>
@@ -29,9 +31,11 @@ namespace Renci.SshNet.Abstractions
         public static void ExecuteThread(Action action)
         {
             if (action == null)
-                throw new ArgumentNullException("action");
+            {
+                throw new ArgumentNullException(nameof(action));
+            }
 
-            System.Threading.ThreadPool.QueueUserWorkItem(o => action());
+            _ = System.Threading.ThreadPool.QueueUserWorkItem(o => action());
         }
     }
 }

+ 7 - 4
src/Renci.SshNet/AuthenticationMethod.cs

@@ -1,10 +1,11 @@
-using Renci.SshNet.Common;
-using System;
+using System;
+
+using Renci.SshNet.Common;
 
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Base class for all supported authentication methods
+    /// Base class for all supported authentication methods.
     /// </summary>
     public abstract class AuthenticationMethod : IAuthenticationMethod
     {
@@ -22,7 +23,7 @@ namespace Renci.SshNet
         public string Username { get; private set; }
 
         /// <summary>
-        /// Gets list of allowed authentications.
+        /// Gets or sets the list of allowed authentications.
         /// </summary>
         public string[] AllowedAuthentications { get; protected set; }
 
@@ -34,7 +35,9 @@ namespace Renci.SshNet
         protected AuthenticationMethod(string username)
         {
             if (username.IsNullOrWhiteSpace())
+            {
                 throw new ArgumentException("username");
+            }
 
             Username = username;
         }

+ 52 - 42
src/Renci.SshNet/BaseClient.cs

@@ -24,6 +24,7 @@ namespace Renci.SshNet
         private TimeSpan _keepAliveInterval;
         private Timer _keepAliveTimer;
         private ConnectionInfo _connectionInfo;
+        private bool _isDisposed;
 
         /// <summary>
         /// Gets the current session.
@@ -101,7 +102,9 @@ namespace Renci.SshNet
                 CheckDisposed();
 
                 if (value == _keepAliveInterval)
+                {
                     return;
+                }
 
                 if (value == SshNet.Session.InfiniteTimeSpan)
                 {
@@ -114,8 +117,7 @@ namespace Renci.SshNet
                     {
                         // change the due time and interval of the timer if has already
                         // been created (which means the client is connected)
-
-                        _keepAliveTimer.Change(value, value);
+                        _ = _keepAliveTimer.Change(value, value);
                     }
                     else if (IsSessionConnected())
                     {
@@ -127,9 +129,10 @@ namespace Renci.SshNet
                         _keepAliveTimer = CreateKeepAliveTimer(value, value);
                     }
 
-                    // note that if the client is not yet connected, then the timer will be created with the 
+                    // note that if the client is not yet connected, then the timer will be created with the
                     // new interval when Connect() is invoked
                 }
+
                 _keepAliveInterval = value;
             }
         }
@@ -180,9 +183,14 @@ namespace Renci.SshNet
         internal BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory)
         {
             if (connectionInfo == null)
-                throw new ArgumentNullException("connectionInfo");
+            {
+                throw new ArgumentNullException(nameof(connectionInfo));
+            }
+
             if (serviceFactory == null)
-                throw new ArgumentNullException("serviceFactory");
+            {
+                throw new ArgumentNullException(nameof(serviceFactory));
+            }
 
             ConnectionInfo = connectionInfo;
             _ownsConnectionInfo = ownsConnectionInfo;
@@ -205,26 +213,29 @@ namespace Renci.SshNet
 
             // TODO (see issue #1758):
             // we're not stopping the keep-alive timer and disposing the session here
-            // 
+            //
             // we could do this but there would still be side effects as concrete
             // implementations may still hang on to the original session
-            // 
+            //
             // therefore it would be better to actually invoke the Disconnect method
             // (and then the Dispose on the session) but even that would have side effects
             // eg. it would remove all forwarded ports from SshClient
-            // 
+            //
             // I think we should modify our concrete clients to better deal with a
-            // disconnect. In case of SshClient this would mean not removing the 
+            // disconnect. In case of SshClient this would mean not removing the
             // forwarded ports on disconnect (but only on dispose ?) and link a
             // forwarded port with a client instead of with a session
             //
             // To be discussed with Oleg (or whoever is interested)
             if (IsSessionConnected())
+            {
                 throw new InvalidOperationException("The client is already connected.");
+            }
 
             OnConnecting();
 
             Session = CreateAndConnectSession();
+
             try
             {
                 // Even though the method we invoke makes you believe otherwise, at this point only
@@ -238,6 +249,7 @@ namespace Renci.SshNet
                 DisposeSession();
                 throw;
             }
+
             StartKeepAliveTimer();
         }
 
@@ -260,26 +272,29 @@ namespace Renci.SshNet
 
             // TODO (see issue #1758):
             // we're not stopping the keep-alive timer and disposing the session here
-            // 
+            //
             // we could do this but there would still be side effects as concrete
             // implementations may still hang on to the original session
-            // 
+            //
             // therefore it would be better to actually invoke the Disconnect method
             // (and then the Dispose on the session) but even that would have side effects
             // eg. it would remove all forwarded ports from SshClient
-            // 
+            //
             // I think we should modify our concrete clients to better deal with a
-            // disconnect. In case of SshClient this would mean not removing the 
+            // disconnect. In case of SshClient this would mean not removing the
             // forwarded ports on disconnect (but only on dispose ?) and link a
             // forwarded port with a client instead of with a session
             //
             // To be discussed with Oleg (or whoever is interested)
             if (IsSessionConnected())
+            {
                 throw new InvalidOperationException("The client is already connected.");
+            }
 
             OnConnecting();
 
             Session = await CreateAndConnectSessionAsync(cancellationToken).ConfigureAwait(false);
+
             try
             {
                 // Even though the method we invoke makes you believe otherwise, at this point only
@@ -293,6 +308,7 @@ namespace Renci.SshNet
                 DisposeSession();
                 throw;
             }
+
             StartKeepAliveTimer();
         }
 
@@ -352,11 +368,7 @@ namespace Renci.SshNet
         /// </summary>
         protected virtual void OnDisconnecting()
         {
-            var session = Session;
-            if (session != null)
-            {
-                session.OnDisconnecting();
-            }
+            Session?.OnDisconnecting();
         }
 
         /// <summary>
@@ -368,26 +380,14 @@ namespace Renci.SshNet
 
         private void Session_ErrorOccured(object sender, ExceptionEventArgs e)
         {
-            var handler = ErrorOccurred;
-            if (handler != null)
-            {
-                handler(this, e);
-            }
+            ErrorOccurred?.Invoke(this, e);
         }
 
         private void Session_HostKeyReceived(object sender, HostKeyEventArgs e)
         {
-            var handler = HostKeyReceived;
-            if (handler != null)
-            {
-                handler(this, e);
-            }
+            HostKeyReceived?.Invoke(this, e);
         }
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
@@ -395,18 +395,20 @@ namespace Renci.SshNet
         {
             DiagnosticAbstraction.Log("Disposing client.");
 
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             if (disposing)
             {
@@ -414,9 +416,10 @@ namespace Renci.SshNet
 
                 if (_ownsConnectionInfo && _connectionInfo != null)
                 {
-                    var connectionInfoDisposable = _connectionInfo as IDisposable;
-                    if (connectionInfoDisposable != null)
+                    if (_connectionInfo is IDisposable connectionInfoDisposable)
+                    {
                         connectionInfoDisposable.Dispose();
+                    }
                     _connectionInfo = null;
                 }
 
@@ -431,20 +434,19 @@ namespace Renci.SshNet
         protected void CheckDisposed()
         {
             if (_isDisposed)
+            {
                 throw new ObjectDisposedException(GetType().FullName);
+            }
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="BaseClient"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="BaseClient"/> class.
         /// </summary>
         ~BaseClient()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
 
-        #endregion
-
         /// <summary>
         /// Stops the keep-alive timer, and waits until all timer callbacks have been
         /// executed.
@@ -452,7 +454,9 @@ namespace Renci.SshNet
         private void StopKeepAliveTimer()
         {
             if (_keepAliveTimer == null)
+            {
                 return;
+            }
 
             _keepAliveTimer.Dispose();
             _keepAliveTimer = null;
@@ -464,14 +468,16 @@ namespace Renci.SshNet
 
             // do nothing if we have disposed or disconnected
             if (session == null)
+            {
                 return;
+            }
 
             // do not send multiple keep-alive messages concurrently
             if (Monitor.TryEnter(_keepAliveLock))
             {
                 try
                 {
-                    session.TrySendMessage(new IgnoreMessage());
+                    _ = session.TrySendMessage(new IgnoreMessage());
                 }
                 finally
                 {
@@ -490,11 +496,15 @@ namespace Renci.SshNet
         private void StartKeepAliveTimer()
         {
             if (_keepAliveInterval == SshNet.Session.InfiniteTimeSpan)
+            {
                 return;
+            }
 
             if (_keepAliveTimer != null)
+            {
                 // timer is already started
                 return;
+            }
 
             _keepAliveTimer = CreateKeepAliveTimer(_keepAliveInterval, _keepAliveInterval);
         }

+ 67 - 80
src/Renci.SshNet/Channels/Channel.cs

@@ -1,11 +1,12 @@
 using System;
+using System.Globalization;
 using System.Net.Sockets;
 using System.Threading;
+
+using Renci.SshNet.Abstractions;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages;
 using Renci.SshNet.Messages.Connection;
-using System.Globalization;
-using Renci.SshNet.Abstractions;
 
 namespace Renci.SshNet.Channels
 {
@@ -14,14 +15,15 @@ namespace Renci.SshNet.Channels
     /// </summary>
     internal abstract class Channel : IChannel
     {
-        private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(false);
-        private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(false);
         private readonly object _serverWindowSizeLock = new object();
         private readonly uint _initialWindowSize;
+        private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false);
+        private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(initialState: false);
         private uint? _remoteWindowSize;
         private uint? _remoteChannelNumber;
         private uint? _remotePacketSize;
         private ISession _session;
+        private bool _isDisposed;
 
         /// <summary>
         /// Holds a value indicating whether the SSH_MSG_CHANNEL_CLOSE has been sent to the remote party.
@@ -66,7 +68,7 @@ namespace Renci.SshNet.Channels
         public event EventHandler<ExceptionEventArgs> Exception;
 
         /// <summary>
-        /// Initializes a new <see cref="Channel"/> instance.
+        /// Initializes a new instance of the <see cref="Channel"/> class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="localChannelNumber">The local channel number.</param>
@@ -155,7 +157,10 @@ namespace Renci.SshNet.Channels
             get
             {
                 if (!_remoteChannelNumber.HasValue)
+                {
                     throw CreateRemoteChannelInfoNotAvailableException();
+                }
+
                 return _remoteChannelNumber.Value;
             }
             private set
@@ -177,7 +182,10 @@ namespace Renci.SshNet.Channels
             get
             {
                 if (!_remotePacketSize.HasValue)
+                {
                     throw CreateRemoteChannelInfoNotAvailableException();
+                }
+
                 return _remotePacketSize.Value;
             }
             private set
@@ -197,7 +205,10 @@ namespace Renci.SshNet.Channels
             get
             {
                 if (!_remoteWindowSize.HasValue)
+                {
                     throw CreateRemoteChannelInfoNotAvailableException();
+                }
+
                 return _remoteWindowSize.Value;
             }
             private set
@@ -207,15 +218,13 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Gets a value indicating whether this channel is open.
+        /// Gets or sets a value indicating whether this channel is open.
         /// </summary>
         /// <value>
         /// <c>true</c> if this channel is open; otherwise, <c>false</c>.
         /// </value>
         public bool IsOpen { get; protected set; }
 
-        #region Message events
-
         /// <summary>
         /// Occurs when <see cref="ChannelDataMessage"/> is received.
         /// </summary>
@@ -251,8 +260,6 @@ namespace Renci.SshNet.Channels
         /// </summary>
         public event EventHandler<ChannelEventArgs> RequestFailed;
 
-        #endregion
-
         /// <summary>
         /// Gets a value indicating whether the session is connected.
         /// </summary>
@@ -282,6 +289,12 @@ namespace Renci.SshNet.Channels
             get { return _session.SessionSemaphore; }
         }
 
+        /// <summary>
+        /// Initializes the information on the remote channel.
+        /// </summary>
+        /// <param name="remoteChannelNumber">The remote channel number.</param>
+        /// <param name="remoteWindowSize">The remote window size.</param>
+        /// <param name="remotePacketSize">The remote packet size.</param>
         protected void InitializeRemoteInfo(uint remoteChannelNumber, uint remoteWindowSize, uint remotePacketSize)
         {
             RemoteChannelNumber = remoteChannelNumber;
@@ -320,7 +333,9 @@ namespace Renci.SshNet.Channels
         {
             // send channel messages only while channel is open
             if (!IsOpen)
+            {
                 return;
+            }
 
             var totalBytesToSend = size;
             while (totalBytesToSend > 0)
@@ -338,8 +353,6 @@ namespace Renci.SshNet.Channels
             }
         }
 
-        #region Channel virtual methods
-
         /// <summary>
         /// Called when channel window need to be adjust.
         /// </summary>
@@ -350,7 +363,8 @@ namespace Renci.SshNet.Channels
             {
                 RemoteWindowSize += bytesToAdd;
             }
-            _channelServerWindowAdjustWaitHandle.Set();
+
+            _ = _channelServerWindowAdjustWaitHandle.Set();
         }
 
         /// <summary>
@@ -361,9 +375,7 @@ namespace Renci.SshNet.Channels
         {
             AdjustDataWindow(data);
 
-            var dataReceived = DataReceived;
-            if (dataReceived != null)
-                dataReceived(this, new ChannelDataEventArgs(LocalChannelNumber, data));
+            DataReceived?.Invoke(this, new ChannelDataEventArgs(LocalChannelNumber, data));
         }
 
         /// <summary>
@@ -375,9 +387,7 @@ namespace Renci.SshNet.Channels
         {
             AdjustDataWindow(data);
 
-            var extendedDataReceived = ExtendedDataReceived;
-            if (extendedDataReceived != null)
-                extendedDataReceived(this, new ChannelExtendedDataEventArgs(LocalChannelNumber, data, dataTypeCode));
+            ExtendedDataReceived?.Invoke(this, new ChannelExtendedDataEventArgs(LocalChannelNumber, data, dataTypeCode));
         }
 
         /// <summary>
@@ -387,9 +397,7 @@ namespace Renci.SshNet.Channels
         {
             _eofMessageReceived = true;
 
-            var endOfData = EndOfData;
-            if (endOfData != null)
-                endOfData(this, new ChannelEventArgs(LocalChannelNumber));
+            EndOfData?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));
         }
 
         /// <summary>
@@ -404,7 +412,9 @@ namespace Renci.SshNet.Channels
             // be blocked waiting for this signal.
             var channelClosedWaitHandle = _channelClosedWaitHandle;
             if (channelClosedWaitHandle != null)
-                channelClosedWaitHandle.Set();
+            {
+                _ = channelClosedWaitHandle.Set();
+            }
 
             // close the channel
             Close();
@@ -416,19 +426,15 @@ namespace Renci.SshNet.Channels
         /// <param name="info">Channel request information.</param>
         protected virtual void OnRequest(RequestInfo info)
         {
-            var requestReceived = RequestReceived;
-            if (requestReceived != null)
-                requestReceived(this, new ChannelRequestEventArgs(info));
+            RequestReceived?.Invoke(this, new ChannelRequestEventArgs(info));
         }
 
         /// <summary>
-        /// Called when channel request was successful
+        /// Called when channel request was successful.
         /// </summary>
         protected virtual void OnSuccess()
         {
-            var requestSuccessed = RequestSucceeded;
-            if (requestSuccessed != null)
-                requestSuccessed(this, new ChannelEventArgs(LocalChannelNumber));
+            RequestSucceeded?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));
         }
 
         /// <summary>
@@ -436,24 +442,16 @@ namespace Renci.SshNet.Channels
         /// </summary>
         protected virtual void OnFailure()
         {
-            var requestFailed = RequestFailed;
-            if (requestFailed != null)
-                requestFailed(this, new ChannelEventArgs(LocalChannelNumber));
+            RequestFailed?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));
         }
 
-        #endregion // Channel virtual methods
-
         /// <summary>
         /// Raises <see cref="Exception"/> event.
         /// </summary>
         /// <param name="exception">The exception.</param>
         private void RaiseExceptionEvent(Exception exception)
         {
-            var handlers = Exception;
-            if (handlers != null)
-            {
-                handlers(this, new ExceptionEventArgs(exception));
-            }
+            Exception?.Invoke(this, new ExceptionEventArgs(exception));
         }
 
         /// <summary>
@@ -479,9 +477,11 @@ namespace Renci.SshNet.Channels
         /// <param name="message">The message.</param>
         protected void SendMessage(Message message)
         {
-            // send channel messages only while channel is open
+            // Send channel messages only while channel is open
             if (!IsOpen)
+            {
                 return;
+            }
 
             _session.SendMessage(message);
         }
@@ -493,7 +493,9 @@ namespace Renci.SshNet.Channels
         public void SendEof()
         {
             if (!IsOpen)
+            {
                 throw CreateChannelClosedException();
+            }
 
             lock (this)
             {
@@ -516,14 +518,16 @@ namespace Renci.SshNet.Channels
         /// </summary>
         protected virtual void Close()
         {
-            // synchronize sending SSH_MSG_CHANNEL_EOF and SSH_MSG_CHANNEL_CLOSE to ensure that these messages
-            // are sent in that other; when both the client and the server attempt to close the channel at the
-            // same time we would otherwise risk sending the SSH_MSG_CHANNEL_EOF after the SSH_MSG_CHANNEL_CLOSE
-            // message causing the server to disconnect the session.
+            /*
+             * Synchronize sending SSH_MSG_CHANNEL_EOF and SSH_MSG_CHANNEL_CLOSE to ensure that these messages
+             * are sent in that other; when both the client and the server attempt to close the channel at the
+             * same time we would otherwise risk sending the SSH_MSG_CHANNEL_EOF after the SSH_MSG_CHANNEL_CLOSE
+             * message causing the server to disconnect the session.
+             */
 
             lock (this)
             {
-                // send EOF message first the following conditions are met:
+                // Send EOF message first the following conditions are met:
                 // * we have not sent a SSH_MSG_CHANNEL_EOF message
                 // * remote party has not already sent a SSH_MSG_CHANNEL_EOF message
                 // * remote party has not already sent a SSH_MSG_CHANNEL_CLOSE message
@@ -565,11 +569,7 @@ namespace Renci.SshNet.Channels
                     if (_closeMessageReceived)
                     {
                         // raise event signaling that both ends of the channel have been closed
-                        var closed = Closed;
-                        if (closed != null)
-                        {
-                            closed(this, new ChannelEventArgs(LocalChannelNumber));
-                        }
+                        Closed?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));
                     }
                 }
             }
@@ -623,8 +623,6 @@ namespace Renci.SshNet.Channels
             }
         }
 
-        #region Channel message event handlers
-
         private void OnChannelWindowAdjust(object sender, MessageEventArgs<ChannelWindowAdjustMessage> e)
         {
             if (e.Message.LocalChannelNumber == LocalChannelNumber)
@@ -706,14 +704,13 @@ namespace Renci.SshNet.Channels
             {
                 try
                 {
-                    RequestInfo requestInfo;
 
-                    if (_session.ConnectionInfo.ChannelRequests.TryGetValue(e.Message.RequestName, out requestInfo))
+                    if (_session.ConnectionInfo.ChannelRequests.TryGetValue(e.Message.RequestName, out var requestInfo))
                     {
-                        //  Load request specific data
+                        // Load request specific data
                         requestInfo.Load(e.Message.RequestData);
 
-                        //  Raise request specific event
+                        // Raise request specific event
                         OnRequest(requestInfo);
                     }
                     else
@@ -759,13 +756,11 @@ namespace Renci.SshNet.Channels
             }
         }
 
-        #endregion // Channel message event handlers
-
         private void AdjustDataWindow(byte[] messageData)
         {
-            LocalWindowSize -= (uint)messageData.Length;
+            LocalWindowSize -= (uint) messageData.Length;
 
-            //  Adjust window if window size is too low
+            // Adjust window if window size is too low
             if (LocalWindowSize < LocalPacketSize)
             {
                 SendMessage(new ChannelWindowAdjustMessage(RemoteChannelNumber, _initialWindowSize - LocalWindowSize));
@@ -789,8 +784,8 @@ namespace Renci.SshNet.Channels
                     var serverWindowSize = RemoteWindowSize;
                     if (serverWindowSize == 0U)
                     {
-                        // allow us to be signal when remote window size is adjusted
-                        _channelServerWindowAdjustWaitHandle.Reset();
+                        // Allow us to be signal when remote window size is adjusted
+                        _ = _channelServerWindowAdjustWaitHandle.Reset();
                     }
                     else
                     {
@@ -800,9 +795,11 @@ namespace Renci.SshNet.Channels
                         return (int) bytesThatCanBeSent;
                     }
                 }
-                // wait for remote window size to change
+
+                // Wait for remote window size to change
                 WaitOnHandle(_channelServerWindowAdjustWaitHandle);
-            } while (true);
+            }
+            while (true);
         }
 
         private static InvalidOperationException CreateRemoteChannelInfoNotAvailableException()
@@ -815,29 +812,22 @@ namespace Renci.SshNet.Channels
             throw new InvalidOperationException("The channel is closed.");
         }
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
-            if (_isDisposed)
-                return;
-
-            if (disposing)
+            if (!_isDisposed && disposing)
             {
                 Close();
 
@@ -876,14 +866,11 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="Channel"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="Channel"/> class.
         /// </summary>
         ~Channel()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion // IDisposable Members
     }
 }

+ 28 - 10
src/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -15,13 +15,13 @@ namespace Renci.SshNet.Channels
     {
         private readonly object _socketLock = new object();
 
-        private EventWaitHandle _channelOpen = new AutoResetEvent(false);
-        private EventWaitHandle _channelData = new AutoResetEvent(false);
+        private EventWaitHandle _channelOpen = new AutoResetEvent(initialState: false);
+        private EventWaitHandle _channelData = new AutoResetEvent(initialState: false);
         private IForwardedPort _forwardedPort;
         private Socket _socket;
 
         /// <summary>
-        /// Initializes a new <see cref="ChannelDirectTcpip"/> instance.
+        /// Initializes a new instance of the <see cref="ChannelDirectTcpip"/> class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="localChannelNumber">The local channel number.</param>
@@ -46,9 +46,14 @@ namespace Renci.SshNet.Channels
         public void Open(string remoteHost, uint port, IForwardedPort forwardedPort, Socket socket)
         {
             if (IsOpen)
+            {
                 throw new SshException("Channel is already open.");
+            }
+
             if (!IsConnected)
+            {
                 throw new SshException("Session is not connected.");
+            }
 
             _socket = socket;
             _forwardedPort = forwardedPort;
@@ -56,10 +61,13 @@ namespace Renci.SshNet.Channels
 
             var ep = (IPEndPoint) socket.RemoteEndPoint;
 
-            // open channel
-            SendMessage(new ChannelOpenMessage(LocalChannelNumber, LocalWindowSize, LocalPacketSize,
-                new DirectTcpipChannelInfo(remoteHost, port, ep.Address.ToString(), (uint) ep.Port)));
-            //  Wait for channel to open
+            // Open channel
+            SendMessage(new ChannelOpenMessage(LocalChannelNumber,
+                                               LocalWindowSize,
+                                               LocalPacketSize,
+                                               new DirectTcpipChannelInfo(remoteHost, port, ep.Address.ToString(), (uint) ep.Port)));
+
+            // Wait for channel to open
             WaitOnHandle(_channelOpen);
         }
 
@@ -82,9 +90,11 @@ namespace Renci.SshNet.Channels
         /// </summary>
         public void Bind()
         {
-            //  Cannot bind if channel is not open
+            // Cannot bind if channel is not open
             if (!IsOpen)
+            {
                 return;
+            }
 
             var buffer = new byte[RemotePacketSize];
 
@@ -104,12 +114,16 @@ namespace Renci.SshNet.Channels
         private void CloseSocket()
         {
             if (_socket == null)
+            {
                 return;
+            }
 
             lock (_socketLock)
             {
                 if (_socket == null)
+                {
                     return;
+                }
 
                 // closing a socket actually disposes the socket, so we can safely dereference
                 // the field to avoid entering the lock again later
@@ -125,12 +139,16 @@ namespace Renci.SshNet.Channels
         private void ShutdownSocket(SocketShutdown how)
         {
             if (_socket == null)
+            {
                 return;
+            }
 
             lock (_socketLock)
             {
                 if (!_socket.IsConnected())
+                {
                     return;
+                }
 
                 try
                 {
@@ -199,14 +217,14 @@ namespace Renci.SshNet.Channels
         {
             base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize);
 
-            _channelOpen.Set();
+            _ = _channelOpen.Set();
         }
 
         protected override void OnOpenFailure(uint reasonCode, string description, string language)
         {
             base.OnOpenFailure(reasonCode, description, language);
 
-            _channelOpen.Set();
+            _ = _channelOpen.Set();
         }
 
         /// <summary>

+ 6 - 0
src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs

@@ -120,13 +120,17 @@ namespace Renci.SshNet.Channels
         private void ShutdownSocket(SocketShutdown how)
         {
             if (_socket == null)
+            {
                 return;
+            }
 
             lock (_socketShutdownAndCloseLock)
             {
                 var socket = _socket;
                 if (!socket.IsConnected())
+                {
                     return;
+                }
 
                 try
                 {
@@ -146,7 +150,9 @@ namespace Renci.SshNet.Channels
         private void CloseSocket()
         {
             if (_socket == null)
+            {
                 return;
+            }
 
             lock (_socketShutdownAndCloseLock)
             {

+ 31 - 29
src/Renci.SshNet/Channels/ChannelSession.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Globalization;
 using System.Threading;
+
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
 
@@ -13,7 +14,7 @@ namespace Renci.SshNet.Channels
     internal sealed class ChannelSession : ClientChannel, IChannelSession
     {
         /// <summary>
-        /// Counts failed channel open attempts
+        /// Counts failed channel open attempts.
         /// </summary>
         private int _failedOpenAttempts;
 
@@ -28,16 +29,16 @@ namespace Renci.SshNet.Channels
         private int _sessionSemaphoreObtained;
 
         /// <summary>
-        /// Wait handle to signal when response was received to open the channel
+        /// Wait handle to signal when response was received to open the channel.
         /// </summary>
-        private EventWaitHandle _channelOpenResponseWaitHandle = new AutoResetEvent(false);
+        private EventWaitHandle _channelOpenResponseWaitHandle = new AutoResetEvent(initialState: false);
 
-        private EventWaitHandle _channelRequestResponse = new ManualResetEvent(false);
+        private EventWaitHandle _channelRequestResponse = new ManualResetEvent(initialState: false);
 
         private bool _channelRequestSucces;
 
         /// <summary>
-        /// Initializes a new <see cref="ChannelSession"/> instance.
+        /// Initializes a new instance of the <see cref="ChannelSession"/> class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="localChannelNumber">The local channel number.</param>
@@ -64,7 +65,7 @@ namespace Renci.SshNet.Channels
         /// </summary>
         public void Open()
         {
-            //  Try to open channel several times
+            // Try to open channel several times
             while (!IsOpen && _failedOpenAttempts < ConnectionInfo.RetryAttempts)
             {
                 SendChannelOpenMessage();
@@ -81,7 +82,9 @@ namespace Renci.SshNet.Channels
             }
 
             if (!IsOpen)
+            {
                 throw new SshException(string.Format(CultureInfo.CurrentCulture, "Failed to open a channel after {0} attempts.", _failedOpenAttempts));
+            }
         }
 
         /// <summary>
@@ -93,7 +96,8 @@ namespace Renci.SshNet.Channels
         protected override void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize)
         {
             base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize);
-            _channelOpenResponseWaitHandle.Set();
+
+            _ = _channelOpenResponseWaitHandle.Set();
         }
 
         /// <summary>
@@ -106,7 +110,7 @@ namespace Renci.SshNet.Channels
         {
             _failedOpenAttempts++;
             ReleaseSemaphore();
-            _channelOpenResponseWaitHandle.Set();
+            _ = _channelOpenResponseWaitHandle.Set();
         }
 
         protected override void Close()
@@ -129,7 +133,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendPseudoTerminalRequest(string environmentVariable, uint columns, uint rows, uint width, uint height, IDictionary<TerminalModes, uint> terminalModeValues)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new PseudoTerminalRequestInfo(environmentVariable, columns, rows, width, height, terminalModeValues)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -147,7 +151,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendX11ForwardingRequest(bool isSingleConnection, string protocol, byte[] cookie, uint screenNumber)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new X11ForwardingRequestInfo(isSingleConnection, protocol, cookie, screenNumber)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -163,7 +167,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendEnvironmentVariableRequest(string variableName, string variableValue)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new EnvironmentVariableRequestInfo(variableName, variableValue)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -177,7 +181,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendShellRequest()
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new ShellRequestInfo()));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -192,7 +196,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendExecRequest(string command)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new ExecRequestInfo(command, ConnectionInfo.Encoding)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -207,7 +211,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendBreakRequest(uint breakLength)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new BreakRequestInfo(breakLength)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -222,7 +226,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendSubsystemRequest(string subsystem)
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new SubsystemRequestInfo(subsystem)));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -307,7 +311,7 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendEndOfWriteRequest()
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new EndOfWriteRequestInfo()));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
@@ -321,23 +325,21 @@ namespace Renci.SshNet.Channels
         /// </returns>
         public bool SendKeepAliveRequest()
         {
-            _channelRequestResponse.Reset();
+            _ = _channelRequestResponse.Reset();
             SendMessage(new ChannelRequestMessage(RemoteChannelNumber, new KeepAliveRequestInfo()));
             WaitOnHandle(_channelRequestResponse);
             return _channelRequestSucces;
         }
 
         /// <summary>
-        /// Called when channel request was successful
+        /// Called when channel request was successful.
         /// </summary>
         protected override void OnSuccess()
         {
             base.OnSuccess();
-            _channelRequestSucces = true;
 
-            var channelRequestResponse = _channelRequestResponse;
-            if (channelRequestResponse != null)
-                channelRequestResponse.Set();
+            _channelRequestSucces = true;
+            _ = _channelRequestResponse?.Set();
         }
 
         /// <summary>
@@ -346,11 +348,9 @@ namespace Renci.SshNet.Channels
         protected override void OnFailure()
         {
             base.OnFailure();
-            _channelRequestSucces = false;
 
-            var channelRequestResponse = _channelRequestResponse;
-            if (channelRequestResponse != null)
-                channelRequestResponse.Set();
+            _channelRequestSucces = false;
+            _ = _channelRequestResponse?.Set();
         }
 
         /// <summary>
@@ -407,9 +407,9 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
-        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+        /// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langword="false"/> to release only unmanaged resources.</param>
         protected override void Dispose(bool disposing)
         {
             base.Dispose(disposing);
@@ -442,7 +442,9 @@ namespace Renci.SshNet.Channels
         private void ReleaseSemaphore()
         {
             if (Interlocked.CompareExchange(ref _sessionSemaphoreObtained, 0, 1) == 1)
-                SessionSemaphore.Release();
+            {
+                _ = SessionSemaphore.Release();
+            }
         }
     }
 }

+ 8 - 9
src/Renci.SshNet/Channels/ClientChannel.cs

@@ -7,7 +7,7 @@ namespace Renci.SshNet.Channels
     internal abstract class ClientChannel : Channel
     {
         /// <summary>
-        /// Initializes a new <see cref="ClientChannel"/> instance.
+        /// Initializes a new instance of the <see cref="ClientChannel"/> class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="localChannelNumber">The local channel number.</param>
@@ -43,9 +43,7 @@ namespace Renci.SshNet.Channels
             // Channel is consider to be open when confirmation message was received
             IsOpen = true;
 
-            var openConfirmed = OpenConfirmed;
-            if (openConfirmed != null)
-                openConfirmed(this, new ChannelOpenConfirmedEventArgs(remoteChannelNumber, initialWindowSize, maximumPacketSize));
+            OpenConfirmed?.Invoke(this, new ChannelOpenConfirmedEventArgs(remoteChannelNumber, initialWindowSize, maximumPacketSize));
         }
 
         /// <summary>
@@ -68,9 +66,7 @@ namespace Renci.SshNet.Channels
         /// <param name="language">The language.</param>
         protected virtual void OnOpenFailure(uint reasonCode, string description, string language)
         {
-            var openFailed = OpenFailed;
-            if (openFailed != null)
-                openFailed(this, new ChannelOpenFailedEventArgs(LocalChannelNumber, reasonCode, description, language));
+            OpenFailed?.Invoke(this, new ChannelOpenFailedEventArgs(LocalChannelNumber, reasonCode, description, language));
         }
 
         private void OnChannelOpenConfirmation(object sender, MessageEventArgs<ChannelOpenConfirmationMessage> e)
@@ -79,8 +75,9 @@ namespace Renci.SshNet.Channels
             {
                 try
                 {
-                    OnOpenConfirmation(e.Message.RemoteChannelNumber, e.Message.InitialWindowSize,
-                        e.Message.MaximumPacketSize);
+                    OnOpenConfirmation(e.Message.RemoteChannelNumber,
+                                       e.Message.InitialWindowSize,
+                                       e.Message.MaximumPacketSize);
                 }
                 catch (Exception ex)
                 {
@@ -121,7 +118,9 @@ namespace Renci.SshNet.Channels
         private void UnsubscribeFromSessionEvents(ISession session)
         {
             if (session == null)
+            {
                 return;
+            }
 
             session.ChannelOpenConfirmationReceived -= OnChannelOpenConfirmation;
             session.ChannelOpenFailureReceived -= OnChannelOpenFailure;

+ 10 - 4
src/Renci.SshNet/Channels/ServerChannel.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet.Channels
     internal abstract class ServerChannel : Channel
     {
         /// <summary>
-        /// Initializes a new <see cref="ServerChannel"/> instance.
+        /// Initializes a new instance of the <see cref="ServerChannel"/> class.
         /// </summary>
         /// <param name="session">The session.</param>
         /// <param name="localChannelNumber">The local channel number.</param>
@@ -14,7 +14,13 @@ namespace Renci.SshNet.Channels
         /// <param name="remoteChannelNumber">The remote channel number.</param>
         /// <param name="remoteWindowSize">The window size of the remote party.</param>
         /// <param name="remotePacketSize">The maximum size of a data packet that we can send to the remote party.</param>
-        protected ServerChannel(ISession session, uint localChannelNumber, uint localWindowSize, uint localPacketSize, uint remoteChannelNumber, uint remoteWindowSize, uint remotePacketSize)
+        protected ServerChannel(ISession session,
+                                uint localChannelNumber,
+                                uint localWindowSize,
+                                uint localPacketSize,
+                                uint remoteChannelNumber,
+                                uint remoteWindowSize,
+                                uint remotePacketSize)
             : base(session, localChannelNumber, localWindowSize, localPacketSize)
         {
             InitializeRemoteInfo(remoteChannelNumber, remoteWindowSize, remotePacketSize);
@@ -22,10 +28,10 @@ namespace Renci.SshNet.Channels
 
         protected void SendMessage(ChannelOpenConfirmationMessage message)
         {
-            //  No need to check whether channel is open when trying to open a channel
+            // No need to check whether channel is open when trying to open a channel
             Session.SendMessage(message);
 
-            //  When we act as server, consider the channel open when we've sent the
+            // When we act as server, consider the channel open when we've sent the
             // confirmation message to the peer
             IsOpen = true;
         }

+ 1 - 1
src/Renci.SshNet/CipherInfo.cs

@@ -30,7 +30,7 @@ namespace Renci.SshNet
         public CipherInfo(int keySize, Func<byte[], byte[], Cipher> cipher)
         {
             KeySize = keySize;
-            Cipher = (key, iv) => (cipher(key.Take(KeySize / 8), iv));
+            Cipher = (key, iv) => cipher(key.Take(KeySize / 8), iv);
         }
     }
 }

+ 21 - 8
src/Renci.SshNet/ClientAuthentication.cs

@@ -9,14 +9,16 @@ namespace Renci.SshNet
         private readonly int _partialSuccessLimit;
 
         /// <summary>
-        /// Initializes a new <see cref="ClientAuthentication"/> instance.
+        /// Initializes a new instance of the <see cref="ClientAuthentication"/> class.
         /// </summary>
         /// <param name="partialSuccessLimit">The number of times an authentication attempt with any given <see cref="IAuthenticationMethod"/> can result in <see cref="AuthenticationResult.PartialSuccess"/> before it is disregarded.</param>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="partialSuccessLimit"/> is less than one.</exception>
         public ClientAuthentication(int partialSuccessLimit)
         {
             if (partialSuccessLimit < 1)
-                throw new ArgumentOutOfRangeException("partialSuccessLimit", "Cannot be less than one.");
+            {
+                throw new ArgumentOutOfRangeException(nameof(partialSuccessLimit), "Cannot be less than one.");
+            }
 
             _partialSuccessLimit = partialSuccessLimit;
         }
@@ -43,9 +45,14 @@ namespace Renci.SshNet
         public void Authenticate(IConnectionInfoInternal connectionInfo, ISession session)
         {
             if (connectionInfo == null)
-                throw new ArgumentNullException("connectionInfo");
+            {
+                throw new ArgumentNullException(nameof(connectionInfo));
+            }
+
             if (session == null)
-                throw new ArgumentNullException("session");
+            {
+                throw new ArgumentNullException(nameof(session));
+            }
 
             session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE");
             session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS");
@@ -122,6 +129,7 @@ namespace Renci.SshNet
                         {
                             authenticationResult = AuthenticationResult.Success;
                         }
+
                         break;
                     case AuthenticationResult.Failure:
                         authenticationState.RecordFailure(authenticationMethod);
@@ -133,7 +141,9 @@ namespace Renci.SshNet
                 }
 
                 if (authenticationResult == AuthenticationResult.Success)
+                {
                     return true;
+                }
             }
 
             return false;
@@ -181,8 +191,7 @@ namespace Renci.SshNet
             /// <param name="authenticationMethod">An <see cref="IAuthenticationMethod"/> for which to record the result of an authentication attempt.</param>
             public void RecordPartialSuccess(IAuthenticationMethod authenticationMethod)
             {
-                int partialSuccessCount;
-                if (_authenticationMethodPartialSuccessRegister.TryGetValue(authenticationMethod, out partialSuccessCount))
+                if (_authenticationMethodPartialSuccessRegister.TryGetValue(authenticationMethod, out var partialSuccessCount))
                 {
                     _authenticationMethodPartialSuccessRegister[authenticationMethod] = ++partialSuccessCount;
                 }
@@ -203,11 +212,11 @@ namespace Renci.SshNet
             /// </returns>
             public int GetPartialSuccessCount(IAuthenticationMethod authenticationMethod)
             {
-                int partialSuccessCount;
-                if (_authenticationMethodPartialSuccessRegister.TryGetValue(authenticationMethod, out partialSuccessCount))
+                if (_authenticationMethodPartialSuccessRegister.TryGetValue(authenticationMethod, out var partialSuccessCount))
                 {
                     return partialSuccessCount;
                 }
+
                 return 0;
             }
 
@@ -270,7 +279,9 @@ namespace Renci.SshNet
 
                     // skip authentication methods that have already failed
                     if (_failedAuthenticationMethods.Contains(authenticationMethod))
+                    {
                         continue;
+                    }
 
                     // delay use of authentication methods that had a PartialSuccess result
                     if (_authenticationMethodPartialSuccessRegister.ContainsKey(authenticationMethod))
@@ -283,7 +294,9 @@ namespace Renci.SshNet
                 }
 
                 foreach (var authenticationMethod in skippedAuthenticationMethods)
+                {
                     yield return authenticationMethod;
+                }
             }
         }
     }

+ 14 - 12
src/Renci.SshNet/CommandAsyncResult.cs

@@ -4,7 +4,7 @@ using System.Threading;
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Provides additional information for asynchronous command execution
+    /// Provides additional information for asynchronous command execution.
     /// </summary>
     public class CommandAsyncResult : IAsyncResult
     {
@@ -27,8 +27,6 @@ namespace Renci.SshNet
         /// <value>Total bytes sent.</value>
         public int BytesSent { get; set; }
 
-        #region IAsyncResult Members
-
         /// <summary>
         /// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
         /// </summary>
@@ -36,27 +34,31 @@ namespace Renci.SshNet
         public object AsyncState { get; internal set; }
 
         /// <summary>
-        /// Gets a <see cref="T:System.Threading.WaitHandle"/> that is used to wait for an asynchronous operation to complete.
+        /// Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
         /// </summary>
-        /// <returns>A <see cref="T:System.Threading.WaitHandle"/> that is used to wait for an asynchronous operation to complete.</returns>
+        /// <returns>
+        /// A <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
+        /// </returns>
         public WaitHandle AsyncWaitHandle { get; internal set; }
 
         /// <summary>
-        /// Gets a value that indicates whether the asynchronous operation completed synchronously.
+        /// Gets a value indicating whether the asynchronous operation completed synchronously.
         /// </summary>
-        /// <returns>true if the asynchronous operation completed synchronously; otherwise, false.</returns>
+        /// <returns>
+        /// true if the asynchronous operation completed synchronously; otherwise, false.
+        /// </returns>
         public bool CompletedSynchronously { get; internal set; }
 
         /// <summary>
-        /// Gets a value that indicates whether the asynchronous operation has completed.
+        /// Gets a value indicating whether the asynchronous operation has completed.
         /// </summary>
-        /// <returns>true if the operation is complete; otherwise, false.</returns>
+        /// <returns>
+        /// true if the operation is complete; otherwise, false.
+        /// </returns>
         public bool IsCompleted { get; internal set; }
 
-        #endregion
-
         /// <summary>
-        /// Gets a value indicating whether <see cref="SshCommand.EndExecute(IAsyncResult)"/> was already called for this
+        /// Gets or sets a value indicating whether <see cref="SshCommand.EndExecute(IAsyncResult)"/> was already called for this
         /// <see cref="CommandAsyncResult"/>.
         /// </summary>
         /// <returns>

+ 47 - 51
src/Renci.SshNet/Common/AsyncResult.cs

@@ -8,36 +8,18 @@ namespace Renci.SshNet.Common
     /// </summary>
     public abstract class AsyncResult : IAsyncResult
     {
-        // Fields set at construction which never change while operation is pending
-        private readonly AsyncCallback _asyncCallback;
-
-        private readonly object _asyncState;
-
-        // Field set at construction which do change after operation completes
         private const int StatePending = 0;
 
         private const int StateCompletedSynchronously = 1;
 
         private const int StateCompletedAsynchronously = 2;
 
+        private readonly AsyncCallback _asyncCallback;
+        private readonly object _asyncState;
         private int _completedState = StatePending;
-
-        // Field that may or may not get set depending on usage
         private ManualResetEvent _asyncWaitHandle;
-
-        // Fields set when operation completes
         private Exception _exception;
 
-        /// <summary>
-        /// Gets or sets a value indicating whether <see cref="EndInvoke()"/> has been called on the current
-        /// <see cref="AsyncResult"/>.
-        /// </summary>
-        /// <value>
-        /// <c>true</c> if <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>;
-        /// otherwise, <c>false</c>.
-        /// </value>
-        public bool EndInvokeCalled { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="AsyncResult"/> class.
         /// </summary>
@@ -49,37 +31,43 @@ namespace Renci.SshNet.Common
             _asyncState = state;
         }
 
+        /// <summary>
+        /// Gets a value indicating whether <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>;
+        /// otherwise, <c>false</c>.
+        /// </value>
+        public bool EndInvokeCalled { get; private set; }
+
         /// <summary>
         /// Marks asynchronous operation as completed.
         /// </summary>
         /// <param name="exception">The exception.</param>
-        /// <param name="completedSynchronously">if set to <c>true</c> [completed synchronously].</param>
+        /// <param name="completedSynchronously">If set to <see langword="true"/>, completed synchronously.</param>
         public void SetAsCompleted(Exception exception, bool completedSynchronously)
         {
             // Passing null for exception means no error occurred; this is the common case
             _exception = exception;
 
-            // The m_CompletedState field MUST be set prior calling the callback
+            // The '_completedState' field MUST be set prior calling the callback
             var prevState = Interlocked.Exchange(ref _completedState,
-               completedSynchronously ? StateCompletedSynchronously : StateCompletedAsynchronously);
+                                                 completedSynchronously ? StateCompletedSynchronously : StateCompletedAsynchronously);
+
             if (prevState != StatePending)
+            {
                 throw new InvalidOperationException("You can set a result only once");
+            }
 
             // If the event exists, set it
-            if (_asyncWaitHandle != null)
-            {
-                _asyncWaitHandle.Set();
-            }
+            _ = _asyncWaitHandle?.Set();
 
             // If a callback method was set, call it
-            if (_asyncCallback != null)
-            {
-                _asyncCallback(this);
-            }
+            _asyncCallback?.Invoke(this);
         }
 
         /// <summary>
-        /// Waits until the asynchronous operation completes, and then returns. 
+        /// Waits until the asynchronous operation completes, and then returns.
         /// </summary>
         internal void EndInvoke()
         {
@@ -87,7 +75,7 @@ namespace Renci.SshNet.Common
             if (!IsCompleted)
             {
                 // If the operation isn't done, wait for it
-                AsyncWaitHandle.WaitOne();
+                _ = AsyncWaitHandle.WaitOne();
                 _asyncWaitHandle = null;  // Allow early GC
                 AsyncWaitHandle.Dispose();
             }
@@ -96,21 +84,28 @@ namespace Renci.SshNet.Common
 
             // Operation is done: if an exception occurred, throw it
             if (_exception != null)
+            {
                 throw _exception;
+            }
         }
 
-        #region Implementation of IAsyncResult
-
         /// <summary>
         /// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
         /// </summary>
-        /// <returns>A user-defined object that qualifies or contains information about an asynchronous operation.</returns>
-        public object AsyncState { get { return _asyncState; } }
+        /// <returns>
+        /// A user-defined object that qualifies or contains information about an asynchronous operation.
+        /// </returns>
+        public object AsyncState
+        {
+            get { return _asyncState; }
+        }
 
         /// <summary>
-        /// Gets a value that indicates whether the asynchronous operation completed synchronously.
+        /// Gets a value indicating whether the asynchronous operation completed synchronously.
         /// </summary>
-        /// <returns>true if the asynchronous operation completed synchronously; otherwise, false.</returns>
+        /// <returns>
+        /// <see langword="true"/> if the asynchronous operation completed synchronously; otherwise, <see langword="false"/>.
+        /// </returns>
         public bool CompletedSynchronously
         {
             get { return _completedState == StateCompletedSynchronously; }
@@ -119,7 +114,9 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
         /// </summary>
-        /// <returns>A <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.</returns>
+        /// <returns>
+        /// A <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
+        /// </returns>
         public WaitHandle AsyncWaitHandle
         {
             get
@@ -128,7 +125,7 @@ namespace Renci.SshNet.Common
                 {
                     var done = IsCompleted;
                     var mre = new ManualResetEvent(done);
-                    if (Interlocked.CompareExchange(ref _asyncWaitHandle, mre, null) != null)
+                    if (Interlocked.CompareExchange(ref _asyncWaitHandle, mre, comparand: null) != null)
                     {
                         // Another thread created this object's event; dispose the event we just created
                         mre.Dispose();
@@ -137,27 +134,26 @@ namespace Renci.SshNet.Common
                     {
                         if (!done && IsCompleted)
                         {
-                            // If the operation wasn't done when we created 
-                            // the event but now it is done, set the event
-                            _asyncWaitHandle.Set();
+                            // If the operation wasn't done when we created the event but now it is done, set the event
+                            _ = _asyncWaitHandle.Set();
                         }
                     }
                 }
+
                 return _asyncWaitHandle;
             }
         }
 
         /// <summary>
-        /// Gets a value that indicates whether the asynchronous operation has completed.
+        /// Gets a value indicating whether the asynchronous operation has completed.
         /// </summary>
         /// <returns>
-        /// <c>true</c> if the operation is complete; otherwise, <c>false</c>.</returns>
+        /// <see langword="true"/> if the operation is complete; otherwise, <see langword="false"/>.
+        /// </returns>
         public bool IsCompleted
         {
             get { return _completedState != StatePending; }
         }
-
-        #endregion
     }
 
     /// <summary>
@@ -190,7 +186,7 @@ namespace Renci.SshNet.Common
             _result = result;
 
             // Tell the base class that the operation completed successfully (no exception)
-            SetAsCompleted(null, completedSynchronously);
+            SetAsCompleted(exception: null, completedSynchronously);
         }
 
         /// <summary>
@@ -201,8 +197,8 @@ namespace Renci.SshNet.Common
         /// </returns>
         public new TResult EndInvoke()
         {
-            base.EndInvoke(); // Wait until operation has completed 
+            base.EndInvoke(); // Wait until operation has completed
             return _result;  // Return the result (if above didn't throw)
         }
     }
-}
+}

+ 1 - 1
src/Renci.SshNet/Common/AuthenticationBannerEventArgs.cs

@@ -1,7 +1,7 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.ConnectionInfo.AuthenticationBanner"/> event.
+    /// Provides data for <see cref="ConnectionInfo.AuthenticationBanner"/> event.
     /// </summary>
     public class AuthenticationBannerEventArgs : AuthenticationEventArgs
     {

+ 5 - 5
src/Renci.SshNet/Common/AuthenticationEventArgs.cs

@@ -7,11 +7,6 @@ namespace Renci.SshNet.Common
     /// </summary>
     public abstract class AuthenticationEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the username.
-        /// </summary>
-        public string Username { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="AuthenticationEventArgs"/> class.
         /// </summary>
@@ -20,5 +15,10 @@ namespace Renci.SshNet.Common
         {
             Username = username;
         }
+
+        /// <summary>
+        /// Gets the username.
+        /// </summary>
+        public string Username { get; }
     }
 }

+ 9 - 9
src/Renci.SshNet/Common/AuthenticationPasswordChangeEventArgs.cs

@@ -1,18 +1,10 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.PasswordConnectionInfo.PasswordExpired"/> event.
+    /// Provides data for <see cref="PasswordConnectionInfo.PasswordExpired"/> event.
     /// </summary>
     public class AuthenticationPasswordChangeEventArgs : AuthenticationEventArgs
     {
-        /// <summary>
-        /// Gets or sets the new password.
-        /// </summary>
-        /// <value>
-        /// The new password.
-        /// </value>
-        public byte[] NewPassword { get; set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="AuthenticationPasswordChangeEventArgs"/> class.
         /// </summary>
@@ -21,5 +13,13 @@
             : base(username)
         {
         }
+
+        /// <summary>
+        /// Gets or sets the new password.
+        /// </summary>
+        /// <value>
+        /// The new password.
+        /// </value>
+        public byte[] NewPassword { get; set; }
     }
 }

+ 18 - 18
src/Renci.SshNet/Common/AuthenticationPrompt.cs

@@ -1,27 +1,40 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides prompt information when <see cref="Renci.SshNet.KeyboardInteractiveConnectionInfo.AuthenticationPrompt"/> is raised
+    /// Provides prompt information when <see cref="KeyboardInteractiveConnectionInfo.AuthenticationPrompt"/> is raised.
     /// </summary>
     public class AuthenticationPrompt
     {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AuthenticationPrompt"/> class.
+        /// </summary>
+        /// <param name="id">The sequence id.</param>
+        /// <param name="isEchoed">if set to <c>true</c> the user input should be echoed.</param>
+        /// <param name="request">The request.</param>
+        public AuthenticationPrompt(int id, bool isEchoed, string request)
+        {
+            Id = id;
+            IsEchoed = isEchoed;
+            Request = request;
+        }
+
         /// <summary>
         /// Gets the prompt sequence id.
         /// </summary>
-        public int Id { get; private set; }
+        public int Id { get; }
 
         /// <summary>
-        /// Gets or sets a value indicating whether the user input should be echoed as characters are typed.
+        /// Gets a value indicating whether the user input should be echoed as characters are typed.
         /// </summary>
         /// <value>
         ///   <c>true</c> if the user input should be echoed as characters are typed; otherwise, <c>false</c>.
         /// </value>
-        public bool IsEchoed { get; private set; }
+        public bool IsEchoed { get; }
 
         /// <summary>
         /// Gets server information request.
         /// </summary>
-        public string Request { get; private set; }
+        public string Request { get; }
 
         /// <summary>
         /// Gets or sets server information response.
@@ -30,18 +43,5 @@
         /// The response.
         /// </value>
         public string Response { get; set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="AuthenticationPrompt"/> class.
-        /// </summary>
-        /// <param name="id">The sequence id.</param>
-        /// <param name="isEchoed">if set to <c>true</c> the user input should be echoed.</param>
-        /// <param name="request">The request.</param>
-        public AuthenticationPrompt(int id, bool isEchoed, string request)
-        {
-            Id = id;
-            IsEchoed = isEchoed;
-            Request = request;
-        }
     }
 }

+ 16 - 16
src/Renci.SshNet/Common/AuthenticationPromptEventArgs.cs

@@ -3,25 +3,10 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.KeyboardInteractiveConnectionInfo.AuthenticationPrompt"/> event.
+    /// Provides data for <see cref="KeyboardInteractiveConnectionInfo.AuthenticationPrompt"/> event.
     /// </summary>
     public class AuthenticationPromptEventArgs : AuthenticationEventArgs
     {
-        /// <summary>
-        /// Gets prompt language.
-        /// </summary>
-        public string Language { get; private set; }
-
-        /// <summary>
-        /// Gets prompt instruction.
-        /// </summary>
-        public string Instruction { get; private set; }
-
-        /// <summary>
-        /// Gets server information request prompts.
-        /// </summary>
-        public IEnumerable<AuthenticationPrompt> Prompts { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="AuthenticationPromptEventArgs"/> class.
         /// </summary>
@@ -36,5 +21,20 @@ namespace Renci.SshNet.Common
             Language = language;
             Prompts = prompts;
         }
+
+        /// <summary>
+        /// Gets prompt language.
+        /// </summary>
+        public string Language { get; }
+
+        /// <summary>
+        /// Gets prompt instruction.
+        /// </summary>
+        public string Instruction { get; }
+
+        /// <summary>
+        /// Gets server information request prompts.
+        /// </summary>
+        public IEnumerable<AuthenticationPrompt> Prompts { get; }
     }
 }

Plik diff jest za duży
+ 282 - 100
src/Renci.SshNet/Common/BigInteger.cs


+ 6 - 6
src/Renci.SshNet/Common/ChannelDataEventArgs.cs

@@ -1,15 +1,10 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.DataReceived"/> event.
+    /// Provides data for <see cref="Channels.Channel.DataReceived"/> event.
     /// </summary>
     internal class ChannelDataEventArgs : ChannelEventArgs
     {
-        /// <summary>
-        /// Gets channel data.
-        /// </summary>
-        public byte[] Data { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelDataEventArgs"/> class.
         /// </summary>
@@ -20,5 +15,10 @@
         {
             Data = data;
         }
+
+        /// <summary>
+        /// Gets channel data.
+        /// </summary>
+        public byte[] Data { get; }
     }
 }

+ 8 - 5
src/Renci.SshNet/Common/ChannelEventArgs.cs

@@ -7,11 +7,6 @@ namespace Renci.SshNet.Common
     /// </summary>
     internal class ChannelEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the channel number.
-        /// </summary>
-        public uint ChannelNumber { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelEventArgs"/> class.
         /// </summary>
@@ -20,5 +15,13 @@ namespace Renci.SshNet.Common
         {
             ChannelNumber = channelNumber;
         }
+
+        /// <summary>
+        /// Gets the channel number.
+        /// </summary>
+        /// <value>
+        /// The channel number.
+        /// </value>
+        public uint ChannelNumber { get; }
     }
 }

+ 7 - 3
src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs

@@ -1,7 +1,7 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.ExtendedDataReceived"/> events.
+    /// Provides data for <see cref="Channels.Channel.ExtendedDataReceived"/> events.
     /// </summary>
     internal class ChannelExtendedDataEventArgs : ChannelDataEventArgs
     {
@@ -11,7 +11,8 @@
         /// <param name="channelNumber">Channel number.</param>
         /// <param name="data">Channel data.</param>
         /// <param name="dataTypeCode">Channel data type code.</param>
-        public ChannelExtendedDataEventArgs(uint channelNumber, byte[] data, uint dataTypeCode) : base(channelNumber, data)
+        public ChannelExtendedDataEventArgs(uint channelNumber, byte[] data, uint dataTypeCode)
+            : base(channelNumber, data)
         {
             DataTypeCode = dataTypeCode;
         }
@@ -19,6 +20,9 @@
         /// <summary>
         /// Gets the data type code.
         /// </summary>
-        public uint DataTypeCode { get; private set; }
+        /// <value>
+        /// The data type code.
+        /// </value>
+        public uint DataTypeCode { get; }
     }
 }

+ 3 - 3
src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs

@@ -1,7 +1,7 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.ClientChannel.OpenConfirmed"/> event.
+    /// Provides data for <see cref="Channels.ClientChannel.OpenConfirmed"/> event.
     /// </summary>
     internal class ChannelOpenConfirmedEventArgs : ChannelEventArgs
     {
@@ -24,7 +24,7 @@
         /// <value>
         /// The initial size of the window.
         /// </value>
-        public uint InitialWindowSize { get; private set; }
+        public uint InitialWindowSize { get; }
 
         /// <summary>
         /// Gets the maximum size of the packet.
@@ -32,6 +32,6 @@
         /// <value>
         /// The maximum size of the packet.
         /// </value>
-        public uint MaximumPacketSize { get; private set; }
+        public uint MaximumPacketSize { get; }
     }
 }

+ 16 - 16
src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs

@@ -1,25 +1,10 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.ClientChannel.OpenFailed"/> event.
+    /// Provides data for <see cref="Channels.ClientChannel.OpenFailed"/> event.
     /// </summary>
     internal class ChannelOpenFailedEventArgs : ChannelEventArgs
     {
-        /// <summary>
-        /// Gets failure reason code.
-        /// </summary>
-        public uint ReasonCode { get; private set; }
-
-        /// <summary>
-        /// Gets failure description.
-        /// </summary>
-        public string Description { get; private set; }
-
-        /// <summary>
-        /// Gets failure language.
-        /// </summary>
-        public string Language { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelOpenFailedEventArgs"/> class.
         /// </summary>
@@ -34,5 +19,20 @@
             Description = description;
             Language = language;
         }
+
+        /// <summary>
+        /// Gets failure reason code.
+        /// </summary>
+        public uint ReasonCode { get; }
+
+        /// <summary>
+        /// Gets failure description.
+        /// </summary>
+        public string Description { get; }
+
+        /// <summary>
+        /// Gets failure language.
+        /// </summary>
+        public string Language { get; }
     }
 }

+ 10 - 6
src/Renci.SshNet/Common/ChannelRequestEventArgs.cs

@@ -1,18 +1,14 @@
 using System;
+
 using Renci.SshNet.Messages.Connection;
 
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.RequestReceived"/> event.
+    /// Provides data for <see cref="Channels.Channel.RequestReceived"/> event.
     /// </summary>
     internal class ChannelRequestEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets request information.
-        /// </summary>
-        public RequestInfo Info { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelRequestEventArgs"/> class.
         /// </summary>
@@ -21,5 +17,13 @@ namespace Renci.SshNet.Common
         {
             Info = info;
         }
+
+        /// <summary>
+        /// Gets the request information.
+        /// </summary>
+        /// <value>
+        /// The request information.
+        /// </value>
+        public RequestInfo Info { get; }
     }
 }

+ 46 - 39
src/Renci.SshNet/Common/DerData.cs

@@ -16,39 +16,17 @@ namespace Renci.SshNet.Common
         private const byte Octetstring = 0x04;
         private const byte Null = 0x05;
         private const byte Objectidentifier = 0x06;
-        //private const byte EXTERNAL = 0x08;
-        //private const byte ENUMERATED = 0x0a;
         private const byte Sequence = 0x10;
-        //private const byte SEQUENCEOF = 0x10; // for completeness
-        //private const byte SET = 0x11;
-        //private const byte SETOF = 0x11; // for completeness
-
-        //private const byte NUMERICSTRING = 0x12;
-        //private const byte PRINTABLESTRING = 0x13;
-        //private const byte T61STRING = 0x14;
-        //private const byte VIDEOTEXSTRING = 0x15;
-        //private const byte IA5STRING = 0x16;
-        //private const byte UTCTIME = 0x17;
-        //private const byte GENERALIZEDTIME = 0x18;
-        //private const byte GRAPHICSTRING = 0x19;
-        //private const byte VISIBLESTRING = 0x1a;
-        //private const byte GENERALSTRING = 0x1b;
-        //private const byte UNIVERSALSTRING = 0x1c;
-        //private const byte BMPSTRING = 0x1e;
-        //private const byte UTF8STRING = 0x0c;
-        //private const byte APPLICATION = 0x40;
-        //private const byte TAGGED = 0x80;
 
         private readonly List<byte> _data;
-
-        private int _readerIndex;
         private readonly int _lastIndex;
+        private int _readerIndex;
 
         /// <summary>
         /// Gets a value indicating whether end of data is reached.
         /// </summary>
         /// <value>
-        /// 	<c>true</c> if end of data is reached; otherwise, <c>false</c>.
+        /// <c>true</c> if end of data is reached; otherwise, <c>false</c>.
         /// </value>
         public bool IsEndOfData
         {
@@ -80,7 +58,7 @@ namespace Renci.SshNet.Common
             }
             else
             {
-                ReadByte(); // skip dataType
+                _ = ReadByte(); // skip dataType
                 var length = ReadLength();
                 _lastIndex = _readerIndex + length;
             }
@@ -109,7 +87,9 @@ namespace Renci.SshNet.Common
         {
             var type = ReadByte();
             if (type != Integer)
+            {
                 throw new InvalidOperationException(string.Format("Invalid data type, INTEGER(02) is expected, but was {0}", type.ToString("X2")));
+            }
 
             var length = ReadLength();
 
@@ -126,14 +106,18 @@ namespace Renci.SshNet.Common
         {
             var type = ReadByte();
             if (type != Integer)
+            {
                 throw new InvalidOperationException(string.Format("Invalid data type, INTEGER(02) is expected, but was {0}", type.ToString("X2")));
+            }
 
             var length = ReadLength();
 
             var data = ReadBytes(length);
 
             if (length > 4)
+            {
                 throw new InvalidOperationException("Integer type cannot occupy more then 4 bytes");
+            }
 
             var result = 0;
             var shift = (length - 1) * 8;
@@ -143,8 +127,6 @@ namespace Renci.SshNet.Common
                 shift -= 8;
             }
 
-            //return (int)(data[0] << 56 | data[1] << 48 | data[2] << 40 | data[3] << 32 | data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]);
-
             return result;
         }
 
@@ -156,7 +138,9 @@ namespace Renci.SshNet.Common
         {
             var type = ReadByte();
             if (type != Octetstring)
+            {
                 throw new InvalidOperationException(string.Format("Invalid data type, OCTETSTRING(04) is expected, but was {0}", type.ToString("X2")));
+            }
 
             var length = ReadLength();
             var data = ReadBytes(length);
@@ -171,7 +155,9 @@ namespace Renci.SshNet.Common
         {
             var type = ReadByte();
             if (type != BITSTRING)
+            {
                 throw new InvalidOperationException(string.Format("Invalid data type, BITSTRING(03) is expected, but was {0}", type.ToString("X2")));
+            }
 
             var length = ReadLength();
             var data = ReadBytes(length);
@@ -186,7 +172,9 @@ namespace Renci.SshNet.Common
         {
             var type = ReadByte();
             if (type != Objectidentifier)
+            {
                 throw new InvalidOperationException(string.Format("Invalid data type, OBJECT(06) is expected, but was {0}", type.ToString("X2")));
+            }
 
             var length = ReadLength();
             var data = ReadBytes(length);
@@ -261,7 +249,7 @@ namespace Renci.SshNet.Common
         public void Write(ObjectIdentifier identifier)
         {
             var temp = new ulong[identifier.Identifiers.Length - 1];
-            temp[0] = identifier.Identifiers[0] * 40 + identifier.Identifiers[1];
+            temp[0] = (identifier.Identifiers[0] * 40) + identifier.Identifiers[1];
             Buffer.BlockCopy(identifier.Identifiers, 2 * sizeof(ulong), temp, 1 * sizeof(ulong), (identifier.Identifiers.Length - 2) * sizeof(ulong));
             var bytes = new List<byte>();
             foreach (var subidentifier in temp)
@@ -275,7 +263,10 @@ namespace Renci.SshNet.Common
                 {
                     buffer[bufferIndex] = current;
                     if (bufferIndex < buffer.Length - 1)
+                    {
                         buffer[bufferIndex] |= 0x80;
+                    }
+
                     item >>= 7;
                     current = (byte)(item & 0x7F);
                     bufferIndex--;
@@ -325,7 +316,7 @@ namespace Renci.SshNet.Common
             _data.AddRange(bytes);
         }
 
-        private static IEnumerable<byte> GetLength(int length)
+        private static byte[] GetLength(int length)
         {
             if (length > 127)
             {
@@ -333,7 +324,9 @@ namespace Renci.SshNet.Common
                 var val = length;
 
                 while ((val >>= 8) != 0)
+                {
                     size++;
+                }
 
                 var data = new byte[size];
                 data[0] = (byte)(size | 0x80);
@@ -345,12 +338,16 @@ namespace Renci.SshNet.Common
 
                 return data;
             }
-            return new[] { (byte)length };
+
+            return new[] { (byte) length };
         }
+
         /// <summary>
-        /// Gets Data Length
+        /// Gets Data Length.
         /// </summary>
-        /// <returns>length</returns>
+        /// <returns>
+        /// The length.
+        /// </returns>
         public int ReadLength()
         {
             int length = ReadByte();
@@ -366,7 +363,9 @@ namespace Renci.SshNet.Common
 
                 // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
                 if (size > 4)
+                {
                     throw new InvalidOperationException(string.Format("DER length is '{0}' and cannot be more than 4 bytes.", size));
+                }
 
                 length = 0;
                 for (var i = 0; i < size; i++)
@@ -377,10 +376,9 @@ namespace Renci.SshNet.Common
                 }
 
                 if (length < 0)
+                {
                     throw new InvalidOperationException("Corrupted data - negative length found");
-
-                //if (length >= limit)   // after all we must have read at least 1 byte
-                //    throw new IOException("Corrupted stream - out of bounds length found");
+                }
             }
 
             return length;
@@ -389,6 +387,7 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Write Byte data into internal buffer.
         /// </summary>
+        /// <param name="data">The data to write.</param>
         public void WriteBytes(IEnumerable<byte> data)
         {
             _data.AddRange(data);
@@ -397,11 +396,15 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Reads Byte data into internal buffer.
         /// </summary>
-        /// <returns>data read</returns>
+        /// <returns>
+        /// The data read.
+        /// </returns>
         public byte ReadByte()
         {
             if (_readerIndex > _data.Count)
+            {
                 throw new InvalidOperationException("Read out of boundaries.");
+            }
 
             return _data[_readerIndex++];
         }
@@ -409,12 +412,16 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Reads lengths Bytes data into internal buffer.
         /// </summary>
-        /// <returns>data read</returns>
-        ///  <param name="length">amount of data to read.</param>
+        /// <returns>
+        /// The data read.
+        /// </returns>
+        /// <param name="length">amount of data to read.</param>
         public byte[] ReadBytes(int length)
         {
             if (_readerIndex + length > _data.Count)
+            {
                 throw new InvalidOperationException("Read out of boundaries.");
+            }
 
             var result = new byte[length];
             _data.CopyTo(_readerIndex, result, 0, length);
@@ -422,4 +429,4 @@ namespace Renci.SshNet.Common
             return result;
         }
     }
-}
+}

+ 8 - 5
src/Renci.SshNet/Common/ExceptionEventArgs.cs

@@ -7,11 +7,6 @@ namespace Renci.SshNet.Common
     /// </summary>
     public class ExceptionEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the System.Exception that represents the error that occurred.
-        /// </summary>
-        public Exception Exception { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ExceptionEventArgs"/> class.
         /// </summary>
@@ -20,5 +15,13 @@ namespace Renci.SshNet.Common
         {
             Exception = exception;
         }
+
+        /// <summary>
+        /// Gets the <see cref="Exception"/> that represents the error that occurred.
+        /// </summary>
+        /// <value>
+        /// The <see cref="Exception"/> that represents the error that occurred.
+        /// </value>
+        public Exception Exception { get; }
     }
 }

+ 68 - 18
src/Renci.SshNet/Common/Extensions.cs

@@ -11,7 +11,7 @@ using Renci.SshNet.Messages;
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Collection of different extension method
+    /// Collection of different extension methods.
     /// </summary>
     internal static partial class Extensions
     {
@@ -24,12 +24,17 @@ namespace Renci.SshNet.Common
         /// </returns>
         public static bool IsNullOrWhiteSpace(this string value)
         {
-            if (string.IsNullOrEmpty(value)) return true;
+            if (string.IsNullOrEmpty(value))
+            {
+                return true;
+            }
 
             for (var i = 0; i < value.Length; i++)
             {
                 if (!char.IsWhiteSpace(value[i]))
+                {
                     return false;
+                }
             }
 
             return true;
@@ -97,7 +102,7 @@ namespace Renci.SshNet.Common
         }
 
         /// <summary>
-        /// Prints out 
+        /// Prints out the specified bytes.
         /// </summary>
         /// <param name="bytes">The bytes.</param>
         internal static void DebugPrint(this IEnumerable<byte> bytes)
@@ -106,8 +111,9 @@ namespace Renci.SshNet.Common
 
             foreach (var b in bytes)
             {
-                sb.AppendFormat(CultureInfo.CurrentCulture, "0x{0:x2}, ", b);
+                _ = sb.AppendFormat(CultureInfo.CurrentCulture, "0x{0:x2}, ", b);
             }
+
             Debug.WriteLine(sb.ToString());
         }
 
@@ -117,32 +123,37 @@ namespace Renci.SshNet.Common
         /// <typeparam name="T">The type to create.</typeparam>
         /// <param name="type">Type of the instance to create.</param>
         /// <returns>A reference to the newly created object.</returns>
-        internal static T CreateInstance<T>(this Type type) where T : class
+        internal static T CreateInstance<T>(this Type type)
+            where T : class
         {
             if (type == null)
+            {
                 return null;
+            }
+
             return Activator.CreateInstance(type) as T;
         }
 
         internal static void ValidatePort(this uint value, string argument)
         {
             if (value > IPEndPoint.MaxPort)
+            {
                 throw new ArgumentOutOfRangeException(argument,
-                    string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.",
-                        IPEndPoint.MaxPort));
+                                                      string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.", IPEndPoint.MaxPort));
+            }
         }
 
         internal static void ValidatePort(this int value, string argument)
         {
             if (value < IPEndPoint.MinPort)
-                throw new ArgumentOutOfRangeException(argument,
-                    string.Format(CultureInfo.InvariantCulture, "Specified value cannot be less than {0}.",
-                        IPEndPoint.MinPort));
+            {
+                throw new ArgumentOutOfRangeException(argument, string.Format(CultureInfo.InvariantCulture, "Specified value cannot be less than {0}.", IPEndPoint.MinPort));
+            }
 
             if (value > IPEndPoint.MaxPort)
-                throw new ArgumentOutOfRangeException(argument,
-                    string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.",
-                        IPEndPoint.MaxPort));
+            {
+                throw new ArgumentOutOfRangeException(argument, string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.", IPEndPoint.MaxPort));
+            }
         }
 
         /// <summary>
@@ -163,13 +174,19 @@ namespace Renci.SshNet.Common
         public static byte[] Take(this byte[] value, int offset, int count)
         {
             if (value == null)
-                throw new ArgumentNullException("value");
+            {
+                throw new ArgumentNullException(nameof(value));
+            }
 
             if (count == 0)
+            {
                 return Array<byte>.Empty;
+            }
 
             if (offset == 0 && value.Length == count)
+            {
                 return value;
+            }
 
             var taken = new byte[count];
             Buffer.BlockCopy(value, offset, taken, 0, count);
@@ -192,13 +209,19 @@ namespace Renci.SshNet.Common
         public static byte[] Take(this byte[] value, int count)
         {
             if (value == null)
-                throw new ArgumentNullException("value");
+            {
+                throw new ArgumentNullException(nameof(value));
+            }
 
             if (count == 0)
+            {
                 return Array<byte>.Empty;
+            }
 
             if (value.Length == count)
+            {
                 return value;
+            }
 
             var taken = new byte[count];
             Buffer.BlockCopy(value, 0, taken, 0, count);
@@ -208,20 +231,31 @@ namespace Renci.SshNet.Common
         public static bool IsEqualTo(this byte[] left, byte[] right)
         {
             if (left == null)
-                throw new ArgumentNullException("left");
+            {
+                throw new ArgumentNullException(nameof(left));
+            }
+
             if (right == null)
-                throw new ArgumentNullException("right");
+            {
+                throw new ArgumentNullException(nameof(right));
+            }
 
             if (left == right)
+            {
                 return true;
+            }
 
             if (left.Length != right.Length)
+            {
                 return false;
+            }
 
             for (var i = 0; i < left.Length; i++)
             {
                 if (left[i] != right[i])
+                {
                     return false;
+                }
             }
 
             return true;
@@ -237,16 +271,22 @@ namespace Renci.SshNet.Common
         public static byte[] TrimLeadingZeros(this byte[] value)
         {
             if (value == null)
-                throw new ArgumentNullException("value");
+            {
+                throw new ArgumentNullException(nameof(value));
+            }
 
             for (var i = 0; i < value.Length; i++)
             {
                 if (value[i] == 0)
+                {
                     continue;
+                }
 
                 // if the first byte is non-zero, then we return the byte array as is
                 if (i == 0)
+                {
                     return value;
+                }
 
                 var remainingBytes = value.Length - i;
 
@@ -266,7 +306,10 @@ namespace Renci.SshNet.Common
         public static byte[] Pad(this byte[] data, int length)
         {
             if (length <= data.Length)
+            {
                 return data;
+            }
+
             var newData = new byte[length];
             Buffer.BlockCopy(data, 0, newData, newData.Length - data.Length, data.Length);
             return newData;
@@ -275,10 +318,14 @@ namespace Renci.SshNet.Common
         public static byte[] Concat(this byte[] first, byte[] second)
         {
             if (first == null || first.Length == 0)
+            {
                 return second;
+            }
 
             if (second == null || second.Length == 0)
+            {
                 return first;
+            }
 
             var concat = new byte[first.Length + second.Length];
             Buffer.BlockCopy(first, 0, concat, 0, first.Length);
@@ -299,7 +346,10 @@ namespace Renci.SshNet.Common
         internal static bool IsConnected(this Socket socket)
         {
             if (socket == null)
+            {
                 return false;
+            }
+
             return socket.Connected;
         }
     }

+ 1 - 4
src/Renci.SshNet/Common/HostKeyEventArgs.cs

@@ -46,12 +46,9 @@ namespace Renci.SshNet.Common
         /// <param name="host">The host.</param>
         public HostKeyEventArgs(KeyHostAlgorithm host)
         {
-            CanTrust = true;   //  Set default value
-
+            CanTrust = true;
             HostKey = host.Data;
-
             HostKeyName = host.Name;
-
             KeyLength = host.Key.KeyLength;
 
             using (var md5 = CryptoAbstraction.CreateMD5())

+ 2 - 2
src/Renci.SshNet/Common/NetConfServerException.cs

@@ -34,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public NetConfServerException(string message, Exception innerException) :
-            base(message, innerException)
+        public NetConfServerException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 12 - 4
src/Renci.SshNet/Common/ObjectIdentifier.cs

@@ -3,7 +3,7 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Describes object identifier for DER encoding
+    /// Describes object identifier for DER encoding.
     /// </summary>
     public struct ObjectIdentifier
     {
@@ -13,14 +13,22 @@ namespace Renci.SshNet.Common
         public ulong[] Identifiers { get; private set; }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="ObjectIdentifier"/> class.
+        /// Initializes a new instance of the <see cref="ObjectIdentifier"/> struct.
         /// </summary>
         /// <param name="identifiers">The identifiers.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="identifiers"/> is <see langword="null"/>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="identifiers"/> has less than two elements.</exception>
         public ObjectIdentifier(params ulong[] identifiers)
-            : this()
         {
+            if (identifiers == null)
+            {
+                throw new ArgumentNullException(nameof(identifiers));
+            }
+
             if (identifiers.Length < 2)
-                throw new ArgumentException("identifiers");
+            {
+                throw new ArgumentException("Must contain at least two elements.", nameof(identifiers));
+            }
 
             Identifiers = identifiers;
         }

+ 23 - 17
src/Renci.SshNet/Common/PacketDump.cs

@@ -5,7 +5,7 @@ using System.Text;
 
 namespace Renci.SshNet.Common
 {
-    internal class PacketDump
+    internal static class PacketDump
     {
         public static string Create(List<byte> data, int indentLevel)
         {
@@ -15,9 +15,14 @@ namespace Renci.SshNet.Common
         public static string Create(byte[] data, int indentLevel)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
+
             if (indentLevel < 0)
-                throw new ArgumentOutOfRangeException("indentLevel", "Cannot be less than zero.");
+            {
+                throw new ArgumentOutOfRangeException(nameof(indentLevel), "Cannot be less than zero.");
+            }
 
             const int lineWidth = 16;
 
@@ -31,12 +36,12 @@ namespace Renci.SshNet.Common
 
                 if (result.Length > 0)
                 {
-                    result.Append(Environment.NewLine);
+                    _ = result.Append(Environment.NewLine);
                 }
 
-                result.Append(indentChars);
-                result.Append(pos.ToString("X8"));
-                result.Append("  ");
+                _ = result.Append(indentChars);
+                _ = result.Append(pos.ToString("X8"));
+                _ = result.Append("  ");
 
                 while (true)
                 {
@@ -48,10 +53,11 @@ namespace Renci.SshNet.Common
                     }
                 }
 
-                result.Append(AsHex(line, linePos));
-                result.Append("  ");
-                result.Append(AsAscii(line, linePos));
+                _ = result.Append(AsHex(line, linePos));
+                _ = result.Append("  ");
+                _ = result.Append(AsAscii(line, linePos));
             }
+
             return result.ToString();
         }
 
@@ -63,15 +69,15 @@ namespace Renci.SshNet.Common
             {
                 if (i > 0)
                 {
-                    hex.Append(' ');
+                    _ = hex.Append(' ');
                 }
 
-                hex.Append(data[i].ToString("X2", CultureInfo.InvariantCulture));
+                _ = hex.Append(data[i].ToString("X2", CultureInfo.InvariantCulture));
             }
 
             if (length < data.Length)
             {
-                hex.Append(new string(' ', (data.Length - length) * 3));
+                _ = hex.Append(new string(' ', (data.Length - length) * 3));
             }
 
             return hex.ToString();
@@ -88,17 +94,17 @@ namespace Renci.SshNet.Common
             {
                 var b = data[i];
 
-                if (b < 32 || b >= 127)
+                if (b is < 32 or >= 127)
                 {
-                    ascii.Append(dot);
+                    _ = ascii.Append(dot);
                 }
                 else
                 {
-                    ascii.Append(encoding.GetString(data, i, 1));
+                    _ = ascii.Append(encoding.GetString(data, i, 1));
                 }
             }
 
             return ascii.ToString();
         }
     }
-}
+}

+ 122 - 84
src/Renci.SshNet/Common/PipeStream.cs

@@ -1,40 +1,38 @@
-namespace Renci.SshNet.Common
-{
-    using System;
-    using System.Collections.Generic;
-    using System.IO;
-    using System.Threading;
-    using System.Globalization;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Threading;
 
+namespace Renci.SshNet.Common
+{
     /// <summary>
-    /// PipeStream is a thread-safe read/write data stream for use between two threads in a 
+    /// PipeStream is a thread-safe read/write data stream for use between two threads in a
     /// single-producer/single-consumer type problem.
     /// </summary>
     /// <version>2006/10/13 1.0</version>
     /// <remarks>Update on 2008/10/9 1.1 - uses Monitor instead of Manual Reset events for more elegant synchronicity.</remarks>
     /// <license>
-    ///	Copyright (c) 2006 James Kolpack (james dot kolpack at google mail)
-    ///	
-    ///	Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
-    ///	associated documentation files (the "Software"), to deal in the Software without restriction, 
-    ///	including without limitation the rights to use, copy, modify, merge, publish, distribute, 
-    ///	sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
-    ///	furnished to do so, subject to the following conditions:
-    ///	
-    ///	The above copyright notice and this permission notice shall be included in all copies or 
-    ///	substantial portions of the Software.
-    ///	
-    ///	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
-    ///	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
-    ///	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
-    ///	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
-    ///	OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
-    ///	OTHER DEALINGS IN THE SOFTWARE.
+    /// Copyright (c) 2006 James Kolpack (james dot kolpack at google mail)
+    ///
+    /// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+    /// associated documentation files (the "Software"), to deal in the Software without restriction,
+    /// including without limitation the rights to use, copy, modify, merge, publish, distribute,
+    /// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+    /// furnished to do so, subject to the following conditions:
+    ///
+    /// The above copyright notice and this permission notice shall be included in all copies or
+    /// substantial portions of the Software.
+    ///
+    /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+    /// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+    /// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+    /// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+    /// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    /// OTHER DEALINGS IN THE SOFTWARE.
     /// </license>
     public class PipeStream : Stream
     {
-        #region Private members
-
         /// <summary>
         /// Queue of bytes provides the datastructure for transmitting from an
         /// input stream to an output stream.
@@ -64,10 +62,6 @@
         /// </summary>
         private bool _isDisposed;
 
-        #endregion
-
-        #region Public properties
-
         /// <summary>
         /// Gets or sets the maximum number of bytes to store in the buffer.
         /// </summary>
@@ -87,7 +81,7 @@
         /// Setting to true will remove the possibility of ending a stream reader prematurely.
         /// </remarks>
         /// <value>
-        /// 	<c>true</c> if block last read method before the buffer is empty; otherwise, <c>false</c>.
+        /// <c>true</c> if block last read method before the buffer is empty; otherwise, <c>false</c>.
         /// </value>
         /// <exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
         public bool BlockLastReadBuffer
@@ -95,28 +89,32 @@
             get
             {
                 if (_isDisposed)
+                {
                     throw CreateObjectDisposedException();
+                }
 
                 return _canBlockLastRead;
             }
             set
             {
                 if (_isDisposed)
+                {
                     throw CreateObjectDisposedException();
+                }
 
                 _canBlockLastRead = value;
 
                 // when turning off the block last read, signal Read() that it may now read the rest of the buffer.
                 if (!_canBlockLastRead)
+                {
                     lock (_buffer)
+                    {
                         Monitor.Pulse(_buffer);
+                    }
+                }
             }
         }
 
-        #endregion
-
-        #region Stream overide methods
-
         /// <summary>
         /// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device.
         /// </summary>
@@ -129,7 +127,9 @@
         public override void Flush()
         {
             if (_isDisposed)
+            {
                 throw CreateObjectDisposedException();
+            }
 
             _isFlushed = true;
             lock (_buffer)
@@ -163,37 +163,57 @@
             throw new NotSupportedException();
         }
 
-        ///<summary>
-        ///When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
-        ///</summary>
-        ///<returns>
-        ///The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the stream is closed or end of the stream has been reached.
-        ///</returns>
-        ///<param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
-        ///<param name="count">The maximum number of bytes to be read from the current stream.</param>
-        ///<param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.</param>
-        ///<exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
-        ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
-        ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
-        ///<exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
-        ///<exception cref="IOException">An I/O error occurs.</exception>
-        ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
+        /// <summary>
+        /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
+        /// </summary>
+        /// <returns>
+        /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the stream is closed or end of the stream has been reached.
+        /// </returns>
+        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.</param>
+        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
+        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
+        /// <exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
+        /// <exception cref="NotSupportedException">The stream does not support reading.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
+        /// <exception cref="IOException">An I/O error occurs.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
         public override int Read(byte[] buffer, int offset, int count)
         {
             if (offset != 0)
+            {
                 throw new NotSupportedException("Offsets with value of non-zero are not supported");
+            }
+
             if (buffer == null)
-                throw new ArgumentNullException("buffer");
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+
             if (offset + count > buffer.Length)
+            {
                 throw new ArgumentException("The sum of offset and count is greater than the buffer length.");
+            }
+
             if (offset < 0 || count < 0)
-                throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset), "offset or count is negative.");
+            }
+
             if (BlockLastReadBuffer && count >= _maxBufferLength)
+            {
                 throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "count({0}) > mMaxBufferLength({1})", count, _maxBufferLength));
+            }
+
             if (_isDisposed)
+            {
                 throw CreateObjectDisposedException();
+            }
+
             if (count == 0)
+            {
                 return 0;
+            }
 
             var readLength = 0;
 
@@ -201,7 +221,7 @@
             {
                 while (!_isDisposed && !ReadAvailable(count))
                 {
-                    Monitor.Wait(_buffer);
+                    _ = Monitor.Wait(_buffer);
                 }
 
                 // return zero when the read is interrupted by a close/dispose of the stream
@@ -223,46 +243,64 @@
         }
 
         /// <summary>
-        /// Returns true if there are
+        /// Returns a value indicating whether data is available.
         /// </summary>
         /// <param name="count">The count.</param>
-        /// <returns><c>True</c> if data available; otherwise<c>false</c>.</returns>
+        /// <returns>
+        /// <see langword="true"/> if data is available; otherwise, <see langword="false"/>.
+        /// </returns>
         private bool ReadAvailable(int count)
         {
             var length = Length;
             return (_isFlushed || length >= count) && (length >= (count + 1) || !BlockLastReadBuffer);
         }
 
-        ///<summary>
-        ///When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
-        ///</summary>
-        ///<param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
-        ///<param name="count">The number of bytes to be written to the current stream.</param>
-        ///<param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
-        ///<exception cref="IOException">An I/O error occurs.</exception>
-        ///<exception cref="NotSupportedException">The stream does not support writing.</exception>
-        ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
-        ///<exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
-        ///<exception cref="ArgumentException">The sum of offset and count is greater than the buffer length.</exception>
-        ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
+        /// <summary>
+        /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
+        /// </summary>
+        /// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
+        /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
+        /// <param name="count">The number of bytes to be written to the current stream.</param>
+        /// <exception cref="IOException">An I/O error occurs.</exception>
+        /// <exception cref="NotSupportedException">The stream does not support writing.</exception>
+        /// <exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException">The sum of offset and count is greater than the buffer length.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
         public override void Write(byte[] buffer, int offset, int count)
         {
             if (buffer == null)
-                throw new ArgumentNullException("buffer");
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+
             if (offset + count > buffer.Length)
+            {
                 throw new ArgumentException("The sum of offset and count is greater than the buffer length.");
+            }
+
             if (offset < 0 || count < 0)
-                throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
+            {
+                throw new ArgumentOutOfRangeException(nameof(offset), "offset or count is negative.");
+            }
+
             if (_isDisposed)
+            {
                 throw CreateObjectDisposedException();
+            }
+
             if (count == 0)
+            {
                 return;
+            }
 
             lock (_buffer)
             {
                 // wait until the buffer isn't full
                 while (Length >= _maxBufferLength)
-                    Monitor.Wait(_buffer);
+                {
+                    _ = Monitor.Wait(_buffer);
+                }
 
                 _isFlushed = false; // if it were flushed before, it soon will not be.
 
@@ -297,30 +335,30 @@
             }
         }
 
-        ///<summary>
-        ///When overridden in a derived class, gets a value indicating whether the current stream supports reading.
-        ///</summary>
-        ///<returns>
-        ///true if the stream supports reading; otherwise, false.
-        ///</returns>
+        /// <summary>
+        /// Gets a value indicating whether the current stream supports reading.
+        /// </summary>
+        /// <returns>
+        /// true if the stream supports reading; otherwise, false.
+        /// </returns>
         public override bool CanRead
         {
             get { return !_isDisposed; }
         }
 
         /// <summary>
-        /// When overridden in a derived class, gets a value indicating whether the current stream supports seeking.
+        /// Gets a value indicating whether the current stream supports seeking.
         /// </summary>
         /// <returns>
         /// <c>true</c> if the stream supports seeking; otherwise, <c>false</c>.
-        ///</returns>
+        /// </returns>
         public override bool CanSeek
         {
             get { return false; }
         }
 
         /// <summary>
-        /// When overridden in a derived class, gets a value indicating whether the current stream supports writing.
+        /// Gets a value indicating whether the current stream supports writing.
         /// </summary>
         /// <returns>
         /// <c>true</c> if the stream supports writing; otherwise, <c>false</c>.
@@ -331,7 +369,7 @@
         }
 
         /// <summary>
-        /// When overridden in a derived class, gets the length in bytes of the stream.
+        /// Gets the length in bytes of the stream.
         /// </summary>
         /// <returns>
         /// A long value representing the length of the stream in bytes.
@@ -343,14 +381,16 @@
             get
             {
                 if (_isDisposed)
+                {
                     throw CreateObjectDisposedException();
+                }
 
                 return _buffer.Count;
             }
         }
 
         /// <summary>
-        /// When overridden in a derived class, gets or sets the position within the current stream.
+        /// Gets or sets the position within the current stream.
         /// </summary>
         /// <returns>
         /// The current position within the stream.
@@ -362,8 +402,6 @@
             set { throw new NotSupportedException(); }
         }
 
-        #endregion
-
         private ObjectDisposedException CreateObjectDisposedException()
         {
             return new ObjectDisposedException(GetType().FullName);

+ 17 - 13
src/Renci.SshNet/Common/PortForwardEventArgs.cs

@@ -1,37 +1,41 @@
 using System;
+using System.Net;
 
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.ForwardedPort.RequestReceived"/> event.
+    /// Provides data for <see cref="ForwardedPort.RequestReceived"/> event.
     /// </summary>
     public class PortForwardEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets request originator host.
-        /// </summary>
-        public string OriginatorHost { get; private set; }
-
-        /// <summary>
-        /// Gets request originator port.
-        /// </summary>
-        public uint OriginatorPort { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="PortForwardEventArgs"/> class.
         /// </summary>
         /// <param name="host">The host.</param>
         /// <param name="port">The port.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="IPEndPoint.MinPort" /> and <see cref="IPEndPoint.MaxPort" />.</exception>
         internal PortForwardEventArgs(string host, uint port)
         {
             if (host == null)
-                throw new ArgumentNullException("host");
+            {
+                throw new ArgumentNullException(nameof(host));
+            }
+
             port.ValidatePort("port");
 
             OriginatorHost = host;
             OriginatorPort = port;
         }
+
+        /// <summary>
+        /// Gets request originator host.
+        /// </summary>
+        public string OriginatorHost { get; }
+
+        /// <summary>
+        /// Gets request originator port.
+        /// </summary>
+        public uint OriginatorPort { get; }
     }
 }

+ 53 - 5
src/Renci.SshNet/Common/PosixPath.cs

@@ -2,16 +2,45 @@
 
 namespace Renci.SshNet.Common
 {
+    /// <summary>
+    /// Represents a POSIX path.
+    /// </summary>
     internal class PosixPath
     {
+        private PosixPath()
+        {
+        }
+
+        /// <summary>
+        /// Gets the directory of the path.
+        /// </summary>
+        /// <value>
+        /// The directory of the path.
+        /// </value>
         public string Directory { get; private set; }
+
+        /// <summary>
+        /// Gets the file part of the path.
+        /// </summary>
+        /// <value>
+        /// The file part of the path, or <see langword="null"/> if the path represents a directory.
+        /// </value>
         public string File { get; private set; }
 
+        /// <summary>
+        /// Create a <see cref="PosixPath"/> from the specified path.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <returns>
+        /// A <see cref="PosixPath"/> created from the specified path.
+        /// </returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="path"/> is empty ("").</exception>
         public static PosixPath CreateAbsoluteOrRelativeFilePath(string path)
         {
             if (path == null)
             {
-                throw new ArgumentNullException("path");
+                throw new ArgumentNullException(nameof(path));
             }
 
             var posixPath = new PosixPath();
@@ -21,7 +50,7 @@ namespace Renci.SshNet.Common
             {
                 if (path.Length == 0)
                 {
-                    throw new ArgumentException("The path is a zero-length string.", "path");
+                    throw new ArgumentException("The path is a zero-length string.", nameof(path));
                 }
 
                 posixPath.Directory = ".";
@@ -54,7 +83,7 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The file name part of <paramref name="path"/>.
         /// </returns>
-        /// <exception cref="NullReferenceException"><paramref name="path"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c>.</exception>
         /// <remarks>
         /// <para>
         /// If <paramref name="path"/> contains no forward slash, then <paramref name="path"/>
@@ -67,13 +96,21 @@ namespace Renci.SshNet.Common
         public static string GetFileName(string path)
         {
             if (path == null)
-                throw new ArgumentNullException("path");
+            {
+                throw new ArgumentNullException(nameof(path));
+            }
 
             var pathEnd = path.LastIndexOf('/');
             if (pathEnd == -1)
+            {
                 return path;
+            }
+
             if (pathEnd == path.Length - 1)
+            {
                 return string.Empty;
+            }
+
             return path.Substring(pathEnd + 1);
         }
 
@@ -89,15 +126,26 @@ namespace Renci.SshNet.Common
         public static string GetDirectoryName(string path)
         {
             if (path == null)
-                throw new ArgumentNullException("path");
+            {
+                throw new ArgumentNullException(nameof(path));
+            }
 
             var pathEnd = path.LastIndexOf('/');
             if (pathEnd == -1)
+            {
                 return ".";
+            }
+
             if (pathEnd == 0)
+            {
                 return "/";
+            }
+
             if (pathEnd == path.Length - 1)
+            {
                 return path.Substring(0, pathEnd);
+            }
+
             return path.Substring(0, pathEnd);
         }
     }

+ 5 - 5
src/Renci.SshNet/Common/ProxyException.cs

@@ -14,14 +14,14 @@ namespace Renci.SshNet.Common
     public class ProxyException : SshException
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// Initializes a new instance of the <see cref="ProxyException"/> class.
         /// </summary>
         public ProxyException()
         {
         }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// Initializes a new instance of the <see cref="ProxyException"/> class.
         /// </summary>
         /// <param name="message">The message.</param>
         public ProxyException(string message)
@@ -30,12 +30,12 @@ namespace Renci.SshNet.Common
         }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="ScpException"/> class.
+        /// Initializes a new instance of the <see cref="ProxyException"/> class.
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public ProxyException(string message, Exception innerException) :
-            base(message, innerException)
+        public ProxyException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 15 - 15
src/Renci.SshNet/Common/ScpDownloadEventArgs.cs

@@ -7,21 +7,6 @@ namespace Renci.SshNet.Common
     /// </summary>
     public class ScpDownloadEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the downloaded filename.
-        /// </summary>
-        public string Filename { get; private set; }
-
-        /// <summary>
-        /// Gets the downloaded file size.
-        /// </summary>
-        public long Size { get; private set; }
-
-        /// <summary>
-        /// Gets number of downloaded bytes so far.
-        /// </summary>
-        public long Downloaded { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ScpDownloadEventArgs"/> class.
         /// </summary>
@@ -34,5 +19,20 @@ namespace Renci.SshNet.Common
             Size = size;
             Downloaded = downloaded;
         }
+
+        /// <summary>
+        /// Gets the downloaded filename.
+        /// </summary>
+        public string Filename { get; }
+
+        /// <summary>
+        /// Gets the downloaded file size.
+        /// </summary>
+        public long Size { get; }
+
+        /// <summary>
+        /// Gets number of downloaded bytes so far.
+        /// </summary>
+        public long Downloaded { get; }
     }
 }

+ 2 - 2
src/Renci.SshNet/Common/ScpException.cs

@@ -34,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public ScpException(string message, Exception innerException) :
-            base(message, innerException)
+        public ScpException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 15 - 15
src/Renci.SshNet/Common/ScpUploadEventArgs.cs

@@ -7,21 +7,6 @@ namespace Renci.SshNet.Common
     /// </summary>
     public class ScpUploadEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the uploaded filename.
-        /// </summary>
-        public string Filename { get; private set; }
-
-        /// <summary>
-        /// Gets the uploaded file size.
-        /// </summary>
-        public long Size { get; private set; }
-
-        /// <summary>
-        /// Gets number of uploaded bytes so far.
-        /// </summary>
-        public long Uploaded { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ScpUploadEventArgs"/> class.
         /// </summary>
@@ -34,5 +19,20 @@ namespace Renci.SshNet.Common
             Size = size;
             Uploaded = uploaded;
         }
+
+        /// <summary>
+        /// Gets the uploaded filename.
+        /// </summary>
+        public string Filename { get; }
+
+        /// <summary>
+        /// Gets the uploaded file size.
+        /// </summary>
+        public long Size { get; }
+
+        /// <summary>
+        /// Gets number of uploaded bytes so far.
+        /// </summary>
+        public long Uploaded { get; }
     }
 }

+ 34 - 22
src/Renci.SshNet/Common/SemaphoreLight.cs

@@ -14,15 +14,17 @@ namespace Renci.SshNet.Common
         private int _currentCount;
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="SemaphoreLight"/> class, specifying 
-        /// the initial number of requests that can be granted concurrently.
+        /// Initializes a new instance of the <see cref="SemaphoreLight"/> class, specifying the initial number of requests that can
+        /// be granted concurrently.
         /// </summary>
         /// <param name="initialCount">The initial number of requests for the semaphore that can be granted concurrently.</param>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount"/> is a negative number.</exception>
         public SemaphoreLight(int initialCount)
         {
-            if (initialCount < 0 )
-                throw new ArgumentOutOfRangeException("initialCount", "The value cannot be negative.");
+            if (initialCount < 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(initialCount), "The value cannot be negative.");
+            }
 
             _currentCount = initialCount;
         }
@@ -30,10 +32,13 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Gets the current count of the <see cref="SemaphoreLight"/>.
         /// </summary>
-        public int CurrentCount { get { return _currentCount; } }
+        public int CurrentCount
+        {
+            get { return _currentCount; }
+        }
 
         /// <summary>
-        /// Returns a <see cref="WaitHandle"/> that can be used to wait on the semaphore.
+        /// Gets a <see cref="WaitHandle"/> that can be used to wait on the semaphore.
         /// </summary>
         /// <value>
         /// A <see cref="WaitHandle"/> that can be used to wait on the semaphore.
@@ -51,10 +56,7 @@ namespace Renci.SshNet.Common
                 {
                     lock (_lock)
                     {
-                        if (_waitHandle == null)
-                        {
-                            _waitHandle = new ManualResetEvent(_currentCount > 0);
-                        }
+                        _waitHandle ??= new ManualResetEvent(_currentCount > 0);
                     }
                 }
 
@@ -89,7 +91,7 @@ namespace Renci.SshNet.Common
                 // signal waithandle when the original semaphore count was zero
                 if (_waitHandle != null && oldCount == 0)
                 {
-                    _waitHandle.Set();
+                    _ = _waitHandle.Set();
                 }
 
                 Monitor.PulseAll(_lock);
@@ -107,7 +109,7 @@ namespace Renci.SshNet.Common
             {
                 while (_currentCount < 1)
                 {
-                    Monitor.Wait(_lock);
+                    _ = Monitor.Wait(_lock);
                 }
 
                 _currentCount--;
@@ -115,7 +117,7 @@ namespace Renci.SshNet.Common
                 // unsignal waithandle when the semaphore count reaches zero
                 if (_waitHandle != null && _currentCount == 0)
                 {
-                    _waitHandle.Reset();
+                    _ = _waitHandle.Reset();
                 }
 
                 Monitor.PulseAll(_lock);
@@ -133,7 +135,9 @@ namespace Renci.SshNet.Common
         public bool Wait(int millisecondsTimeout)
         {
             if (millisecondsTimeout < -1)
-                throw new ArgumentOutOfRangeException("millisecondsTimeout", "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
+            {
+                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
+            }
 
             return WaitWithTimeout(millisecondsTimeout);
         }
@@ -149,8 +153,10 @@ namespace Renci.SshNet.Common
         public bool Wait(TimeSpan timeout)
         {
             var timeoutInMilliseconds = timeout.TotalMilliseconds;
-            if (timeoutInMilliseconds < -1d || timeoutInMilliseconds > int.MaxValue)
-                throw new ArgumentOutOfRangeException("timeout", "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
+            if (timeoutInMilliseconds is < -1d or > int.MaxValue)
+            {
+                throw new ArgumentOutOfRangeException(nameof(timeout), "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
+            }
 
             return WaitWithTimeout((int) timeoutInMilliseconds);
         }
@@ -162,14 +168,18 @@ namespace Renci.SshNet.Common
                 if (timeoutInMilliseconds == Session.Infinite)
                 {
                     while (_currentCount < 1)
-                        Monitor.Wait(_lock);
+                    {
+                        _ = Monitor.Wait(_lock);
+                    }
                 }
                 else
                 {
                     if (_currentCount < 1)
                     {
                         if (timeoutInMilliseconds > 0)
+                        {
                             return false;
+                        }
 
                         var remainingTimeInMilliseconds = timeoutInMilliseconds;
                         var startTicks = Environment.TickCount;
@@ -184,7 +194,9 @@ namespace Renci.SshNet.Common
                             var elapsed = Environment.TickCount - startTicks;
                             remainingTimeInMilliseconds -= elapsed;
                             if (remainingTimeInMilliseconds < 0)
+                            {
                                 return false;
+                            }
                         }
                     }
                 }
@@ -194,7 +206,7 @@ namespace Renci.SshNet.Common
                 // unsignal waithandle when the semaphore count is zero
                 if (_waitHandle != null && _currentCount == 0)
                 {
-                    _waitHandle.Reset();
+                    _ = _waitHandle.Reset();
                 }
 
                 Monitor.PulseAll(_lock);
@@ -204,11 +216,11 @@ namespace Renci.SshNet.Common
         }
 
         /// <summary>
-        /// Finalizes the current <see cref="SemaphoreLight"/>.
+        /// Finalizes an instance of the <see cref="SemaphoreLight"/> class.
         /// </summary>
         ~SemaphoreLight()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
 
         /// <summary>
@@ -216,12 +228,12 @@ namespace Renci.SshNet.Common
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected void Dispose(bool disposing)

+ 2 - 2
src/Renci.SshNet/Common/SftpPathNotFoundException.cs

@@ -34,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public SftpPathNotFoundException(string message, Exception innerException) :
-            base(message, innerException)
+        public SftpPathNotFoundException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 2 - 2
src/Renci.SshNet/Common/SftpPermissionDeniedException.cs

@@ -34,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public SftpPermissionDeniedException(string message, Exception innerException) :
-            base(message, innerException)
+        public SftpPermissionDeniedException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 11 - 11
src/Renci.SshNet/Common/ShellDataEventArgs.cs

@@ -3,20 +3,10 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for Shell DataReceived event
+    /// Provides data for Shell DataReceived event.
     /// </summary>
     public class ShellDataEventArgs : EventArgs
     {
-        /// <summary>
-        /// Gets the data.
-        /// </summary>
-        public byte[] Data { get; private set; }
-
-        /// <summary>
-        /// Gets the line data.
-        /// </summary>
-        public string Line { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ShellDataEventArgs"/> class.
         /// </summary>
@@ -34,5 +24,15 @@ namespace Renci.SshNet.Common
         {
             Line = line;
         }
+
+        /// <summary>
+        /// Gets the data.
+        /// </summary>
+        public byte[] Data { get; }
+
+        /// <summary>
+        /// Gets the line data.
+        /// </summary>
+        public string Line { get; }
     }
 }

+ 2 - 4
src/Renci.SshNet/Common/SshAuthenticationException.cs

@@ -18,7 +18,6 @@ namespace Renci.SshNet.Common
         /// </summary>
         public SshAuthenticationException()
         {
-
         }
 
         /// <summary>
@@ -28,7 +27,6 @@ namespace Renci.SshNet.Common
         public SshAuthenticationException(string message)
             : base(message)
         {
-
         }
 
         /// <summary>
@@ -36,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public SshAuthenticationException(string message, Exception innerException) :
-            base(message, innerException)
+        public SshAuthenticationException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 41 - 19
src/Renci.SshNet/Common/SshData.cs

@@ -5,7 +5,7 @@ using System.Text;
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Base ssh data serialization type
+    /// Base ssh data serialization type.
     /// </summary>
     public abstract class SshData
     {
@@ -57,7 +57,7 @@ namespace Renci.SshNet.Common
         /// Gets data bytes array.
         /// </summary>
         /// <returns>
-        /// A <see cref="Byte"/> array representation of data structure.
+        /// A <see cref="byte"/> array representation of data structure.
         /// </returns>
         public byte[] GetBytes()
         {
@@ -86,7 +86,9 @@ namespace Renci.SshNet.Common
         public void Load(byte[] data)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
 
             LoadInternal(data, 0, data.Length);
         }
@@ -101,7 +103,9 @@ namespace Renci.SshNet.Common
         public void Load(byte[] data, int offset, int count)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
 
             LoadInternal(data, offset, count);
         }
@@ -130,7 +134,7 @@ namespace Renci.SshNet.Common
         {
             var bytesLength = (int) (_stream.Length - _stream.Position);
             var data = new byte[bytesLength];
-            _stream.Read(data, 0, bytesLength);
+            _ = _stream.Read(data, 0, bytesLength);
             return data;
         }
 
@@ -142,15 +146,19 @@ namespace Renci.SshNet.Common
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
         protected byte[] ReadBytes(int length)
         {
-            // Note that this also prevents allocating non-relevant lengths, such as if length is greater than _data.Count but less than int.MaxValue.
-            // For the nerds, the condition translates to: if (length > data.Count && length < int.MaxValue)
-            // Which probably would cause all sorts of exception, most notably OutOfMemoryException.
+            /*
+             * Note that this also prevents allocating non-relevant lengths, such as if length is greater than _data.Count but less than int.MaxValue.
+             * For the nerds, the condition translates to: if (length > data.Count && length < int.MaxValue)
+             * Which probably would cause all sorts of exception, most notably OutOfMemoryException.
+             */
 
             var data = new byte[length];
             var bytesRead = _stream.Read(data, 0, length);
 
             if (bytesRead < length)
-                throw new ArgumentOutOfRangeException("length");
+            {
+                throw new ArgumentOutOfRangeException(nameof(length));
+            }
 
             return data;
         }
@@ -163,51 +171,63 @@ namespace Renci.SshNet.Common
         {
             var byteRead = _stream.ReadByte();
             if (byteRead == -1)
+            {
                 throw new InvalidOperationException("Attempt to read past the end of the SSH data stream.");
+            }
+
             return (byte) byteRead;
         }
 
         /// <summary>
-        /// Reads next boolean data type from internal buffer.
+        /// Reads the next <see cref="bool"/> from the internal buffer.
         /// </summary>
-        /// <returns>Boolean read.</returns>
+        /// <returns>
+        /// The <see cref="bool"/> that was read.
+        /// </returns>
         protected bool ReadBoolean()
         {
             return ReadByte() != 0;
         }
 
         /// <summary>
-        /// Reads next uint16 data type from internal buffer.
+        /// Reads the next <see cref="ushort"/> from the internal buffer.
         /// </summary>
-        /// <returns>uint16 read</returns>
+        /// <returns>
+        /// The <see cref="ushort"/> that was read.
+        /// </returns>
         protected ushort ReadUInt16()
         {
             return Pack.BigEndianToUInt16(ReadBytes(2));
         }
 
         /// <summary>
-        /// Reads next uint32 data type from internal buffer.
+        /// Reads the next <see cref="uint"/> from the internal buffer.
         /// </summary>
-        /// <returns>uint32 read</returns>
+        /// <returns>
+        /// The <see cref="uint"/> that was read.
+        /// </returns>
         protected uint ReadUInt32()
         {
             return Pack.BigEndianToUInt32(ReadBytes(4));
         }
 
         /// <summary>
-        /// Reads next uint64 data type from internal buffer.
+        /// Reads the next <see cref="ulong"/> from the internal buffer.
         /// </summary>
-        /// <returns>uint64 read</returns>
+        /// <returns>
+        /// The <see cref="ulong"/> that was read.
+        /// </returns>
         protected ulong ReadUInt64()
         {
             return Pack.BigEndianToUInt64(ReadBytes(8));
         }
 
         /// <summary>
-        /// Reads next string data type from internal buffer using the specific encoding.
+        /// Reads the next <see cref="string"/> from the internal buffer using the specified encoding.
         /// </summary>
+        /// <param name="encoding">The character encoding to use.</param>
         /// <returns>
-        /// The <see cref="string"/> read.
+        /// The <see cref="string"/> that was read.
         /// </returns>
         protected string ReadString(Encoding encoding)
         {
@@ -244,12 +264,14 @@ namespace Renci.SshNet.Common
         protected IDictionary<string, string> ReadExtensionPair()
         {
             var result = new Dictionary<string, string>();
+
             while (!IsEndOfData)
             {
                 var extensionName = ReadString(Ascii);
                 var extensionData = ReadString(Ascii);
                 result.Add(extensionName, extensionData);
             }
+
             return result;
         }
 

+ 34 - 26
src/Renci.SshNet/Common/SshDataStream.cs

@@ -21,7 +21,7 @@ namespace Renci.SshNet.Common
         }
 
         /// <summary>
-        /// Initializes a new non-resizable instance of the <see cref="SshDataStream"/> class based on the specified byte array.
+        /// Initializes a new instance of the <see cref="SshDataStream"/> class for the specified byte array.
         /// </summary>
         /// <param name="buffer">The array of unsigned bytes from which to create the current stream.</param>
         /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
@@ -31,7 +31,7 @@ namespace Renci.SshNet.Common
         }
 
         /// <summary>
-        /// Initializes a new non-resizable instance of the <see cref="SshDataStream"/> class based on the specified byte array.
+        /// Initializes a new instance of the <see cref="SshDataStream"/> class for the specified byte array.
         /// </summary>
         /// <param name="buffer">The array of unsigned bytes from which to create the current stream.</param>
         /// <param name="offset">The zero-based offset in <paramref name="buffer"/> at which to begin reading SSH data.</param>
@@ -94,7 +94,9 @@ namespace Renci.SshNet.Common
         public void Write(byte[] data)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
 
             Write(data, 0, data.Length);
         }
@@ -125,7 +127,9 @@ namespace Renci.SshNet.Common
         public void WriteBinary(byte[] buffer)
         {
             if (buffer == null)
-                throw new ArgumentNullException("buffer");
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
 
             WriteBinary(buffer, 0, buffer.Length);
         }
@@ -155,7 +159,9 @@ namespace Renci.SshNet.Common
         public void Write(string s, Encoding encoding)
         {
             if (encoding == null)
-                throw new ArgumentNullException("encoding");
+            {
+                throw new ArgumentNullException(nameof(encoding));
+            }
 
             var bytes = encoding.GetBytes(s);
             WriteBinary(bytes, 0, bytes.Length);
@@ -201,6 +207,7 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Reads the next <see cref="string"/> data type from the SSH data stream.
         /// </summary>
+        /// <param name="encoding">The character encoding to use.</param>
         /// <returns>
         /// The <see cref="string"/> read from the SSH data stream.
         /// </returns>
@@ -217,27 +224,6 @@ namespace Renci.SshNet.Common
             return encoding.GetString(bytes, 0, bytes.Length);
         }
 
-        /// <summary>
-        /// Reads next specified number of bytes data type from internal buffer.
-        /// </summary>
-        /// <param name="length">Number of bytes to read.</param>
-        /// <returns>
-        /// An array of bytes that was read from the internal buffer.
-        /// </returns>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
-        private byte[] ReadBytes(int length)
-        {
-            var data = new byte[length];
-            var bytesRead = Read(data, 0, length);
-
-            if (bytesRead < length)
-                throw new ArgumentOutOfRangeException("length",
-                    string.Format(CultureInfo.InvariantCulture,
-                        "The requested length ({0}) is greater than the actual number of bytes read ({1}).", length, bytesRead));
-
-            return data;
-        }
-
         /// <summary>
         /// Writes the stream contents to a byte array, regardless of the <see cref="MemoryStream.Position"/>.
         /// </summary>
@@ -254,7 +240,29 @@ namespace Renci.SshNet.Common
             {
                 return GetBuffer();
             }
+
             return base.ToArray();
         }
+
+        /// <summary>
+        /// Reads next specified number of bytes data type from internal buffer.
+        /// </summary>
+        /// <param name="length">Number of bytes to read.</param>
+        /// <returns>
+        /// An array of bytes that was read from the internal buffer.
+        /// </returns>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
+        private byte[] ReadBytes(int length)
+        {
+            var data = new byte[length];
+            var bytesRead = Read(data, 0, length);
+
+            if (bytesRead < length)
+            {
+                throw new ArgumentOutOfRangeException(nameof(length), string.Format(CultureInfo.InvariantCulture, "The requested length ({0}) is greater than the actual number of bytes read ({1}).", length, bytesRead));
+            }
+
+            return data;
+        }
     }
 }

+ 2 - 2
src/Renci.SshNet/Common/SshOperationTimeoutException.cs

@@ -34,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public SshOperationTimeoutException(string message, Exception innerException) :
-            base(message, innerException)
+        public SshOperationTimeoutException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 3 - 5
src/Renci.SshNet/Common/SshPassPhraseNullOrEmptyException.cs

@@ -6,7 +6,7 @@ using System.Runtime.Serialization;
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// The exception that is thrown when pass phrase for key file is empty or null
+    /// The exception that is thrown when pass phrase for key file is empty or <see langword="null"/>.
     /// </summary>
 #if FEATURE_BINARY_SERIALIZATION
     [Serializable]
@@ -18,7 +18,6 @@ namespace Renci.SshNet.Common
         /// </summary>
         public SshPassPhraseNullOrEmptyException()
         {
-
         }
 
         /// <summary>
@@ -28,7 +27,6 @@ namespace Renci.SshNet.Common
         public SshPassPhraseNullOrEmptyException(string message)
             : base(message)
         {
-
         }
 
         /// <summary>
@@ -36,8 +34,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="message">The message.</param>
         /// <param name="innerException">The inner exception.</param>
-        public SshPassPhraseNullOrEmptyException(string message, Exception innerException) :
-            base(message, innerException)
+        public SshPassPhraseNullOrEmptyException(string message, Exception innerException)
+            : base(message, innerException)
         {
         }
 

+ 13 - 13
src/Renci.SshNet/Common/TerminalModes.cs

@@ -7,21 +7,21 @@
     {
         /// <summary>
         /// Indicates end of options.
-        /// </summary> 
+        /// </summary>
         TTY_OP_END = 0,
-        
+
         /// <summary>
         /// Interrupt character; 255 if none.  Similarly for the other characters.  Not all of these characters are supported on all systems.
-        /// </summary> 
+        /// </summary>
         VINTR = 1,
 
         /// <summary>
         /// The quit character (sends SIGQUIT signal on POSIX systems).
-        /// </summary> 
+        /// </summary>
         VQUIT = 2,
-        
+
         /// <summary>
-        /// Erase the character to left of the cursor. 
+        /// Erase the character to left of the cursor.
         /// </summary>
         VERASE = 3,
 
@@ -34,32 +34,32 @@
         /// End-of-file character (sends EOF from the terminal).
         /// </summary>
         VEOF = 5,
-        
+
         /// <summary>
         /// End-of-line character in addition to carriage return and/or linefeed.
         /// </summary>
         VEOL = 6,
-        
+
         /// <summary>
         /// Additional end-of-line character.
         /// </summary>
         VEOL2 = 7,
-        
+
         /// <summary>
         /// Continues paused output (normally control-Q).
         /// </summary>
         VSTART = 8,
-        
+
         /// <summary>
         /// Pauses output (normally control-S).
         /// </summary>
         VSTOP = 9,
-        
+
         /// <summary>
         /// Suspends the current program.
         /// </summary>
         VSUSP = 10,
-        
+
         /// <summary>
         /// Another suspend character.
         /// </summary>
@@ -76,7 +76,7 @@
         VWERASE = 13,
 
         /// <summary>
-        /// Enter the next character typed literally, even if it is a special character
+        /// Enter the next character typed literally, even if it is a special character.
         /// </summary>
         VLNEXT = 14,
 

+ 12 - 11
src/Renci.SshNet/Compression/Compressor.cs

@@ -1,6 +1,7 @@
-using Renci.SshNet.Security;
+using System;
 using System.IO;
-using System;
+
+using Renci.SshNet.Security;
 
 namespace Renci.SshNet.Compression
 {
@@ -11,9 +12,9 @@ namespace Renci.SshNet.Compression
     {
         private readonly ZlibStream _compressor;
         private readonly ZlibStream _decompressor;
-
         private MemoryStream _compressorStream;
         private MemoryStream _decompressorStream;
+        private bool _isDisposed;
 
         /// <summary>
         /// Gets or sets a value indicating whether compression is active.
@@ -73,7 +74,9 @@ namespace Renci.SshNet.Compression
             if (!IsActive)
             {
                 if (offset == 0 && length == data.Length)
+                {
                     return data;
+                }
 
                 var buffer = new byte[length];
                 Buffer.BlockCopy(data, offset, buffer, 0, length);
@@ -113,7 +116,9 @@ namespace Renci.SshNet.Compression
             if (!IsActive)
             {
                 if (offset == 0 && length == data.Length)
+                {
                     return data;
+                }
 
                 var buffer = new byte[length];
                 Buffer.BlockCopy(data, offset, buffer, 0, length);
@@ -127,16 +132,12 @@ namespace Renci.SshNet.Compression
             return _decompressorStream.ToArray();
         }
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
@@ -147,7 +148,9 @@ namespace Renci.SshNet.Compression
         protected virtual void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             if (disposing)
             {
@@ -175,9 +178,7 @@ namespace Renci.SshNet.Compression
         /// </summary>
         ~Compressor()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion
     }
 }

+ 11 - 7
src/Renci.SshNet/Connection/ConnectorBase.cs

@@ -1,12 +1,13 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using Renci.SshNet.Messages.Transport;
-using System;
+using System;
 using System.Net;
 using System.Net.Sockets;
 using System.Threading;
 using System.Threading.Tasks;
 
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
+using Renci.SshNet.Messages.Transport;
+
 namespace Renci.SshNet.Connection
 {
     internal abstract class ConnectorBase : IConnector
@@ -14,7 +15,9 @@ namespace Renci.SshNet.Connection
         protected ConnectorBase(ISocketFactory socketFactory)
         {
             if (socketFactory == null)
-                throw new ArgumentNullException("socketFactory");
+            {
+                throw new ArgumentNullException(nameof(socketFactory));
+            }
 
             SocketFactory = socketFactory;
         }
@@ -95,14 +98,14 @@ namespace Renci.SshNet.Connection
         protected static byte SocketReadByte(Socket socket)
         {
             var buffer = new byte[1];
-            SocketRead(socket, buffer, 0, 1, Session.InfiniteTimeSpan);
+            _ = SocketRead(socket, buffer, 0, 1, Session.InfiniteTimeSpan);
             return buffer[0];
         }
 
         protected static byte SocketReadByte(Socket socket, TimeSpan readTimeout)
         {
             var buffer = new byte[1];
-            SocketRead(socket, buffer, 0, 1, readTimeout);
+            _ = SocketRead(socket, buffer, 0, 1, readTimeout);
             return buffer[0];
         }
 
@@ -145,6 +148,7 @@ namespace Renci.SshNet.Connection
                 throw new SshConnectionException("An established connection was aborted by the server.",
                                                  DisconnectReason.ConnectionLost);
             }
+
             return bytesRead;
         }
     }

+ 2 - 1
src/Renci.SshNet/Connection/DirectConnector.cs

@@ -5,7 +5,8 @@ namespace Renci.SshNet.Connection
 {
     internal sealed class DirectConnector : ConnectorBase
     {
-        public DirectConnector(ISocketFactory socketFactory) : base(socketFactory)
+        public DirectConnector(ISocketFactory socketFactory)
+            : base(socketFactory)
         {
         }
 

+ 22 - 16
src/Renci.SshNet/Connection/HttpConnector.cs

@@ -1,11 +1,12 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using System;
+using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Net;
 using System.Net.Sockets;
 using System.Text.RegularExpressions;
-using System.Threading;
+
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
 
 namespace Renci.SshNet.Connection
 {
@@ -30,7 +31,8 @@ namespace Renci.SshNet.Connection
     /// </remarks>
     internal sealed class HttpConnector : ProxyConnector
     {
-        public HttpConnector(ISocketFactory socketFactory) : base(socketFactory)
+        public HttpConnector(ISocketFactory socketFactory)
+            : base(socketFactory)
         {
         }
 
@@ -39,13 +41,17 @@ namespace Renci.SshNet.Connection
             var httpResponseRe = new Regex(@"HTTP/(?<version>\d[.]\d) (?<statusCode>\d{3}) (?<reasonPhrase>.+)$");
             var httpHeaderRe = new Regex(@"(?<fieldName>[^\[\]()<>@,;:\""/?={} \t]+):(?<fieldValue>.+)?");
 
-            SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(string.Format("CONNECT {0}:{1} HTTP/1.0\r\n", connectionInfo.Host, connectionInfo.Port)));
+            SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(string.Format(CultureInfo.InvariantCulture,
+                                                                                "CONNECT {0}:{1} HTTP/1.0\r\n",
+                                                                                connectionInfo.Host,
+                                                                                connectionInfo.Port)));
 
-            //  Sent proxy authorization if specified
+            // Send proxy authorization if specified
             if (!string.IsNullOrEmpty(connectionInfo.ProxyUsername))
             {
-                var authorization = string.Format("Proxy-Authorization: Basic {0}\r\n",
-                                                  Convert.ToBase64String(SshData.Ascii.GetBytes(string.Format("{0}:{1}", connectionInfo.ProxyUsername, connectionInfo.ProxyPassword))));
+                var authorization = string.Format(CultureInfo.InvariantCulture,
+                                                  "Proxy-Authorization: Basic {0}\r\n",
+                                                  Convert.ToBase64String(SshData.Ascii.GetBytes($"{connectionInfo.ProxyUsername}:{connectionInfo.ProxyPassword}")));
                 SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(authorization));
             }
 
@@ -69,12 +75,10 @@ namespace Renci.SshNet.Connection
                     if (statusMatch.Success)
                     {
                         var httpStatusCode = statusMatch.Result("${statusCode}");
-                        statusCode = (HttpStatusCode)int.Parse(httpStatusCode);
+                        statusCode = (HttpStatusCode) int.Parse(httpStatusCode, CultureInfo.InvariantCulture);
                         if (statusCode != HttpStatusCode.OK)
                         {
-                            throw new ProxyException(string.Format("HTTP: Status code {0}, \"{1}\"",
-                                                                   httpStatusCode,
-                                                                   statusMatch.Result("${reasonPhrase}")));
+                            throw new ProxyException($"HTTP: Status code {httpStatusCode}, \"{statusMatch.Result("${reasonPhrase}")}\"");
                         }
                     }
 
@@ -88,20 +92,22 @@ namespace Renci.SshNet.Connection
                     var fieldName = headerMatch.Result("${fieldName}");
                     if (fieldName.Equals("Content-Length", StringComparison.OrdinalIgnoreCase))
                     {
-                        contentLength = int.Parse(headerMatch.Result("${fieldValue}"));
+                        contentLength = int.Parse(headerMatch.Result("${fieldValue}"), CultureInfo.InvariantCulture);
                     }
+
                     continue;
                 }
 
                 // check if we've reached the CRLF which separates request line and headers from the message body
                 if (response.Length == 0)
                 {
-                    //  read response body if specified
+                    // read response body if specified
                     if (contentLength > 0)
                     {
                         var contentBody = new byte[contentLength];
-                        SocketRead(socket, contentBody, 0, contentLength, connectionInfo.Timeout);
+                        _ = SocketRead(socket, contentBody, 0, contentLength, connectionInfo.Timeout);
                     }
+
                     break;
                 }
             }

+ 68 - 61
src/Renci.SshNet/Connection/ProtocolVersionExchange.cs

@@ -1,7 +1,4 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using Renci.SshNet.Messages.Transport;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Net.Sockets;
@@ -10,13 +7,17 @@ using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
 
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
+using Renci.SshNet.Messages.Transport;
+
 namespace Renci.SshNet.Connection
 {
     /// <summary>
     /// Handles the SSH protocol version exchange.
     /// </summary>
     /// <remarks>
-    /// https://tools.ietf.org/html/rfc4253#section-4.2
+    /// https://tools.ietf.org/html/rfc4253#section-4.2.
     /// </remarks>
     internal class ProtocolVersionExchange : IProtocolVersionExchange
     {
@@ -50,20 +51,10 @@ namespace Renci.SshNet.Connection
                 {
                     if (bytesReceived.Count == 0)
                     {
-                        throw new SshConnectionException(string.Format("The server response does not contain an SSH identification string.{0}" +
-                                                                       "The connection to the remote server was closed before any data was received.{0}{0}" +
-                                                                       "More information on the Protocol Version Exchange is available here:{0}" +
-                                                                       "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                       Environment.NewLine),
-                                                         DisconnectReason.ConnectionLost);
+                        throw CreateConnectionLostException();
                     }
 
-                    throw new SshConnectionException(string.Format("The server response does not contain an SSH identification string:{0}{0}{1}{0}{0}" +
-                                                                   "More information on the Protocol Version Exchange is available here:{0}" +
-                                                                   "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                   Environment.NewLine,
-                                                                   PacketDump.Create(bytesReceived, 2)),
-                                                     DisconnectReason.ProtocolError);
+                    throw CreateServerResponseDoesNotContainIdentification(bytesReceived);
                 }
 
                 var identificationMatch = ServerVersionRe.Match(line);
@@ -88,25 +79,15 @@ namespace Renci.SshNet.Connection
             // ignore text lines which are sent before if any
             while (true)
             {
-                var line = await SocketReadLineAsync(socket, cancellationToken, bytesReceived).ConfigureAwait(false);
+                var line = await SocketReadLineAsync(socket, bytesReceived, cancellationToken).ConfigureAwait(false);
                 if (line == null)
                 {
                     if (bytesReceived.Count == 0)
                     {
-                        throw new SshConnectionException(string.Format("The server response does not contain an SSH identification string.{0}" +
-                                                                       "The connection to the remote server was closed before any data was received.{0}{0}" +
-                                                                       "More information on the Protocol Version Exchange is available here:{0}" +
-                                                                       "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                       Environment.NewLine),
-                                                         DisconnectReason.ConnectionLost);
+                        throw CreateConnectionLostException();
                     }
 
-                    throw new SshConnectionException(string.Format("The server response does not contain an SSH identification string:{0}{0}{1}{0}{0}" +
-                                                                   "More information on the Protocol Version Exchange is available here:{0}" +
-                                                                   "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                   Environment.NewLine,
-                                                                   PacketDump.Create(bytesReceived, 2)),
-                                                     DisconnectReason.ProtocolError);
+                    throw CreateServerResponseDoesNotContainIdentification(bytesReceived);
                 }
 
                 var identificationMatch = ServerVersionRe.Match(line);
@@ -164,14 +145,7 @@ namespace Renci.SshNet.Connection
                 // The null character MUST NOT be sent
                 if (byteRead == Null)
                 {
-                    throw new SshConnectionException(string.Format(CultureInfo.InvariantCulture,
-                                                                   "The server response contains a null character at position 0x{0:X8}:{1}{1}{2}{1}{1}" +
-                                                                   "A server must not send a null character before the Protocol Version Exchange is complete.{1}{1}" +
-                                                                   "More information is available here:{1}" +
-                                                                   "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                   buffer.Count,
-                                                                   Environment.NewLine,
-                                                                   PacketDump.Create(buffer.ToArray(), 2)));
+                    throw CreateServerResponseContainsNullCharacterException(buffer);
                 }
 
                 if (byteRead == Session.LineFeed)
@@ -181,21 +155,19 @@ namespace Renci.SshNet.Connection
                         // Return current line without CRLF
                         return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 2));
                     }
-                    else
-                    {
-                        // Even though RFC4253 clearly indicates that the identification string should be terminated
-                        // by a CR LF we also support banners and identification strings that are terminated by a LF
 
-                        // Return current line without LF
-                        return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 1));
-                    }
+                    // Even though RFC4253 clearly indicates that the identification string should be terminated
+                    // by a CR LF we also support banners and identification strings that are terminated by a LF
+
+                    // Return current line without LF
+                    return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 1));
                 }
             }
 
             return null;
         }
 
-        private static async Task<string> SocketReadLineAsync(Socket socket, CancellationToken cancellationToken, List<byte> buffer)
+        private static async Task<string> SocketReadLineAsync(Socket socket, List<byte> buffer, CancellationToken cancellationToken)
         {
             var data = new byte[1];
 
@@ -217,14 +189,7 @@ namespace Renci.SshNet.Connection
                 // The null character MUST NOT be sent
                 if (byteRead == Null)
                 {
-                    throw new SshConnectionException(string.Format(CultureInfo.InvariantCulture,
-                                                                   "The server response contains a null character at position 0x{0:X8}:{1}{1}{2}{1}{1}" +
-                                                                   "A server must not send a null character before the Protocol Version Exchange is complete.{1}{1}" +
-                                                                   "More information is available here:{1}" +
-                                                                   "https://tools.ietf.org/html/rfc4253#section-4.2",
-                                                                   buffer.Count,
-                                                                   Environment.NewLine,
-                                                                   PacketDump.Create(buffer.ToArray(), 2)));
+                    throw CreateServerResponseContainsNullCharacterException(buffer);
                 }
 
                 if (byteRead == Session.LineFeed)
@@ -234,16 +199,58 @@ namespace Renci.SshNet.Connection
                         // Return current line without CRLF
                         return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 2));
                     }
-                    else
-                    {
-                        // Even though RFC4253 clearly indicates that the identification string should be terminated
-                        // by a CR LF we also support banners and identification strings that are terminated by a LF
 
-                        // Return current line without LF
-                        return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 1));
-                    }
+                    // Even though RFC4253 clearly indicates that the identification string should be terminated
+                    // by a CR LF we also support banners and identification strings that are terminated by a LF
+
+                    // Return current line without LF
+                    return Encoding.UTF8.GetString(buffer.ToArray(), startPosition, buffer.Count - (startPosition + 1));
                 }
             }
         }
+
+        private static SshConnectionException CreateConnectionLostException()
+        {
+#pragma warning disable SA1118 // Parameter should not span multiple lines
+            var message = string.Format(CultureInfo.InvariantCulture,
+                                        "The server response does not contain an SSH identification string.{0}" +
+                                        "The connection to the remote server was closed before any data was received.{0}{0}" +
+                                        "More information on the Protocol Version Exchange is available here:{0}" +
+                                        "https://tools.ietf.org/html/rfc4253#section-4.2",
+                                        Environment.NewLine);
+#pragma warning restore SA1118 // Parameter should not span multiple lines
+
+            return new SshConnectionException(message, DisconnectReason.ConnectionLost);
+        }
+
+        private static SshConnectionException CreateServerResponseContainsNullCharacterException(List<byte> buffer)
+        {
+#pragma warning disable SA1118 // Parameter should not span multiple lines
+            var message = string.Format(CultureInfo.InvariantCulture,
+                                        "The server response contains a null character at position 0x{0:X8}:{1}{1}{2}{1}{1}" +
+                                        "A server must not send a null character before the Protocol Version Exchange is complete.{1}{1}" +
+                                        "More information is available here:{1}" +
+                                        "https://tools.ietf.org/html/rfc4253#section-4.2",
+                                        buffer.Count,
+                                        Environment.NewLine,
+                                        PacketDump.Create(buffer.ToArray(), 2));
+#pragma warning restore SA1118 // Parameter should not span multiple lines
+
+            throw new SshConnectionException(message);
+        }
+
+        private static SshConnectionException CreateServerResponseDoesNotContainIdentification(List<byte> bytesReceived)
+        {
+#pragma warning disable SA1118 // Parameter should not span multiple lines
+            var message = string.Format(CultureInfo.InvariantCulture,
+                                        "The server response does not contain an SSH identification string:{0}{0}{1}{0}{0}" +
+                                        "More information on the Protocol Version Exchange is available here:{0}" +
+                                        "https://tools.ietf.org/html/rfc4253#section-4.2",
+                                        Environment.NewLine,
+                                        PacketDump.Create(bytesReceived, 2));
+#pragma warning restore SA1118 // Parameter should not span multiple lines
+
+            throw new SshConnectionException(message, DisconnectReason.ProtocolError);
+        }
     }
 }

+ 4 - 4
src/Renci.SshNet/Connection/ProxyConnector.cs

@@ -3,13 +3,12 @@ using System.Net.Sockets;
 using System.Threading;
 using System.Threading.Tasks;
 
-
 namespace Renci.SshNet.Connection
 {
     internal abstract class ProxyConnector : ConnectorBase
     {
-        public ProxyConnector(ISocketFactory socketFactory) :
-            base(socketFactory)
+        public ProxyConnector(ISocketFactory socketFactory)
+            : base(socketFactory)
         {
         }
 
@@ -20,10 +19,11 @@ namespace Renci.SshNet.Connection
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-            using (cancellationToken.Register(o => ((Socket)o).Dispose(), socket, false))
+            using (cancellationToken.Register(o => ((Socket)o).Dispose(), socket, useSynchronizationContext: false))
             {
                 HandleProxyConnect(connectionInfo, socket);
             }
+
             return Task.CompletedTask;
         }
 

+ 10 - 8
src/Renci.SshNet/Connection/Socks4Connector.cs

@@ -1,20 +1,22 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using System;
+using System;
 using System.Net.Sockets;
 using System.Text;
 
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
+
 namespace Renci.SshNet.Connection
 {
     /// <summary>
     /// Establishes a tunnel via a SOCKS4 proxy server.
     /// </summary>
     /// <remarks>
-    /// https://www.openssh.com/txt/socks4.protocol
+    /// https://www.openssh.com/txt/socks4.protocol.
     /// </remarks>
     internal sealed class Socks4Connector : ProxyConnector
     {
-        public Socks4Connector(ISocketFactory socketFactory) : base(socketFactory)
+        public Socks4Connector(ISocketFactory socketFactory)
+            : base(socketFactory)
         {
         }
 
@@ -28,13 +30,13 @@ namespace Renci.SshNet.Connection
             var connectionRequest = CreateSocks4ConnectionRequest(connectionInfo.Host, (ushort)connectionInfo.Port, connectionInfo.ProxyUsername);
             SocketAbstraction.Send(socket, connectionRequest);
 
-            //  Read reply version
+            // Read reply version
             if (SocketReadByte(socket, connectionInfo.Timeout) != 0x00)
             {
                 throw new ProxyException("SOCKS4: Null is expected.");
             }
 
-            //  Read response code
+            // Read response code
             var code = SocketReadByte(socket, connectionInfo.Timeout);
 
             switch (code)
@@ -52,7 +54,7 @@ namespace Renci.SshNet.Connection
             }
 
             var destBuffer = new byte[6]; // destination port and IP address should be ignored
-            SocketRead(socket, destBuffer, 0, destBuffer.Length, connectionInfo.Timeout);
+            _ = SocketRead(socket, destBuffer, 0, destBuffer.Length, connectionInfo.Timeout);
         }
 
         private static byte[] CreateSocks4ConnectionRequest(string hostname, ushort port, string username)

+ 31 - 17
src/Renci.SshNet/Connection/Socks5Connector.cs

@@ -1,19 +1,21 @@
-using Renci.SshNet.Abstractions;
-using Renci.SshNet.Common;
-using System;
+using System;
 using System.Net.Sockets;
 
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
+
 namespace Renci.SshNet.Connection
 {
     /// <summary>
     /// Establishes a tunnel via a SOCKS5 proxy server.
     /// </summary>
     /// <remarks>
-    /// https://en.wikipedia.org/wiki/SOCKS#SOCKS5
+    /// https://en.wikipedia.org/wiki/SOCKS#SOCKS5.
     /// </remarks>
     internal sealed class Socks5Connector : ProxyConnector
     {
-        public Socks5Connector(ISocketFactory socketFactory) : base(socketFactory)
+        public Socks5Connector(ISocketFactory socketFactory)
+            : base(socketFactory)
         {
         }
 
@@ -51,15 +53,23 @@ namespace Renci.SshNet.Connection
                 case 0x02:
                     // Create username/password authentication request
                     var authenticationRequest = CreateSocks5UserNameAndPasswordAuthenticationRequest(connectionInfo.ProxyUsername, connectionInfo.ProxyPassword);
+
                     // Send authentication request
                     SocketAbstraction.Send(socket, authenticationRequest);
+
                     // Read authentication result
                     var authenticationResult = SocketAbstraction.Read(socket, 2, connectionInfo.Timeout);
 
                     if (authenticationResult[0] != 0x01)
+                    {
                         throw new ProxyException("SOCKS5: Server authentication version is not valid.");
+                    }
+
                     if (authenticationResult[1] != 0x00)
+                    {
                         throw new ProxyException("SOCKS5: Username/Password authentication failed.");
+                    }
+
                     break;
                 case 0xFF:
                     throw new ProxyException("SOCKS5: No acceptable authentication methods were offered.");
@@ -68,13 +78,13 @@ namespace Renci.SshNet.Connection
             var connectionRequest = CreateSocks5ConnectionRequest(connectionInfo.Host, (ushort) connectionInfo.Port);
             SocketAbstraction.Send(socket, connectionRequest);
 
-            //  Read Server SOCKS5 version
+            // Read Server SOCKS5 version
             if (SocketReadByte(socket) != 5)
             {
                 throw new ProxyException("SOCKS5: Version 5 is expected.");
             }
 
-            //  Read response code
+            // Read response code
             var status = SocketReadByte(socket);
 
             switch (status)
@@ -101,7 +111,7 @@ namespace Renci.SshNet.Connection
                     throw new ProxyException("SOCKS5: Not valid response.");
             }
 
-            //  Read reserved byte
+            // Read reserved byte
             if (SocketReadByte(socket) != 0)
             {
                 throw new ProxyException("SOCKS5: 0 byte is expected.");
@@ -112,11 +122,11 @@ namespace Renci.SshNet.Connection
             {
                 case 0x01:
                     var ipv4 = new byte[4];
-                    SocketRead(socket, ipv4, 0, 4);
+                    _ = SocketRead(socket, ipv4, 0, 4);
                     break;
                 case 0x04:
                     var ipv6 = new byte[16];
-                    SocketRead(socket, ipv6, 0, 16);
+                    _ =SocketRead(socket, ipv6, 0, 16);
                     break;
                 default:
                     throw new ProxyException(string.Format("Address type '{0}' is not supported.", addressType));
@@ -124,19 +134,24 @@ namespace Renci.SshNet.Connection
 
             var port = new byte[2];
 
-            //  Read 2 bytes to be ignored
-            SocketRead(socket, port, 0, 2);
+            // Read 2 bytes to be ignored
+            _ = SocketRead(socket, port, 0, 2);
         }
 
         /// <summary>
-        /// https://tools.ietf.org/html/rfc1929
+        /// https://tools.ietf.org/html/rfc1929.
         /// </summary>
         private static byte[] CreateSocks5UserNameAndPasswordAuthenticationRequest(string username, string password)
         {
             if (username.Length > byte.MaxValue)
+            {
                 throw new ProxyException("Proxy username is too long.");
+            }
+
             if (password.Length > byte.MaxValue)
+            {
                 throw new ProxyException("Proxy password is too long.");
+            }
 
             var authenticationRequest = new byte
                 [
@@ -161,22 +176,21 @@ namespace Renci.SshNet.Connection
             authenticationRequest[index++] = (byte) username.Length;
 
             // Username
-            SshData.Ascii.GetBytes(username, 0, username.Length, authenticationRequest, index);
+            _ = SshData.Ascii.GetBytes(username, 0, username.Length, authenticationRequest, index);
             index += username.Length;
 
             // Length of the password
             authenticationRequest[index++] = (byte) password.Length;
 
             // Password
-            SshData.Ascii.GetBytes(password, 0, password.Length, authenticationRequest, index);
+            _ =SshData.Ascii.GetBytes(password, 0, password.Length, authenticationRequest, index);
 
             return authenticationRequest;
         }
 
         private static byte[] CreateSocks5ConnectionRequest(string hostname, ushort port)
         {
-            byte addressType;
-            var addressBytes = GetSocks5DestinationAddress(hostname, out addressType);
+            var addressBytes = GetSocks5DestinationAddress(hostname, out var addressType);
 
             var connectionRequest = new byte
                 [

+ 20 - 13
src/Renci.SshNet/Connection/SshIdentification.cs

@@ -8,33 +8,38 @@ namespace Renci.SshNet.Connection
     internal class SshIdentification
     {
         /// <summary>
-        /// Initializes a new <see cref="SshIdentification"/> instance with the specified protocol version
+        /// Initializes a new instance of the <see cref="SshIdentification"/> class with the specified protocol version
         /// and software version.
         /// </summary>
         /// <param name="protocolVersion">The SSH protocol version.</param>
-        /// <param name="softwareVersion">The software version of the implementation</param>
+        /// <param name="softwareVersion">The software version of the implementation.</param>
         /// <exception cref="ArgumentNullException"><paramref name="protocolVersion"/> is <see langword="null"/>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="softwareVersion"/> is <see langword="null"/>.</exception>
         public SshIdentification(string protocolVersion, string softwareVersion)
-            : this(protocolVersion, softwareVersion, null)
+            : this(protocolVersion, softwareVersion, comments: null)
         {
         }
 
         /// <summary>
-        /// Initializes a new <see cref="SshIdentification"/> instance with the specified protocol version,
+        /// Initializes a new instance of the <see cref="SshIdentification"/> class with the specified protocol version,
         /// software version and comments.
         /// </summary>
         /// <param name="protocolVersion">The SSH protocol version.</param>
-        /// <param name="softwareVersion">The software version of the implementation</param>
+        /// <param name="softwareVersion">The software version of the implementation.</param>
         /// <param name="comments">The comments.</param>
         /// <exception cref="ArgumentNullException"><paramref name="protocolVersion"/> is <see langword="null"/>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="softwareVersion"/> is <see langword="null"/>.</exception>
         public SshIdentification(string protocolVersion, string softwareVersion, string comments)
         {
             if (protocolVersion == null)
-                throw new ArgumentNullException("protocolVersion");
+            {
+                throw new ArgumentNullException(nameof(protocolVersion));
+            }
+
             if (softwareVersion == null)
-                throw new ArgumentNullException("softwareVersion");
+            {
+                throw new ArgumentNullException(nameof(softwareVersion));
+            }
 
             ProtocolVersion = protocolVersion;
             SoftwareVersion = softwareVersion;
@@ -42,7 +47,7 @@ namespace Renci.SshNet.Connection
         }
 
         /// <summary>
-        /// Gets or sets the software version of the implementation.
+        /// Gets the software version of the implementation.
         /// </summary>
         /// <value>
         /// The software version of the implementation.
@@ -51,18 +56,18 @@ namespace Renci.SshNet.Connection
         /// This is primarily used to trigger compatibility extensions and to indicate
         /// the capabilities of an implementation.
         /// </remarks>
-        public string SoftwareVersion { get; private set; }
+        public string SoftwareVersion { get; }
 
         /// <summary>
-        /// Gets or sets the SSH protocol version.
+        /// Gets the SSH protocol version.
         /// </summary>
         /// <value>
         /// The SSH protocol version.
         /// </value>
-        public string ProtocolVersion { get; private set; }
+        public string ProtocolVersion { get; }
 
         /// <summary>
-        /// Gets or sets the comments.
+        /// Gets the comments.
         /// </summary>
         /// <value>
         /// The comments, or <see langword="null"/> if there are no comments.
@@ -71,7 +76,7 @@ namespace Renci.SshNet.Connection
         /// <see cref="Comments"/> should contain additional information that might be useful
         /// in solving user problems.
         /// </remarks>
-        public string Comments { get; private set; }
+        public string Comments { get; }
 
         /// <summary>
         /// Returns the SSH identification string.
@@ -82,10 +87,12 @@ namespace Renci.SshNet.Connection
         public override string ToString()
         {
             var identificationString = "SSH-" + ProtocolVersion + "-" + SoftwareVersion;
+
             if (Comments != null)
             {
                 identificationString += " " + Comments;
             }
+
             return identificationString;
         }
     }

+ 97 - 97
src/Renci.SshNet/ConnectionInfo.cs

@@ -1,14 +1,16 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net;
 using System.Text;
+
 using Renci.SshNet.Abstractions;
-using Renci.SshNet.Security;
-using Renci.SshNet.Messages.Connection;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Authentication;
-using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
+using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Security;
 using Renci.SshNet.Security.Cryptography.Ciphers;
+using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
 
 namespace Renci.SshNet
 {
@@ -161,7 +163,7 @@ namespace Renci.SshNet
         /// Gets or sets the character encoding.
         /// </summary>
         /// <value>
-        /// The character encoding. The default is <see cref="System.Text.Encoding.UTF8"/>.
+        /// The character encoding. The default is <see cref="Encoding.UTF8"/>.
         /// </value>
         public Encoding Encoding { get; set; }
 
@@ -232,7 +234,7 @@ namespace Renci.SshNet
         public string ServerVersion { get; internal set; }
 
         /// <summary>
-        /// Get the client version.
+        /// Gets the client version.
         /// </summary>
         public string ClientVersion { get; internal set; }
 
@@ -253,7 +255,7 @@ namespace Renci.SshNet
         /// <exception cref="ArgumentNullException"><paramref name="authenticationMethods"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">No <paramref name="authenticationMethods"/> specified.</exception>
         public ConnectionInfo(string host, string username, params AuthenticationMethod[] authenticationMethods)
-            : this(host, DefaultPort, username, ProxyTypes.None, null, 0, null, null, authenticationMethods)
+            : this(host, DefaultPort, username, ProxyTypes.None, proxyHost: null, 0, proxyUsername: null, proxyPassword: null, authenticationMethods)
         {
         }
 
@@ -266,11 +268,11 @@ namespace Renci.SshNet
         /// <param name="authenticationMethods">The authentication methods.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException"><paramref name="username" /> is <c>null</c>, a zero-length string or contains only whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="IPEndPoint.MinPort" /> and <see cref="IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="authenticationMethods"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">No <paramref name="authenticationMethods"/> specified.</exception>
         public ConnectionInfo(string host, int port, string username, params AuthenticationMethod[] authenticationMethods)
-            : this(host, port, username, ProxyTypes.None, null, 0, null, null, authenticationMethods)
+            : this(host, port, username, ProxyTypes.None, proxyHost: null, 0, proxyUsername: null, proxyPassword: null, authenticationMethods)
         {
         }
 
@@ -288,35 +290,51 @@ namespace Renci.SshNet
         /// <param name="authenticationMethods">The authentication methods.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException"><paramref name="username" /> is <c>null</c>, a zero-length string or contains only whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="IPEndPoint.MinPort" /> and <see cref="IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="proxyType"/> is not <see cref="ProxyTypes.None"/> and <paramref name="proxyHost" /> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="proxyType"/> is not <see cref="ProxyTypes.None"/> and <paramref name="proxyPort" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="proxyType"/> is not <see cref="ProxyTypes.None"/> and <paramref name="proxyPort" /> is not within <see cref="IPEndPoint.MinPort" /> and <see cref="IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="authenticationMethods"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">No <paramref name="authenticationMethods"/> specified.</exception>
         public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params AuthenticationMethod[] authenticationMethods)
         {
             if (host == null)
-                throw new ArgumentNullException("host");
+            {
+                throw new ArgumentNullException(nameof(host));
+            }
+
             port.ValidatePort("port");
 
             if (username == null)
-                throw new ArgumentNullException("username");
+            {
+                throw new ArgumentNullException(nameof(username));
+            }
+
             if (username.All(char.IsWhiteSpace))
-                throw new ArgumentException("Cannot be empty or contain only whitespace.", "username");
+            {
+                throw new ArgumentException("Cannot be empty or contain only whitespace.", nameof(username));
+            }
 
             if (proxyType != ProxyTypes.None)
             {
                 if (proxyHost == null)
-                    throw new ArgumentNullException("proxyHost");
+                {
+                    throw new ArgumentNullException(nameof(proxyHost));
+                }
+
                 proxyPort.ValidatePort("proxyPort");
             }
 
             if (authenticationMethods == null)
-                throw new ArgumentNullException("authenticationMethods");
+            {
+                throw new ArgumentNullException(nameof(authenticationMethods));
+            }
+
             if (authenticationMethods.Length == 0)
-                throw new ArgumentException("At least one authentication method should be specified.", "authenticationMethods");
+            {
+                throw new ArgumentException("At least one authentication method should be specified.", nameof(authenticationMethods));
+            }
 
-            //  Set default connection values
+            // Set default connection values
             Timeout = DefaultTimeout;
             ChannelCloseTimeout = DefaultChannelCloseTimeout;
             RetryAttempts = 10;
@@ -325,98 +343,83 @@ namespace Renci.SshNet
 
             KeyExchangeAlgorithms = new Dictionary<string, Type>
                 {
-                    {"curve25519-sha256", typeof(KeyExchangeECCurve25519)},
-                    {"curve25519-sha256@libssh.org", typeof(KeyExchangeECCurve25519)},
-                    {"ecdh-sha2-nistp256", typeof(KeyExchangeECDH256)},
-                    {"ecdh-sha2-nistp384", typeof(KeyExchangeECDH384)},
-                    {"ecdh-sha2-nistp521", typeof(KeyExchangeECDH521)},
-                    {"diffie-hellman-group-exchange-sha256", typeof (KeyExchangeDiffieHellmanGroupExchangeSha256)},
-                    {"diffie-hellman-group-exchange-sha1", typeof (KeyExchangeDiffieHellmanGroupExchangeSha1)},
-                    {"diffie-hellman-group16-sha512", typeof(KeyExchangeDiffieHellmanGroup16Sha512)},
-                    {"diffie-hellman-group14-sha256", typeof (KeyExchangeDiffieHellmanGroup14Sha256)},
-                    {"diffie-hellman-group14-sha1", typeof (KeyExchangeDiffieHellmanGroup14Sha1)},
-                    {"diffie-hellman-group1-sha1", typeof (KeyExchangeDiffieHellmanGroup1Sha1)},
+                    { "curve25519-sha256", typeof(KeyExchangeECCurve25519) },
+                    { "curve25519-sha256@libssh.org", typeof(KeyExchangeECCurve25519) },
+                    { "ecdh-sha2-nistp256", typeof(KeyExchangeECDH256) },
+                    { "ecdh-sha2-nistp384", typeof(KeyExchangeECDH384) },
+                    { "ecdh-sha2-nistp521", typeof(KeyExchangeECDH521) },
+                    { "diffie-hellman-group-exchange-sha256", typeof(KeyExchangeDiffieHellmanGroupExchangeSha256) },
+                    { "diffie-hellman-group-exchange-sha1", typeof(KeyExchangeDiffieHellmanGroupExchangeSha1) },
+                    { "diffie-hellman-group16-sha512", typeof(KeyExchangeDiffieHellmanGroup16Sha512) },
+                    { "diffie-hellman-group14-sha256", typeof(KeyExchangeDiffieHellmanGroup14Sha256) },
+                    { "diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1) },
+                    { "diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1) },
                 };
 
             Encryptions = new Dictionary<string, CipherInfo>
                 {
-                    {"aes256-ctr", new CipherInfo(256, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), null))},
-                    {"3des-cbc", new CipherInfo(192, (key, iv) => new TripleDesCipher(key, new CbcCipherMode(iv), null))},
-                    {"aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), null))},
-                    {"aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), null))},
-                    {"aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), null))},
-                    {"blowfish-cbc", new CipherInfo(128, (key, iv) => new BlowfishCipher(key, new CbcCipherMode(iv), null))},
-                    {"twofish-cbc", new CipherInfo(256, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), null))},
-                    {"twofish192-cbc", new CipherInfo(192, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), null))},
-                    {"twofish128-cbc", new CipherInfo(128, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), null))},
-                    {"twofish256-cbc", new CipherInfo(256, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), null))},
-                    ////{"serpent256-cbc", typeof(CipherSerpent256CBC)},
-                    ////{"serpent192-cbc", typeof(...)},
-                    ////{"serpent128-cbc", typeof(...)},
-                    {"arcfour", new CipherInfo(128, (key, iv) => new Arc4Cipher(key, false))},
-                    {"arcfour128", new CipherInfo(128, (key, iv) => new Arc4Cipher(key, true))},
-                    {"arcfour256", new CipherInfo(256, (key, iv) => new Arc4Cipher(key, true))},
-                    ////{"idea-cbc", typeof(...)},
-                    {"cast128-cbc", new CipherInfo(128, (key, iv) => new CastCipher(key, new CbcCipherMode(iv), null))},
-                    ////{"rijndael-cbc@lysator.liu.se", typeof(...)},                
-                    {"aes128-ctr", new CipherInfo(128, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), null))},
-                    {"aes192-ctr", new CipherInfo(192, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), null))},
+                    { "aes256-ctr", new CipherInfo(256, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), padding: null)) },
+                    { "3des-cbc", new CipherInfo(192, (key, iv) => new TripleDesCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "blowfish-cbc", new CipherInfo(128, (key, iv) => new BlowfishCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "twofish-cbc", new CipherInfo(256, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "twofish192-cbc", new CipherInfo(192, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "twofish128-cbc", new CipherInfo(128, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "twofish256-cbc", new CipherInfo(256, (key, iv) => new TwofishCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "arcfour", new CipherInfo(128, (key, iv) => new Arc4Cipher(key, dischargeFirstBytes: false)) },
+                    { "arcfour128", new CipherInfo(128, (key, iv) => new Arc4Cipher(key, dischargeFirstBytes: true)) },
+                    { "arcfour256", new CipherInfo(256, (key, iv) => new Arc4Cipher(key, dischargeFirstBytes: true)) },
+                    { "cast128-cbc", new CipherInfo(128, (key, iv) => new CastCipher(key, new CbcCipherMode(iv), padding: null)) },
+                    { "aes128-ctr", new CipherInfo(128, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), padding: null)) },
+                    { "aes192-ctr", new CipherInfo(192, (key, iv) => new AesCipher(key, new CtrCipherMode(iv), padding: null)) },
                 };
 
             HmacAlgorithms = new Dictionary<string, HashInfo>
                 {
-                    {"hmac-md5", new HashInfo(16*8, CryptoAbstraction.CreateHMACMD5)},
-                    {"hmac-md5-96", new HashInfo(16*8, key => CryptoAbstraction.CreateHMACMD5(key, 96))},
-                    {"hmac-sha1", new HashInfo(20*8, CryptoAbstraction.CreateHMACSHA1)},
-                    {"hmac-sha1-96", new HashInfo(20*8, key => CryptoAbstraction.CreateHMACSHA1(key, 96))},
-                    {"hmac-sha2-256", new HashInfo(32*8, CryptoAbstraction.CreateHMACSHA256)},
-                    {"hmac-sha2-256-96", new HashInfo(32*8, key => CryptoAbstraction.CreateHMACSHA256(key, 96))},
-                    {"hmac-sha2-512", new HashInfo(64 * 8, CryptoAbstraction.CreateHMACSHA512)},
-                    {"hmac-sha2-512-96", new HashInfo(64 * 8,  key => CryptoAbstraction.CreateHMACSHA512(key, 96))},
-                    //{"umac-64@openssh.com", typeof(HMacSha1)},
-                    {"hmac-ripemd160", new HashInfo(160, CryptoAbstraction.CreateHMACRIPEMD160)},
-                    {"hmac-ripemd160@openssh.com", new HashInfo(160, CryptoAbstraction.CreateHMACRIPEMD160)},
-                    //{"none", typeof(...)},
+                    { "hmac-md5", new HashInfo(16*8, CryptoAbstraction.CreateHMACMD5) },
+                    { "hmac-md5-96", new HashInfo(16*8, key => CryptoAbstraction.CreateHMACMD5(key, 96)) },
+                    { "hmac-sha1", new HashInfo(20*8, CryptoAbstraction.CreateHMACSHA1) },
+                    { "hmac-sha1-96", new HashInfo(20*8, key => CryptoAbstraction.CreateHMACSHA1(key, 96)) },
+                    { "hmac-sha2-256", new HashInfo(32*8, CryptoAbstraction.CreateHMACSHA256) },
+                    { "hmac-sha2-256-96", new HashInfo(32*8, key => CryptoAbstraction.CreateHMACSHA256(key, 96)) },
+                    { "hmac-sha2-512", new HashInfo(64 * 8, CryptoAbstraction.CreateHMACSHA512) },
+                    { "hmac-sha2-512-96", new HashInfo(64 * 8,  key => CryptoAbstraction.CreateHMACSHA512(key, 96)) },
+                    { "hmac-ripemd160", new HashInfo(160, CryptoAbstraction.CreateHMACRIPEMD160) },
+                    { "hmac-ripemd160@openssh.com", new HashInfo(160, CryptoAbstraction.CreateHMACRIPEMD160) },
                 };
 
             HostKeyAlgorithms = new Dictionary<string, Func<byte[], KeyHostAlgorithm>>
                 {
-                    {"ssh-ed25519", data => new KeyHostAlgorithm("ssh-ed25519", new ED25519Key(), data)},
-                    {"ecdsa-sha2-nistp256", data => new KeyHostAlgorithm("ecdsa-sha2-nistp256", new EcdsaKey(), data)},
-                    {"ecdsa-sha2-nistp384", data => new KeyHostAlgorithm("ecdsa-sha2-nistp384", new EcdsaKey(), data)},
-                    {"ecdsa-sha2-nistp521", data => new KeyHostAlgorithm("ecdsa-sha2-nistp521", new EcdsaKey(), data)},
-                    {"ssh-rsa", data => new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data)},
-                    {"ssh-dss", data => new KeyHostAlgorithm("ssh-dss", new DsaKey(), data)},
-                    //{"x509v3-sign-rsa", () => { ... },
-                    //{"x509v3-sign-dss", () => { ... },
-                    //{"spki-sign-rsa", () => { ... },
-                    //{"spki-sign-dss", () => { ... },
-                    //{"pgp-sign-rsa", () => { ... },
-                    //{"pgp-sign-dss", () => { ... },
+                    { "ssh-ed25519", data => new KeyHostAlgorithm("ssh-ed25519", new ED25519Key(), data) },
+                    { "ecdsa-sha2-nistp256", data => new KeyHostAlgorithm("ecdsa-sha2-nistp256", new EcdsaKey(), data) },
+                    { "ecdsa-sha2-nistp384", data => new KeyHostAlgorithm("ecdsa-sha2-nistp384", new EcdsaKey(), data) },
+                    { "ecdsa-sha2-nistp521", data => new KeyHostAlgorithm("ecdsa-sha2-nistp521", new EcdsaKey(), data) },
+                    { "ssh-rsa", data => new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data) },
+                    { "ssh-dss", data => new KeyHostAlgorithm("ssh-dss", new DsaKey(), data) },
                 };
 
             CompressionAlgorithms = new Dictionary<string, Type>
                 {
-                    //{"zlib@openssh.com", typeof(ZlibOpenSsh)}, 
-                    //{"zlib", typeof(Zlib)}, 
-                    {"none", null},
+                    { "none", null },
                 };
 
             ChannelRequests = new Dictionary<string, RequestInfo>
                 {
-                    {EnvironmentVariableRequestInfo.Name, new EnvironmentVariableRequestInfo()},
-                    {ExecRequestInfo.Name, new ExecRequestInfo()},
-                    {ExitSignalRequestInfo.Name, new ExitSignalRequestInfo()},
-                    {ExitStatusRequestInfo.Name, new ExitStatusRequestInfo()},
-                    {PseudoTerminalRequestInfo.Name, new PseudoTerminalRequestInfo()},
-                    {ShellRequestInfo.Name, new ShellRequestInfo()},
-                    {SignalRequestInfo.Name, new SignalRequestInfo()},
-                    {SubsystemRequestInfo.Name, new SubsystemRequestInfo()},
-                    {WindowChangeRequestInfo.Name, new WindowChangeRequestInfo()},
-                    {X11ForwardingRequestInfo.Name, new X11ForwardingRequestInfo()},
-                    {XonXoffRequestInfo.Name, new XonXoffRequestInfo()},
-                    {EndOfWriteRequestInfo.Name, new EndOfWriteRequestInfo()},
-                    {KeepAliveRequestInfo.Name, new KeepAliveRequestInfo()},
+                    { EnvironmentVariableRequestInfo.Name, new EnvironmentVariableRequestInfo() },
+                    { ExecRequestInfo.Name, new ExecRequestInfo() },
+                    { ExitSignalRequestInfo.Name, new ExitSignalRequestInfo() },
+                    { ExitStatusRequestInfo.Name, new ExitStatusRequestInfo() },
+                    { PseudoTerminalRequestInfo.Name, new PseudoTerminalRequestInfo() },
+                    { ShellRequestInfo.Name, new ShellRequestInfo() },
+                    { SignalRequestInfo.Name, new SignalRequestInfo() },
+                    { SubsystemRequestInfo.Name, new SubsystemRequestInfo() },
+                    { WindowChangeRequestInfo.Name, new WindowChangeRequestInfo() },
+                    { X11ForwardingRequestInfo.Name, new X11ForwardingRequestInfo() },
+                    { XonXoffRequestInfo.Name, new XonXoffRequestInfo() },
+                    { EndOfWriteRequestInfo.Name, new EndOfWriteRequestInfo() },
+                    { KeepAliveRequestInfo.Name, new KeepAliveRequestInfo() },
                 };
 
             Host = host;
@@ -443,7 +446,9 @@ namespace Renci.SshNet
         internal void Authenticate(ISession session, IServiceFactory serviceFactory)
         {
             if (serviceFactory == null)
-                throw new ArgumentNullException("serviceFactory");
+            {
+                throw new ArgumentNullException(nameof(serviceFactory));
+            }
 
             IsAuthenticated = false;
             var clientAuthentication = serviceFactory.CreateClientAuthentication();
@@ -455,15 +460,10 @@ namespace Renci.SshNet
         /// Signals that an authentication banner message was received from the server.
         /// </summary>
         /// <param name="sender">The session in which the banner message was received.</param>
-        /// <param name="e">The banner message.{</param>
+        /// <param name="e">The banner message.</param>
         void IConnectionInfoInternal.UserAuthenticationBannerReceived(object sender, MessageEventArgs<BannerMessage> e)
         {
-            var authenticationBanner = AuthenticationBanner;
-            if (authenticationBanner != null)
-            {
-                authenticationBanner(this,
-                    new AuthenticationBannerEventArgs(Username, e.Message.Message, e.Message.Language));
-            }
+            AuthenticationBanner?.Invoke(this, new AuthenticationBannerEventArgs(Username, e.Message.Message, e.Message.Language));
         }
 
         IAuthenticationMethod IConnectionInfoInternal.CreateNoneAuthenticationMethod()

+ 13 - 5
src/Renci.SshNet/ExpectAction.cs

@@ -4,7 +4,7 @@ using System.Text.RegularExpressions;
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Specifies behavior for expected expression
+    /// Specifies behavior for expected expression.
     /// </summary>
     public class ExpectAction
     {
@@ -27,10 +27,14 @@ namespace Renci.SshNet
         public ExpectAction(Regex expect, Action<string> action)
         {
             if (expect == null)
-                throw new ArgumentNullException("expect");
+            {
+                throw new ArgumentNullException(nameof(expect));
+            }
 
             if (action == null)
-                throw new ArgumentNullException("action");
+            {
+                throw new ArgumentNullException(nameof(action));
+            }
 
             Expect = expect;
             Action = action;
@@ -45,10 +49,14 @@ namespace Renci.SshNet
         public ExpectAction(string expect, Action<string> action)
         {
             if (expect == null)
-                throw new ArgumentNullException("expect");
+            {
+                throw new ArgumentNullException(nameof(expect));
+            }
 
             if (action == null)
-                throw new ArgumentNullException("action");
+            {
+                throw new ArgumentNullException(nameof(action));
+            }
 
             Expect = new Regex(Regex.Escape(expect));
             Action = action;

+ 5 - 4
src/Renci.SshNet/ExpectAsyncResult.cs

@@ -1,10 +1,11 @@
-using Renci.SshNet.Common;
-using System;
+using System;
+
+using Renci.SshNet.Common;
 
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Provides additional information for asynchronous command execution
+    /// Provides additional information for asynchronous command execution.
     /// </summary>
     public class ExpectAsyncResult : AsyncResult<string>
     {
@@ -13,7 +14,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="asyncCallback">The async callback.</param>
         /// <param name="state">The state.</param>
-        internal ExpectAsyncResult(AsyncCallback asyncCallback, Object state)
+        internal ExpectAsyncResult(AsyncCallback asyncCallback, object state)
             : base(asyncCallback, state)
         {
         }

+ 11 - 15
src/Renci.SshNet/ForwardedPort.cs

@@ -56,11 +56,19 @@ namespace Renci.SshNet
             CheckDisposed();
 
             if (IsStarted)
+            {
                 throw new InvalidOperationException("Forwarded port is already started.");
+            }
+
             if (Session == null)
+            {
                 throw new InvalidOperationException("Forwarded port is not added to a client.");
+            }
+
             if (!Session.IsConnected)
+            {
                 throw new SshConnectionException("Client not connected.");
+            }
 
             Session.ErrorOccured += Session_ErrorOccured;
             StartPort();
@@ -127,11 +135,7 @@ namespace Renci.SshNet
         /// <param name="exception">The exception.</param>
         protected void RaiseExceptionEvent(Exception exception)
         {
-            var handlers = Exception;
-            if (handlers != null)
-            {
-                handlers(this, new ExceptionEventArgs(exception));
-            }
+            Exception?.Invoke(this, new ExceptionEventArgs(exception));
         }
 
         /// <summary>
@@ -141,11 +145,7 @@ namespace Renci.SshNet
         /// <param name="port">Request originator port.</param>
         protected void RaiseRequestReceived(string host, uint port)
         {
-            var handlers = RequestReceived;
-            if (handlers != null)
-            {
-                handlers(this, new PortForwardEventArgs(host, port));
-            }
+            RequestReceived?.Invoke(this, new PortForwardEventArgs(host, port));
         }
 
         /// <summary>
@@ -153,11 +153,7 @@ namespace Renci.SshNet
         /// </summary>
         private void RaiseClosing()
         {
-            var handlers = Closing;
-            if (handlers != null)
-            {
-                handlers(this, EventArgs.Empty);
-            }
+            Closing?.Invoke(this, EventArgs.Empty);
         }
 
         /// <summary>

+ 14 - 18
src/Renci.SshNet/ForwardedPortDynamic.NET.cs

@@ -1,9 +1,10 @@
 using System;
 using System.Linq;
-using System.Text;
 using System.Net;
 using System.Net.Sockets;
+using System.Text;
 using System.Threading;
+
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
@@ -78,7 +79,7 @@ namespace Renci.SshNet
 
         private void AcceptCompleted(object sender, SocketAsyncEventArgs e)
         {
-            if (e.SocketError == SocketError.OperationAborted || e.SocketError == SocketError.NotSocket)
+            if (e.SocketError is SocketError.OperationAborted or SocketError.NotSocket)
             {
                 // server was stopped
                 return;
@@ -91,6 +92,7 @@ namespace Renci.SshNet
             {
                 // accept new connection
                 StartAccept(e);
+
                 // dispose broken client socket
                 CloseClientSocket(clientSocket);
                 return;
@@ -98,6 +100,7 @@ namespace Renci.SshNet
 
             // accept new connection
             StartAccept(e);
+
             // process connection
             ProcessAccept(clientSocket);
         }
@@ -146,7 +149,7 @@ namespace Renci.SshNet
                 // the CountdownEvent will be disposed
                 try
                 {
-                    pendingChannelCountdown.Signal();
+                    _ = pendingChannelCountdown.Signal();
                 }
                 catch (ObjectDisposedException)
                 {
@@ -170,10 +173,7 @@ namespace Renci.SshNet
         private void InitializePendingChannelCountdown()
         {
             var original = Interlocked.Exchange(ref _pendingChannelCountdown, new CountdownEvent(1));
-            if (original != null)
-            {
-                original.Dispose();
-            }
+            original?.Dispose();
         }
 
         private bool HandleSocks(IChannelDirectTcpip channel, Socket clientSocket, TimeSpan timeout)
@@ -251,11 +251,7 @@ namespace Renci.SshNet
         partial void StopListener()
         {
             // close listener socket
-            var listener = _listener;
-            if (listener != null)
-            {
-                listener.Dispose();
-            }
+            _listener?.Dispose();
 
             // unsubscribe from session events
             var session = Session;
@@ -272,7 +268,8 @@ namespace Renci.SshNet
         /// <param name="timeout">The maximum time to wait for the pending channels to close.</param>
         partial void InternalStop(TimeSpan timeout)
         {
-            _pendingChannelCountdown.Signal();
+            _ = _pendingChannelCountdown.Signal();
+
             if (!_pendingChannelCountdown.Wait(timeout))
             {
                 // TODO: log as warning
@@ -401,12 +398,12 @@ namespace Renci.SshNet
             {
                 // no user authentication is one of the authentication methods supported
                 // by the SOCKS client
-                SocketAbstraction.Send(socket, new byte[] {0x05, 0x00}, 0, 2);
+                SocketAbstraction.Send(socket, new byte[] { 0x05, 0x00 }, 0, 2);
             }
             else
             {
                 // the SOCKS client requires authentication, which we currently do not support
-                SocketAbstraction.Send(socket, new byte[] {0x05, 0xFF}, 0, 2);
+                SocketAbstraction.Send(socket, new byte[] { 0x05, 0xFF }, 0, 2);
 
                 // we continue business as usual but expect the client to close the connection
                 // so one of the subsequent reads should return -1 signaling that the client
@@ -592,11 +589,10 @@ namespace Renci.SshNet
                     break;
                 }
 
-                var c = (char) byteRead;
-                text.Append(c);
+                _ = text.Append((char) byteRead);
             }
+
             return text.ToString();
         }
     }
 }
-

+ 28 - 21
src/Renci.SshNet/ForwardedPortDynamic.cs

@@ -10,15 +10,23 @@ namespace Renci.SshNet
     {
         private ForwardedPortStatus _status;
 
+        /// <summary>
+        /// Holds a value indicating whether the current instance is disposed.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if the current instance is disposed; otherwise, <c>false</c>.
+        /// </value>
+        private bool _isDisposed;
+
         /// <summary>
         /// Gets the bound host.
         /// </summary>
-        public string BoundHost { get; private set; }
+        public string BoundHost { get; }
 
         /// <summary>
         /// Gets the bound port.
         /// </summary>
-        public uint BoundPort { get; private set; }
+        public uint BoundPort { get; }
 
         /// <summary>
         /// Gets a value indicating whether port forwarding is started.
@@ -35,7 +43,8 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="ForwardedPortDynamic"/> class.
         /// </summary>
         /// <param name="port">The port.</param>
-        public ForwardedPortDynamic(uint port) : this(string.Empty, port)
+        public ForwardedPortDynamic(uint port)
+            : this(string.Empty, port)
         {
         }
 
@@ -57,7 +66,9 @@ namespace Renci.SshNet
         protected override void StartPort()
         {
             if (!ForwardedPortStatus.ToStarting(ref _status))
+            {
                 return;
+            }
 
             try
             {
@@ -78,14 +89,19 @@ namespace Renci.SshNet
         protected override void StopPort(TimeSpan timeout)
         {
             if (!ForwardedPortStatus.ToStopping(ref _status))
+            {
                 return;
+            }
 
             // signal existing channels that the port is closing
             base.StopPort(timeout);
+
             // prevent new requests from getting processed
             StopListener();
+
             // wait for open channels to close
             InternalStop(timeout);
+
             // mark port stopped
             _status = ForwardedPortStatus.Stopped;
         }
@@ -97,7 +113,9 @@ namespace Renci.SshNet
         protected override void CheckDisposed()
         {
             if (_isDisposed)
+            {
                 throw new ObjectDisposedException(GetType().FullName);
+            }
         }
 
         partial void InternalStart();
@@ -113,51 +131,40 @@ namespace Renci.SshNet
         /// <param name="timeout">The maximum time to wait for the forwarded port to stop.</param>
         partial void InternalStop(TimeSpan timeout);
 
-        #region IDisposable Members
-
-        /// <summary>
-        /// Holds a value indicating whether the current instance is disposed.
-        /// </summary>
-        /// <value>
-        /// <c>true</c> if the current instance is disposed; otherwise, <c>false</c>.
-        /// </value>
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         partial void InternalDispose(bool disposing);
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected override void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             base.Dispose(disposing);
-            InternalDispose(disposing);
 
+            InternalDispose(disposing);
             _isDisposed = true;
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="ForwardedPortDynamic"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="ForwardedPortDynamic"/> class.
         /// </summary>
         ~ForwardedPortDynamic()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion
     }
 }

+ 10 - 13
src/Renci.SshNet/ForwardedPortLocal.NET.cs

@@ -1,7 +1,8 @@
 using System;
-using System.Net.Sockets;
 using System.Net;
+using System.Net.Sockets;
 using System.Threading;
+
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Common;
 
@@ -73,7 +74,7 @@ namespace Renci.SshNet
 
         private void AcceptCompleted(object sender, SocketAsyncEventArgs e)
         {
-            if (e.SocketError == SocketError.OperationAborted || e.SocketError == SocketError.NotSocket)
+            if (e.SocketError is SocketError.OperationAborted or SocketError.NotSocket)
             {
                 // server was stopped
                 return;
@@ -86,6 +87,7 @@ namespace Renci.SshNet
             {
                 // accept new connection
                 StartAccept(e);
+
                 // dispose broken client socket
                 CloseClientSocket(clientSocket);
                 return;
@@ -93,6 +95,7 @@ namespace Renci.SshNet
 
             // accept new connection
             StartAccept(e);
+
             // process connection
             ProcessAccept(clientSocket);
         }
@@ -139,7 +142,7 @@ namespace Renci.SshNet
                 // the CountdownEvent will be disposed
                 try
                 {
-                    pendingChannelCountdown.Signal();
+                    _ = pendingChannelCountdown.Signal();
                 }
                 catch (ObjectDisposedException)
                 {
@@ -163,10 +166,7 @@ namespace Renci.SshNet
         private void InitializePendingChannelCountdown()
         {
             var original = Interlocked.Exchange(ref _pendingChannelCountdown, new CountdownEvent(1));
-            if (original != null)
-            {
-                original.Dispose();
-            }
+            original?.Dispose();
         }
 
         private static void CloseClientSocket(Socket clientSocket)
@@ -192,11 +192,7 @@ namespace Renci.SshNet
         partial void StopListener()
         {
             // close listener socket
-            var listener = _listener;
-            if (listener != null)
-            {
-                listener.Dispose();
-            }
+            _listener?.Dispose();
 
             // unsubscribe from session events
             var session = Session;
@@ -213,7 +209,8 @@ namespace Renci.SshNet
         /// <param name="timeout">The maximum time to wait for the pending channels to close.</param>
         partial void InternalStop(TimeSpan timeout)
         {
-            _pendingChannelCountdown.Signal();
+            _ = _pendingChannelCountdown.Signal();
+
             if (!_pendingChannelCountdown.Wait(timeout))
             {
                 // TODO: log as warning

+ 32 - 21
src/Renci.SshNet/ForwardedPortLocal.cs

@@ -1,14 +1,17 @@
 using System;
+using System.Net;
+
 using Renci.SshNet.Common;
 
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Provides functionality for local port forwarding
+    /// Provides functionality for local port forwarding.
     /// </summary>
     public partial class ForwardedPortLocal : ForwardedPort, IDisposable
     {
         private ForwardedPortStatus _status;
+        private bool _isDisposed;
 
         /// <summary>
         /// Gets the bound host.
@@ -47,9 +50,9 @@ namespace Renci.SshNet
         /// <param name="boundPort">The bound port.</param>
         /// <param name="host">The host.</param>
         /// <param name="port">The port.</param>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
         /// <example>
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\ForwardedPortLocalTest.cs" region="Example SshClient AddForwardedPort Start Stop ForwardedPortLocal" language="C#" title="Local port forwarding" />
         /// </example>
@@ -66,9 +69,9 @@ namespace Renci.SshNet
         /// <param name="port">The port.</param>
         /// <exception cref="ArgumentNullException"><paramref name="boundHost"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
         public ForwardedPortLocal(string boundHost, string host, uint port)
-            : this(boundHost, 0, host, port) 
+            : this(boundHost, 0, host, port)
         {
         }
 
@@ -81,15 +84,19 @@ namespace Renci.SshNet
         /// <param name="port">The port.</param>
         /// <exception cref="ArgumentNullException"><paramref name="boundHost"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
         public ForwardedPortLocal(string boundHost, uint boundPort, string host, uint port)
         {
             if (boundHost == null)
-                throw new ArgumentNullException("boundHost");
+            {
+                throw new ArgumentNullException(nameof(boundHost));
+            }
 
             if (host == null)
-                throw new ArgumentNullException("host");
+            {
+                throw new ArgumentNullException(nameof(host));
+            }
 
             boundPort.ValidatePort("boundPort");
             port.ValidatePort("port");
@@ -107,7 +114,9 @@ namespace Renci.SshNet
         protected override void StartPort()
         {
             if (!ForwardedPortStatus.ToStarting(ref _status))
+            {
                 return;
+            }
 
             try
             {
@@ -128,14 +137,19 @@ namespace Renci.SshNet
         protected override void StopPort(TimeSpan timeout)
         {
             if (!ForwardedPortStatus.ToStopping(ref _status))
+            {
                 return;
+            }
 
             // signal existing channels that the port is closing
             base.StopPort(timeout);
+
             // prevent new requests from getting processed
             StopListener();
+
             // wait for open channels to close
             InternalStop(timeout);
+
             // mark port stopped
             _status = ForwardedPortStatus.Stopped;
         }
@@ -147,7 +161,9 @@ namespace Renci.SshNet
         protected override void CheckDisposed()
         {
             if (_isDisposed)
+            {
                 throw new ObjectDisposedException(GetType().FullName);
+            }
         }
 
         partial void InternalStart();
@@ -162,45 +178,40 @@ namespace Renci.SshNet
 
         partial void InternalStop(TimeSpan timeout);
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         partial void InternalDispose(bool disposing);
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected override void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             base.Dispose(disposing);
-            InternalDispose(disposing);
 
+            InternalDispose(disposing);
             _isDisposed = true;
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="ForwardedPortLocal"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="ForwardedPortLocal"/> class.
         /// </summary>
         ~ForwardedPortLocal()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion
     }
 }

+ 40 - 32
src/Renci.SshNet/ForwardedPortRemote.cs

@@ -1,23 +1,24 @@
 using System;
-using System.Threading;
-using Renci.SshNet.Messages.Connection;
-using Renci.SshNet.Common;
 using System.Globalization;
 using System.Net;
+using System.Threading;
+
 using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
+using Renci.SshNet.Messages.Connection;
 
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Provides functionality for remote port forwarding
+    /// Provides functionality for remote port forwarding.
     /// </summary>
     public class ForwardedPortRemote : ForwardedPort, IDisposable
     {
         private ForwardedPortStatus _status;
         private bool _requestStatus;
-
         private EventWaitHandle _globalRequestResponse = new AutoResetEvent(false);
         private CountdownEvent _pendingChannelCountdown;
+        private bool _isDisposed;
 
         /// <summary>
         /// Gets a value indicating whether port forwarding is started.
@@ -81,14 +82,19 @@ namespace Renci.SshNet
         /// <param name="port">The port.</param>
         /// <exception cref="ArgumentNullException"><paramref name="boundHostAddress"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="hostAddress"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="IPEndPoint.MaxPort" />.</exception>
         public ForwardedPortRemote(IPAddress boundHostAddress, uint boundPort, IPAddress hostAddress, uint port)
         {
             if (boundHostAddress == null)
-                throw new ArgumentNullException("boundHostAddress");
+            {
+                throw new ArgumentNullException(nameof(boundHostAddress));
+            }
+
             if (hostAddress == null)
-                throw new ArgumentNullException("hostAddress");
+            {
+                throw new ArgumentNullException(nameof(hostAddress));
+            }
 
             boundPort.ValidatePort("boundPort");
             port.ValidatePort("port");
@@ -135,7 +141,9 @@ namespace Renci.SshNet
         protected override void StartPort()
         {
             if (!ForwardedPortStatus.ToStarting(ref _status))
+            {
                 return;
+            }
 
             InitializePendingChannelCountdown();
 
@@ -151,6 +159,7 @@ namespace Renci.SshNet
 
                 // send global request to start forwarding
                 Session.SendMessage(new TcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
+
                 // wat for response on global request to start direct tcpip
                 Session.WaitOnHandle(_globalRequestResponse);
 
@@ -183,15 +192,18 @@ namespace Renci.SshNet
         protected override void StopPort(TimeSpan timeout)
         {
             if (!ForwardedPortStatus.ToStopping(ref _status))
+            {
                 return;
+            }
 
             base.StopPort(timeout);
 
             // send global request to cancel direct tcpip
             Session.SendMessage(new CancelTcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
+
             // wait for response on global request to cancel direct tcpip or completion of message
             // listener loop (in which case response on global request can never be received)
-            WaitHandle.WaitAny(new[] { _globalRequestResponse, Session.MessageListenerCompleted }, timeout);
+            _ = WaitHandle.WaitAny(new[] { _globalRequestResponse, Session.MessageListenerCompleted }, timeout);
 
             // unsubscribe from session events as either the tcpip forward is cancelled at the
             // server, or our session message loop has completed
@@ -200,8 +212,8 @@ namespace Renci.SshNet
             Session.ChannelOpenReceived -= Session_ChannelOpening;
 
             // wait for pending channels to close
-            _pendingChannelCountdown.Signal();
-            
+            _ = _pendingChannelCountdown.Signal();
+
             if (!_pendingChannelCountdown.Wait(timeout))
             {
                 // TODO: log as warning
@@ -218,21 +230,24 @@ namespace Renci.SshNet
         protected override void CheckDisposed()
         {
             if (_isDisposed)
+            {
                 throw new ObjectDisposedException(GetType().FullName);
+            }
         }
 
         private void Session_ChannelOpening(object sender, MessageEventArgs<ChannelOpenMessage> e)
         {
             var channelOpenMessage = e.Message;
-            var info = channelOpenMessage.Info as ForwardedTcpipChannelInfo;
-            if (info != null)
+            if (channelOpenMessage.Info is ForwardedTcpipChannelInfo info)
             {
-                //  Ensure this is the corresponding request
+                // Ensure this is the corresponding request
                 if (info.ConnectedAddress == BoundHost && info.ConnectedPort == BoundPort)
                 {
                     if (!IsStarted)
                     {
-                        Session.SendMessage(new ChannelOpenFailureMessage(channelOpenMessage.LocalChannelNumber, "", ChannelOpenFailureMessage.AdministrativelyProhibited));
+                        Session.SendMessage(new ChannelOpenFailureMessage(channelOpenMessage.LocalChannelNumber,
+                                                                          string.Empty,
+                                                                          ChannelOpenFailureMessage.AdministrativelyProhibited));
                         return;
                     }
 
@@ -266,7 +281,7 @@ namespace Renci.SshNet
                                 // the CountdownEvent will be disposed
                                 try
                                 {
-                                    pendingChannelCountdown.Signal();
+                                    _ = pendingChannelCountdown.Signal();
                                 }
                                 catch (ObjectDisposedException)
                                 {
@@ -293,10 +308,7 @@ namespace Renci.SshNet
         private void InitializePendingChannelCountdown()
         {
             var original = Interlocked.Exchange(ref _pendingChannelCountdown, new CountdownEvent(1));
-            if (original != null)
-            {
-                original.Dispose();
-            }
+            original?.Dispose();
         }
 
         private void Channel_Exception(object sender, ExceptionEventArgs exceptionEventArgs)
@@ -307,30 +319,27 @@ namespace Renci.SshNet
         private void Session_RequestFailure(object sender, EventArgs e)
         {
             _requestStatus = false;
-            _globalRequestResponse.Set();
+            _ = _globalRequestResponse.Set();
         }
 
         private void Session_RequestSuccess(object sender, MessageEventArgs<RequestSuccessMessage> e)
         {
             _requestStatus = true;
+
             if (BoundPort == 0)
             {
                 BoundPort = (e.Message.BoundPort == null) ? 0 : e.Message.BoundPort.Value;
             }
 
-            _globalRequestResponse.Set();
+            _ = _globalRequestResponse.Set();
         }
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
@@ -341,7 +350,9 @@ namespace Renci.SshNet
         protected override void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             base.Dispose(disposing);
 
@@ -375,14 +386,11 @@ namespace Renci.SshNet
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="ForwardedPortRemote"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="ForwardedPortRemote"/> class.
         /// </summary>
         ~ForwardedPortRemote()
         {
             Dispose(false);
         }
-
-        #endregion
     }
 }

+ 18 - 6
src/Renci.SshNet/ForwardedPortStatus.cs

@@ -5,14 +5,14 @@ namespace Renci.SshNet
 {
     internal class ForwardedPortStatus
     {
-        private readonly int _value;
-        private readonly string _name;
-
         public static readonly ForwardedPortStatus Stopped = new ForwardedPortStatus(1, "Stopped");
         public static readonly ForwardedPortStatus Stopping = new ForwardedPortStatus(2, "Stopping");
         public static readonly ForwardedPortStatus Started = new ForwardedPortStatus(3, "Started");
         public static readonly ForwardedPortStatus Starting = new ForwardedPortStatus(4, "Starting");
 
+        private readonly int _value;
+        private readonly string _name;
+
         private ForwardedPortStatus(int value, string name)
         {
             _value = value;
@@ -21,15 +21,21 @@ namespace Renci.SshNet
 
         public override bool Equals(object other)
         {
-            if (ReferenceEquals(other, null))
+            if (other is null)
+            {
                 return false;
+            }
 
             if (ReferenceEquals(this, other))
+            {
                 return true;
+            }
 
             var forwardedPortStatus = other as ForwardedPortStatus;
             if (forwardedPortStatus == null)
+            {
                 return false;
+            }
 
             return forwardedPortStatus._value == _value;
         }
@@ -37,10 +43,10 @@ namespace Renci.SshNet
         public static bool operator ==(ForwardedPortStatus left, ForwardedPortStatus right)
         {
             // check if lhs is null
-            if (ReferenceEquals(left, null))
+            if (left is null)
             {
                 // check if both lhs and rhs are null
-                return (ReferenceEquals(right, null));
+                return right is null;
             }
 
             return left.Equals(right);
@@ -85,7 +91,9 @@ namespace Renci.SshNet
 
             // we've successfully transitioned from Started to Stopping
             if (status == Stopping)
+            {
                 return true;
+            }
 
             // attempt to transition from Starting to Stopping
             previousStatus = Interlocked.CompareExchange(ref status, Stopping, Starting);
@@ -97,7 +105,9 @@ namespace Renci.SshNet
 
             // we've successfully transitioned from Starting to Stopping
             if (status == Stopping)
+            {
                 return true;
+            }
 
             // there's no valid transition from status to Stopping
             throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
@@ -129,7 +139,9 @@ namespace Renci.SshNet
 
             // we've successfully transitioned from Stopped to Starting
             if (status == Starting)
+            {
                 return true;
+            }
 
             // there's no valid transition from status to Starting
             throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",

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

@@ -1,9 +1,10 @@
-using Renci.SshNet.Common;
-using System;
+using System;
 using System.Net.Sockets;
 using System.Threading;
 using System.Threading.Tasks;
 
+using Renci.SshNet.Common;
+
 namespace Renci.SshNet
 {
     /// <summary>
@@ -101,4 +102,4 @@ namespace Renci.SshNet
         /// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
         void SendKeepAlive();
     }
-}
+}

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

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Authentication;
 using Renci.SshNet.Messages.Connection;
@@ -13,7 +14,7 @@ namespace Renci.SshNet
         /// Signals that an authentication banner message was received from the server.
         /// </summary>
         /// <param name="sender">The session in which the banner message was received.</param>
-        /// <param name="e">The banner message.{</param>
+        /// <param name="e">The banner message.</param>
         void UserAuthenticationBannerReceived(object sender, MessageEventArgs<BannerMessage> e);
 
         /// <summary>
@@ -41,7 +42,7 @@ namespace Renci.SshNet
     internal interface IConnectionInfo
     {
         /// <summary>
-        /// Gets or sets the timeout to used when waiting for a server to acknowledge closing a channel.
+        /// Gets the timeout to used when waiting for a server to acknowledge closing a channel.
         /// </summary>
         /// <value>
         /// The channel close timeout. The default value is 1 second.
@@ -121,7 +122,7 @@ namespace Renci.SshNet
         int RetryAttempts { get; }
 
         /// <summary>
-        /// Gets or sets connection timeout.
+        /// Gets the connection timeout.
         /// </summary>
         /// <value>
         /// The connection timeout. The default value is 30 seconds.

+ 0 - 2
src/Renci.SshNet/IRemotePathTransformation.cs

@@ -14,6 +14,4 @@
         /// </returns>
         string Transform(string path);
     }
-
-
 }

+ 2 - 2
src/Renci.SshNet/IServiceFactory.cs

@@ -75,10 +75,10 @@ namespace Renci.SshNet
         /// <param name="terminalName">The <c>TERM</c> environment variable.</param>
         /// <param name="columns">The terminal width in columns.</param>
         /// <param name="rows">The terminal width in rows.</param>
-        /// <param name="width">The terminal height in pixels.</param>
+        /// <param name="width">The terminal width in pixels.</param>
         /// <param name="height">The terminal height in pixels.</param>
-        /// <param name="bufferSize">Size of the buffer.</param>
         /// <param name="terminalModeValues">The terminal mode values.</param>
+        /// <param name="bufferSize">Size of the buffer.</param>
         /// <returns>
         /// The created <see cref="ShellStream"/> instance.
         /// </returns>

+ 2 - 1
src/Renci.SshNet/ISession.cs

@@ -1,12 +1,13 @@
 using System;
 using System.Net.Sockets;
 using System.Threading;
+using System.Threading.Tasks;
+
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages;
 using Renci.SshNet.Messages.Authentication;
 using Renci.SshNet.Messages.Connection;
-using System.Threading.Tasks;
 
 namespace Renci.SshNet
 {

+ 5 - 4
src/Renci.SshNet/ISftpClient.cs

@@ -2,11 +2,12 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-using Renci.SshNet.Sftp;
-using Renci.SshNet.Common;
 using System.Threading;
 using System.Threading.Tasks;
 
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+
 namespace Renci.SshNet
 {
     /// <summary>
@@ -55,7 +56,7 @@ namespace Renci.SshNet
         /// one (-1) milliseconds, which indicates an infinite timeout period.
         /// </value>
         /// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> represents a value that is less than -1 or greater than <see cref="Int32.MaxValue"/> milliseconds.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> represents a value that is less than -1 or greater than <see cref="int.MaxValue"/> milliseconds.</exception>
         TimeSpan OperationTimeout { get; set; }
 
         /// <summary>
@@ -1138,4 +1139,4 @@ namespace Renci.SshNet
         /// </remarks>
         void WriteAllText(string path, string contents, Encoding encoding);
     }
-}
+}

+ 25 - 23
src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs

@@ -1,10 +1,11 @@
 using System;
 using System.Linq;
 using System.Threading;
+
 using Renci.SshNet.Abstractions;
+using Renci.SshNet.Common;
 using Renci.SshNet.Messages;
 using Renci.SshNet.Messages.Authentication;
-using Renci.SshNet.Common;
 
 namespace Renci.SshNet
 {
@@ -13,16 +14,19 @@ namespace Renci.SshNet
     /// </summary>
     public class KeyboardInteractiveAuthenticationMethod : AuthenticationMethod, IDisposable
     {
+        private readonly RequestMessage _requestMessage;
         private AuthenticationResult _authenticationResult = AuthenticationResult.Failure;
-
         private Session _session;
         private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
         private Exception _exception;
-        private readonly RequestMessage _requestMessage;
+        private bool _isDisposed;
 
         /// <summary>
-        /// Gets authentication method name
+        /// Gets the name of the authentication method.
         /// </summary>
+        /// <value>
+        /// The name of the authentication method.
+        /// </value>
         public override string Name
         {
             get { return _requestMessage.MethodName; }
@@ -73,7 +77,9 @@ namespace Renci.SshNet
             }
 
             if (_exception != null)
+            {
                 throw _exception;
+            }
 
             return _authenticationResult;
         }
@@ -81,20 +87,24 @@ namespace Renci.SshNet
         private void Session_UserAuthenticationSuccessReceived(object sender, MessageEventArgs<SuccessMessage> e)
         {
             _authenticationResult = AuthenticationResult.Success;
-            _authenticationCompleted.Set();
+            _ = _authenticationCompleted.Set();
         }
 
         private void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
         {
             if (e.Message.PartialSuccess)
+            {
                 _authenticationResult = AuthenticationResult.PartialSuccess;
+            }
             else
+            {
                 _authenticationResult = AuthenticationResult.Failure;
+            }
 
             // Copy allowed authentication methods
             AllowedAuthentications = e.Message.AllowedAuthentications;
 
-            _authenticationCompleted.Set();
+            _ = _authenticationCompleted.Set();
         }
 
         private void Session_UserAuthenticationInformationRequestReceived(object sender, MessageEventArgs<InformationRequestMessage> e)
@@ -110,10 +120,7 @@ namespace Renci.SshNet
                 {
                     try
                     {
-                        if (AuthenticationPrompt != null)
-                        {
-                            AuthenticationPrompt(this, eventArgs);
-                        }
+                        AuthenticationPrompt?.Invoke(this, eventArgs);
 
                         var informationResponse = new InformationResponseMessage();
 
@@ -122,38 +129,36 @@ namespace Renci.SshNet
                             informationResponse.Responses.Add(response);
                         }
 
-                        //  Send information response message
+                        // Send information response message
                         _session.SendMessage(informationResponse);
                     }
                     catch (Exception exp)
                     {
                         _exception = exp;
-                        _authenticationCompleted.Set();
+                        _ = _authenticationCompleted.Set();
                     }
                 });
         }
 
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             if (disposing)
             {
@@ -169,14 +174,11 @@ namespace Renci.SshNet
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="KeyboardInteractiveAuthenticationMethod"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="KeyboardInteractiveAuthenticationMethod"/> class.
         /// </summary>
         ~KeyboardInteractiveAuthenticationMethod()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion
     }
 }

+ 12 - 25
src/Renci.SshNet/KeyboardInteractiveConnectionInfo.cs

@@ -4,13 +4,15 @@ using Renci.SshNet.Common;
 namespace Renci.SshNet
 {
     /// <summary>
-    /// Provides connection information when keyboard interactive authentication method is used
+    /// Provides connection information when keyboard interactive authentication method is used.
     /// </summary>
     /// <example>
     ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\KeyboardInteractiveConnectionInfoTest.cs" region="Example KeyboardInteractiveConnectionInfo AuthenticationPrompt" language="C#" title="Connect using interactive method" />
     /// </example>
     public class KeyboardInteractiveConnectionInfo : ConnectionInfo, IDisposable
     {
+        private bool _isDisposed;
+
         /// <summary>
         /// Occurs when server prompts for more authentication information.
         /// </summary>
@@ -19,8 +21,6 @@ namespace Renci.SshNet
         /// </example>
         public event EventHandler<AuthenticationPromptEventArgs> AuthenticationPrompt;
 
-        //  TODO: DOCS Add exception documentation for this class.
-
         /// <summary>
         /// Initializes a new instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
         /// </summary>
@@ -29,7 +29,6 @@ namespace Renci.SshNet
         public KeyboardInteractiveConnectionInfo(string host, string username)
             : this(host, DefaultPort, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {
-
         }
 
         /// <summary>
@@ -41,7 +40,6 @@ namespace Renci.SshNet
         public KeyboardInteractiveConnectionInfo(string host, int port, string username)
             : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {
-
         }
 
         /// <summary>
@@ -131,8 +129,7 @@ namespace Renci.SshNet
         {
             foreach (var authenticationMethod in AuthenticationMethods)
             {
-                var kbdInteractive = authenticationMethod as KeyboardInteractiveAuthenticationMethod;
-                if (kbdInteractive != null)
+                if (authenticationMethod is KeyboardInteractiveAuthenticationMethod kbdInteractive)
                 {
                     kbdInteractive.AuthenticationPrompt += AuthenticationMethod_AuthenticationPrompt;
                 }
@@ -142,34 +139,28 @@ namespace Renci.SshNet
 
         private void AuthenticationMethod_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
         {
-            if (AuthenticationPrompt != null)
-            {
-                AuthenticationPrompt(sender, e);
-            }
+            AuthenticationPrompt?.Invoke(sender, e);
         }
 
-
-        #region IDisposable Members
-
-        private bool _isDisposed;
-
         /// <summary>
         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
         /// </summary>
         public void Dispose()
         {
-            Dispose(true);
+            Dispose(disposing: true);
             GC.SuppressFinalize(this);
         }
 
         /// <summary>
-        /// Releases unmanaged and - optionally - managed resources
+        /// Releases unmanaged and - optionally - managed resources.
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
             if (_isDisposed)
+            {
                 return;
+            }
 
             if (disposing)
             {
@@ -177,8 +168,7 @@ namespace Renci.SshNet
                 {
                     foreach (var authenticationMethods in AuthenticationMethods)
                     {
-                        var disposable = authenticationMethods as IDisposable;
-                        if (disposable != null)
+                        if (authenticationMethods is IDisposable disposable)
                         {
                             disposable.Dispose();
                         }
@@ -190,14 +180,11 @@ namespace Renci.SshNet
         }
 
         /// <summary>
-        /// Releases unmanaged resources and performs other cleanup operations before the
-        /// <see cref="KeyboardInteractiveConnectionInfo"/> is reclaimed by garbage collection.
+        /// Finalizes an instance of the <see cref="KeyboardInteractiveConnectionInfo"/> class.
         /// </summary>
         ~KeyboardInteractiveConnectionInfo()
         {
-            Dispose(false);
+            Dispose(disposing: false);
         }
-
-        #endregion
     }
 }

+ 5 - 3
src/Renci.SshNet/MessageEventArgs.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet
     /// <summary>
     /// Provides data for message events.
     /// </summary>
-    /// <typeparam name="T">Message type</typeparam>
+    /// <typeparam name="T">Message type.</typeparam>
     public class MessageEventArgs<T> : EventArgs
     {
         /// <summary>
@@ -14,14 +14,16 @@ namespace Renci.SshNet
         public T Message { get; private set; }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="MessageEventArgs&lt;T&gt;"/> class.
+        /// Initializes a new instance of the <see cref="MessageEventArgs{T}"/> class.
         /// </summary>
         /// <param name="message">The message.</param>
         /// <exception cref="ArgumentNullException"><paramref name="message"/> is <c>null</c>.</exception>
         public MessageEventArgs(T message)
         {
             if (message == null)
-                throw new ArgumentNullException("message");
+            {
+                throw new ArgumentNullException(nameof(message));
+            }
 
             Message = message;
         }

+ 10 - 10
src/Renci.SshNet/Messages/Authentication/RequestMessageHost.cs

@@ -3,44 +3,44 @@
     /// <summary>
     /// Represents "hostbased" SSH_MSG_USERAUTH_REQUEST message.
     /// </summary>
-    internal class RequestMessageHost : RequestMessage
+    internal sealed class RequestMessageHost : RequestMessage
     {
         /// <summary>
         /// Gets the public key algorithm for host key as ASCII encoded byte array.
         /// </summary>
-        public byte[] PublicKeyAlgorithm { get; private set; }
+        public byte[] PublicKeyAlgorithm { get; }
 
         /// <summary>
-        /// Gets or sets the public host key and certificates for client host.
+        /// Gets the public host key and certificates for client host.
         /// </summary>
         /// <value>
         /// The public host key.
         /// </value>
-        public byte[] PublicHostKey { get; private set; }
+        public byte[] PublicHostKey { get; }
 
         /// <summary>
-        /// Gets or sets the name of the client host as ASCII encoded byte array.
+        /// Gets the name of the client host as ASCII encoded byte array.
         /// </summary>
         /// <value>
         /// The name of the client host.
         /// </value>
-        public byte[] ClientHostName { get; private set; }
+        public byte[] ClientHostName { get; }
 
         /// <summary>
-        /// Gets or sets the client username on the client host as UTF-8 encoded byte array.
+        /// Gets the client username on the client host as UTF-8 encoded byte array.
         /// </summary>
         /// <value>
         /// The client username.
         /// </value>
-        public byte[] ClientUsername { get; private set; }
+        public byte[] ClientUsername { get; }
 
         /// <summary>
-        /// Gets or sets the signature.
+        /// Gets the signature.
         /// </summary>
         /// <value>
         /// The signature.
         /// </value>
-        public byte[] Signature { get; private set; }
+        public byte[] Signature { get; }
 
         /// <summary>
         /// Gets the size of the message in bytes.

+ 11 - 5
src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs

@@ -11,7 +11,7 @@ namespace Renci.SshNet.Messages.Connection
         internal const byte MessageNumber = 94;
 
         /// <summary>
-        /// Gets or sets message data.
+        /// Gets the message data.
         /// </summary>
         /// <value>
         /// The data.
@@ -27,7 +27,7 @@ namespace Renci.SshNet.Messages.Connection
         /// <value>
         /// The zero-based offset in <see cref="Data"/> at which the data begins.
         /// </value>
-        public int Offset { get; set; }
+        public int Offset { get; private set; }
 
         /// <summary>
         /// Gets the number of bytes of <see cref="Data"/> to read or write.
@@ -35,7 +35,7 @@ namespace Renci.SshNet.Messages.Connection
         /// <value>
         /// The number of bytes of <see cref="Data"/> to read or write.
         /// </value>
-        public int Size { get; set; }
+        public int Size { get; private set; }
 
         /// <summary>
         /// Gets the size of the message in bytes.
@@ -75,7 +75,9 @@ namespace Renci.SshNet.Messages.Connection
             : base(localChannelNumber)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
 
             Data = data;
             Offset = 0;
@@ -93,7 +95,9 @@ namespace Renci.SshNet.Messages.Connection
             : base(localChannelNumber)
         {
             if (data == null)
-                throw new ArgumentNullException("data");
+            {
+                throw new ArgumentNullException(nameof(data));
+            }
 
             Data = data;
             Offset = offset;
@@ -106,6 +110,7 @@ namespace Renci.SshNet.Messages.Connection
         protected override void LoadData()
         {
             base.LoadData();
+
             Data = ReadBinary();
             Offset = 0;
             Size = Data.Length;
@@ -117,6 +122,7 @@ namespace Renci.SshNet.Messages.Connection
         protected override void SaveData()
         {
             base.SaveData();
+
             WriteBinary(Data, Offset, Size);
         }
     }

+ 4 - 4
src/Renci.SshNet/Messages/Connection/ChannelMessage.cs

@@ -32,14 +32,14 @@ namespace Renci.SshNet.Messages.Connection
         }
 
         /// <summary>
-        /// Initializes a new <see cref="ChannelMessage"/>.
+        /// Initializes a new instance of the <see cref="ChannelMessage"/> class.
         /// </summary>
         protected ChannelMessage()
         {
         }
 
         /// <summary>
-        /// Initializes a new <see cref="ChannelMessage"/> with the specified local channel number.
+        /// Initializes a new instance of the <see cref="ChannelMessage"/> class with the specified local channel number.
         /// </summary>
         /// <param name="localChannelNumber">The local channel number.</param>
         protected ChannelMessage(uint localChannelNumber)
@@ -64,10 +64,10 @@ namespace Renci.SshNet.Messages.Connection
         }
 
         /// <summary>
-        /// Returns a <see cref="System.String"/> that represents this instance.
+        /// Returns a <see cref="string"/> that represents this instance.
         /// </summary>
         /// <returns>
-        /// A <see cref="System.String"/> that represents this instance.
+        /// A <see cref="string"/> that represents this instance.
         /// </returns>
         public override string ToString()
         {

+ 4 - 2
src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs

@@ -76,7 +76,7 @@ namespace Renci.SshNet.Messages.Connection
         /// </summary>
         public ChannelOpenMessage()
         {
-            //  Required for dynamicly loading request type when it comes from the server
+            // Required for dynamicly loading request type when it comes from the server
         }
 
         /// <summary>
@@ -90,7 +90,9 @@ namespace Renci.SshNet.Messages.Connection
         public ChannelOpenMessage(uint channelNumber, uint initialWindowSize, uint maximumPacketSize, ChannelOpenInfo info)
         {
             if (info == null)
-                throw new ArgumentNullException("info");
+            {
+                throw new ArgumentNullException(nameof(info));
+            }
 
             ChannelType = Ascii.GetBytes(info.ChannelType);
             LocalChannelNumber = channelNumber;

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelOpen/DirectTcpipChannelInfo.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet.Messages.Connection
     /// <summary>
     /// Used to open "direct-tcpip" channel type
     /// </summary>
-    internal class DirectTcpipChannelInfo : ChannelOpenInfo
+    internal sealed class DirectTcpipChannelInfo : ChannelOpenInfo
     {
         private byte[] _hostToConnect;
         private byte[] _originatorAddress;

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelOpen/ForwardedTcpipChannelInfo.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet.Messages.Connection
     /// <summary>
     /// Used to open "forwarded-tcpip" channel type
     /// </summary>
-    internal class ForwardedTcpipChannelInfo : ChannelOpenInfo
+    internal sealed class ForwardedTcpipChannelInfo : ChannelOpenInfo
     {
         private byte[] _connectedAddress;
         private byte[] _originatorAddress;

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelOpen/SessionChannelOpenInfo.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet.Messages.Connection
     /// <summary>
     /// Used to open "session" channel type
     /// </summary>
-    internal class SessionChannelOpenInfo : ChannelOpenInfo
+    internal sealed class SessionChannelOpenInfo : ChannelOpenInfo
     {
         /// <summary>
         /// Specifies channel open type

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelOpen/X11ChannelOpenInfo.cs

@@ -5,7 +5,7 @@ namespace Renci.SshNet.Messages.Connection
     /// <summary>
     /// Used to open "x11" channel type
     /// </summary>
-    internal class X11ChannelOpenInfo : ChannelOpenInfo
+    internal sealed class X11ChannelOpenInfo : ChannelOpenInfo
     {
         private byte[] _originatorAddress;
 

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelRequest/BreakRequestInfo.cs

@@ -3,7 +3,7 @@
     /// <summary>
     /// Represents "break" type channel request information
     /// </summary>
-    internal class BreakRequestInfo : RequestInfo
+    internal sealed class BreakRequestInfo : RequestInfo
     {
         /// <summary>
         /// Channel request name

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików