Add unit tests for scrobble module pause episode request.

--- Source/Tests/TraktApiSharp.Tests/Modules/TraktScrobbleModuleTests.cs
+++ Source/Tests/TraktApiSharp.Tests/Modules/TraktScrobbleModuleTests.cs
@@ -3177,66 +3177,1334 @@
         // -----------------------------------------------------------------------------------------------
         // -----------------------------------------------------------------------------------------------

-        #region PauseMovie
+        #region PauseEpisode

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisode()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShow()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithAppVersion()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppVersion = appVersion
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, appVersion).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndAppVersion()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppVersion = appVersion
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, appVersion).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithAppDate()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, null, appBuildDate).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndAppDate()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, null, appBuildDate).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithExtendedOption()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, null, null, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndExtendedOption()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, null, null, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithAppVersionAndAppDate()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppVersion = appVersion,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, appVersion, appBuildDate).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndAppVersionAndAppDate()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppVersion = appVersion,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, appVersion, appBuildDate).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithAppVersionAndExtendedOption()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppVersion = appVersion
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, appVersion, null, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndAppVersionAndExtendedOption()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppVersion = appVersion
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, appVersion, null, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeWithAppDateAndExtendedOption()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, null, appBuildDate, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowAndAppDateAndExtendedOption()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, null, appBuildDate, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeComplete()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Progress = progress,
+                AppVersion = appVersion,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, null, appVersion, appBuildDate, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowComplete()
+        {
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+            var appVersion = "app_version";
+            var appBuildDate = DateTime.UtcNow;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress,
+                AppVersion = appVersion,
+                AppDate = appBuildDate.ToString("yyyy-MM-dd")
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            var extendedOption = new TraktExtendedOption
+            {
+                Full = true,
+                Images = true
+            };
+
+            TestUtility.SetupMockResponseWithOAuth($"scrobble/pause?extended={extendedOption.ToString()}", postJson, episodePauseScrobbleResponse);
+
+            var response = TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show, appVersion, appBuildDate, extendedOption).Result;
+
+            response.Should().NotBeNull();
+            response.Action.Should().Be(TraktScrobbleActionType.Pause);
+            response.Progress.Should().Be(progress);
+            response.Sharing.Should().NotBeNull();
+            response.Sharing.Facebook.Should().BeFalse();
+            response.Sharing.Twitter.Should().BeTrue();
+            response.Sharing.Tumblr.Should().BeFalse();
+            response.Episode.Should().NotBeNull();
+            response.Episode.SeasonNumber.Should().Be(1);
+            response.Episode.Number.Should().Be(1);
+            response.Episode.Title.Should().Be("Pilot");
+            response.Episode.Ids.Should().NotBeNull();
+            response.Episode.Ids.Trakt.Should().Be(16);
+            response.Episode.Ids.Tvdb.Should().Be(349232);
+            response.Episode.Ids.Imdb.Should().Be("tt0959621");
+            response.Episode.Ids.Tmdb.Should().Be(62085);
+            response.Episode.Ids.TvRage.Should().Be(637041);
+            response.Show.Title.Should().Be("Breaking Bad");
+            response.Show.Year.Should().Be(2008);
+            response.Show.Ids.Should().NotBeNull();
+            response.Show.Ids.Trakt.Should().Be(1);
+            response.Show.Ids.Slug.Should().Be("breaking-bad");
+            response.Show.Ids.Tvdb.Should().Be(81189);
+            response.Show.Ids.Imdb.Should().Be("tt0903747");
+            response.Show.Ids.Tmdb.Should().Be(1396);
+            response.Show.Ids.TvRage.Should().Be(18164);
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeExceptions()
         {
-            Assert.Fail();
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var progress = 75.0f;
+
+            var uri = "scrobble/pause";
+
+            TestUtility.SetupMockResponseWithoutOAuth(uri, HttpStatusCode.Unauthorized);
+
+            Func<Task<TraktEpisodeScrobblePostResponse>> act =
+                async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress);
+            act.ShouldThrow<TraktAuthorizationException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.BadRequest);
+            act.ShouldThrow<TraktBadRequestException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.Forbidden);
+            act.ShouldThrow<TraktForbiddenException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)412);
+            act.ShouldThrow<TraktPreconditionFailedException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)429);
+            act.ShouldThrow<TraktRateLimitException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.InternalServerError);
+            act.ShouldThrow<TraktServerException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)503);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)504);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)520);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)521);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)522);
+            act.ShouldThrow<TraktServerUnavailableException>();
+        }
+
+        [TestMethod]
+        public void TestTraktScrobbleModulePauseEpisodeWithShowExceptions()
+        {
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 1,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 75.0f;
+
+            var uri = "scrobble/pause";
+
+            TestUtility.SetupMockResponseWithoutOAuth(uri, HttpStatusCode.Unauthorized);
+
+            Func<Task<TraktEpisodeScrobblePostResponse>> act =
+                async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<TraktAuthorizationException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.BadRequest);
+            act.ShouldThrow<TraktBadRequestException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.Forbidden);
+            act.ShouldThrow<TraktForbiddenException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)412);
+            act.ShouldThrow<TraktPreconditionFailedException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)429);
+            act.ShouldThrow<TraktRateLimitException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, HttpStatusCode.InternalServerError);
+            act.ShouldThrow<TraktServerException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)503);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)504);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)520);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)521);
+            act.ShouldThrow<TraktServerUnavailableException>();
+
+            TestUtility.ClearMockHttpClient();
+            TestUtility.SetupMockResponseWithOAuth(uri, (HttpStatusCode)522);
+            act.ShouldThrow<TraktServerUnavailableException>();
         }

         [TestMethod]
         public void TestTraktScrobbleModulePauseEpisodeArgumentExceptions()
         {
-            Assert.Fail();
+            var episodePauseScrobbleResponse = TestUtility.ReadFileContents(@"Objects\Post\Scrobbles\Responses\EpisodePauseScrobblePostResponse.json");
+            episodePauseScrobbleResponse.Should().NotBeNullOrEmpty();
+
+            var episode = new TraktEpisode
+            {
+                SeasonNumber = 0,
+                Number = 1,
+                Ids = new TraktEpisodeIds
+                {
+                    Trakt = 16,
+                    Tvdb = 349232,
+                    Imdb = "tt0959621",
+                    Tmdb = 62085,
+                    TvRage = 637041
+                }
+            };
+
+            var show = new TraktShow
+            {
+                Title = "Breaking Bad"
+            };
+
+            var progress = 10.0f;
+
+            var episodePauseScrobblePost = new TraktEpisodeScrobblePost
+            {
+                Episode = episode,
+                Show = show,
+                Progress = progress
+            };
+
+            var postJson = TestUtility.SerializeObject(episodePauseScrobblePost);
+            postJson.Should().NotBeNullOrEmpty();
+
+            TestUtility.SetupMockResponseWithOAuth("scrobble/pause", postJson, episodePauseScrobbleResponse);
+
+            Func<Task<TraktEpisodeScrobblePostResponse>> act =
+                async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(null, progress);
+
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = null;
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds
+            {
+                Trakt = 16,
+                Tvdb = 349232,
+                Imdb = "tt0959621",
+                Tmdb = 62085,
+                TvRage = 637041
+            };
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, -0.01f);
+            act.ShouldThrow<ArgumentException>();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, 100.01f);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = null;
+            episode.SeasonNumber = -1;
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = null;
+            episode.SeasonNumber = 0;
+            episode.Number = 0;
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds();
+            episode.Number = 0;
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = null;
+            episode.Number = 1;
+            show.Title = string.Empty;
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, progress, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = null;
+            show.Title = "Breaking Bad";
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, -0.01f, show);
+            act.ShouldThrow<ArgumentException>();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, 100.01f, show);
+            act.ShouldThrow<ArgumentException>();
+
+            episode.Ids = new TraktEpisodeIds();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, -0.01f, show);
+            act.ShouldThrow<ArgumentException>();
+
+            act = async () => await TestUtility.MOCK_TEST_CLIENT.Scrobble.PauseEpisodeAsync(episode, 100.01f, show);
+            act.ShouldThrow<ArgumentException>();
         }

         #endregion
