Remove superfluous tests for EmailAddressLocalPart.

--- Src/AutoFixtureUnitTest/EmailAddressLocalPartTest.cs
+++ Src/AutoFixtureUnitTest/EmailAddressLocalPartTest.cs
@@ -56,19 +56,6 @@
             // Teardown
         }

-        [Fact]
-        public void SutDoesNotEqualNullSut()
-        {
-            // Fixture setup
-            var sut = new EmailAddressLocalPart(Guid.NewGuid().ToString());
-            EmailAddressLocalPart other = null;
-            // Exercise system
-            bool result = sut.Equals(other);
-            // Verify outcome
-            Assert.False(result);
-            // Teardown
-        }
-
         [Fact]
         public void SutDoesNotEqualAnonymousObject()
         {
@@ -94,19 +81,6 @@
             Assert.False(result);
             // Teardown
         }
-
-        [Fact]
-        public void SutDoesNotEqualOtherSutWhenLocalPartsDiffer()
-        {
-            // Fixture setup
-            var sut = new EmailAddressLocalPart(Guid.NewGuid().ToString());
-            var other = new EmailAddressLocalPart(Guid.NewGuid().ToString());
-            // Exercise system
-            bool result = sut.Equals(other);
-            // Verify outcome
-            Assert.False(result);
-            // Teardown
-        }

         [Fact]
         public void SutEqualsOtherSutWhenLocalPartsAreEqual()


http client on mono needs uri scheme specified

--- Src/Metrics.Tests/OwinAdapter/OwinMetricsTestData.cs
+++ Src/Metrics.Tests/OwinAdapter/OwinMetricsTestData.cs
@@ -76,14 +76,14 @@

             ExpectedResults = new OwinExpectedMetrics(timePerRequest, 6, 1);

-            server.HttpClient.GetAsync("/test/error").Result.StatusCode.Should().Be(HttpStatusCode.InternalServerError);
-            server.HttpClient.GetAsync("/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
-            server.HttpClient.GetAsync("/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
-            server.HttpClient.GetAsync("/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
-            server.HttpClient.GetAsync("/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
+            server.HttpClient.GetAsync("http://local.test/test/error").Result.StatusCode.Should().Be(HttpStatusCode.InternalServerError);
+            server.HttpClient.GetAsync("http://local.test/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
+            server.HttpClient.GetAsync("http://local.test/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
+            server.HttpClient.GetAsync("http://local.test/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
+            server.HttpClient.GetAsync("http://local.test/test/action").Result.StatusCode.Should().Be(HttpStatusCode.OK);
             var postContent = new StringContent(json);
             postContent.Headers.Add("Content-Length", json.Length.ToString());
-            server.HttpClient.PostAsync("/test/post", postContent);
+            server.HttpClient.PostAsync("http://local.test/test/post", postContent);
         }
     }
 }


Fix test failure on Mono

Fix test failure on Mono

Mono's HttpHeaders.Add rejects valid values for ETag that we use in
our tests. https://bugzilla.xamarin.com/show_bug.cgi?id=39569

--- Src/Support/GoogleApis/Apis/Requests/BatchRequest.cs
+++ Src/Support/GoogleApis/Apis/Requests/BatchRequest.cs
@@ -283,7 +283,14 @@
                     {
                         headers = response.Content.Headers;
                     }
-                    headers.Add(keyValue.Key, keyValue.Value);
+
+                    // Use TryAddWithoutValidation rather than Add because Mono's validation is
+                    // improperly strict. https://bugzilla.xamarin.com/show_bug.cgi?id=39569
+                    if (!headers.TryAddWithoutValidation(keyValue.Key, keyValue.Value))
+                    {
+                        throw new FormatException(String.Format(
+                            "Could not parse header {0} from batch reply", keyValue.Key));
+                    }
                 }

                 // TODO(peleyal): ContentLength header is x while the "real" content that we read from the stream is


Random positions now have pre-definied points

--- StroopTest/Views/MatchingPages/MatchingExposition.cs
+++ StroopTest/Views/MatchingPages/MatchingExposition.cs
@@ -338,6 +338,101 @@
                         throw new InvalidOperationException();
                 }
                 return position;
+            }
+            public static Point getRandomPosition(Size clientSize, Size stimuluSize)
+            {
+                float[] clientMiddle = { (clientSize.Width / 2), (clientSize.Height / 2) };
+                Point p = new Point();
+                Random rng = new Random(Guid.NewGuid().GetHashCode());
+                int number = rng.Next(21);
+                    switch (number)
+                    {
+                        case 0:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 1:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4); ;
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 2:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 3:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 4:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 5:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 6:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 7:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 8:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 9:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 10:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 11:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4); ;
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) - (int)(clientMiddle[Y] / 2);
+                            break;
+                        case 12:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 13:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 14:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 15:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 16:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 17:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 18:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) + (int)(clientMiddle[X] / 2) + (int)(clientMiddle[X] / 4); ;
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 19:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2) - (int)(clientMiddle[X] / 4);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2);
+                            break;
+                        case 20:
+                            p.X = (int)clientMiddle[X] - (stimuluSize.Width / 2) - (int)(clientMiddle[X] / 2);
+                            p.Y = (int)clientMiddle[Y] - (stimuluSize.Height / 2) + (int)(clientMiddle[Y] / 2);
+                            break;
+                    }
+                return p;
             }
             public static string getStimuluPositionMap(Point position, Size clientSize, Size stimuluSize)
             {
@@ -916,8 +1011,7 @@
                 newPicBox.Size = new Size(executingTest.ProgramInUse.StimuluSize, executingTest.ProgramInUse.StimuluSize);
                 if (this.executingTest.ProgramInUse.RandomPosition)
                 {
-                    int[] screenPosition = randomScreenPosition(newPicBox.Size);
-                    newPicBox.Location = new Point(screenPosition[X], screenPosition[Y]);
+                    newPicBox.Location = StimuluPosition.getRandomPosition(ClientSize, newPicBox.Size);
                 }
                 else
                 {


add VirtualHost#TryMatch overload with callback instead of "out" argument

--- Core/VirtualHost.cs
+++ Core/VirtualHost.cs
@@ -72,6 +72,7 @@
         /// virtual host's domain.
         /// </summary>
         /// <param name="host">The hostname to attempt to match.</param>
+        /// <param name="port">The port to attempt to match to.</param>
         /// <param name="parameters">
         ///     The parameters extracted from the format string and
         ///     provided hostname
@@ -98,5 +99,22 @@
                     )
                 && (port == this.Port);
         }
+        /// <summary>
+        /// Attempts to match the provided host with this
+        /// virtual host's domain.
+        /// </summary>
+        /// <param name="host">The hostname to attempt to match.</param>
+        /// <param name="port">The port to attempt to match to.</param>
+        /// <param name="callback">A callback that is passed any parameters.</param>
+        /// <returns>True if the provided hostname is a match.</returns>
+        public bool TryMatch(string host, ushort port, Action<dynamic> callback)
+        {
+            dynamic parameters;
+            bool success = this.TryMatch(host, port, out parameters);
+
+            if (success) callback(parameters);
+
+            return success;
+        }
     }
 }


Read Exif orientation and transform image data accordingly.

Since the Exif data isn't automatically applied during opening
of the image file we need to do that manually.

--- CyclesBackground.cs
+++ CyclesBackground.cs
@@ -20,6 +20,7 @@
 using System.Drawing.Imaging;
 using System.IO;
 using System.Text;
+using System.Collections.Generic;
 using Rhino;
 using Rhino.Display;
 using Rhino.DocObjects;
@@ -327,6 +328,44 @@
 				{
 					newBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
 				}
+				const int ExifOrientationId = 0x112;
+				List<int> propertyIdList = new List<int>(bm.PropertyIdList);
+				// Read orientation tag
+				if (propertyIdList.Contains(ExifOrientationId))
+				{
+					var prop = bm.GetPropertyItem(ExifOrientationId);
+					var orient = BitConverter.ToInt16(prop.Value, 0);
+					switch(orient)
+					{
+						case 1:
+							newBitmap.RotateFlip(RotateFlipType.RotateNoneFlipNone);
+							break;
+						case 2:
+							newBitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
+							break;
+						case 3:
+							newBitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
+							break;
+						case 4:
+							newBitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
+							break;
+						case 5:
+							newBitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
+							break;
+						case 6:
+							newBitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
+							break;
+						case 7:
+							newBitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
+							break;
+						case 8:
+							newBitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
+							break;
+						default:
+							newBitmap.RotateFlip(RotateFlipType.RotateNoneFlipNone);
+							break;
+					}
+				}
 				var wallpaperbm = _bitmapConverter.ReadByteBitmapFromBitmap(crc, newBitmap.Size.Width, newBitmap.Size.Height, newBitmap, false);
 				wallpaperbm.ApplyGamma(Gamma);
 				Wallpaper.TexByte = wallpaperbm.Data as SimpleArrayByte;


Simplify scaling code for wallpaper image.

The initial implementation was flawed. It would
correctly calculated scaled dimensions for the
wallpaper image only in a very few cases.

In many cases it would result in blown up wall-
paper images.

--- CyclesBackground.cs
+++ CyclesBackground.cs
@@ -154,26 +154,19 @@
 				var w = Math.Abs(right - left);
 				var h = Math.Abs(bottom - top);
 				Bitmap bm = new Bitmap(view.WallpaperFilename);
-				var ar = (float) bm.Size.Width/bm.Size.Height;
-				int nw = 0;
-				int nh = 0;
+				var ar = (float) bm.Width/bm.Height;
+				var fac = 1.0f;
 				if (ar < 1.0f)
 				{
-					var fac = (h/(float)bm.Size.Height);
-					nw = (int)(w * fac);
-					nh = h;
+					fac = (h/(float)bm.Height);
 				}
 				else if (ar > 1.0f)
 				{
-					var fac = (w/(float)bm.Size.Width);
-					nh = (int) (h * fac);
-					nw = w;
-				}
-				else
-				{
-					nw = w;
-					nh = h;
-				}
+					fac = (w/(float)bm.Width);
+				}
+
+				int nw = (int)(bm.Width * fac);
+				int nh = (int)(bm.Height * fac);
 				int x = (w - nw)/2;
 				int y = (h - nh)/2;
 				Bitmap newBitmap = new Bitmap(w, h);


Don't instantiate the various core gallery pages until we actually need them

--- Xamarin.Forms.Controls/CoreGallery.cs
+++ Xamarin.Forms.Controls/CoreGallery.cs
@@ -215,136 +215,156 @@
 		}
 	}

+
+
 	internal class CorePageView : ListView
 	{
+		internal class GalleryPageFactory
+		{
+			public GalleryPageFactory(Func<Page> create, string title)
+			{
+				Realize = () =>
+				{
+					var p = create();
+					p.Title = title;
+					return p;
+				};
+
+				Title = title;
+			}
+
+			public Func<Page> Realize { get; set; }
+			public string Title { get; set; }
+		}
+
+		List<GalleryPageFactory> _pages = new List<GalleryPageFactory> {
+				new GalleryPageFactory(() => new PlatformSpecificsGallery(), "Platform Specifics"),
+				new GalleryPageFactory(() => new NativeBindingGalleryPage(), "Native Binding Controls Gallery"),
+				new GalleryPageFactory(() => new XamlNativeViews(), "Xaml Native Views Gallery"),
+				new GalleryPageFactory(() => new AppLinkPageGallery(), "App Link Page Gallery"),
+				new GalleryPageFactory(() => new NestedNativeControlGalleryPage(), "Nested Native Controls Gallery"),
+				new GalleryPageFactory(() => new CellForceUpdateSizeGalleryPage(), "Cell Force Update Size Gallery"),
+				new GalleryPageFactory(() => new AppearingGalleryPage(), "Appearing Gallery"),
+				new GalleryPageFactory(() => new EntryCoreGalleryPage(), "Entry Gallery"),
+				new GalleryPageFactory(() => new NavBarTitleTestPage(), "Titles And Navbar Windows"),
+				new GalleryPageFactory(() => new PanGestureGalleryPage(), "Pan gesture Gallery"),
+				new GalleryPageFactory(() => new PinchGestureTestPage(), "Pinch gesture Gallery"),
+				new GalleryPageFactory(() => new AutomationIdGallery(), "AutomationID Gallery"),
+				new GalleryPageFactory(() => new LayoutPerformanceGallery(), "Layout Perf Gallery"),
+				new GalleryPageFactory(() => new ListViewSelectionColor(), "ListView SelectionColor Gallery"),
+				new GalleryPageFactory(() => new AlertGallery(), "DisplayAlert Gallery"),
+				new GalleryPageFactory(() => new ToolbarItems(), "ToolbarItems Gallery"),
+				new GalleryPageFactory(() => new ActionSheetGallery(), "ActionSheet Gallery"),
+				new GalleryPageFactory(() => new ActivityIndicatorCoreGalleryPage(), "ActivityIndicator Gallery"),
+				new GalleryPageFactory(() => new BehaviorsAndTriggers(), "BehaviorsTriggers Gallery"),
+				new GalleryPageFactory(() => new ContextActionsGallery(), "ContextActions List Gallery"),
+				new GalleryPageFactory(() => new ContextActionsGallery (tableView: true), "ContextActions Table Gallery"),
+				new GalleryPageFactory(() => new CoreBoxViewGalleryPage(), "BoxView Gallery"),
+				new GalleryPageFactory(() => new ButtonCoreGalleryPage(), "Button Gallery"),
+				new GalleryPageFactory(() => new DatePickerCoreGalleryPage(), "DatePicker Gallery"),
+				new GalleryPageFactory(() => new EditorCoreGalleryPage(), "Editor Gallery"),
+				new GalleryPageFactory(() => new FrameCoreGalleryPage(), "Frame Gallery"),
+				new GalleryPageFactory(() => new ImageCoreGalleryPage(), "Image Gallery"),
+				new GalleryPageFactory(() => new KeyboardCoreGallery(), "Keyboard Gallery"),
+				new GalleryPageFactory(() => new LabelCoreGalleryPage(), "Label Gallery"),
+				new GalleryPageFactory(() => new ListViewCoreGalleryPage(), "ListView Gallery"),
+				new GalleryPageFactory(() => new OpenGLViewCoreGalleryPage(), "OpenGLView Gallery"),
+				new GalleryPageFactory(() => new PickerCoreGalleryPage(), "Picker Gallery"),
+				new GalleryPageFactory(() => new ProgressBarCoreGalleryPage(), "ProgressBar Gallery"),
+				new GalleryPageFactory(() => new ScrollGallery(), "ScrollView Gallery"),
+				new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
+				new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Both), "ScrollView Gallery 2D"),
+				new GalleryPageFactory(() => new SearchBarCoreGalleryPage(), "SearchBar Gallery"),
+				new GalleryPageFactory(() => new SliderCoreGalleryPage(), "Slider Gallery"),
+				new GalleryPageFactory(() => new StepperCoreGalleryPage(), "Stepper Gallery"),
+				new GalleryPageFactory(() => new SwitchCoreGalleryPage(), "Switch Gallery"),
+				new GalleryPageFactory(() => new TableViewCoreGalleryPage(), "TableView Gallery"),
+				new GalleryPageFactory(() => new TimePickerCoreGalleryPage(), "TimePicker Gallery"),
+				new GalleryPageFactory(() => new WebViewCoreGalleryPage(), "WebView Gallery"),
+				//pages
+ 				new GalleryPageFactory(() => new RootContentPage ("Content"), "RootPages Gallery"),
+				new GalleryPageFactory(() => new MasterDetailPageTabletPage(), "MasterDetailPage Tablet Page"),
+				// legacy galleries
+				new GalleryPageFactory(() => new AbsoluteLayoutGallery(), "AbsoluteLayout Gallery - Legacy"),
+				new GalleryPageFactory(() => new BoundContentPage(), "BoundPage Gallery - Legacy"),
+				new GalleryPageFactory(() => new BackgroundImageGallery(), "BackgroundImage gallery"),
+				new GalleryPageFactory(() => new ButtonGallery(), "Button Gallery - Legacy"),
+				new GalleryPageFactory(() => new CarouselPageGallery(), "CarouselPage Gallery - Legacy"),
+				new GalleryPageFactory(() => new CellTypesListPage(), "Cells Gallery - Legacy"),
+				new GalleryPageFactory(() => new ClipToBoundsGallery(), "ClipToBounds Gallery - Legacy"),
+				new GalleryPageFactory(() => new ControlTemplatePage(), "ControlTemplated Gallery - Legacy"),
+				new GalleryPageFactory(() => new ControlTemplateXamlPage(), "ControlTemplated XAML Gallery - Legacy"),
+				new GalleryPageFactory(() => new DisposeGallery(), "Dispose Gallery - Legacy"),
+				new GalleryPageFactory(() => new EditorGallery(), "Editor Gallery - Legacy"),
+				new GalleryPageFactory(() => new EntryGallery(), "Entry Gallery - Legacy"),
+				new GalleryPageFactory(() => new FrameGallery (), "Frame Gallery - Legacy"),
+				new GalleryPageFactory(() => new GridGallery(), "Grid Gallery - Legacy"),
+				new GalleryPageFactory(() => new GroupedListActionsGallery(), "GroupedListActions Gallery - Legacy"),
+				new GalleryPageFactory(() => new GroupedListContactsGallery(), "GroupedList Gallery - Legacy"),
+				new GalleryPageFactory(() => new ImageGallery (), "Image Gallery - Legacy"),
+				new GalleryPageFactory(() => new ImageLoadingGallery (), "ImageLoading Gallery - Legacy"),
+				new GalleryPageFactory(() => new InputIntentGallery(), "InputIntent Gallery - Legacy"),
+				new GalleryPageFactory(() => new LabelGallery(), "Label Gallery - Legacy"),
+				new GalleryPageFactory(() => new LayoutAddPerformance(), "Layout Add Performance - Legacy"),
+				new GalleryPageFactory(() => new LayoutOptionsGallery(), "LayoutOptions Gallery - Legacy"),
+				new GalleryPageFactory(() => new LineBreakModeGallery(), "LineBreakMode Gallery - Legacy"),
+				new GalleryPageFactory(() => new ListPage(), "ListView Gallery - Legacy"),
+				new GalleryPageFactory(() => new ListScrollTo(), "ListView.ScrollTo"),
+				new GalleryPageFactory(() => new ListRefresh(), "ListView.PullToRefresh"),
+				new GalleryPageFactory(() => new ListViewDemoPage(), "ListView Demo Gallery - Legacy"),
+				new GalleryPageFactory(() => new MapGallery(), "Map Gallery - Legacy"),
+				new GalleryPageFactory(() => new MinimumSizeGallery(), "MinimumSize Gallery - Legacy"),
+				new GalleryPageFactory(() => new MultiGallery(), "Multi Gallery - Legacy"),
+				new GalleryPageFactory(() => new NavigationMenuGallery(), "NavigationMenu Gallery - Legacy"),
+				new GalleryPageFactory(() => new NavigationPropertiesGallery(), "Navigation Properties"),
+#if HAVE_OPENTK
+				new GalleryPageFactory(() => new OpenGLGallery(), "OpenGLGallery - Legacy"),
+#endif
+				new GalleryPageFactory(() => new PickerGallery(), "Picker Gallery - Legacy"),
+				new GalleryPageFactory(() => new ProgressBarGallery(), "ProgressBar Gallery - Legacy"),
+				new GalleryPageFactory(() => new RelativeLayoutGallery(), "RelativeLayout Gallery - Legacy"),
+				new GalleryPageFactory(() => new ScaleRotate(), "Scale Rotate Gallery - Legacy"),
+				new GalleryPageFactory(() => new SearchBarGallery(), "SearchBar Gallery - Legacy"),
+				new GalleryPageFactory(() => new SettingsPage(), "Settings Page - Legacy"),
+				new GalleryPageFactory(() => new SliderGallery(), "Slider Gallery - Legacy"),
+				new GalleryPageFactory(() => new StackLayoutGallery(), "StackLayout Gallery - Legacy"),
+				new GalleryPageFactory(() => new StepperGallery(), "Stepper Gallery - Legacy"),
+				new GalleryPageFactory(() => new StyleGallery(), "Style Gallery"),
+				new GalleryPageFactory(() => new StyleXamlGallery(), "Style Gallery in Xaml"),
+				new GalleryPageFactory(() => new SwitchGallery(), "Switch Gallery - Legacy"),
+				new GalleryPageFactory(() => new TableViewGallery(), "TableView Gallery - Legacy"),
+				new GalleryPageFactory(() => new TemplatedCarouselGallery(), "TemplatedCarouselPage Gallery - Legacy"),
+				new GalleryPageFactory(() => new TemplatedTabbedGallery(), "TemplatedTabbedPage Gallery - Legacy"),
+				 new GalleryPageFactory(() => new UnevenViewCellGallery(), "UnevenViewCell Gallery - Legacy"),
+				new GalleryPageFactory(() => new UnevenListGallery(), "UnevenList Gallery - Legacy"),
+				new GalleryPageFactory(() => new ViewCellGallery(), "ViewCell Gallery - Legacy"),
+				new GalleryPageFactory(() => new WebViewGallery(), "WebView Gallery - Legacy"),
+			};
+
 		public CorePageView (Page rootPage, NavigationBehavior navigationBehavior = NavigationBehavior.PushAsync)
 		{
-			var pages = new List<Page> {
-				new PlatformSpecificsGallery() {Title = "Platform Specifics"},
-				new NativeBindingGalleryPage {Title = "Native Binding Controls Gallery"},
-				new XamlNativeViews {Title = "Xaml Native Views Gallery"},
-				new AppLinkPageGallery {Title = "App Link Page Gallery"},
-				new NestedNativeControlGalleryPage {Title = "Nested Native Controls Gallery"},
-				new CellForceUpdateSizeGalleryPage {Title = "Cell Force Update Size Gallery"},
-				new AppearingGalleryPage {Title = "Appearing Gallery"},
-				new EntryCoreGalleryPage { Title = "Entry Gallery" },
-				new NavBarTitleTestPage {Title = "Titles And Navbar Windows"},
-				new PanGestureGalleryPage {Title = "Pan gesture Gallery"},
-				new PinchGestureTestPage {Title = "Pinch gesture Gallery"},
-				new AutomationIdGallery { Title ="AutomationID Gallery" },
-				new LayoutPerformanceGallery {Title = "Layout Perf Gallery"},
-				new ListViewSelectionColor { Title = "ListView SelectionColor Gallery" },
-				new AlertGallery { Title = "DisplayAlert Gallery" },
-				new ToolbarItems { Title = "ToolbarItems Gallery" },
-				new ActionSheetGallery { Title = "ActionSheet Gallery" },
-				new ActivityIndicatorCoreGalleryPage { Title = "ActivityIndicator Gallery" },
-				new BehaviorsAndTriggers { Title = "BehaviorsTriggers Gallery" },
-				new ContextActionsGallery { Title = "ContextActions List Gallery"},
-				new ContextActionsGallery (tableView: true) { Title = "ContextActions Table Gallery"},
-				new CoreBoxViewGalleryPage { Title = "BoxView Gallery" },
-				new ButtonCoreGalleryPage { Title = "Button Gallery" },
-				new DatePickerCoreGalleryPage { Title = "DatePicker Gallery" },
-				new EditorCoreGalleryPage { Title = "Editor Gallery" },
-				new FrameCoreGalleryPage { Title = "Frame Gallery" },
-				new ImageCoreGalleryPage { Title = "Image Gallery" },
-				new KeyboardCoreGallery { Title = "Keyboard Gallery" },
-				new LabelCoreGalleryPage { Title = "Label Gallery" },
-				new ListViewCoreGalleryPage { Title = "ListView Gallery" },
-				new OpenGLViewCoreGalleryPage { Title = "OpenGLView Gallery" },
-				new PickerCoreGalleryPage { Title = "Picker Gallery" },
-				new ProgressBarCoreGalleryPage { Title = "ProgressBar Gallery" },
-				new ScrollGallery { Title = "ScrollView Gallery" },
-				new ScrollGallery(ScrollOrientation.Horizontal) { Title = "ScrollView Gallery Horizontal" },
-				new ScrollGallery(ScrollOrientation.Both) { Title = "ScrollView Gallery 2D" },
-				new SearchBarCoreGalleryPage { Title = "SearchBar Gallery" },
-				new SliderCoreGalleryPage { Title = "Slider Gallery" },
-				new StepperCoreGalleryPage { Title = "Stepper Gallery" },
-				new SwitchCoreGalleryPage { Title = "Switch Gallery" },
-				new TableViewCoreGalleryPage { Title = "TableView Gallery" },
-				new TimePickerCoreGalleryPage { Title = "TimePicker Gallery" },
-				new WebViewCoreGalleryPage { Title = "WebView Gallery" },
-				//pages
- 				new RootContentPage ("Content") { Title = "RootPages Gallery" },
-				new MasterDetailPageTabletPage { Title = "MasterDetailPage Tablet Page" },
-				// legacy galleries
-				new AbsoluteLayoutGallery { Title = "AbsoluteLayout Gallery - Legacy" },
-				new BoundContentPage { Title = "BoundPage Gallery - Legacy" },
-				new BackgroundImageGallery { Title = "BackgroundImage gallery" },
-				new ButtonGallery { Title = "Button Gallery - Legacy" },
-				new CarouselPageGallery { Title = "CarouselPage Gallery - Legacy" },
-				new CellTypesListPage { Title = "Cells Gallery - Legacy" },
-				new ClipToBoundsGallery { Title = "ClipToBounds Gallery - Legacy" },
-				new ControlTemplatePage { Title = "ControlTemplated Gallery - Legacy" },
-				new ControlTemplateXamlPage { Title = "ControlTemplated XAML Gallery - Legacy" },
-				new DisposeGallery { Title = "Dispose Gallery - Legacy" },
-				new EditorGallery { Title = "Editor Gallery - Legacy" },
-				new EntryGallery { Title = "Entry Gallery - Legacy" },
-				new FrameGallery  { Title = "Frame Gallery - Legacy" },
-				new GridGallery { Title = "Grid Gallery - Legacy" },
-				new GroupedListActionsGallery { Title = "GroupedListActions Gallery - Legacy" },
-				new GroupedListContactsGallery { Title = "GroupedList Gallery - Legacy" },
-				new ImageGallery  { Title = "Image Gallery - Legacy" },
-				new ImageLoadingGallery  { Title = "ImageLoading Gallery - Legacy" },
-				new InputIntentGallery { Title = "InputIntent Gallery - Legacy" },
-				new LabelGallery { Title = "Label Gallery - Legacy" },
-				new LayoutAddPerformance { Title = "Layout Add Performance - Legacy" },
-				new LayoutOptionsGallery { Title = "LayoutOptions Gallery - Legacy" },
-				new LineBreakModeGallery { Title = "LineBreakMode Gallery - Legacy" },
-				new ListPage { Title = "ListView Gallery - Legacy" },
-				new ListScrollTo { Title = "ListView.ScrollTo" },
-				new ListRefresh { Title = "ListView.PullToRefresh" },
-				new ListViewDemoPage { Title = "ListView Demo Gallery - Legacy" },
-				new MapGallery { Title = "Map Gallery - Legacy" },
-				new MinimumSizeGallery { Title = "MinimumSize Gallery - Legacy" },
-				new MultiGallery { Title = "Multi Gallery - Legacy" },
-				new NavigationMenuGallery { Title = "NavigationMenu Gallery - Legacy" },
-				new NavigationPropertiesGallery { Title = "Navigation Properties" },
-#if HAVE_OPENTK
-				new OpenGLGallery { Title = "OpenGLGallery - Legacy" },
-#endif
-				new PickerGallery {Title = "Picker Gallery - Legacy"},
-				new ProgressBarGallery { Title = "ProgressBar Gallery - Legacy" },
-				new RelativeLayoutGallery { Title = "RelativeLayout Gallery - Legacy" },
-				new ScaleRotate { Title = "Scale Rotate Gallery - Legacy" },
-				new SearchBarGallery { Title = "SearchBar Gallery - Legacy" },
-				new SettingsPage { Title = "Settings Page - Legacy" },
-				new SliderGallery { Title = "Slider Gallery - Legacy" },
-				new StackLayoutGallery { Title = "StackLayout Gallery - Legacy" },
-				new StepperGallery { Title = "Stepper Gallery - Legacy" },
-				new StyleGallery {Title = "Style Gallery"},
-				new StyleXamlGallery {Title = "Style Gallery in Xaml"},
-				new SwitchGallery { Title = "Switch Gallery - Legacy" },
-				new TableViewGallery { Title = "TableView Gallery - Legacy" },
-				new TemplatedCarouselGallery { Title = "TemplatedCarouselPage Gallery - Legacy" },
-				new TemplatedTabbedGallery { Title = "TemplatedTabbedPage Gallery - Legacy" },
- 				new UnevenViewCellGallery { Title = "UnevenViewCell Gallery - Legacy" },
-				new UnevenListGallery { Title = "UnevenList Gallery - Legacy" },
-				new ViewCellGallery { Title = "ViewCell Gallery - Legacy" },
-				new WebViewGallery {Title = "WebView Gallery - Legacy"},
-			};
-
-			titleToPage = pages.ToDictionary (o => o.Title);
+			_titleToPage = _pages.ToDictionary (o => o.Title);

 			// avoid NRE for root pages without NavigationBar
 			if (navigationBehavior == NavigationBehavior.PushAsync && rootPage.GetType () == typeof (CoreNavigationPage)) {
-				pages.Add (new NavigationBarGallery ((NavigationPage)rootPage) { Title = "NavigationBar Gallery - Legacy" });
+				_pages.Add (new GalleryPageFactory(() => new NavigationBarGallery((NavigationPage)rootPage), "NavigationBar Gallery - Legacy"));
 			}

 			var template = new DataTemplate (typeof(TextCell));
 			template.SetBinding (TextCell.TextProperty, "Title");

-			BindingContext = pages;
+			BindingContext = _pages;
 			ItemTemplate = template;
-			ItemsSource = pages;
+			ItemsSource = _pages;

 			ItemSelected += async (sender, args) => {
 				if (SelectedItem == null)
 					return;

 				var item = args.SelectedItem;
-				var page = item as Page;
+				var page = item as GalleryPageFactory;
 				if (page != null)
-					await PushPage (page);
+					await PushPage (page.Realize());

 				SelectedItem = null;
 			};
@@ -367,13 +387,15 @@
 			}
 		}