@@ -3244,7 +4512,7 @@
         // -----------------------------------------------------------------------------------------------
         // -----------------------------------------------------------------------------------------------

-        #region StopMovie
+        #region StopEpisode

         [TestMethod]
         public void TestTraktScrobbleModuleStopEpisode()


update version

update version

--- src/Pustota.Maven.Cmd/Properties/AssemblyInfo.cs
+++ src/Pustota.Maven.Cmd/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.0.*")]
+[assembly: AssemblyFileVersion("1.0.0.10")]


Refactoring

Refactoring

--- src/sendstorm/MessagePublisher.cs
+++ src/sendstorm/MessagePublisher.cs
@@ -10,28 +10,28 @@
 {
     public class MessagePublisher : IMessagePublisher
     {
-        private readonly Ref<ImmutableTree<Type, Ref<ImmutableTree<object, StandardSubscription>>>> subscriptionRepository;
+        private ImmutableTree<Type, ImmutableTree<object, StandardSubscription>> subscriptionRepository;
         private readonly object syncObject = new object();
         private readonly SynchronizationContext context = SynchronizationContext.Current;

         public MessagePublisher()
         {
-            this.subscriptionRepository = new Ref<ImmutableTree<Type, Ref<ImmutableTree<object, StandardSubscription>>>>(ImmutableTree<Type, Ref<ImmutableTree<object, StandardSubscription>>>.Empty);
+            this.subscriptionRepository = ImmutableTree<Type, ImmutableTree<object, StandardSubscription>>.Empty;
         }

         public void Subscribe<TMessage>(IMessageReceiver<TMessage> messageReciever, Func<TMessage, bool> filter = null, ExecutionTarget executionTarget = ExecutionTarget.BroadcastThread)
         {
             var messageType = typeof(TMessage);

-            var immutableTree = new Ref<ImmutableTree<object, StandardSubscription>>(ImmutableTree<object, StandardSubscription>.Empty);
+            var immutableTree = ImmutableTree<object, StandardSubscription>.Empty;
             var subscription = this.CreateSubscription(messageReciever, filter, executionTarget);
-            var newTree = new Ref<ImmutableTree<object, StandardSubscription>>(immutableTree.Value.AddOrUpdate(messageReciever, subscription));
+            var newTree = immutableTree.AddOrUpdate(messageReciever, subscription);

             lock (this.syncObject)
             {
-                var newRepository = this.subscriptionRepository.Value.AddOrUpdate(messageType, newTree, (oldValue, newValue) =>
+                var newRepository = this.subscriptionRepository.AddOrUpdate(messageType, newTree, (oldValue, newValue) =>
                 {
-                    var newSubscription = oldValue.Value.AddOrUpdate(messageReciever, subscription, (oldSubscription, newSubs) =>
+                    return oldValue.AddOrUpdate(messageReciever, subscription, (oldSubscription, newSubs) =>
                     {
                         object target;
                         if (!oldSubscription.Subscriber.TryGetTarget(out target))
@@ -45,14 +45,9 @@

                         return oldSubscription;
                     });
-
-                    if (!oldValue.TrySwapIfStillCurrent(oldValue.Value, newSubscription))
-                        oldValue.Swap(_ => newSubscription);
-                    return oldValue;
                 });

-                if (!this.subscriptionRepository.TrySwapIfStillCurrent(this.subscriptionRepository.Value, newRepository))
-                    this.subscriptionRepository.Swap(_ => newRepository);
+                this.subscriptionRepository = newRepository;
             }
         }

@@ -61,17 +56,8 @@
             lock (this.syncObject)
             {
                 var messageType = typeof(TMessage);
-                var currentRepository = this.subscriptionRepository.Value.GetValueOrDefault(messageType);
-
-                var newSubscribers = currentRepository.Value.Update(messageReciever, null);
-
-                if (!currentRepository.TrySwapIfStillCurrent(currentRepository.Value, newSubscribers))
-                    currentRepository.Swap(_ => newSubscribers);
-
-                var newRepository = this.subscriptionRepository.Value.Update(messageType, currentRepository);
-
-                if (!this.subscriptionRepository.TrySwapIfStillCurrent(this.subscriptionRepository.Value, newRepository))
-                    this.subscriptionRepository.Swap(_ => newRepository);
+                var currentRepository = this.subscriptionRepository.GetValueOrDefault(messageType).Update(messageReciever, null);
+                this.subscriptionRepository = this.subscriptionRepository.Update(messageType, currentRepository);
             }
         }

@@ -103,8 +89,8 @@
         private StandardSubscription[] GetSubscribers<TMessage>(TMessage message)
         {
             var messageType = typeof(TMessage);
-            var subscriptions = this.subscriptionRepository.Value.GetValueOrDefault(messageType);
-            return subscriptions?.Value?.Enumerate().Where(sub => sub.Value != null).Select(sub => sub.Value).ToArray();
+            var subscriptions = this.subscriptionRepository.GetValueOrDefault(messageType);
+            return subscriptions?.Enumerate().Where(sub => sub.Value != null).Select(sub => sub.Value).ToArray();
         }
     }
 }


#3248 Some autoformatting annoyances

#3248 Some autoformatting annoyances

--- src/R/Editor/Impl/Formatting/FormatOperations.cs
+++ src/R/Editor/Impl/Formatting/FormatOperations.cs
@@ -98,16 +98,13 @@
             ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber + offset);
             ITextRange formatRange = new TextRange(line.Start, line.Length);

-            UndoableFormatRange(textView, textBuffer, formatRange, editorShell, exactRange: true);
+            UndoableFormatRange(textView, textBuffer, formatRange, editorShell);
         }

-        public static void UndoableFormatRange(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, IEditorShell editorShell, bool exactRange = false) {
+        public static void UndoableFormatRange(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange, IEditorShell editorShell) {
             using (var undoAction = editorShell.CreateCompoundAction(textView, textView.TextBuffer)) {
                 undoAction.Open(Resources.AutoFormat);
-                var result = exactRange
-                    ? RangeFormatter.FormatRangeExact(textView, textBuffer, formatRange, REditorSettings.FormatOptions, editorShell)
-                    : RangeFormatter.FormatRange(textView, textBuffer, formatRange, REditorSettings.FormatOptions, editorShell);
-
+                var result = RangeFormatter.FormatRange(textView, textBuffer, formatRange, REditorSettings.FormatOptions, editorShell);
                 if (result) {
                     undoAction.Commit();
                 }


Directly return task

Directly return task

--- osu.Game/Tests/Visual/RealtimeMultiplayer/TestRealtimeMultiplayerClient.cs
+++ osu.Game/Tests/Visual/RealtimeMultiplayer/TestRealtimeMultiplayerClient.cs
@@ -106,14 +106,14 @@
             return Task.CompletedTask;
         }

-        public override async Task StartMatch()
+        public override Task StartMatch()
         {
             Debug.Assert(Room != null);

             foreach (var user in Room.Users.Where(u => u.State == MultiplayerUserState.Ready))
                 ChangeUserState(user.UserID, MultiplayerUserState.WaitingForLoad);

-            await ((IMultiplayerClient)this).LoadRequested();
+            return ((IMultiplayerClient)this).LoadRequested();
         }
     }
 }


Additional handling to avoid some errors when deleting temp files.

--- src/SJP.Schematic.Graphviz/TemporaryDirectory.cs
+++ src/SJP.Schematic.Graphviz/TemporaryDirectory.cs
@@ -21,12 +21,28 @@
             );
         }

+        private static void DeleteDirectory(string dirPath)
+        {
+            File.SetAttributes(dirPath, FileAttributes.Normal);
+
+            foreach (var filePath in Directory.EnumerateFiles(dirPath))
+            {
+                File.SetAttributes(filePath, FileAttributes.Normal);
+                File.Delete(filePath);
+            }
+
+            foreach (var dir in Directory.GetDirectories(dirPath))
+                DeleteDirectory(dir);
+
+            Directory.Delete(dirPath, false);
+        }
+
         public void Dispose()
         {
             if (_disposed)
                 return;

-            Directory.Delete(DirectoryPath, true);
+            DeleteDirectory(DirectoryPath);
             _disposed = true;
         }


Redis v1.2.0 序列化方式改为 JSON

Redis v1.2.0 序列化方式改为 JSON

--- src/Senparc.Weixin.WxOpen.Tests/SerializeTest.cs
+++ src/Senparc.Weixin.WxOpen.Tests/SerializeTest.cs
@@ -1,8 +1,10 @@
 using System;
 using System.IO;
 using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Senparc.Weixin.Cache.Redis;
+using Senparc.Weixin.Helpers;
 using Senparc.Weixin.MP.Test.CommonAPIs;
 using Senparc.Weixin.WxOpen.Containers;

@@ -44,8 +46,8 @@
                 return sessionBag;
             };