-		Dictionary<string, Page> titleToPage = new Dictionary<string, Page>();
+		readonly Dictionary<string, GalleryPageFactory> _titleToPage;
 		public async Task PushPage (string pageTitle)
 		{

-			Page page = null;
-			if (!titleToPage.TryGetValue (pageTitle, out page))
+			GalleryPageFactory pageFactory = null;
+			if (!_titleToPage.TryGetValue (pageTitle, out pageFactory))
 				return;
+
+			var page = pageFactory.Realize();

 			if (Insights.IsInitialized) {
 				Insights.Track ("Navigation", new Dictionary<string, string> {


[Mac] Fix ListView.BorderVisible

[Mac] Fix ListView.BorderVisible

--- Xwt.XamMac/Xwt.Mac/ListViewBackend.cs
+++ Xwt.XamMac/Xwt.Mac/ListViewBackend.cs
@@ -149,10 +149,6 @@
 			CurrentEventRow = (int)pos;
 		}

-		// TODO
-		public bool BorderVisible { get; set; }
-
-
 		public int GetRowAtPosition (Point p)
 		{
 			return (int) Table.GetRow (new CGPoint ((nfloat)p.X, (nfloat)p.Y));


(GH-27) fix match logic (to lower)

(GH-27) fix match logic (to lower)

Ensure chocolateyinstaller.psm1 is checked as a lowercase
statement.

--- src/chocolatey.package.validator/infrastructure.app/rules/ScriptsDoNotContainImportOfChocolateyModuleRequirement.cs
+++ src/chocolatey.package.validator/infrastructure.app/rules/ScriptsDoNotContainImportOfChocolateyModuleRequirement.cs
@@ -21,8 +21,7 @@

     public class ScriptsDoNotContainImportOfChocolateyModuleRequirement : BasePackageRule
     {
-        public override string ValidationFailureMessage { get { return @"Directly importing the Chocolatey PowerShell Module is not prohibited, but this has been found in your automation scripts. Remove the usage of this module.  This can also give a false positive for commented code with the words:
-  * chocolateyInstaller.psm1"; } }
+        public override string ValidationFailureMessage { get { return @"Directly importing the Chocolatey PowerShell Module is not allowed in automation scripts. Please remove it. This can flag also based on the use of the word 'chocolateyInstaller.psm1' in comments."; } }

         protected override PackageValidationOutput is_valid(IPackage package)
         {
@@ -36,7 +35,7 @@

                 var contents = packageFile.GetStream().ReadToEnd().to_lower();

-                if (contents.Contains("chocolateyInstaller.psm1")) valid = false;
+                if (contents.Contains("chocolateyinstaller.psm1")) valid = false;
             }

             return valid;


Added extra BaseDirectory check.

Added extra BaseDirectory check.

--- Tests/Magick.NET.Tests/Framework/MagickImageTests.cs
+++ Tests/Magick.NET.Tests/Framework/MagickImageTests.cs
@@ -178,6 +178,13 @@

         string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
         Assert.IsTrue(exception.Message.Contains(baseDirectory));
+
+        exception = ExceptionAssert.Throws<ArgumentException>(() =>
+        {
+          image.Read("~");
+        });
+
+        Assert.IsTrue(exception.Message.Contains("~"));
       }
     }


Tweak client join validation

Tweak client join validation

--- Torch.Server/Managers/MultiplayerManagerDedicated.cs
+++ Torch.Server/Managers/MultiplayerManagerDedicated.cs
@@ -196,19 +196,29 @@
                 else if (_isClientKicked(MyMultiplayer.Static, info.SteamID) ||
                          _isClientKicked(MyMultiplayer.Static, info.SteamOwner))
                     CommitVerdict(info.SteamID, JoinResult.KickedRecently);
-                else if (info.SteamResponse != JoinResult.OK)
+                else if (info.SteamResponse == JoinResult.OK)
+                {
+                    //Admins can bypass member limit
+                    if (MySandboxGame.ConfigDedicated.Administrators.Contains(info.SteamID.ToString()) ||
+                        MySandboxGame.ConfigDedicated.Administrators.Contains(_convertSteamIDFrom64(info.SteamID)))
+                        CommitVerdict(info.SteamID, JoinResult.OK);
+                    //Server counts as a client, so subtract 1 from MemberCount
+                    else if (MyMultiplayer.Static.MemberLimit > 0 &&
+                             MyMultiplayer.Static.MemberCount - 1 >= MyMultiplayer.Static.MemberLimit)
+                        CommitVerdict(info.SteamID, JoinResult.ServerFull);
+                    else if (MySandboxGame.ConfigDedicated.GroupID == 0uL)
+                        CommitVerdict(info.SteamID, JoinResult.OK);
+                    else
+                    {
+                        if (MySandboxGame.ConfigDedicated.GroupID == info.Group && (info.Member || info.Officer))
+                            CommitVerdict(info.SteamID, JoinResult.OK);
+                        else
+                            CommitVerdict(info.SteamID, JoinResult.NotInGroup);
+                    }
+                }
+                else
                     CommitVerdict(info.SteamID, info.SteamResponse);
-                else if (MySandboxGame.ConfigDedicated.Administrators.Contains(info.SteamID.ToString()) ||
-                         MySandboxGame.ConfigDedicated.Administrators.Contains(_convertSteamIDFrom64(info.SteamID)))
-                    CommitVerdict(info.SteamID, JoinResult.OK);
-                else if (MyMultiplayer.Static.MemberLimit > 0 &&
-                         MyMultiplayer.Static.MemberCount + 1 > MyMultiplayer.Static.MemberLimit)
-                    CommitVerdict(info.SteamID, JoinResult.ServerFull);
-                else if (MySandboxGame.ConfigDedicated.GroupID == 0uL ||
-                         MySandboxGame.ConfigDedicated.GroupID == info.Group && (info.Member || info.Officer))
-                    CommitVerdict(info.SteamID, JoinResult.OK);
-                else
-                    CommitVerdict(info.SteamID, JoinResult.NotInGroup);
+
                 return;
             }


Adds a ContainsKey check into RemoveHandler

Stops the RemoveHandler funciton of the EventManager class from checking if the event key is null before checking its existance.


WIP Predictive space walk jerkiness fix

WIP Predictive space walk jerkiness fix

--- UnityProject/Assets/Scripts/PlayGroups/PlayerSync.cs
+++ UnityProject/Assets/Scripts/PlayGroups/PlayerSync.cs
@@ -543,6 +543,12 @@

 		private void UpdatePredictedState()
 		{
+			//Experimental: ignore prediction while flying
+			if (FloatingClient() || PseudoFloatingClient())
+			{
+				ResetClientQueue();
+				return;
+			}
 			if ( pendingActions.Count == 0 )
 			{
 				//plain assignment if there's nothing to predict
@@ -613,14 +619,22 @@

 		public void UpdateClientState(PlayerState state)
 		{
-			playerState = state;
+			//Experiment: not updating client state if player is already floating in the same direction
+//			if (!PseudoFloatingClient() || predictedState.Impulse != state.Impulse)
+//			{
+				playerState = state;
+//			}
+
 			Debug.Log($"Got server update {playerState}");
-			if ( FloatingClient() )
+			if ( FloatingClient() || PseudoFloatingClient() )
 			{
 //				Don't let prediction interfere while player is floating
 				ResetClientQueue();
 				LastDirection = playerState.Impulse;
-				predictedState = playerState;
+				if (!PseudoFloatingClient() || predictedState.Impulse != state.Impulse)
+				{
+					predictedState = playerState;
+				}
 				return;
 			}
 			if (pendingActions != null)
@@ -703,9 +717,7 @@
 						//initiate floating
 						//notify players that we started floating
 						Push(Vector2Int.RoundToInt(serverLastDirection));
-					}
-					if ( ServerPositionsMatch() )
-					{
+					} else if ( ServerPositionsMatch() ) {
 						//continue floating
 						serverTargetState.Position = Vector3Int.RoundToInt(serverState.Position + (Vector3) serverTargetState.Impulse);
 						ClearPendingServer();
@@ -723,7 +735,7 @@
 			//Simulating using predictedState for your own player and playerState for others
 			var state = isLocalPlayer ? predictedState : playerState;
 			Vector3Int pos = Vector3Int.RoundToInt( state.Position );
-			if ( FloatingClient() && !matrix.IsFloatingAt(pos) )
+			if ( ( FloatingClient() || PseudoFloatingClient() ) && !matrix.IsFloatingAt(pos) )
 			{
 //				Debug.Log("stop floating to avoid that dumb rubberband");
 				//stop floating on client (if server isn't responding in time) to avoid players going through walls
@@ -740,15 +752,19 @@
 //				if (rayHit.Length > 0){
 //					return;
 //				}
-				if ( !FloatingClient() && LastDirection != Vector2.zero )
+				if ( state.Impulse == Vector2.zero && LastDirection != Vector2.zero )
 				{
 					Debug.Log($"Wasn't floating on client, now floating with impulse {LastDirection}");
 				//client initiated space dive.
 					state.Impulse = LastDirection;
 				}
-				Vector3Int newGoal = Vector3Int.RoundToInt(pos + (Vector3) state.Impulse);
-				playerState.Position = newGoal;
-				predictedState.Position = newGoal;
+
+				if (transform.localPosition == state.Position)
+				{
+					Vector3Int newGoal = Vector3Int.RoundToInt(pos + (Vector3) state.Impulse);
+					playerState.Position = newGoal;
+					predictedState.Position = newGoal;
+				}
 //				}
 			}
 //			if (matrix.IsSpaceAt(pos) && !healthBehaviorScript.IsDead && isServer && !isApplyingSpaceDmg)
@@ -763,6 +779,10 @@
 		{
 			return playerState.Impulse != Vector2.zero;
 		}
+		private bool PseudoFloatingClient()
+		{
+			return predictedState.Impulse != Vector2.zero;
+		}
 		[Server]
 		private bool FloatingServer()
 		{


Typo in config.

Typo in config.

--- DotOPDS/Settings.cs
+++ DotOPDS/Settings.cs
@@ -127,7 +127,7 @@
     {
         public bool Enabled { get; set; } = false;
         public string Path { get; set; }
-        public string Level { get; set; } = "inforamtion";
+        public string Level { get; set; } = "information";
     }

     public class SettingsAuthentication


Update Game.Database.cs

Update Game.Database.cs

--- PokemonUnity.Shared/Game/Game.Database.cs
+++ PokemonUnity.Shared/Game/Game.Database.cs
@@ -340,41 +340,42 @@
 		{
 			try
 			{
-				//for(int n = 1; n <= Enum.GetValues(typeof(Pokemons)).Length; n++)
-				//{
-					//Step 3: Running a Command
-					SQLiteCommand stmt = con.CreateCommand();
-
-					#region DataReader
-					stmt.CommandText = "select * from pokemon_items group by pokemon_id, item_id";
-					//	@"select *
-					//from pokemon_items
-					//group by pokemon_id, item_id";
-					SQLiteDataReader reader = stmt.ExecuteReader();
-
-					//Step 4: Read the results
-					using(reader)
-					{
-						Dictionary<Pokemons, List<Monster.Data.PokemonWildItems>> p = new Dictionary<Pokemons, List<Monster.Data.PokemonWildItems>>();
-						while(reader.Read()) //if(reader.Read())
-						{
-							if (!p.ContainsKey((Pokemons)int.Parse((string)reader["pokemon_id"].ToString())))
-								p.Add((Pokemons)int.Parse((string)reader["pokemon_id"].ToString()),
-									new List<Monster.Data.PokemonWildItems>());
-							p[(Pokemons)int.Parse((string)reader["pokemon_id"].ToString())].Add(
-								new PokemonUnity.Monster.Data.PokemonWildItems(
-									itemId: (Items)int.Parse((string)reader["item_id"].ToString())
-									,generation: int.Parse((string)reader["version_id"].ToString())
-									,rarity: int.Parse((string)reader["rarity"].ToString())
-								)
-							);
-						}
-					//}
+				Dictionary<Pokemons, List<Monster.Data.PokemonWildItems>> p = new Dictionary<Pokemons, List<Monster.Data.PokemonWildItems>>();
+				foreach (Pokemons x in PokemonData.Keys)//for(int n = 1; n <= PokemonData.Keys.Length; n++)
+				{
+					p.Add(x, new List<Monster.Data.PokemonWildItems>());
+				}
+				//Step 3: Running a Command
+				SQLiteCommand stmt = con.CreateCommand();
+
+				#region DataReader
+				stmt.CommandText = "select * from pokemon_items group by pokemon_id, item_id";
+				//	@"select *
+				//from pokemon_items
+				//group by pokemon_id, item_id";
+				SQLiteDataReader reader = stmt.ExecuteReader();
+
+				//Step 4: Read the results
+				using(reader)
+				{
+					while(reader.Read()) //if(reader.Read())
+					{
+						//if (!p.ContainsKey((Pokemons)int.Parse((string)reader["pokemon_id"].ToString())))
+						//	p.Add((Pokemons)int.Parse((string)reader["pokemon_id"].ToString()),
+						//		new List<Monster.Data.PokemonWildItems>());
+						p[(Pokemons)int.Parse((string)reader["pokemon_id"].ToString())].Add(
+							new PokemonUnity.Monster.Data.PokemonWildItems(
+								itemId: (Items)int.Parse((string)reader["item_id"].ToString())
+								,generation: int.Parse((string)reader["version_id"].ToString())
+								,rarity: int.Parse((string)reader["rarity"].ToString())
+							)
+						);
+					}
 					//Step 5: Closing up
 					reader.Close();
 					reader.Dispose();
 					#endregion
-					PokemonItemsData.Add(Pokemons.NONE, new Monster.Data.PokemonWildItems[] { });
+					//PokemonItemsData.Add(Pokemons.NONE, new Monster.Data.PokemonWildItems[] { });
 					foreach (var pkmn in p)
 					{
 						PokemonItemsData.Add(pkmn.Key, pkmn.Value.ToArray());


Remove parallel connectThread logic, collapse into single call

--- PrinterCommunication/PrinterConnection.cs
+++ PrinterCommunication/PrinterConnection.cs
@@ -169,8 +169,6 @@
 		private CommunicationStates communicationState = CommunicationStates.Disconnected;

 		private string connectionFailureMessage = "Unknown Reason";
-
-		private Thread connectThread;

 		private PrinterMove currentDestination;

@@ -843,12 +841,6 @@
 			// Set .Disconnecting to allow the read loop to exit gracefully before a forced thread join (and extended timeout)
 			CommunicationState = CommunicationStates.Disconnecting;

-			// Shutdown the connectionAttempt thread
-			if (connectThread != null)
-			{
-				connectThread.Join(JoinThreadTimeoutMs); //Halt connection thread
-			}
-
 			// Shutdown the readFromPrinter thread
 			if (shutdownReadLoop)
 			{
@@ -929,15 +921,11 @@

 			if (SerialPortIsAvailable(this.ComPort))
 			{
-				//Create a timed callback to determine whether connection succeeded
-				Timer connectionTimer = new Timer(new TimerCallback(ConnectionCallbackTimer));
-				connectionTimer.Change(100, 0);
-
 				//Create and start connection thread
-				connectThread = new Thread(Connect_Thread);
-				connectThread.Name = "Connect To Printer";
-				connectThread.IsBackground = true;
-				connectThread.Start();
+				Task.Run(() =>
+				{
+					Connect_Thread();
+				});
 			}
 			else
 			{
@@ -1949,7 +1937,8 @@

 				case CommunicationStates.AttemptingToConnect:
 					CommunicationState = CommunicationStates.FailedToConnect;
-					connectThread.Join(JoinThreadTimeoutMs);
+					//connectThread.Join(JoinThreadTimeoutMs);
+
 					CommunicationState = CommunicationStates.Disconnecting;
 					ReadThread.Join();
 					if (serialPort != null)
@@ -2109,12 +2098,15 @@
 		private void Connect_Thread()
 		{
 			Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+
 			// Allow the user to set the appropriate properties.
 			var portNames = FrostedSerialPort.GetPortNames();
+
 			//Debug.WriteLine("Open ports: {0}".FormatWith(portNames.Length));
 			if (portNames.Length > 0 || IsNetworkPrinting())
 			{
 				AttemptToConnect(this.ComPort, this.BaudRate);
+
 				if (CommunicationState == CommunicationStates.FailedToConnect)
 				{
 					OnConnectionFailed(null);
@@ -2124,46 +2116,23 @@
 			{
 				OnConnectionFailed(null);
 			}
-		}
-
-		private void ConnectionCallbackTimer(object state)
-		{
-			Timer t = (Timer)state;
-			if (!ContinueConnectionThread())
-			{
-				t.Dispose();
-			}
-			else
-			{
-				t.Change(100, 0);
-			}
-		}
-
-		private bool ContinueConnectionThread()
-		{
-			if (CommunicationState == CommunicationStates.AttemptingToConnect)
-			{
-				if (this.stopTryingToConnect)
-				{
-					connectThread.Join(JoinThreadTimeoutMs); //Halt connection thread
-					Disable();
-					connectionFailureMessage = "Canceled".Localize();
-					OnConnectionFailed(null);
-					return false;
-				}
-				else
-				{
-					return true;
-				}
-			}
-			else
-			{
-				// If we're no longer in the .AttemptingToConnect state, shutdown the connection thread and fire the
-				// OnConnectonSuccess event if we're connected and not Disconnecting
-				connectThread.Join(JoinThreadTimeoutMs);
-
-				return false;
-			}
+
+			//// From ContinueConnectionThread
+			//if (CommunicationState == CommunicationStates.AttemptingToConnect)
+			//{
+			//	if (this.stopTryingToConnect)
+			//	{
+			//		connectThread.Join(JoinThreadTimeoutMs); //Halt connection thread
+			//		Disable();
+			//		connectionFailureMessage = "Canceled".Localize();
+			//		OnConnectionFailed(null);
+			//		return false;
+			//	}
+			//	else
+			//	{
+			//		return true;
+			//	}
+			//}
 		}

 		private void DonePrintingSdFile(object sender, FoundStringEventArgs e)


more changes

more changes

--- src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/BulkUploadValidateRequest/ValidateCost.cs
+++ src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/BulkUploadValidateRequest/ValidateCost.cs
@@ -19,11 +19,11 @@
             {
                 domainErrors.Add(new Error("TotalPrice", "Enter the total cost of training in whole pounds using numbers only"));
             }
-            else if (csvRecord.Cost == 0)
+            else if (csvRecord.Cost.Value == 0)
             {
                 domainErrors.Add(new Error("TotalPrice", "The total cost must be more than £0"));
             }
-            else if (csvRecord.Cost > 100000)
+            else if (csvRecord.Cost.Value > 100000)
             {
                 domainErrors.Add(new Error("TotalPrice", "The total cost must be £100,000 or less"));
             }


Update comments.

Update comments.

--- src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs
+++ src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs
@@ -216,7 +216,7 @@
                                        .ToImmutableArray();

             // Next, generate the full struct that will be used to replace all instances of this
-            // anonymous type.
+            // tuple type.
             var namedTypeSymbol = await GenerateFinalNamedTypeAsync(
                 document, scope, structName, capturedTypeParameters, tupleType, cancellationToken).ConfigureAwait(false);

@@ -565,7 +565,7 @@
                 var childType = semanticModel.GetTypeInfo(childCreation, cancellationToken).Type as INamedTypeSymbol;
                 if (childType == null)
                 {
-                    Debug.Fail("We should always be able to get an anonymous type for any anonymous creation node.");
+                    Debug.Fail("We should always be able to get an tuple type for any tuple expression node.");
                     continue;
                 }

@@ -608,7 +608,7 @@
             ISyntaxFactsService syntaxFacts, SyntaxEditor editor, string typeName, ImmutableArray<ITypeParameterSymbol> typeParameters,
             TNameSyntax qualifiedTypeName, SyntaxNode startingCreationNode, TTupleExpressionSyntax childCreation)
         {
-            // Use the callback form as anonymous types may be nested, and we want to
+            // Use the callback form as tuples types may be nested, and we want to
             // properly replace them even in that case.
             editor.ReplaceNode(
                 childCreation,
@@ -674,7 +674,7 @@
                 var childType = semanticModel.GetTypeInfo(childTupleType, cancellationToken).Type as INamedTypeSymbol;
                 if (childType == null)
                 {
-                    Debug.Fail("We should always be able to get an anonymous type for any anonymous creation node.");
+                    Debug.Fail("We should always be able to get an tuple type for any tuple type syntax node.");
                     continue;
                 }

@@ -693,7 +693,7 @@
             SyntaxEditor editor, string typeName, ImmutableArray<ITypeParameterSymbol> typeParameters,
             TNameSyntax qualifiedTypeName, SyntaxNode startingNode, TTupleTypeSyntax childTupleType)
         {
-            // Use the callback form as anonymous types may be nested, and we want to
+            // Use the callback form as tuple types may be nested, and we want to
             // properly replace them even in that case.
             editor.ReplaceNode(
                 childTupleType,


KSP parts have periods and not underscores in their names.

--- Common/Common.cs
+++ Common/Common.cs
@@ -243,18 +243,18 @@
             stockPartList.Add("omsEngine");
             stockPartList.Add("vernierEngine");
             //0.25 parts
-            stockPartList.Add("delta_small");
+            stockPartList.Add("delta.small");
             stockPartList.Add("elevon2");
             stockPartList.Add("elevon3");
             stockPartList.Add("elevon5");
             stockPartList.Add("IntakeRadialLong");
             stockPartList.Add("MK1IntakeFuselage");
-            stockPartList.Add("mk2_1m_AdapterLong");
-            stockPartList.Add("mk2_1m_Bicoupler");
+            stockPartList.Add("mk2.1m.AdapterLong");
+            stockPartList.Add("mk2.1m.Bicoupler");
             stockPartList.Add("mk2CargoBayL");
             stockPartList.Add("mk2CargoBayS");
-            stockPartList.Add("mk2Cockpit_Inline");
-            stockPartList.Add("mk2Cockpit_Standard");
+            stockPartList.Add("mk2Cockpit.Inline");
+            stockPartList.Add("mk2Cockpit.Standard");
             stockPartList.Add("mk2CrewCabin");
             stockPartList.Add("mk2DockingPort");
             stockPartList.Add("mk2DroneCore");


Implemented InlineCode, Italic and Strikethrough [PM74 - Add formatting toolbar functionality].

--- ProjectMarkdown/Services/TextFormatter.cs
+++ ProjectMarkdown/Services/TextFormatter.cs
@@ -183,6 +183,43 @@

                         break;
                     }
+                    case TextFormats.InlineCode:
+                    {
+                        if (input.StartsWith("`") && input.EndsWith("`"))
+                        {
+                            formattedText = input.Substring(1, input.Length - 2).Trim();
+                        }
+                        else
+                        {
+                            formattedText = "`" + input + "`";
+                        }
+                        break;
+                    }
+                    case TextFormats.Italic:
+                    {
+                        if (input.StartsWith("*") && input.EndsWith("*"))
+                        {
+                            formattedText = input.Substring(1, input.Length - 2).Trim();
+                        }
+                        else
+                        {
+                            formattedText = "*" + input + "*";
+                        }
+                        break;
+                    }
+                    case TextFormats.StrikeThrough:
+                    {
+                        if (input.StartsWith("~~") && input.EndsWith("~~"))
+                        {
+                            formattedText = input.Substring(2, input.Length - 4);
+                        }
+                        else
+                        {
+                            formattedText = "~~" + input + "~~";
+                        }
+
+                        break;
+                    }
                     default:
                     {
                         break;


fix open not setting file name

fix open not setting file name

--- Colours/MainForm.cs
+++ Colours/MainForm.cs
@@ -308,7 +308,7 @@

         public void OpenPalette(string fileName)
         {
-            appPal.NewFromPalette(new Palette(File.ReadAllLines(fileName)));
+            appPal.NewFromPalette(new Palette(File.ReadAllLines(fileName)), fileName);
         }

         private void saveToolStripMenuItem_Click(object sender, EventArgs e)


SWF: use events instead oof manually handling the view

--- Colours/MainForm.cs
+++ Colours/MainForm.cs
@@ -18,33 +18,30 @@
         public MainForm()
         {
             InitializeComponent();
-
-            HsvColor initial = new HsvColor(Properties.Settings.Default.LastColor);
-            app = new AppController(initial, Properties.Settings.Default.SchemeType);
-
             if (Properties.Settings.Default.CustomColors?.Count == 16)
             {
                 colorDialog1.CustomColors = Properties.Settings.Default.CustomColors.ToArray();
             }
-
-            SyncAppViewState();
-        }
-
-        public MainForm(AppState state)
-        {
-            InitializeComponent();
-
+            // don't init the app with this func; init with AppState
+            // this is just a base ctor
+        }
+
+        public MainForm(AppState state) : this()
+        {
             app = new AppController(state);
-
-            if (Properties.Settings.Default.CustomColors?.Count == 16)
-            {
-                colorDialog1.CustomColors = Properties.Settings.Default.CustomColors.ToArray();
-            }
-
-            SyncAppViewState();
-        }
-
-        public void SyncAppViewState()
+            app.ResultChanged += SyncAppViewState;
+            // send an initial event manually, because the event has
+            // already been fired when it was initialized,
+            // but without our handler
+            SyncAppViewState(this, new EventArgs());
+        }
+
+        /// <summary>
+        /// Handle the controller's state updates and sync them to the view.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        public void SyncAppViewState(object sender, EventArgs e)
         {
             comboBox1.SelectedIndex = (int)app.SchemeType;
             Text = String.Format("{0} for {1}", (string)comboBox1.SelectedItem,
@@ -93,14 +90,12 @@
             if (colorDialog1.ShowDialog(this) == DialogResult.OK)
             {
                 app.SetColor(colorDialog1.Color, true);
-                SyncAppViewState();
             }
         }

         private void comboBox1_SelectionChangeCommitted(object sender, EventArgs e)
         {
             app.SetSchemeType((SchemeType)comboBox1.SelectedIndex, true);
-            SyncAppViewState();
         }

         private void copyHexToolStripMenuItem_Click(object sender, EventArgs e)
@@ -140,38 +135,32 @@
         {
             Random r = new Random();
             app.SetColor(Color.FromArgb(r.Next(255), r.Next(255), r.Next(255)), true);
-            SyncAppViewState();
         }

         private void brightenToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Brighten();
-            SyncAppViewState();
         }

         private void darkenToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Darken();
-            SyncAppViewState();
         }

         private void saturateToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Saturate();
-            SyncAppViewState();
         }

         private void desaturateToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Desaturate();
-            SyncAppViewState();
         }

         private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
         {
             try {
                 app.SetColor(ColorTranslator.FromHtml(Clipboard.GetText()), true);
-                SyncAppViewState();
             }
             catch (Exception)
             {
@@ -202,19 +191,16 @@
         private void invertToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.SetColor(app.Color.Invert(), true);
-            SyncAppViewState();
         }

         private void undoToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Undo();
-            SyncAppViewState();
         }

         private void redoToolStripMenuItem_Click(object sender, EventArgs e)
         {
             app.Redo();
-            SyncAppViewState();
         }

         private void saveAsHTMLToolStripMenuItem_Click(object sender, EventArgs e)


using statement is now pervasive.  Small tweaks to options.

--- samples/cs/sz/sz.cs
+++ samples/cs/sz/sz.cs
@@ -241,6 +241,10 @@
 									optionIndex = option.Length;

 									switch (option) {
+										case "-abs":
+											relativePathInfo = false;
+											break;
+
 										case "-add":
 											operation = Operation.Add;
 											break;
@@ -487,7 +491,7 @@
 		/// </summary>
 		void ShowVersion() {
 			seenHelp = true;
-			Console.Out.WriteLine("SharpZip Archiver v0.34   Copyright 2004 John Reilly");
+			Console.Out.WriteLine("SharpZip Archiver v0.35   Copyright 2004 John Reilly");

 			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

@@ -514,6 +518,7 @@
 			Console.Out.WriteLine("usage sz {options} archive files");
 			Console.Out.WriteLine("");
 			Console.Out.WriteLine("Options:");
+			Console.Out.WriteLine("-abs                       Store absolute path info");
 			Console.Out.WriteLine("-?,        --help          Show this help");
 			Console.Out.WriteLine("-c         --create        Create new archive");
 			Console.Out.WriteLine("-v                         List archive contents (default)");
@@ -532,7 +537,7 @@
 			Console.Out.WriteLine("--add                      Add files to archive");
 			Console.Out.WriteLine("-o+                        Overwrite files without prompting");
 			Console.Out.WriteLine("-o-                        Never overwrite files");
-			Console.Out.WriteLine("-p                         Store relative path info");
+			Console.Out.WriteLine("-p                         Store relative path info (default)");
 			Console.Out.WriteLine("-r                         Recurse sub-folders");
 			Console.Out.WriteLine("-q                         Quiet mode");
 			Console.Out.WriteLine("-s=password                Set archive password");
@@ -653,45 +658,54 @@

 				Console.Out.WriteLine(fileName);

-				ZipFile zipFile = new ZipFile(fileName);
 				int entryCount = 0;
 				long totalSize  = 0;

-		 		foreach (ZipEntry theEntry in zipFile) {
+				using (ZipFile zipFile = new ZipFile(fileName))
+				{
+					foreach (ZipEntry theEntry in zipFile)
+					{

-					if ( theEntry.IsDirectory ) {
-						Console.Out.WriteLine("Directory {0}", theEntry.Name);
-						continue;
-					}
-
-					if ( !theEntry.IsFile ) {
-						Console.Out.WriteLine("Non file entry {0}", theEntry.Name);
-						continue;
-					}
-
-					if (entryCount == 0) {
-						Console.Out.WriteLine(headerTitles);
-						Console.Out.WriteLine(headerUnderline);
-					}
+						if ( theEntry.IsDirectory )
+						{
+							Console.Out.WriteLine("Directory {0}", theEntry.Name);
+						}
+						else if ( !theEntry.IsFile )
+						{
+							Console.Out.WriteLine("Non file entry {0}", theEntry.Name);
+							continue;
+						}
+						else
+						{
+							if (entryCount == 0)
+							{
+								Console.Out.WriteLine(headerTitles);
+								Console.Out.WriteLine(headerUnderline);
+							}

-					++entryCount;
-					int ratio = GetCompressionRatio(theEntry.CompressedSize, theEntry.Size);
-					totalSize += theEntry.Size;
+							++entryCount;
+							int ratio = GetCompressionRatio(theEntry.CompressedSize, theEntry.Size);
+							totalSize += theEntry.Size;

-					if (theEntry.Name.Length > 12) {
-						Console.Out.WriteLine(theEntry.Name);
-						Console.Out.WriteLine(
-						    "{0,-12}  {1,10:0}  {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}   {6,4}",
-						    "", theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
-						    InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
-					} else {
-						Console.Out.WriteLine(
-						    "{0,-12}  {1,10:0}  {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}   {6,4}",
-						    theEntry.Name, theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
-						    InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
-					}
-				}
-
+							if (theEntry.Name.Length > 12)
+							{
+								Console.Out.WriteLine(theEntry.Name);
+								Console.Out.WriteLine(
+									"{0,-12}  {1,10:0}  {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}   {6,4}",
+									"", theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
+									InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
+							}
+							else
+							{
+								Console.Out.WriteLine(
+									"{0,-12}  {1,10:0}  {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}   {6,4}",
+									theEntry.Name, theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
+									InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
+							}
+						}
+					}
+				}
+
 				if (entryCount == 0) {
 					Console.Out.WriteLine("Archive is empty!");
 				} else {
@@ -718,7 +732,7 @@
 				string [] names;
 				string pathName = Path.GetDirectoryName(spec);

-				if (pathName == null || pathName.Length == 0) {
+				if ( (pathName == null) || (pathName.Length == 0) ) {
 					pathName = @".\";
 				}
 				names = Directory.GetFiles(pathName, Path.GetFileName(spec));
@@ -793,10 +807,10 @@
 			return CookZipEntryName(name, removablePathPrefix, relativePathInfo);
 		}

+		// TODO: Add equivalent for non-seekable output
 		/// <summary>
 		/// Add a file assuming the output is seekable
 		/// </summary>
-		// TODO Add equivalent for non-seekable output
 		void AddFileSeekableOutput(string file, string entryPath, int maximumBufferSize)
 		{
 			ZipEntry entry = new ZipEntry(entryPath);
@@ -811,9 +825,9 @@
 				entry.CompressionMethod = CompressionMethod.Deflated;
 			}

-			System.IO.FileStream fileStream = System.IO.File.OpenRead(file);
-
-			try {
+			using (System.IO.FileStream fileStream = System.IO.File.OpenRead(file))
+			{
+
 				byte[] transferBuffer;
 				if (fileStream.Length > maximumBufferSize)
 					transferBuffer = new byte[maximumBufferSize];
@@ -828,9 +842,6 @@
 					outputStream.Write(transferBuffer, 0, bytesRead);
 				}
 				while (bytesRead > 0);
-			}
-			finally {
-				fileStream.Close();
 			}
 		}

@@ -859,8 +870,6 @@
 			} else {
 				Console.Error.WriteLine("No such file exists {0}", fileName);
 			}
-
-
 		}

 		/// <summary>
@@ -874,7 +883,9 @@
 #endif
 			folderName = CookZipEntryName(folderName);
 			if (folderName.Length == 0 || folderName[folderName.Length - 1] != '/')
+			{
 				folderName = folderName + '/';
+			}

 			ZipEntry zipEntry = new ZipEntry(folderName);
 			outputStream.PutNextEntry(zipEntry);
@@ -962,10 +973,8 @@
 						// TODO wildcards arent full supported by this
 						if (recursive || fileName.IndexOf('*') >= 0 || fileName.IndexOf('?') >= 0) {

-							// TODO this allows possible conflict in filenames that are added to Zip file
+							// TODO this allows possible conflicts in filenames that are added to Zip file
 							// as part of different file specs.
-							// how to resolve this, could leave for decompression to solve, or try and fix at create time
-
 							totalEntries += CompressFolder(pathName, recursive, fileName);
 						} else {
 							AddFile(pathName + @"\" + fileName, 8192);
@@ -976,8 +985,6 @@
 					if (totalEntries == 0) {
 						Console.Out.WriteLine("File created has no entries!");
 					}
-					outputStream.Close();
-					outputStream = null;
 				}
 			}
 		}
@@ -1002,8 +1009,8 @@

 			string fullPath = Path.GetDirectoryName(Path.GetFullPath(targetName));
 #if TEST
-						Console.WriteLine("Decompress targetfile name " + entryFileName);
-						Console.WriteLine("Decompress targetpath " + fullPath);
+			Console.WriteLine("Decompress targetfile name " + entryFileName);
+			Console.WriteLine("Decompress targetpath " + fullPath);
 #endif

 			// Could be an option or parameter to allow failure or try creation
@@ -1051,9 +1058,7 @@
 #if TEST
 				Console.WriteLine("Extracting...");
 #endif
-				FileStream streamWriter = File.Create(targetName);
-
-				try
+				using (FileStream streamWriter = File.Create(targetName))
 				{
 					byte[] data = new byte[4096];
 					int size;
@@ -1064,10 +1069,6 @@
 						streamWriter.Write(data, 0, size);
 					} while (size > 0);
 				}
-				finally
-				{
-					streamWriter.Close();
-				}

 				if (restoreDateTime)
 				{
@@ -1079,15 +1080,7 @@

 		void ExtractDirectory(ZipInputStream inputStream, ZipEntry theEntry, string targetDir)
 		{
-			/*
-			byte[] data = new byte[4096];
-			int size;
-
-			do
-			{
-				size = inputStream.Read(data, 0, data.Length);
-			} while (size > 0);
-			*/
+			// For now do nothing.
 		}

 		/// <summary>
@@ -1119,7 +1112,6 @@
 							ExtractDirectory(inputStream, theEntry, targetDir);
 						}
 					}
-					inputStream.Close();
 				}
 			}
 			catch (Exception except) {
@@ -1317,7 +1309,7 @@
 		/// <summary>
 		/// Use relative path information
 		/// </summary>
-		bool   relativePathInfo;
+		bool   relativePathInfo = true;

 		/// <summary>
 		/// Operate silently


Re-enable integration tests

Re-enable integration tests

--- build/build.cake
+++ build/build.cake
@@ -112,7 +112,7 @@
     {
         // Specify the path to the test adapter to avoid a warning that no tests
         // were discovered because we filtered them all out
-        settings.TestAdapterPath = project.GetDirectory().CombineWithFilePath("./bin/" + configuration + "/netcoreapp2.0/").FullPath;
+        settings.TestAdapterPath = project.GetDirectory().CombineWithFilePath("./bin/" + configuration + "/netcoreapp2.1/").FullPath;
         DotNetCoreTest(project.FullPath, settings);
     });
 });


SMR report join date takes into account changes in active status.

--- SMR.Extensions/SmrReports_FieldSummary.cs
+++ SMR.Extensions/SmrReports_FieldSummary.cs
@@ -18,8 +18,11 @@
       var memberships = me.db.Value.Units
         .Where(f => f.DisplayName == "SMR")
         .SelectMany(f => f.Memberships.Where(g => (g.EndTime == null || g.EndTime > DateTime.Now) && g.Status.IsActive && g.Status.WacLevel != WacLevel.None));
+
       var members = memberships
         .Select(f => f.Person);
+
+      var memberHistory = members.ToDictionary(f => f.Id, f => f.Memberships.Where(g => g.Status.IsActive && g.Unit.DisplayName == "SMR").OrderByDescending(g => g.Activated).ToList());

       var currentTraining = members.SelectMany(f => f.ComputedAwards)
         .GroupBy(f => f.Member.Id)
@@ -78,14 +81,29 @@
         var memberId = roster[i].Id;
         var col = 1;
         var row = i + 4;
+
+        var joinDate = (DateTime?)null;
+        var joinHistory = memberHistory[memberId];
+        for (int j = 0; j < joinHistory.Count; j++)
+        {
+          if (j == 0 || joinDate.Value.Date == joinHistory[j].EndTime.Value.Date)
+          {
+            joinDate = joinHistory[j].Activated;
+          }
+          else
+          {
+            break;
+          }
+        }
+
         sheet.Cells[row, col++].Value = roster[i].DEM;
         sheet.Cells[row, col++].Value = roster[i].ReverseName;
-        sheet.Cells[row, col++].Value = status[memberId].Activated > oldDate ? status[memberId].Activated : (DateTime?)null;
+        sheet.Cells[row, col++].Value = joinDate > oldDate ? joinDate : (DateTime?)null;
         sheet.Cells[row, col++].Value = roster[i].WacLevel == WacLevel.None ? null : roster[i].WacLevel.ToString();
         sheet.Cells[row, col++].Value = status[memberId].StatusName;
         col++; // MRA

-        if (currentTraining[memberId] != null)
+        if (currentTraining.ContainsKey(memberId) && currentTraining[memberId] != null)
         {
           sheet.Cells[row, col++].Value = currentTraining[memberId].Any(f => f.DisplayName == "Avalanche III") ? "Avy III"
                                         : currentTraining[memberId].Any(f => f.DisplayName == "Avalanche II") ? "Avy II"


Distinguish StateO from StateValidTagName.

--- Sandra.Chess/Pgn/PgnSymbolStateMachine.cs
+++ Sandra.Chess/Pgn/PgnSymbolStateMachine.cs
@@ -79,6 +79,9 @@
         // All digits.
         private const int StateValidMoveNumber = 14;

+        // Distinct states after the first character was a letter.
+        private const int StateO = 15;
+
         private const int StateValidTagName = 39;

         private const int StateLength = 40;
@@ -89,7 +92,8 @@
             | 1ul << StateValidMoveNumber;

         private const ulong ValidTagNameStates
-            = 1ul << StateValidTagName;
+            = 1ul << StateO
+            | 1ul << StateValidTagName;

         // This table is used to transition from state to state given a character class index.
         // It is a low level implementation of a regular expression; it is a theorem
@@ -131,9 +135,11 @@
             StateTransitionTable[State0, Dash] = StateBlackWins2;
             StateTransitionTable[StateBlackWins2, Digit1] = StateBlackWins3;

+            // States when the first character is a letter.
+            StateTransitionTable[StateStart, LetterO] = StateO;
+
             // Tag names must start with a letter or underscore.
             // This deviates from the PGN standard which only allows tag names to start with uppercase letters.
-            StateTransitionTable[StateStart, LetterO] = StateValidTagName;
             StateTransitionTable[StateStart, LetterP] = StateValidTagName;
             StateTransitionTable[StateStart, OtherPieceLetter] = StateValidTagName;
             StateTransitionTable[StateStart, OtherUpperCaseLetter] = StateValidTagName;
@@ -142,18 +148,21 @@
             StateTransitionTable[StateStart, OtherLowercaseLetter] = StateValidTagName;

             // Allow only digits, letters or the underscore character in tag names.
-            StateTransitionTable[StateValidTagName, Digit0] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, Digit1] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, Digit2] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, Digit3_8] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, Digit9] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, LetterO] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, LetterP] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, OtherPieceLetter] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, OtherUpperCaseLetter] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, LowercaseAtoH] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, LowercaseX] = StateValidTagName;
-            StateTransitionTable[StateValidTagName, OtherLowercaseLetter] = StateValidTagName;
+            new[] { StateO, StateValidTagName }.ForEach(state =>
+            {
+                StateTransitionTable[state, Digit0] = StateValidTagName;
+                StateTransitionTable[state, Digit1] = StateValidTagName;
+                StateTransitionTable[state, Digit2] = StateValidTagName;
+                StateTransitionTable[state, Digit3_8] = StateValidTagName;
+                StateTransitionTable[state, Digit9] = StateValidTagName;
+                StateTransitionTable[state, LetterO] = StateValidTagName;
+                StateTransitionTable[state, LetterP] = StateValidTagName;
+                StateTransitionTable[state, OtherPieceLetter] = StateValidTagName;
+                StateTransitionTable[state, OtherUpperCaseLetter] = StateValidTagName;
+                StateTransitionTable[state, LowercaseAtoH] = StateValidTagName;
+                StateTransitionTable[state, LowercaseX] = StateValidTagName;
+                StateTransitionTable[state, OtherLowercaseLetter] = StateValidTagName;
+            });
         }

         private int CurrentState;


Cleaned up SceneTransitionManager, added comments.

Semibreaking changes:
SceneTransitionManager now persists through scenes so it only needs to be Setup() once.
SceneTransitionManager also supports being setup as a GameObject, using its public properties.
SceneTransitionManager can only have a single instance. Any additional SceneTransitionManager will destory themselves.

--- SceneManagement/SceneTransitionManager.cs
+++ SceneManagement/SceneTransitionManager.cs
@@ -2,25 +2,35 @@
 using UnityEngine;
 using UnityEngine.SceneManagement;

+/**
+ * SceneTransitionManager helps easily fade between scenes using TransitionManager.
+ * Once SceneTransitionManager is setup, just use SceneTransitionManager.LoadScene() to jump to another scene.
+ *
+ * SceneTransitionManager.LoadScene(sceneName)
+ *
+ * SceneTransitionManager can be setup in 2 ways:
+ * - Through code: SceneTransitionManager.Setup();
+ *      Setup() should be called early in the scene so that the FadeIn can start immediately.
+ *      Setup() default params override the public object properties.
+ *
+ * - As a GameObject in the Scene:
+ *      Add SceneTransitionManager to a GameObject in your first scene, setup the public properties, and it will live until the game is closed.
+ *      If multiple SceneTransitionManagers exist (like one per scene), existing ones should automatically be deleted, and only the original one will remain.
+ */
 public class SceneTransitionManager : MonoBehaviour {
-    private float TransitionFadeDuration = 0.17f;
-    private Color TransitionFadeColor = "15574E".HexAsColor();
+    public float FadeInWaitDelaySeconds = 0.1f;
+    public float TransitionFadeDurationSeconds = 0.5f;
+    public Color TransitionFadeColor = "262626".HexAsColor();
+    public Action LoadingFinishedCallback;
+
     private bool HasStartedNextLevel = false;

-    private Action LoadingFinishedCallback;

-
-    public static void Setup(Action loadingFinishedCallback = null) {
+    public static void Setup(float fadeInWaitDelaySeconds = 0.1f, float transitionFadeDuration = 0.5f, Color transitionFadeColor = new Color(/*Black*/), Action loadingFinishedCallback = null) {
+        Instance.FadeInWaitDelaySeconds = fadeInWaitDelaySeconds;
+        Instance.TransitionFadeDurationSeconds = transitionFadeDuration;
+        Instance.TransitionFadeColor = transitionFadeColor;
         Instance.LoadingFinishedCallback += loadingFinishedCallback;
-    }
-
-    private void Start() {
-        // Wait until most things are loaded.
-        WaitUntil.Seconds(0.1f, delegate {
-            TransitionManager.FadeIn(TransitionFadeDuration, TransitionFadeColor, delegate {
-                LoadingFinishedCallback?.Invoke();
-            });
-        });
     }

     public static void LoadScene(string sceneName) {
@@ -29,7 +39,7 @@
         }
         Instance.HasStartedNextLevel = true;

-        TransitionManager.FadeOut(Instance.TransitionFadeDuration, Instance.TransitionFadeColor, delegate {
+        TransitionManager.FadeOut(Instance.TransitionFadeDurationSeconds, Instance.TransitionFadeColor, delegate {
             SceneManager.LoadScene(sceneName);
         });
     }
@@ -47,12 +57,33 @@
     }

     private void Awake() {
+        if (_Instance != null && _Instance != this) { // Already exists, we're the duplicate.
+            Destroy(this.gameObject);
+            return;
+        }
+
         _Instance = this;
         TransitionManager.SetFaded(true, TransitionFadeColor);
+        SceneManager.sceneLoaded += OnSceneLoaded;
+        DontDestroyOnLoad(this.gameObject);
+    }
+
+    private void OnSceneLoaded(Scene scene, LoadSceneMode mode) {
+        Instance.HasStartedNextLevel = false;
+
+        // FadeIn
+        WaitUntil.Seconds(FadeInWaitDelaySeconds, delegate { // Wait until most things are loaded.
+            TransitionManager.FadeIn(TransitionFadeDurationSeconds, TransitionFadeColor, delegate {
+                LoadingFinishedCallback?.Invoke();
+            });
+        });
     }

     private void OnDestroy() {
-        _Instance = null;
+        SceneManager.sceneLoaded -= OnSceneLoaded;
+        if (_Instance == this) {
+            _Instance = null;
+        }
     }
     #endregion Instance
 }


Move debug argument overriding out of the code and into a text file in CRAYON_HOME.

--- Compiler/Program.cs
+++ Compiler/Program.cs
@@ -81,11 +81,20 @@
 #if DEBUG
             if (args.Length == 0)
             {
-                string command;
-
-                command = @"C:\Crayon\UnitTests\UnitTests.build -target windows";
-
-                args = command.Split(' ');
+                string crayonHome = System.Environment.GetEnvironmentVariable("CRAYON_HOME");
+                if (crayonHome != null)
+                {
+                    string debugArgsFile = System.IO.Path.Combine(crayonHome, "DEBUG_ARGS.txt");
+                    if (System.IO.File.Exists(debugArgsFile ))
+                    {
+                        string[] debugArgs = System.IO.File.ReadAllText(debugArgsFile).Trim().Split('\n');
+                        string lastArgSet = debugArgs[debugArgs.Length - 1].Trim();
+                        if (lastArgSet.Length > 0)
+                        {
+                            args = lastArgSet.Split(' ');
+                        }
+                    }
+                }
             }
 #endif


Marshal string as LPWSTR only when not running on mono. TODO: Implement full unicode marshaling cross platform.

--- Driver/Driver.cs
+++ Driver/Driver.cs
@@ -617,13 +617,16 @@
             return !t.IsPrimitive && t != typeof(void) && t != typeof(string);
         }

+
+        private static bool isMono = Type.GetType ("Mono.Runtime") != null;
+
         /// <summary>
         /// Returns the type of 'MarshalAs' attribute that should be attached to
         /// parameters/results of the given type, if any.
         /// </summary>
         private static UnmanagedType? MarshalTypeAs(Type t)
         {
-            if (t == typeof(string))
+            if (!isMono && t == typeof(string))
                 return UnmanagedType.LPWStr;
             else
                 return null;


Cleaned the macros up a bit.

Cleaned the macros up a bit.

--- GUI/GadgetWindow.cs
+++ GUI/GadgetWindow.cs
@@ -427,20 +427,20 @@
     /// Some macros imported and converted from the Windows SDK
     /// </summary>
     private static class Macros {
-      public static UInt16 LOWORD(IntPtr l) {
-        return ((UInt16) (((UInt64) (l)) & 0xffff));
+      public static ushort LOWORD(IntPtr l) {
+        return (ushort) ((ulong)l & 0xFFFF);
       }

       public static UInt16 HIWORD(IntPtr l) {
-        return ((UInt16) ((((UInt64) (l)) >> 16) & 0xffff));
+        return (ushort) (((ulong)l >> 16) & 0xFFFF);
       }

       public static int GET_X_LPARAM(IntPtr lp) {
-        return ((int) (short) LOWORD(lp));
+        return (short) LOWORD(lp);
       }

       public static int GET_Y_LPARAM(IntPtr lp) {
-        return ((int) (short) HIWORD(lp));
+        return (short) HIWORD(lp);
       }
     }


parser update

parser update

--- Silent/SilentVM/Silent_Compiler/Parser.cs
+++ Silent/SilentVM/Silent_Compiler/Parser.cs
@@ -49,10 +49,8 @@
                 //If the current token is a decleration of a namespace
                 if (scope.tokens[i] == Tokens.Namespace)
                 {
-                    //Save current position in the list
-                    scope.pos = i;
                     //Add a namespace object to the list of namespaces
-                    scope.namespaces.Add(PrepareNamespace(scope, out i));
+                    scope.namespaces.Add(PrepareNamespace(scope, i, out i));
                 }

                 //If the current token is a decleration of a namespace
@@ -82,14 +80,14 @@
             }
         }

-        List<silent_Expression> PrepareExpression(silent_Namespace scope)
+        silent_Expression PrepareExpression(List<Tokens> tokens)
         {
             List<silent_Expression> expression = new List<silent_Expression>();

             return expression;
         }

-        silent_Function PrepareFunction(silent_Namespace scope)
+        silent_Function PrepareFunction(silent_Namespace upperScope, int pos, out int position)
         {
             silent_Function function = new silent_Function();
             //function.returnType = (Types)tokens[++pos];
@@ -97,13 +95,13 @@
             return function;
         }

-        silent_Class PrepareClass(silent_Namespace Namespace)
+        silent_Class PrepareClass(silent_Namespace scope, int pos, out int position)
         {
             silent_Class silent_class = new silent_Class()
             {
                 members = new List<silent_ClassVariable>(),
                 methods = new List<silent_Method>(),
-                pos = Namespace.pos
+                pos = scope.pos
             };

             //Used to get the length of the scope
@@ -170,18 +168,18 @@
         }

         //Sort namespace in the global scope
-        silent_Namespace PrepareNamespace(silent_Namespace scope, out int position)
+        silent_Namespace PrepareNamespace(silent_Namespace upperScope,int pos, out int position)
         {
             //Create new namespace
             silent_Namespace Namespace = new silent_Namespace()
             {
                 tokens = new List<Tokens>(),
                 //Assign the namespace position in the code
-                pos = scope.pos
+                pos = pos
             };

             //Used to get the length of the scope
-            int startPos = scope.pos;
+            int startPos = pos;
             int endPos = 0;

             //Number of scopes within the namespace
@@ -190,18 +188,18 @@
             bool namespaceOpened = false;

             //Isolate the scope from the rest of the program
-            for(int i = startPos; i < scope.tokens.Count; i++)
+            for(int i = startPos; i < upperScope.tokens.Count; i++)
             {

                 //If opening bracket appears, a new scope is created
-                if (scope.tokens[i] == Tokens.OpenCurlyBracket)
+                if (upperScope.tokens[i] == Tokens.OpenCurlyBracket)
                 {
                     noScopes++;
                     namespaceOpened = true;
                 }

                 //If closing bracket appears, a scope is closed
-                if(scope.tokens[i] == Tokens.CloseCurlyBracket)
+                if(upperScope.tokens[i] == Tokens.CloseCurlyBracket)
                 {
                     noScopes--;
                 }
@@ -210,17 +208,12 @@
                 if(noScopes == 0 && namespaceOpened == true)
                 {
                     endPos = i + 1;
-
-

                     //Copy the namespace code into the namespace object
                     for (int x = startPos; x < endPos; x++)
                     {
-                        Namespace.tokens.Add(scope.tokens[x]);
+                        Namespace.tokens.Add(upperScope.tokens[x]);
                     }
-
-                    //Remove used code from the global scope as it won't be needed
-                    //scope.tokens.RemoveRange(startPos, (endPos - startPos));
                     break;
                 }

@@ -231,6 +224,7 @@
             {
                 //Declare the namespace's name
                 Namespace.name = this.values[CountVal(Namespace.pos)];
+
             }

             //Check for incorrect namespace declaration
@@ -244,36 +238,25 @@
             //Iterate through the list of tokens
             for (int i = 0; i < Namespace.tokens.Count; i++)
             {
-
-
                 //If the current token is a decleration of a namespace
-                if (scope.tokens[i] == Tokens.Namespace)
-                {
-                    //Save current position in the list
-                    scope.pos = i;
+                if (Namespace.tokens[i] == Tokens.Namespace)
+                {
                     //Add a namespace object to the list of namespaces
-                    scope.namespaces.Add(PrepareNamespace(scope, out i));
-
-                }
-
-                //If the current token is a decleration of a namespace
+                    Namespace.namespaces.Add(PrepareNamespace(Namespace, i , out i));
+                }
+
+                //If the current token is a decleration of a class
                 if (Namespace.tokens[i] == Tokens.Class)
                 {
-                    //Save current position in the list
-                    Namespace.pos = i;
-                    //Add a namespace object to the list of namespaces
-                    scope.classes.Add(PrepareClass(scope));
-                    i = 0;
-                }
-
-                //If the current token is a decleration of a namespace
-                else if (scope.tokens[i] == Tokens.Function)
-                {
-                    //Save current position in the list
-                    scope.pos = i;
+                    //Add a class object to the list of namespaces
+                    Namespace.classes.Add(PrepareClass(Namespace, i, out i));
+                }
+
+                //If the current token is a decleration of a function
+                else if (Namespace.tokens[i] == Tokens.Function)
+                {
                     //Add a function object to the list of functions
-                    scope.functions.Add(PrepareFunction(scope));
-                    i = 0;
+                    Namespace.functions.Add(PrepareFunction(Namespace, i, out i));
                 }

                 else
@@ -281,10 +264,44 @@
                     PrintError("Instructions can't be executed within an uncallable scope");
                 }
             }
-
             Namespace.pos = startPos;
             position = endPos;
             return Namespace;
+        }
+
+        silent_Namespace scanForName(string name, silent_Namespace namespaceToScan)
+        {
+            silent_Namespace objectPath = new silent_Namespace()
+            {
+                name = namespaceToScan.name
+            };
+
+            if(objectPath.name == name)
+            {
+                return objectPath;
+            }
+
+            for(int i = 0; i <= namespaceToScan.namespaces.Count; i++)
+            {
+
+                for(int x = 0; x < namespaceToScan.classes.Count; x++)
+                {
+
+                    if (namespaceToScan.classes[x].name == name)
+                    {
+                        objectPath.classes.Add(namespaceToScan.classes[x]); return objectPath;
+                    }
+
+                    for(int y = 0; y < namespaceToScan.classes[x].members.Count; x++)
+                    {
+
+                    }
+
+                }
+
+            }
+
+            return objectPath;
         }

         int CountVal(int pos)


Oops, other half of fix for issue #189

Oops, other half of fix for issue #189

--- Simple.Data.Ado/EagerLoadingEnumerable.cs
+++ Simple.Data.Ado/EagerLoadingEnumerable.cs
@@ -83,7 +83,10 @@
                     {
                         var withContainer = new WithContainer();
                         withContainer.SetSingle(tuple.Item2);
-                        withContainers.Add(tuple.Item1, withContainer);
+                        if (!ReferenceEquals(withContainer.Single, null))
+                        {
+                            withContainers.Add(tuple.Item1, withContainer);
+                        }
                     }
                 }

@@ -114,6 +117,7 @@

             public void SetSingle(IDictionary<string,object> row)
             {
+                if (row.All(kvp => ReferenceEquals(null, kvp.Value))) return;
                 Single = row;
             }
         }