-            var testCycle = 100000;
-            //使用 Newtonsoft.Json 进行 10 万次序列化并计算时间
+            var testCycle = 50;
+            //使用 Newtonsoft.Json 进行 1 万次序列化并计算时间
             DateTime dt1 = DateTime.Now;
             for (int i = 0; i < testCycle; i++)
             {
@@ -54,30 +56,73 @@
                 //序列化
                 var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(sessionBag);
                 var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<SessionBag>(jsonString);
+
+                if (i==0)
+                {
+                    Console.WriteLine("Newtonsoft.JSON:");
+                    Console.WriteLine(jsonString);//输出字符串
+                    Console.WriteLine(obj.CacheTime);//输出反序列化后的参数
+                    Console.WriteLine("==============");
+                    dt1=DateTime.Now;//过滤启动时间，Newtonsoft启动时间需要200多ms
+                }
             }
             DateTime dt2 = DateTime.Now;

-            //使用 二进制方式序列化
+            DateTime dt3 = DateTime.Now;
+            //使用 Newtonsoft.Json 进行 1 万次序列化并计算时间
             for (int i = 0; i < testCycle; i++)
             {
                 //获取一个 SessionBag 对象
                 var sessionBag = getNewEntity();
                 //序列化
+                SerializerHelper serializerHelper=new SerializerHelper();
+                var jsonString = serializerHelper.GetJsonString(sessionBag);
+                var obj = serializerHelper.GetObject<SessionBag>(jsonString);
+
+                if (i == 0)
+                {
+                    Console.WriteLine(".NET Serializer:");
+                    Console.WriteLine(jsonString);//输出字符串
+                    Console.WriteLine(obj.CacheTime);//输出反序列化后的参数
+                    Console.WriteLine("==============");
+                    dt3=DateTime.Now;//过滤启动时间
+                }
+            }
+            DateTime dt4 = DateTime.Now;
+
+            DateTime dt5 = DateTime.Now;
+            //使用 .NET 内置 JSON 序列化
+            for (int i = 0; i < testCycle; i++)
+            {
+                //获取一个 SessionBag 对象
+                var sessionBag = getNewEntity();
                 BinaryFormatter binaryFormatter = new BinaryFormatter();
                 MemoryStream memoryStream = new MemoryStream();
                 {
+                    //序列化
                     binaryFormatter.Serialize(memoryStream, sessionBag);
                     byte[] objectDataAsStream = memoryStream.ToArray();
+
                     //反序列化
                     var obj = StackExchangeRedisExtensions.Deserialize<SessionBag>(objectDataAsStream);
+
+                    if (i == 0)
+                    {
+                        Console.WriteLine(".NET Serializer:");
+                        Console.WriteLine(Encoding.UTF8.GetString(objectDataAsStream));//输出字符串
+                        Console.WriteLine(obj.CacheTime);//输出反序列化后的参数
+                    Console.WriteLine("==============");
+                    dt5=DateTime.Now;//过滤启动时间
+                    }
                 }
             }
-            DateTime dt3 = DateTime.Now;
+            DateTime dt6 = DateTime.Now;

-            Console.WriteLine("JSON 序列化 {0} 次，耗时：{1}ms", testCycle, (dt2 - dt1).TotalMilliseconds);
-            Console.WriteLine("二进制 序列化 {0} 次，耗时：{1}ms", testCycle, (dt3 - dt2).TotalMilliseconds);
+            Console.WriteLine("Newtonsoft JSON 序列化 {0} 次，耗时：{1}ms", testCycle, (dt2 - dt1).TotalMilliseconds);
+            Console.WriteLine(".NET 内置 JSON 序列化 {0} 次，耗时：{1}ms", testCycle, (dt4 - dt3).TotalMilliseconds);
+            Console.WriteLine("二进制 序列化 {0} 次，耗时：{1}ms", testCycle, (dt6 - dt5).TotalMilliseconds);

-            //结果：Newtonsoft.JSON 效率更高
+            //结果：Newtonsoft.JSON 效率更高，三个结果时间基本上1:2:3
         }
     }
 }


Use OBO for creating KV's so the service doesn't need contrib access to the resource group

--- src/SignService/Services/KeyVaultAdminService.cs
+++ src/SignService/Services/KeyVaultAdminService.cs
@@ -29,13 +29,14 @@
         readonly AdminConfig adminConfig;
         readonly Guid tenantId;
         readonly Guid clientId;
+        readonly string userId;
         readonly KeyVaultManagementClient kvClient;
         readonly IGraphHttpService graphHttpService;

         public KeyVaultAdminService(IOptionsSnapshot<AzureAdOptions> azureAdOptions, IOptionsSnapshot<AdminConfig> adminConfig, IGraphHttpService graphHttpService, IHttpContextAccessor contextAccessor)
         {
             var principal = contextAccessor.HttpContext.User;
-            var userId = principal.FindFirst("oid").Value;
+            userId = principal.FindFirst("oid").Value;
             tenantId = Guid.Parse(principal.FindFirst("tid").Value);
             clientId = Guid.Parse(azureAdOptions.Value.ClientId);

@@ -52,6 +53,13 @@
         async Task<string> GetAppToken(string authority, string resource, string scope)
         {
             var result = await adalContext.AcquireTokenAsync("https://management.core.windows.net/", new ClientCredential(azureAdOptions.ClientId, azureAdOptions.ClientSecret)).ConfigureAwait(false);
+
+            return result.AccessToken;
+        }
+
+        async Task<string> GetOboToken(string authority, string resource, string scope)
+        {
+            var result = await adalContext.AcquireTokenSilentAsync("https://management.core.windows.net/", new ClientCredential(azureAdOptions.ClientId, azureAdOptions.ClientSecret), UserIdentifier.AnyUser).ConfigureAwait(false);

             return result.AccessToken;
         }
@@ -134,6 +142,45 @@
                               }
                           }
                         },
+
+                        // Grant the current user the management plane access for use in the portal/powershell for
+                        // manual tasks
+                        new AccessPolicyEntry
+                        {
+                            ObjectId = userId,
+                            TenantId = tenantId,
+                            Permissions  = new Permissions
+                            {
+                                Keys = new List<string>
+                                {
+                                    "Backup",
+                                    "Create",
+                                    "Delete",
+                                    "Get",
+                                    "Import",
+                                    "List",
+                                    "Restore",
+                                    "Update",
+                                    "Recover"
+                                },
+                                Certificates = new List<string>
+                                {
+                                    "Get",
+                                    "List",
+                                    "Update",
+                                    "Create",
+                                    "Import",
+                                    "Delete",
+                                    "ManageContacts",
+                                    "ManageIssuers",
+                                    "GetIssuers",
+                                    "ListIssuers",
+                                    "SetIssuers",
+                                    "DeleteIssuers"
+                                }
+                            }
+                        },
+
                         // Needs Keys: Get + Sign, Certificates: Get
                         new AccessPolicyEntry
                         {
@@ -169,8 +216,14 @@
             // Truncate to 24 chars
             vaultName = vaultName.Substring(0, 24);

-            var vault = await kvClient.Vaults.CreateOrUpdateAsync(resourceGroup, vaultName, parameters).ConfigureAwait(false);
-            return ToVaultModel(vault);
+            // Create uses an OBO so that this only works if the user has contributer+ access to the resource group
+            using (var client = new KeyVaultManagementClient(new KeyVaultCredential(GetOboToken)))
+            {
+                client.SubscriptionId = adminConfig.SubscriptionId;
+                var vault = await client.Vaults.CreateOrUpdateAsync(resourceGroup, vaultName, parameters).ConfigureAwait(false);
+
+                return ToVaultModel(vault);
+            }
         }
         static VaultModel ToVaultModel(Vault vault)
         {


Added local function GetLocalComponentsPath.


Make fields readonly

Make fields readonly

--- src/SocksSharp/Proxy/Response/ResponseBuilder.cs
+++ src/SocksSharp/Proxy/Response/ResponseBuilder.cs
@@ -213,8 +213,8 @@
         private HttpResponseMessage response;
         private Dictionary<string, List<string>> contentHeaders;

-        private CookieContainer cookies;
-        private Uri uri;
+        private readonly CookieContainer cookies;
+        private readonly Uri uri;

         private ReceiveHelper receiveHelper;


Remove redundant UnderlyingSystemType calls (#24000)

UnderlyingSystemType is virtual

--- src/System.Private.CoreLib/shared/System/Type.cs
+++ src/System.Private.CoreLib/shared/System/Type.cs
@@ -281,8 +281,9 @@
         }
         protected virtual TypeCode GetTypeCodeImpl()
         {
-            if (this != UnderlyingSystemType && UnderlyingSystemType != null)
-                return Type.GetTypeCode(UnderlyingSystemType);
+            Type systemType = UnderlyingSystemType;
+            if (this != systemType && systemType != null)
+                return Type.GetTypeCode(systemType);

             return TypeCode.Object;
         }


Use player prefs to store chilli details

--- UnitySamples/TicTacToe/Assets/Scripts/ChilliConnectDataController.cs
+++ UnitySamples/TicTacToe/Assets/Scripts/ChilliConnectDataController.cs
@@ -50,7 +50,7 @@
         gameController.onSideSelected += CreateNewGame;
         gameController.onTurnEnded += UpdateChilliConnectGameState;
 		onGameStateRetrievedFromServer += InitialiseGameController;
-        chilliConnect = new ChilliConnectSdk("wggM8r8m9qTUr1IHO9pr6sNqrrWTs8Xg", false);
+		chilliConnect = new ChilliConnectSdk("Vv7VANzImRtEUeiYaoz4lWKqB6t349iy", false);
         chilliConnectGameState = new ChilliConnectGameState();
         LoadOrCreatePlayerData();
     }