fix string in test

fix string in test

--- Simpler.Tests/Core/Tasks/CreateJobTest.cs
+++ Simpler.Tests/Core/Tasks/CreateJobTest.cs
@@ -18,7 +18,7 @@

             // Assert
             Assert.That(job.JobInstance, Is.InstanceOf<MockTask>());
-            Assert.That(job.JobInstance.GetType().Name, Is.Not.EqualTo("MockJobWithOnExecuteAttributeProxy"));
+            Assert.That(job.JobInstance.GetType().Name, Is.Not.EqualTo("MockTaskWithAttributesProxy"));
         }

         [Test]
@@ -32,7 +32,7 @@

             // Assert
             Assert.That(job.JobInstance, Is.InstanceOf<MockTaskWithAttributes>());
-            Assert.That(job.JobInstance.GetType().Name, Is.EqualTo("MockJobWithAttributesProxy"));
+            Assert.That(job.JobInstance.GetType().Name, Is.EqualTo("MockTaskWithAttributesProxy"));
         }
     }
 }


Add emitter callback for event success/failure counts (closes #52)

--- Snowplow.Tracker/Emitters/AsyncEmitter.cs
+++ Snowplow.Tracker/Emitters/AsyncEmitter.cs
@@ -28,6 +28,8 @@
 {
     public class AsyncEmitter : IEmitter, IDisposable
     {
+        public delegate void SendSuccessDelegate(int successCount, int failureCount);
+
         private readonly object _startStopLock = new object();
         private readonly object _backOffLock = new object();
         private bool _denyBackOff = false;
@@ -38,6 +40,7 @@
         private IEndpoint _endpoint;
         private int _stopPollIntervalMs;
         private ILogger _logger;
+        private SendSuccessDelegate _sendSuccessMethod;

         private readonly int _backOffIntervalMinMs = 5000;
         private readonly int _backOffIntervalMaxMs = 30000;
@@ -56,14 +59,23 @@
             }
         }

+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="endpoint"></param>
+        /// <param name="queue"></param>
+        /// <param name="stopPollIntervalMs"></param>
+        /// <param name="l"></param>
         public AsyncEmitter(IEndpoint endpoint,
                             IPersistentBlockingQueue queue,
                             int stopPollIntervalMs = 300,
+                            SendSuccessDelegate sendSuccessMethod = null,
                             ILogger l = null)
         {
             _queue = queue;
             _endpoint = endpoint;
             _stopPollIntervalMs = stopPollIntervalMs;
+            _sendSuccessMethod = sendSuccessMethod;
             _logger = l ?? new NoLogging();
         }

@@ -105,12 +117,18 @@

                     _logger.Info(String.Format("Emitter dequeued {0} events", items.Count));

+                    var successCount = 0;
+                    var failureCount = 0;
+
                     foreach (var item in items)
                     {
                         if (!_endpoint.Send(item))
                         {
+                            failureCount++;
+
                             _logger.Warn("Emitter returning event to queue");
                             _queue.Enqueue(new List<Payload>() { item });
+
                             // slow down - back off 30 secs
                             // NB this can be interrupted by Flush
                             lock (_backOffLock)
@@ -126,8 +144,13 @@
                                 }
                             }
                         }
+                        else
+                        {
+                            successCount++;
+                        }
                     }

+                    _sendSuccessMethod?.Invoke(successCount, failureCount);
                 }
                 else
                 {


Gave more RAM allocation to subscribers

Gave more RAM allocation to subscribers

--- Engine/Engine.cs
+++ Engine/Engine.cs
@@ -145,7 +145,7 @@
             get
             {
                 //Total Physical Ram Available:
-                var allocation = 1024;
+                var allocation = 3072;
                 var ram = Convert.ToInt32(OS.TotalPhysicalMemory);

                 if (ram < allocation)
@@ -334,7 +334,7 @@

                             Log.Trace("Engine.Run(): Exiting Algorithm Manager");

-                        }, MaximumRamAllocation);
+                            }, job.UserPlan == UserPlan.Free ? 1024 : MaximumRamAllocation);

                         if (!complete)
                         {


Added: All interfaces implemented to `IChangeTrackable`

--- Source/ChangeTracking/IChangeTrackable.cs
+++ Source/ChangeTracking/IChangeTrackable.cs
@@ -1,13 +1,11 @@
 using System;
-using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
 using System.Linq.Expressions;
-using System.Text;

 namespace ChangeTracking
 {
-    public interface IChangeTrackable<T> : IChangeTrackable, IRevertibleChangeTracking
+    public interface IChangeTrackable<T> : IChangeTrackable
     {
         /// <summary>
         /// Gets the original value of a given property.
@@ -45,7 +43,7 @@
         T GetOriginal();
     }

-    public interface IChangeTrackable : INotifyPropertyChanged
+    public interface IChangeTrackable : INotifyPropertyChanged, IChangeTracking, IRevertibleChangeTracking, IEditableObject
     {
         event EventHandler StatusChanged;
         ChangeStatus ChangeTrackingStatus { get; }


Fixed Comment Typos

Fixed Comment Typos

--- Source/Core/Duality/Drawing/DrawDevice.cs
+++ Source/Core/Duality/Drawing/DrawDevice.cs
@@ -865,15 +865,12 @@
 					matHash = (13 * matHash + 17 * (matHash >> 9)) % (1 << 23);
 				}

-				// Bit significancy is used to achieve sorting by multiple traits at once.
-				// The higher a traits bit significancy, the higher its priority when sorting.
+				// Bit significance is used to achieve sorting by multiple traits at once.
+				// The higher a traits bit significance, the higher its priority when sorting.
 				sortData[i].SortIndex =
 					(((int)vertexMode & 15) << 0) | //                           XXXX  4 Bit   Vertex Mode  Offset 4
 					((matHash & 8388607) << 4) |    //    XXXXXXXXXXXXXXXXXXXXXXXaaaa  23 Bit  Material     Offset 27
 					((vertexTypeIndex & 15) << 27); // XXXbbbbbbbbbbbbbbbbbbbbbbbaaaa  4 Bit   Vertex Type  Offset 31
-
-				// Keep an eye on this. If for example two material hash codes randomly have the same 23 lower bits, they
-				// will be sorted as if equal, resulting in blocking batch aggregation.
 			}
 		}
 		private void AggregateBatches(RawList<SortItem> sortItems, RawList<VertexDrawItem> drawItems, RawList<DrawBatch> batches)