@@ -112,46 +112,31 @@
 	bool LoadPlayerData()
 	{
 		gameController.ShowChilliInfoPanel (k_message_loadingPlayerData);
-		bool success = true;
-		if (File.Exists(fileName))
-		{
-			StreamReader reader = File.OpenText(fileName);
-
-			// We saved the file out in this specific order
-			m_chilliConnectId = reader.ReadLine();
-			m_chilliConnectSecret = reader.ReadLine();
-			reader.Close();
-
-			if (onReadyToLogIn != null)
+
+		var chilliConnectId = PlayerPrefs.GetString ("ChilliConnectID");
+		var chilliConnectSecret = PlayerPrefs.GetString ("ChilliConnectSecret");
+
+		if (chilliConnectId != null && chilliConnectSecret != null)
+		{
+			m_chilliConnectId = chilliConnectId;
+			m_chilliConnectSecret = chilliConnectSecret;
+			if (onReadyToLogIn != null)
 			{
 				onReadyToLogIn.Invoke();
 			}
+
+			return true;
 		}
-		else
-		{
-			Debug.Log("Could not Open the file: " + fileName + " for reading.");
-			success = false;
-		}
-		return success;
+
+		return false;
 	}

 	/// Saves player account data to file
 	///
 	void SavePlayerData(string id, string secret)
 	{
-		if (File.Exists(fileName))
-		{
-			Debug.Log(fileName + " already exists.");
-		}
-		else
-		{
-			var sr = File.CreateText(fileName);
-			sr.WriteLine(id);
-			sr.WriteLine(secret);
-			sr.Close();
-
-			Debug.Log(fileName + " saved successfully.");
-		}
+		PlayerPrefs.SetString("ChilliConnectID", id);
+		PlayerPrefs.SetString("ChilliConnectSecret", secret);
 	}

 	/// Creates a player account and logs it into chilli connect


[Programar em C#/33-Construtores.cs] Add


Sample fixed

Sample fixed

--- src/Takenet.Elephant.Samples/Set/RedisDataset.cs
+++ src/Takenet.Elephant.Samples/Set/RedisDataset.cs
@@ -6,7 +6,7 @@
     public class RedisDataSet : RedisSet<Data>, IDataSet
     {
         public RedisDataSet()
-            : base("data", "localhost", new ValueSerializer<Data>(), true)
+            : base("data", "localhost", new ValueSerializer<Data>(), useScanOnEnumeration: true)
         {
         }
     }


Doc comments for FileStreamResource

Doc comments for FileStreamResource

--- src/Tasks/ResourceHandling/FileStreamResource.cs
+++ src/Tasks/ResourceHandling/FileStreamResource.cs
@@ -20,6 +20,13 @@
         public string OriginatingFile { get; }
         public string FileName { get; }

+        /// <summary>
+        /// Construct a new linked resource.
+        /// </summary>
+        /// <param name="name">The resource's name</param>
+        /// <param name="typeName">The assembly-qualified type name of the resource (at runtime).</param>
+        /// <param name="fileName">The absolute path of the file to be embedded as a resource.</param>
+        /// <param name="originatingFile">The absolute path of the file that defined the ResXFileRef to this resource.</param>
         public FileStreamResource(string name, string typeName, string fileName, string originatingFile)
         {
             Name = name;


1131.1: tiger_whiskers

1131.1: tiger_whiskers

--- src/Tests/TestSamples/Sample03/T108_LionFill2.cs
+++ src/Tests/TestSamples/Sample03/T108_LionFill2.cs
@@ -23,8 +23,11 @@
         protected override void OnReadyForInitGLShaderProgram()
         {

-            VgRenderVx svgRenderVx = SvgRenderVxLoader.CreateSvgRenderVxFromFile("Samples/lion.svg");
-            lionShape = new SpriteShape(svgRenderVx);
+            //string sampleFile = "Samples/lion.svg";
+            string sampleFile = "Samples/tiger_whiskers.svg";
+
+            VgRenderVx svgRenderVx = SvgRenderVxLoader.CreateSvgRenderVxFromFile(sampleFile);
+            lionShape = new SpriteShape(svgRenderVx);
             //flip this lion vertically before use with openGL
             PixelFarm.CpuBlit.VertexProcessing.Affine aff = PixelFarm.CpuBlit.VertexProcessing.Affine.NewMatix(
                  PixelFarm.CpuBlit.VertexProcessing.AffinePlan.Scale(1, -1),


Fixes paging and uses the same Serilog Expression filtering when setting up loggers to query the same LogEvents loaded into memory * StartsWith(SourceContext, 'Umbraco.Core') * StartsWith(SourceContext, 'Umbraco.Core') and @MessageTemplate='[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)' * @MessageTemplate='[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)' and TimingDuration > 1000

--- src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs
+++ src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs
@@ -3,6 +3,7 @@
 using System.IO;
 using System.Linq;
 using Serilog.Events;
+using Serilog.Filters.Expressions;
 using Serilog.Formatting.Compact.Reader;
 using Umbraco.Core.Models;
 using Umbraco.Core.Persistence.DatabaseModelDefinitions;
@@ -84,17 +85,31 @@
             return templates;
         }

-        public PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, int pageNumber = 1, int pageSize = 100, Direction orderDirection = Direction.Descending)
+        public PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
+            int pageNumber = 1, int pageSize = 100,
+            Direction orderDirection = Direction.Descending,
+            string filterExpression = null)
         {
             //Get all logs into memory (Not sure this good or not)
             var logs = GetAllLogs(startDate, endDate);
+
+            //If we have a filter expression, apply it
+            if(string.IsNullOrEmpty(filterExpression) == false)
+            {
+                Func<LogEvent, bool> filter = null;
+                var eval = FilterLanguage.CreateFilter(filterExpression);
+                filter = evt => true.Equals(eval(evt));
+
+                logs = logs.Where(filter);
+            }
+
             long totalRecords = logs.Count();
             long pageIndex = pageNumber - 1;

-            //Skip, Take & Select
-            var logItems = logs
+            //Order By, Skip, Take & Select
+            IEnumerable<LogMessage> logMessages = logs
                 .OrderBy(l => l.Timestamp, orderDirection)
-                .Skip(pageSize * pageNumber)
+                .Skip(pageSize * (pageNumber -1))
                 .Take(pageSize)
                 .Select(x => new LogMessage {
                     Timestamp = x.Timestamp,
@@ -107,7 +122,7 @@

             return new PagedResult<LogMessage>(totalRecords, pageNumber, pageSize)
             {
-                Items = logItems
+                Items = logMessages
             };
         }
     }


fixed a keyword issue

fixed a keyword issue

--- src/Vibrant.QuerySearch/DefaultFilterProvider.cs
+++ src/Vibrant.QuerySearch/DefaultFilterProvider.cs
@@ -81,35 +81,51 @@
          }

          // create predicate1 OR predicate2 as currentBody
-         Expression<Func<TEntity, bool>> currentBody = null;
+         Expression<Func<TEntity, bool>> textPredicate = null;
          if( predicate1 != null && predicate2 != null )
          {
-            currentBody = predicate1.Or( predicate2 );
+            textPredicate = predicate1.Or( predicate2 );
          }
          else if( predicate1 != null )
          {
-            currentBody = predicate1;
+            textPredicate = predicate1;
          }
          else if( predicate2 != null )
          {
-            currentBody = predicate2;
+            textPredicate = predicate2;
          }

          // All of the remaining filters are required
          var localizations = GetLocalizationDictionary();
+         Expression<Func<TEntity, bool>> keywordPredicate = null;
          foreach( var word in words )
          {
             Expression<Func<TEntity, bool>> predicate;
             if( _predefinedPredicates.TryGetValue( word, out predicate ) )
             {
-               currentBody = AddExpression( currentBody, predicate, ExpressionType.AndAlso );
+               keywordPredicate = AddExpression( keywordPredicate, predicate, ExpressionType.AndAlso );
             }

             Expression<Func<TEntity, bool>> localizedPredicate;
             if( localizations.TryGetValue( word, out localizedPredicate ) )
             {
-               currentBody = AddExpression( currentBody, localizedPredicate, ExpressionType.AndAlso );
-            }
+               keywordPredicate = AddExpression( keywordPredicate, localizedPredicate, ExpressionType.AndAlso );
+            }
+         }
+
+         // create textPredicate OR keywordPredicate as currentBody
+         Expression<Func<TEntity, bool>> currentBody = null;
+         if( textPredicate != null && keywordPredicate != null )
+         {
+            currentBody = predicate1.Or( predicate2 );
+         }
+         else if( textPredicate != null )
+         {
+            currentBody = textPredicate;
+         }
+         else if( keywordPredicate != null )
+         {
+            currentBody = keywordPredicate;
          }

          var parameters = filteringForm.GetAdditionalFilters();


Migrations trial clean up

Migrations trial clean up


Disable BuildTaskSimpleCodeFactory test only on netcore

--- src/XMakeTasks/UnitTests/CodeTaskFactoryTests.cs
+++ src/XMakeTasks/UnitTests/CodeTaskFactoryTests.cs
@@ -109,7 +109,11 @@
         /// being in MSBuildToolsPath anymore, that this does NOT affect full fusion AssemblyNames --
         /// it's picked up from the GAC, where it is anyway, so there's no need to redirect.
         /// </summary>
+#if RUNTIME_TYPE_NETCORE
         [Fact(Skip = "FEATURE: LEGACY TASKS")]
+#else
+        [Fact]
+#endif
         public void BuildTaskSimpleCodeFactory_NoAssemblyNameRedirect()
         {
             string projectFileContents = @"


46-improve fetch button

46-improve fetch button


cleanup code

cleanup code

--- benchmark/Benchmark.cs
+++ benchmark/Benchmark.cs
@@ -64,7 +64,7 @@
             byte[] buf = new byte[EncodeSize];
             buf[0] = 1;
             buf[EncodeSize - 1] = 1; // avoid all-zero optimizations of Base58
-            Stopwatch w = Stopwatch.StartNew();
+            var w = Stopwatch.StartNew();
             for (int n = 0; n < Iterations; n++)
             {
                 EncodeFunc(buf);
@@ -76,7 +76,7 @@
         public void TestDecode()
         {
             string str = new String('a', DecodeSize);
-            Stopwatch w = Stopwatch.StartNew();
+            var w = Stopwatch.StartNew();
             for (int n = 0; n < Iterations; n++)
             {
                 DecodeFunc(str);


Create vol_01.cs

Create vol_01.cs

--- vol_01.cs
+++ vol_01.cs
@@ -1 +1,8 @@
+using System;

+namespace vol
+{
+  public class MyClass()
+  {
+  }
+}


symmetry check is optional (no check by default), only elements below diagonal are used

--- ACQ.Math/Linalg/CholeskyDecomposition.cs
+++ ACQ.Math/Linalg/CholeskyDecomposition.cs
@@ -13,15 +13,22 @@
     ///		lower triangular matrix L so that >A = L * L'.
     ///		If the matrix is not symmetric or positive definite, the constructor returns a partial
     ///		decomposition and sets two internal variables that can be queried using the
-    ///		Symmetric and PositiveDefinite properties.
+    ///		 PositiveDefinite property.
+    ///
+    /// TODO: consider adding tolerance to check for positivity, and pivoting
     ///	</remarks>
     public class CholeskyDecomposition
     {
         private Matrix m_l;
-        private bool m_symPosDef; //symmetric and positive definite
-
-        /// Construct a Cholesky Decomposition.
-        public CholeskyDecomposition(Matrix A)
+        private bool m_positiveDefinite; // positive definite (only symmetric matrix can be positive definite)
+        //it is possible to extend definition of "positive definite" to include some non-symmetric real matrices, but we dont need it here
+
+        ///
+        /// Construct a Cholesky Decomposition
+        ///
+        /// <param name="A"></param>
+        /// <param name="checkSymmetry">check if matrix is symmetric, if not use elements below diagonal and assume that it is symmetric</param>
+        public CholeskyDecomposition(Matrix A, bool checkSymmetry = false)
         {
             if (A == null)
             {
@@ -39,8 +46,8 @@
             double[,] a = A.Data;
             double[,] l = m_l.Data;

-            m_symPosDef = (A.Columns == n);
-
+            m_positiveDefinite = (A.Columns == n); //only symmetric can be positive definite
+
             for (int j = 0; j < n; j++)
             {
                 double d = 0.0;
@@ -54,13 +61,19 @@
                     l[j, k] = s = (a[j, k] - s) / l[k, k];
                     d = d + s * s;

-                    m_symPosDef = m_symPosDef && (a[k, j] == a[j, k]);
+                    if (checkSymmetry) //Symmetry check, does not work very well with floating numbers because of truncation errors
+                    {
+                        m_positiveDefinite = m_positiveDefinite && (a[k, j] == a[j, k]);
+                    }
                 }

                 d = a[j, j] - d;

-                m_symPosDef = m_symPosDef & (d > 0.0);
+                //Positive-definite: d > 0,  Positive-semidefinite d >= 0
+                m_positiveDefinite = m_positiveDefinite & (d > 0.0);
+
                 l[j,j] = System.Math.Sqrt(System.Math.Max(d, 0.0));
+
                 for (int k = j + 1; k < n; k++)
                 {
                     l[j, k] = 0.0;
@@ -68,12 +81,12 @@
             }
         }

-        /// Returns true if the matrix is symmetric.
-        public bool IsSymmetricAndPositiveDefinite
+        /// Returns true if the matrix is symmetric and positive definite.
+        public bool IsPositiveDefinite
         {
             get
             {
-                return m_symPosDef;
+                return m_positiveDefinite;
             }
         }

@@ -99,9 +112,9 @@
                 throw new ArgumentException("Matrix dimensions do not match.");
             }

-            if (!IsSymmetricAndPositiveDefinite)
+            if (!IsPositiveDefinite)
             {
-                throw new InvalidOperationException("Matrix is not symmetric and positive definite.");
+                throw new InvalidOperationException("Matrix is not positive definite.");
             }

             int n = m_l.Rows;


Fix active menu if the page doesn't belong to a menu

--- src/Lunet.Menus/MenuObject.cs
+++ src/Lunet.Menus/MenuObject.cs
@@ -148,7 +148,8 @@
             string menuId = $"{kind}-id-{root.Name}-{index}";

             bool isCurrentPageInMenuPath = false;
-            var currentMenu = page["menu"] as MenuObject;
+            var rootMenu = page["menu"] as MenuObject;
+            var currentMenu = rootMenu;
             while (currentMenu != null)
             {
                 if (currentMenu.Page == Page)
@@ -212,6 +213,13 @@
                 }
             }

+
+            // If the page is not in a menu, try to recover it from the same section
+            if (!string.IsNullOrEmpty(page.Section) && page["menu"] == null && page.Section == Page?.Section)
+            {
+                isActive = true;
+            }
+
             bool isBreadcrumb = kind == "breadcrumb";

             var thisLinkItemClass = this["list_item_class"];


Removed: IDisposable base test

Removed: IDisposable base test

--- Algolia.Search.Test/BaseTest/BaseTest.cs
+++ Algolia.Search.Test/BaseTest/BaseTest.cs
@@ -29,7 +29,7 @@

 namespace Algolia.Search.Test
 {
-    public class BaseTest : IDisposable
+    public class BaseTest
     {
         protected SearchClient _client;
         protected SearchIndex _index;
@@ -47,10 +47,5 @@
                 ? name
                 : $"{name}-appveyor-{Environment.GetEnvironmentVariable("APPVEYOR_BUILD_NUMBER")}";
         }
-
-        public void Dispose()
-        {
-            // Todo : clear index
-        }
     }
 }


Only warn about unhandled decorations in the editor.

--- Assets/Scripts/MapGen/Items/ItemModel.cs
+++ Assets/Scripts/MapGen/Items/ItemModel.cs
@@ -96,7 +96,9 @@
                 case ImprovementType.ILLUSTRATION:
                 case ImprovementType.INSTRUMENT_PIECE:
                 default:
+#if UNITY_EDITOR
                     Debug.LogWarning(string.Format("Unhandled improvement {0} on {1}", improvement.type, GO.name));
+#endif
                     break;
             }
         }


Small oeps on the mouse script fixed

Small oeps on the mouse script fixed

--- Assets/Scripts/MouseSensitivityScript.cs
+++ Assets/Scripts/MouseSensitivityScript.cs
@@ -9,6 +9,7 @@

     void Awake() {
         sensitivityPercentage = PlayerPrefs.GetInt("sensitivity", 50);
+        changeSensitivity(0);
     }

     void Update() {


Fix microgame pool override code in CompilationStage


Add WithException tests to BeCompletedResultTest

--- projects/FluentSample/test/FluentSample.Test.Unit/BeCompletedResultTest.cs
+++ projects/FluentSample/test/FluentSample.Test.Unit/BeCompletedResultTest.cs
@@ -134,5 +134,45 @@

             act.ShouldNotThrow();
         }
+
+        [TestMethod]
+        public void ShouldAllowChainingWithTypedException()
+        {
+            Task<bool> task = TaskResultBuilder.Faulted();
+
+            Action act = () => task.Should().BeCompleted().WithException<InvalidCastException>().WithMessage("Expected failure.");
+
+            act.ShouldNotThrow();
+        }
+
+        [TestMethod]
+        public void WithExceptionShouldPassIfAtLeastOneExceptionMatches()
+        {
+            Task<bool> task = TaskResultBuilder.Faulted(new InvalidCastException("Expected failure."), new InvalidProgramException("Other expected failure."));
+
+            Action act = () => task.Should().BeCompleted().WithException<InvalidCastException>().WithMessage("Expected failure.");
+
+            act.ShouldNotThrow();
+        }
+
+        [TestMethod]
+        public void WithExceptionShouldFailIfNoExceptionMatches()
+        {
+            Task<bool> task = TaskResultBuilder.Faulted(new InvalidOperationException("Unexpected failure."));
+
+            Action act = () => task.Should().BeCompleted().WithException<InvalidCastException>().WithMessage("Expected failure.");
+
+            act.ShouldThrow<AssertFailedException>().WithMessage("Expected a <System.InvalidCastException> to be thrown, but found a*System.InvalidOperationException with message \"Unexpected failure.\"*");
+        }
+
+        [TestMethod]
+        public void WithExceptionShouldFailOnNullException()
+        {
+            Task<bool> task = TaskResultBuilder.Completed();
+
+            Action act = () => task.Should().BeCompleted().WithException<InvalidCastException>().WithMessage("Expected failure.");
+
+            act.ShouldThrow<AssertFailedException>().WithMessage("Expected a <System.InvalidCastException> to be thrown, but no exception was thrown.");
+        }
     }
 }