Explorar o código

Merge remote-tracking branch 'upstream/master' into embed

Nikita Tsukanov %!s(int64=9) %!d(string=hai) anos
pai
achega
dccbec50ca
Modificáronse 73 ficheiros con 1710 adicións e 399 borrados
  1. 8 0
      .gitignore
  2. 1 10
      .travis.yml
  3. 42 5
      Avalonia.sln
  4. 7 0
      NuGet.Config
  5. 19 23
      appveyor.yml
  6. 776 0
      build.cake
  7. 201 0
      build.ps1
  8. 105 0
      build.sh
  9. 86 0
      docs/tutorial/nuget.md
  10. 4 0
      docs/tutorial/toc.yml
  11. 0 2
      nuget/.gitignore
  12. 0 35
      nuget/build-appveyor.ps1
  13. 0 84
      nuget/build-version.ps1
  14. 0 1
      nuget/build.ps1
  15. 0 1
      nuget/include.ps1
  16. 0 28
      nuget/template/Avalonia.Android.nuspec
  17. 0 30
      nuget/template/Avalonia.Desktop.nuspec
  18. 0 20
      nuget/template/Avalonia.Skia.Desktop.nuspec
  19. 0 27
      nuget/template/Avalonia.iOS.nuspec
  20. 0 26
      nuget/template/Avalonia.nuspec
  21. 4 0
      samples/BindingTest/BindingTest.csproj
  22. 4 4
      samples/ControlCatalog.Desktop/App.config
  23. 4 0
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  24. 4 0
      samples/TestApplication/TestApplication.csproj
  25. 4 4
      samples/VirtualizationTest/App.config
  26. 4 0
      samples/VirtualizationTest/VirtualizationTest.csproj
  27. 6 2
      samples/XamlTestApplication/XamlTestApplication.csproj
  28. 1 1
      samples/XamlTestApplication/packages.config
  29. 1 1
      src/Android/Avalonia.Android/AndroidPlatform.cs
  30. 1 0
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  31. 18 0
      src/Android/Avalonia.Android/RuntimeInfo.cs
  32. 3 3
      src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
  33. 2 2
      src/Android/Avalonia.AndroidTestApplication/packages.config
  34. 1 1
      src/Avalonia.Base/Avalonia.Base.csproj
  35. 1 1
      src/Avalonia.Base/AvaloniaDisposable.cs
  36. 0 17
      src/Avalonia.Base/Platform/IPclPlatformWrapper.cs
  37. 39 0
      src/Avalonia.Base/Platform/IRuntimePlatform.cs
  38. 2 2
      src/Avalonia.Base/Threading/SingleThreadDispatcher.cs
  39. 31 23
      src/Avalonia.Controls/AppBuilder.cs
  40. 11 3
      src/Avalonia.DesignerSupport/DesignerAssist.cs
  41. 40 0
      src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs
  42. 84 0
      src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
  43. 36 0
      src/Avalonia.DotNetFrameworkRuntime/Properties/AssemblyInfo.cs
  44. 44 0
      src/Avalonia.DotNetFrameworkRuntime/RuntimeInfo.cs
  45. 5 0
      src/Avalonia.DotNetFrameworkRuntime/packages.config
  46. 1 1
      src/Gtk/Avalonia.Cairo/CairoPlatform.cs
  47. 0 1
      src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
  48. 1 3
      src/Gtk/Avalonia.Gtk/GtkPlatform.cs
  49. 3 2
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  50. 1 1
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs
  51. 1 0
      src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs
  52. 39 0
      src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs
  53. 1 1
      src/Markup/Avalonia.Markup.Xaml/packages.config
  54. 3 3
      src/Shared/PlatformSupport/PlatformSupport.projitems
  55. 3 1
      src/Shared/PlatformSupport/StandardRuntimePlatform.cs
  56. 2 2
      src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs
  57. 3 3
      src/Shared/SharedAssemblyInfo.cs
  58. 1 1
      src/Skia/Avalonia.Skia/SkiaPlatform.cs
  59. 1 1
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
  60. 0 1
      src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
  61. 2 4
      src/Windows/Avalonia.Win32/Win32Platform.cs
  62. 1 0
      src/iOS/Avalonia.iOS/Avalonia.iOS.csproj
  63. 17 0
      src/iOS/Avalonia.iOS/RuntimeInfo.cs
  64. 3 3
      src/iOS/Avalonia.iOS/iOSPlatform.cs
  65. 4 0
      tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
  66. 4 1
      tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj
  67. 1 1
      tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs
  68. 4 1
      tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
  69. 2 2
      tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
  70. 1 1
      tests/Avalonia.Markup.Xaml.UnitTests/packages.config
  71. 4 1
      tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj
  72. 7 7
      tests/Avalonia.UnitTests/TestServices.cs
  73. 1 1
      tests/Avalonia.UnitTests/UnitTestApplication.cs

+ 8 - 0
.gitignore

@@ -152,3 +152,11 @@ $RECYCLE.BIN/
 #################
 *.userprefs
 *.nugetreferenceswitcher
+
+#################
+## Cake
+#################
+tools/
+.nuget
+artifacts/
+nuget

+ 1 - 10
.travis.yml

@@ -4,17 +4,8 @@ os:
   - osx
 mono:
   - latest
-solution: Avalonia.travis-mono.sln
-before_install:
-  - mkdir -p .nuget
-  - wget -O .nuget/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
-install:
-  - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y gtk-sharp2 ; fi
-  - mono .nuget/nuget.exe restore Avalonia.sln
-  - mono .nuget/nuget.exe install xunit.runner.console -Version 2.1.0 -OutputDirectory testrunner
 script:
-  - xbuild /p:Platform=Mono /p:Configuration=Release Avalonia.sln
-  - ./tests/run-tests.sh
+  - ./build.sh --target "Travis" --platform "Mono" --configuration "Release"
 notifications:
   email: false
   webhooks:

+ 42 - 5
Avalonia.sln

@@ -168,6 +168,7 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{C7A69145-60B6-4882-97D6-A3921DD43978}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GtkInteropDemo", "samples\interop\GtkInteropDemo\GtkInteropDemo.csproj", "{BD7F352C-6DC1-4740-BAF2-2D34A038728C}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DotNetFrameworkRuntime", "src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj", "{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}"
 EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
@@ -178,11 +179,9 @@ Global
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4
 		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{48840edd-24bf-495d-911e-2eb12ae75d3b}*SharedItemsImports = 13
-		src\Shared\PlatformSupport\PlatformSupport.projitems*{54f237d5-a70a-4752-9656-0c70b1a7b047}*SharedItemsImports = 4
+		src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4
 		samples\TestApplicationShared\TestApplicationShared.projitems*{78345174-5b52-4a14-b9fd-d5f2428137f0}*SharedItemsImports = 13
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4
-		src\Shared\PlatformSupport\PlatformSupport.projitems*{811a76cf-1cf6-440f-963b-bbe31bd72a82}*SharedItemsImports = 4
-		src\Shared\PlatformSupport\PlatformSupport.projitems*{88060192-33d5-4932-b0f9-8bd2763e857d}*SharedItemsImports = 4
 		samples\TestApplicationShared\TestApplicationShared.projitems*{8c923867-8a8f-4f6b-8b80-47d9e8436166}*SharedItemsImports = 4
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4
 		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4
@@ -190,9 +189,7 @@ Global
 		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{bd43f7c0-396b-4aa1-bad9-dfde54d51298}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{d35a9f3d-8bb0-496e-bf72-444038a7debb}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{dabfd304-d6a4-4752-8123-c2ccf7ac7831}*SharedItemsImports = 4
-		src\Shared\PlatformSupport\PlatformSupport.projitems*{db070a10-bf39-4752-8456-86e9d5928478}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{e106cf37-4066-4615-b684-172a6d30b058}*SharedItemsImports = 4
-		src\Shared\PlatformSupport\PlatformSupport.projitems*{e1aa3dbf-9056-4530-9376-18119a7a3ffe}*SharedItemsImports = 4
 		samples\TestApplicationShared\TestApplicationShared.projitems*{e3a1060b-50d0-44e8-88b6-f44ef2e5bd72}*SharedItemsImports = 4
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{fb05ac90-89ba-4f2f-a924-f37875fb547c}*SharedItemsImports = 4
@@ -2328,6 +2325,46 @@ Global
 		{BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|Mono.Build.0 = Release|Any CPU
 		{BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|x86.ActiveCfg = Release|Any CPU
 		{BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|x86.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Mono.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Mono.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Mono.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Mono.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|x86.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|x86.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Mono.Build.0 = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|x86.Build.0 = Debug|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Mono.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Mono.Build.0 = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|x86.ActiveCfg = Release|Any CPU
+		{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 7 - 0
NuGet.Config

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <packageSources>
+    <clear />
+    <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
+  </packageSources>
+</configuration>

+ 19 - 23
appveyor.yml

@@ -1,31 +1,27 @@
-version: 1.0.{build}
 os: Visual Studio 2015
-before_build:
-- git submodule update --init
-- nuget restore Avalonia.sln
-
+platform:
+- Any CPU
+configuration:
+- Release
 environment:
-  myget_key:
-    secure: XOgD5bJUKNOS2kDDgb+affS4pDcslxALh+xvvnr1Koy0PjXlhILsBdNhxRe0KcNm
-
+  NUGET_API_KEY:
+    secure: Xv89dlP2MSBZKhl1nrWSxqcDgCXB0HRhOd4SWQ+jRJ7QoLxQel5mLTipXM++J3G5
+  NUGET_API_URL: https://www.nuget.org/api/v2/package
+  MYGET_API_KEY:
+    secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK
+  MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package
 install:
   - if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi
   - msiexec /i gtk-sharp-2.12.26.msi /qn /norestart
   - cmd: set PATH=%programfiles(x86)%\GtkSharp\2.12\bin\;%PATH%
-
-cache:
-  - gtk-sharp-2.12.26.msi
-  
-configuration:
-  - Release
-
-after_test:
+before_build:
+- git submodule update --init
+build_script:
+- ps: .\build.ps1 -Target "AppVeyor" -Platform "$env:platform" -Configuration "$env:configuration"
+after_build:
 - .\packages\JetBrains.dotMemoryUnit.2.1.20150828.125449\tools\dotMemoryUnit.exe -targetExecutable="%xunit20%\xunit.console.x86.exe" -returnTargetExitCode  --"tests\Avalonia.LeakTests\bin\Release\Avalonia.LeakTests.dll"
-- ps: nuget\build-appveyor.ps1
-
+test: off
 artifacts:
-  - path: nuget\*.nupkg
-
-build:
-  project: Avalonia.sln
-  verbosity: minimal
+  - path: artifacts\nuget\*.nupkg
+cache:
+  - gtk-sharp-2.12.26.msi

+ 776 - 0
build.cake

@@ -0,0 +1,776 @@
+///////////////////////////////////////////////////////////////////////////////
+// ADDINS
+///////////////////////////////////////////////////////////////////////////////
+
+#addin "nuget:?package=Polly&version=4.2.0"
+#addin "nuget:?package=NuGet.Core&version=2.12.0"
+
+///////////////////////////////////////////////////////////////////////////////
+// TOOLS
+///////////////////////////////////////////////////////////////////////////////
+
+#tool "nuget:?package=xunit.runner.console&version=2.1.0"
+
+///////////////////////////////////////////////////////////////////////////////
+// USINGS
+///////////////////////////////////////////////////////////////////////////////
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Polly;
+using NuGet;
+
+///////////////////////////////////////////////////////////////////////////////
+// ARGUMENTS
+///////////////////////////////////////////////////////////////////////////////
+
+var target = Argument("target", "Default");
+var platform = Argument("platform", "Any CPU");
+var configuration = Argument("configuration", "Release");
+var skipTests = HasArgument("skip-tests");
+///////////////////////////////////////////////////////////////////////////////
+// CONFIGURATION
+///////////////////////////////////////////////////////////////////////////////
+
+var MainRepo = "AvaloniaUI/Avalonia";
+var MasterBranch = "master";
+var AssemblyInfoPath = File("./src/Shared/SharedAssemblyInfo.cs");
+var ReleasePlatform = "Any CPU";
+var ReleaseConfiguration = "Release";
+var MSBuildSolution = "./Avalonia.sln";
+var XBuildSolution = "./Avalonia.sln";
+
+///////////////////////////////////////////////////////////////////////////////
+// PARAMETERS
+///////////////////////////////////////////////////////////////////////////////
+
+var isPlatformAnyCPU = StringComparer.OrdinalIgnoreCase.Equals(platform, "Any CPU");
+var isPlatformX86 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x86");
+var isPlatformX64 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x64");
+var isLocalBuild = BuildSystem.IsLocalBuild;
+var isRunningOnUnix = IsRunningOnUnix();
+var isRunningOnWindows = IsRunningOnWindows();
+var isRunningOnAppVeyor = BuildSystem.AppVeyor.IsRunningOnAppVeyor;
+var isPullRequest = BuildSystem.AppVeyor.Environment.PullRequest.IsPullRequest;
+var isMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, BuildSystem.AppVeyor.Environment.Repository.Name);
+var isMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, BuildSystem.AppVeyor.Environment.Repository.Branch);
+var isTagged = BuildSystem.AppVeyor.Environment.Repository.Tag.IsTag 
+               && !string.IsNullOrWhiteSpace(BuildSystem.AppVeyor.Environment.Repository.Tag.Name);
+var isReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleasePlatform, platform) 
+                   && StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, configuration);
+var isMyGetRelease = !isTagged && isReleasable;
+var isNuGetRelease = isTagged && isReleasable;
+
+///////////////////////////////////////////////////////////////////////////////
+// VERSION
+///////////////////////////////////////////////////////////////////////////////
+
+var version = ParseAssemblyInfo(AssemblyInfoPath).AssemblyVersion;
+
+if (isRunningOnAppVeyor)
+{
+    if (isTagged)
+    {
+        // Use Tag Name as version
+        version = BuildSystem.AppVeyor.Environment.Repository.Tag.Name;
+    }
+    else
+    {
+        // Use AssemblyVersion with Build as version
+        version += "-build" + EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-alpha";
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// DIRECTORIES
+///////////////////////////////////////////////////////////////////////////////
+
+var artifactsDir = (DirectoryPath)Directory("./artifacts");
+var nugetRoot = artifactsDir.Combine("nuget");
+
+var dirSuffix = configuration;
+var dirSuffixSkia = (isPlatformAnyCPU ? "x86" : platform) + "/" + configuration;
+var dirSuffixIOS = "iPhone" + "/" + configuration;
+
+var buildDirs = 
+    GetDirectories("./src/**/bin/" + dirSuffix) + 
+    GetDirectories("./src/**/obj/" + dirSuffix) + 
+    GetDirectories("./src/Markup/**/bin/" + dirSuffix) + 
+    GetDirectories("./src/Markup/**/obj/" + dirSuffix) + 
+    GetDirectories("./src/Android/**/bin/" + dirSuffix) + 
+    GetDirectories("./src/Android/**/obj/" + dirSuffix) + 
+    GetDirectories("./src/Gtk/**/bin/" + dirSuffix) + 
+    GetDirectories("./src/Gtk/**/obj/" + dirSuffix) + 
+    GetDirectories("./src/iOS/**/bin/" + dirSuffixIOS) + 
+    GetDirectories("./src/iOS/**/obj/" + dirSuffixIOS) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/obj/" + dirSuffix) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/bin/" + dirSuffix) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/obj/" + dirSuffix) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + dirSuffixSkia) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/obj/" + dirSuffixSkia) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/obj/" + dirSuffixIOS) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/bin/" + dirSuffixIOS) + 
+    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/obj/" + dirSuffixIOS) + 
+    GetDirectories("./src/Windows/**/bin/" + dirSuffix) + 
+    GetDirectories("./src/Windows/**/obj/" + dirSuffix) + 
+    GetDirectories("./tests/**/bin/" + dirSuffix) + 
+    GetDirectories("./tests/**/obj/" + dirSuffix) + 
+    GetDirectories("./Samples/**/bin/" + dirSuffix) + 
+    GetDirectories("./Samples/**/obj/" + dirSuffix);
+
+///////////////////////////////////////////////////////////////////////////////
+// NUGET NUSPECS
+///////////////////////////////////////////////////////////////////////////////
+
+Information("Getting git modules:");
+
+var ignoredSubModulesPaths = System.IO.File.ReadAllLines(".git/config").Where(m=>m.StartsWith("[submodule ")).Select(m => 
+{
+    var path = m.Split(' ')[1].Trim("\"[] \t".ToArray());
+    Information(path);
+    return ((DirectoryPath)Directory(path)).FullPath;
+}).ToList();
+
+var normalizePath = new Func<string, string>(
+    path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant());
+
+// Key: Package Id
+// Value is Tuple where Item1: Package Version, Item2: The packages.config file path.
+var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
+
+System.IO.Directory.EnumerateFiles(((DirectoryPath)Directory("./src")).FullPath, "packages.config", SearchOption.AllDirectories).ToList().ForEach(fileName =>
+{
+    if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i))))
+    {
+        var file = new PackageReferenceFile(fileName);
+        foreach (PackageReference packageReference in file.GetPackageReferences())
+        {
+            IList<Tuple<string, string>> versions;
+            packageVersions.TryGetValue(packageReference.Id, out versions);
+            if (versions == null)
+            {
+                versions = new List<Tuple<string, string>>();
+                packageVersions[packageReference.Id] = versions;
+            }
+            versions.Add(Tuple.Create(packageReference.Version.ToString(), fileName));
+        }
+    }
+});
+
+Information("Checking installed NuGet package dependencies versions:");
+
+packageVersions.ToList().ForEach(package =>
+{
+    var packageVersion = package.Value.First().Item1;
+    bool isValidVersion = package.Value.All(x => x.Item1 == packageVersion);
+    if (!isValidVersion)
+    {
+        Information("Error: package {0} has multiple versions installed:", package.Key);
+        foreach (var v in package.Value)
+        {
+            Information("{0}, file: {1}", v.Item1, v.Item2);
+        }
+        throw new Exception("Detected multiple NuGet package version installed for different projects.");
+    }
+});
+
+Information("Setting NuGet package dependencies versions:");
+
+var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1;
+var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
+var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
+var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
+var SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
+var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
+var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
+var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
+
+Information("Package: Serilog, version: {0}", SerilogVersion);
+Information("Package: Splat, version: {0}", SplatVersion);
+Information("Package: Sprache, version: {0}", SpracheVersion);
+Information("Package: System.Reactive, version: {0}", SystemReactiveVersion);
+Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion);
+Information("Package: SharpDX, version: {0}", SharpDXVersion);
+Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version);
+Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
+
+var SetNuGetNuspecCommonProperties = new Action<NuGetPackSettings> ((nuspec) => {
+    nuspec.Version = version;
+    nuspec.Authors = new [] { "Avalonia Team" };
+    nuspec.Owners = new [] { "stevenk" };
+    nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT");
+    nuspec.ProjectUrl = new Uri("https://github.com/AvaloniaUI/Avalonia/");
+    nuspec.RequireLicenseAcceptance = false;
+    nuspec.Symbols = false;
+    nuspec.NoPackageAnalysis = true;
+    nuspec.Description = "The Avalonia UI framework";
+    nuspec.Copyright = "Copyright 2015";
+    nuspec.Tags = new [] { "Avalonia" };
+});
+
+var coreLibraries = new string[][]
+{
+    new [] { "./src/", "Avalonia.Animation", ".dll" },
+    new [] { "./src/", "Avalonia.Animation", ".xml" },
+    new [] { "./src/", "Avalonia.Base", ".dll" },
+    new [] { "./src/", "Avalonia.Base", ".xml" },
+    new [] { "./src/", "Avalonia.Controls", ".dll" },
+    new [] { "./src/", "Avalonia.Controls", ".xml" },
+    new [] { "./src/", "Avalonia.DesignerSupport", ".dll" },
+    new [] { "./src/", "Avalonia.DesignerSupport", ".xml" },
+    new [] { "./src/", "Avalonia.Diagnostics", ".dll" },
+    new [] { "./src/", "Avalonia.Diagnostics", ".xml" },
+    new [] { "./src/", "Avalonia.Input", ".dll" },
+    new [] { "./src/", "Avalonia.Input", ".xml" },
+    new [] { "./src/", "Avalonia.Interactivity", ".dll" },
+    new [] { "./src/", "Avalonia.Interactivity", ".xml" },
+    new [] { "./src/", "Avalonia.Layout", ".dll" },
+    new [] { "./src/", "Avalonia.Layout", ".xml" },
+    new [] { "./src/", "Avalonia.Logging.Serilog", ".dll" },
+    new [] { "./src/", "Avalonia.Logging.Serilog", ".xml" },
+    new [] { "./src/", "Avalonia.SceneGraph", ".dll" },
+    new [] { "./src/", "Avalonia.SceneGraph", ".xml" },
+    new [] { "./src/", "Avalonia.Styling", ".dll" },
+    new [] { "./src/", "Avalonia.Styling", ".xml" },
+    new [] { "./src/", "Avalonia.ReactiveUI", ".dll" },
+    new [] { "./src/", "Avalonia.Themes.Default", ".dll" },
+    new [] { "./src/", "Avalonia.Themes.Default", ".xml" },
+    new [] { "./src/Markup/", "Avalonia.Markup", ".dll" },
+    new [] { "./src/Markup/", "Avalonia.Markup", ".xml" },
+    new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".dll" },
+    new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".xml" }
+};
+
+var coreLibrariesFiles = coreLibraries.Select((lib) => {
+    return (FilePath)File(lib[0] + lib[1] + "/bin/" + dirSuffix + "/" + lib[1] + lib[2]);
+}).ToList();
+
+var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
+    return new NuSpecContent { 
+        Source = file.FullPath, Target = "lib/portable-windows8+net45" 
+    };
+});
+
+var win32CoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
+    return new NuSpecContent { 
+        Source = file.FullPath, Target = "lib/net45" 
+    };
+});
+
+var net45RuntimePlatformExtensions = new [] {".xml", ".dll"};
+var net45RuntimePlatform = net45RuntimePlatformExtensions.Select(libSuffix => {
+    return new NuSpecContent {
+        Source = ((FilePath)File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + dirSuffix + "/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, 
+        Target = "lib/net45" 
+    };
+});
+
+var nuspecNuGetSettingsCore = new []
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion },
+            new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
+            new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
+            new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion }
+        },
+        Files = coreLibrariesNuSpecContent.Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform).ToList(),
+        BasePath = Directory("./"),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.HtmlRenderer
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.HtmlRenderer",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/portable-windows8+net45" }
+        },
+        BasePath = Directory("./src/Avalonia.HtmlRenderer/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    }
+};
+
+var nuspecNuGetSettingsMobile = new []
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Android
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Android",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" }
+        },
+        BasePath = Directory("./src/Android/Avalonia.Android/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Skia.Android
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Skia.Android",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" }
+        },
+        BasePath = Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.iOS
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.iOS",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Skia.iOS", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.iOS.dll", Target = "lib/Xamarin.iOS10" }
+        },
+        BasePath = Directory("./src/iOS/Avalonia.iOS/bin/" + dirSuffixIOS),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Skia.iOS
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Skia.iOS",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Skia.iOS.dll", Target = "lib/Xamarin.iOS10" }
+        },
+        BasePath = Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Mobile
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Mobile",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia.Android", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.iOS", Version = version }
+        },
+        Files = new NuSpecContent[]
+        {
+            new NuSpecContent { Source = "licence.md", Target = "" }
+        },
+        BasePath = Directory("./"),
+        OutputDirectory = nugetRoot
+    }
+};
+
+var nuspecNuGetSettingsDesktop = new []
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Win32
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Win32",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Win32.dll", Target = "lib/net45" }
+        },
+        BasePath = Directory("./src/Windows/Avalonia.Win32/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Direct2D1
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Direct2D1",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "SharpDX", Version = SharpDXVersion },
+            new NuSpecDependency() { Id = "SharpDX.Direct2D1", Version = SharpDXDirect2D1Version },
+            new NuSpecDependency() { Id = "SharpDX.DXGI", Version = SharpDXDXGIVersion }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/net45" }
+        },
+        BasePath = Directory("./src/Windows/Avalonia.Direct2D1/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Gtk
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Gtk",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Gtk.dll", Target = "lib/net45" }
+        },
+        BasePath = Directory("./src/Gtk/Avalonia.Gtk/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Cairo
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Cairo",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Cairo.dll", Target = "lib/net45" }
+        },
+        BasePath = Directory("./src/Gtk/Avalonia.Cairo/bin/" + dirSuffix),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Skia.Desktop
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Skia.Desktop",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia", Version = version },
+            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
+        },
+        Files = new []
+        {
+            new NuSpecContent { Source = "Avalonia.Skia.Desktop.dll", Target = "lib/net45" }
+        },
+        BasePath = Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + dirSuffixSkia),
+        OutputDirectory = nugetRoot
+    },
+    ///////////////////////////////////////////////////////////////////////////////
+    // Avalonia.Desktop
+    ///////////////////////////////////////////////////////////////////////////////
+    new NuGetPackSettings()
+    {
+        Id = "Avalonia.Desktop",
+        Dependencies = new []
+        {
+            new NuSpecDependency() { Id = "Avalonia.Win32", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Gtk", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Cairo", Version = version },
+            new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = version }
+        },
+        Files = new NuSpecContent[]
+        {
+            new NuSpecContent { Source = "licence.md", Target = "" }
+        },
+        BasePath = Directory("./"),
+        OutputDirectory = nugetRoot
+    }
+};
+
+var nuspecNuGetSettings = new List<NuGetPackSettings>();
+
+nuspecNuGetSettings.AddRange(nuspecNuGetSettingsCore);
+nuspecNuGetSettings.AddRange(nuspecNuGetSettingsDesktop);
+nuspecNuGetSettings.AddRange(nuspecNuGetSettingsMobile);
+
+nuspecNuGetSettings.ForEach((nuspec) => SetNuGetNuspecCommonProperties(nuspec));
+
+var nugetPackages = nuspecNuGetSettings.Select(nuspec => {
+    return nuspec.OutputDirectory.CombineWithFilePath(string.Concat(nuspec.Id, ".", nuspec.Version, ".nupkg"));
+}).ToArray();
+
+///////////////////////////////////////////////////////////////////////////////
+// INFORMATION
+///////////////////////////////////////////////////////////////////////////////
+
+Information("Building version {0} of Avalonia ({1}, {2}, {3}) using version {4} of Cake.", 
+    version,
+    platform,
+    configuration,
+    target,
+    typeof(ICakeContext).Assembly.GetName().Version.ToString());
+
+if (isRunningOnAppVeyor)
+{
+    Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name);
+    Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch);
+}
+
+Information("Target: " + target);
+Information("Platform: " + platform);
+Information("Configuration: " + configuration);
+Information("IsLocalBuild: " + isLocalBuild);
+Information("IsRunningOnUnix: " + isRunningOnUnix);
+Information("IsRunningOnWindows: " + isRunningOnWindows);
+Information("IsRunningOnAppVeyor: " + isRunningOnAppVeyor);
+Information("IsPullRequest: " + isPullRequest);
+Information("IsMainRepo: " + isMainRepo);
+Information("IsMasterBranch: " + isMasterBranch);
+Information("IsTagged: " + isTagged);
+Information("IsReleasable: " + isReleasable);
+Information("IsMyGetRelease: " + isMyGetRelease);
+Information("IsNuGetRelease: " + isNuGetRelease);
+
+///////////////////////////////////////////////////////////////////////////////
+// TASKS
+///////////////////////////////////////////////////////////////////////////////
+
+Task("Clean")
+    .Does(() =>
+{
+    CleanDirectories(buildDirs);
+    CleanDirectory(artifactsDir);
+    CleanDirectory(nugetRoot);
+});
+
+Task("Restore-NuGet-Packages")
+    .IsDependentOn("Clean")
+    .Does(() =>
+{
+    var maxRetryCount = 5;
+    var toolTimeout = 1d;
+    Policy
+        .Handle<Exception>()
+        .Retry(maxRetryCount, (exception, retryCount, context) => {
+            if (retryCount == maxRetryCount)
+            {
+                throw exception;
+            }
+            else
+            {
+                Verbose("{0}", exception);
+                toolTimeout+=0.5;
+            }})
+        .Execute(()=> {
+            if(isRunningOnWindows)
+            {
+                NuGetRestore(MSBuildSolution, new NuGetRestoreSettings {
+                    ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
+                });
+            }
+            else
+            {
+                NuGetRestore(XBuildSolution, new NuGetRestoreSettings {
+                    ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
+                });
+            }
+        });
+});
+
+Task("Build")
+    .IsDependentOn("Restore-NuGet-Packages")
+    .Does(() =>
+{
+    if(isRunningOnWindows)
+    {
+        MSBuild(MSBuildSolution, settings => {
+            settings.SetConfiguration(configuration);
+            settings.WithProperty("Platform", "\"" + platform + "\"");
+            settings.SetVerbosity(Verbosity.Minimal);
+            settings.WithProperty("Windows", "True");
+            settings.UseToolVersion(MSBuildToolVersion.VS2015);
+            settings.SetNodeReuse(false);
+        });
+    }
+    else
+    {
+        XBuild(XBuildSolution, settings => {
+            settings.SetConfiguration(configuration);
+            settings.WithProperty("Platform", "\"" + platform + "\"");
+            settings.SetVerbosity(Verbosity.Minimal);
+        });
+    }
+});
+
+Task("Run-Unit-Tests")
+    .IsDependentOn("Build")
+    .WithCriteria(() => !skipTests)
+    .Does(() =>
+{
+    var pattern = "./tests/Avalonia.*.UnitTests/bin/" + dirSuffix + "/Avalonia.*.UnitTests.dll";
+
+    Func<IFileSystemInfo, bool> ExcludeWindowsTests = i => {
+        return !(i.Path.FullPath.IndexOf("Direct2D", StringComparison.OrdinalIgnoreCase) >= 0);
+    };
+
+    var unitTests = isRunningOnWindows ? GetFiles(pattern) : GetFiles(pattern, ExcludeWindowsTests);
+
+    if (isRunningOnWindows)
+    {
+        var windowsTests = GetFiles("./tests/Avalonia.DesignerSupport.Tests/bin/" + dirSuffix + "/*Tests.dll") + 
+                           GetFiles("./tests/Avalonia.LeakTests/bin/" + dirSuffix + "/*Tests.dll") + 
+                           GetFiles("./tests/Avalonia.RenderTests/bin/" + dirSuffix + "/*Tests.dll");
+
+        unitTests += windowsTests;
+    }
+
+    var toolPath = (isPlatformAnyCPU || isPlatformX86) ? 
+        "./tools/xunit.runner.console/tools/xunit.console.x86.exe" :
+        "./tools/xunit.runner.console/tools/xunit.console.exe";
+
+    var settings = new XUnit2Settings 
+    { 
+        ToolPath = toolPath,
+        Parallelism = ParallelismOption.None 
+    };
+
+    if (isRunningOnWindows)
+    {
+        settings.NoAppDomain = false;
+    }
+
+    foreach (var file in unitTests)
+    {
+        Information("Running test " + file.GetFilenameWithoutExtension());
+        XUnit2(file.FullPath, settings);
+    }
+});
+
+Task("Create-NuGet-Packages")
+    .IsDependentOn("Run-Unit-Tests")
+    .Does(() =>
+{
+    foreach(var nuspec in nuspecNuGetSettings)
+    {
+        NuGetPack(nuspec);
+    }
+});
+
+Task("Publish-MyGet")
+    .IsDependentOn("Create-NuGet-Packages")
+    .WithCriteria(() => !isLocalBuild)
+    .WithCriteria(() => !isPullRequest)
+    .WithCriteria(() => isMainRepo)
+    .WithCriteria(() => isMasterBranch)
+    .WithCriteria(() => isMyGetRelease)
+    .Does(() =>
+{
+    var apiKey = EnvironmentVariable("MYGET_API_KEY");
+    if(string.IsNullOrEmpty(apiKey)) 
+    {
+        throw new InvalidOperationException("Could not resolve MyGet API key.");
+    }
+
+    var apiUrl = EnvironmentVariable("MYGET_API_URL");
+    if(string.IsNullOrEmpty(apiUrl)) 
+    {
+        throw new InvalidOperationException("Could not resolve MyGet API url.");
+    }
+
+    foreach(var nupkg in nugetPackages)
+    {
+        NuGetPush(nupkg, new NuGetPushSettings {
+            Source = apiUrl,
+            ApiKey = apiKey
+        });
+    }
+})
+.OnError(exception =>
+{
+    Information("Publish-MyGet Task failed, but continuing with next Task...");
+});
+
+Task("Publish-NuGet")
+    .IsDependentOn("Create-NuGet-Packages")
+    .WithCriteria(() => !isLocalBuild)
+    .WithCriteria(() => !isPullRequest)
+    .WithCriteria(() => isMainRepo)
+    .WithCriteria(() => isMasterBranch)
+    .WithCriteria(() => isNuGetRelease)
+    .Does(() =>
+{
+    var apiKey = EnvironmentVariable("NUGET_API_KEY");
+    if(string.IsNullOrEmpty(apiKey)) 
+    {
+        throw new InvalidOperationException("Could not resolve NuGet API key.");
+    }
+
+    var apiUrl = EnvironmentVariable("NUGET_API_URL");
+    if(string.IsNullOrEmpty(apiUrl)) 
+    {
+        throw new InvalidOperationException("Could not resolve NuGet API url.");
+    }
+
+    foreach(var nupkg in nugetPackages)
+    {
+        NuGetPush(nupkg, new NuGetPushSettings {
+            ApiKey = apiKey,
+            Source = apiUrl
+        });
+    }
+})
+.OnError(exception =>
+{
+    Information("Publish-NuGet Task failed, but continuing with next Task...");
+});
+
+///////////////////////////////////////////////////////////////////////////////
+// TARGETS
+///////////////////////////////////////////////////////////////////////////////
+
+Task("Package")
+  .IsDependentOn("Create-NuGet-Packages");
+
+Task("Default")
+  .IsDependentOn("Package");
+
+Task("AppVeyor")
+  .IsDependentOn("Publish-MyGet")
+  .IsDependentOn("Publish-NuGet");
+
+Task("Travis")
+  .IsDependentOn("Run-Unit-Tests");
+
+///////////////////////////////////////////////////////////////////////////////
+// EXECUTE
+///////////////////////////////////////////////////////////////////////////////
+
+RunTarget(target);

+ 201 - 0
build.ps1

@@ -0,0 +1,201 @@
+##########################################################################
+# This is the Cake bootstrapper script for PowerShell.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
+
+<#
+
+.SYNOPSIS
+This is a Powershell script to bootstrap a Cake build.
+
+.DESCRIPTION
+This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
+and execute your Cake build script with the parameters you provide.
+
+.PARAMETER Script
+The build script to execute.
+.PARAMETER Target
+The build script target to run.
+.PARAMETER Platform
+The build platform to use.
+.PARAMETER Configuration
+The build configuration to use.
+.PARAMETER Verbosity
+Specifies the amount of information to be displayed.
+.PARAMETER Experimental
+Tells Cake to use the latest Roslyn release.
+.PARAMETER WhatIf
+Performs a dry run of the build script.
+No tasks will be executed.
+.PARAMETER Mono
+Tells Cake to use the Mono scripting engine.
+.PARAMETER SkipToolPackageRestore
+Skips restoring of packages.
+.PARAMETER SkipTests
+Skips unit tests
+.PARAMETER ScriptArgs
+Remaining arguments are added here.
+
+.LINK
+http://cakebuild.net
+
+#>
+
+[CmdletBinding()]
+Param(
+    [string]$Script = "build.cake",
+    [string]$Target = "Default",
+    [ValidateSet("Any CPU", "x86", "x64", "Mono", "iPhone")]
+    [string]$Platform = "Any CPU",
+    [ValidateSet("Release", "Debug")]
+    [string]$Configuration = "Release",
+    [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
+    [string]$Verbosity = "Verbose",
+    [switch]$Experimental,
+    [Alias("DryRun","Noop")]
+    [switch]$WhatIf,
+    [switch]$Mono,
+    [switch]$SkipToolPackageRestore,
+    [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+    [string[]]$ScriptArgs
+)
+
+[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
+function MD5HashFile([string] $filePath)
+{
+    if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
+    {
+        return $null
+    }
+
+    [System.IO.Stream] $file = $null;
+    [System.Security.Cryptography.MD5] $md5 = $null;
+    try
+    {
+        $md5 = [System.Security.Cryptography.MD5]::Create()
+        $file = [System.IO.File]::OpenRead($filePath)
+        return [System.BitConverter]::ToString($md5.ComputeHash($file))
+    }
+    finally
+    {
+        if ($file -ne $null)
+        {
+            $file.Dispose()
+        }
+    }
+}
+
+Write-Host "Preparing to run build script..."
+
+if(!$PSScriptRoot){
+    $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+}
+
+$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
+$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
+$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
+$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
+$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
+$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
+
+# Should we use mono?
+$UseMono = "";
+if($Mono.IsPresent) {
+    Write-Verbose -Message "Using the Mono based scripting engine."
+    $UseMono = "-mono"
+}
+
+# Should we use the new Roslyn?
+$UseExperimental = "";
+if($Experimental.IsPresent -and !($Mono.IsPresent)) {
+    Write-Verbose -Message "Using experimental version of Roslyn."
+    $UseExperimental = "-experimental"
+}
+
+# Is this a dry run?
+$UseDryRun = "";
+if($WhatIf.IsPresent) {
+    $UseDryRun = "-dryrun"
+}
+
+# Is this a dry run?
+$UseSkipTests = "";
+if($SkipTests.IsPresent) {
+    $UseSkipTests = "-skip-tests"
+}
+
+# Make sure tools folder exists
+if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
+    Write-Verbose -Message "Creating tools directory..."
+    New-Item -Path $TOOLS_DIR -Type directory | out-null
+}
+
+# Make sure that packages.config exist.
+if (!(Test-Path $PACKAGES_CONFIG)) {
+    Write-Verbose -Message "Downloading packages.config..."
+    try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
+        Throw "Could not download packages.config."
+    }
+}
+
+# Try find NuGet.exe in path if not exists
+if (!(Test-Path $NUGET_EXE)) {
+    Write-Verbose -Message "Trying to find nuget.exe in PATH..."
+    $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) }
+    $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
+    if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
+        Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
+        $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
+    }
+}
+
+# Try download NuGet.exe if not exists
+if (!(Test-Path $NUGET_EXE)) {
+    Write-Verbose -Message "Downloading NuGet.exe..."
+    try {
+        (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
+    } catch {
+        Throw "Could not download NuGet.exe."
+    }
+}
+
+# Save nuget.exe path to environment to be available to child processed
+$ENV:NUGET_EXE = $NUGET_EXE
+
+# Restore tools from NuGet?
+if(-Not $SkipToolPackageRestore.IsPresent) {
+    Push-Location
+    Set-Location $TOOLS_DIR
+
+    # Check for changes in packages.config and remove installed tools if true.
+    [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
+    if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
+      ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
+        Write-Verbose -Message "Missing or changed package.config hash..."
+        Remove-Item * -Recurse -Exclude packages.config,nuget.exe
+    }
+
+    Write-Verbose -Message "Restoring tools from NuGet..."
+    $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
+
+    if ($LASTEXITCODE -ne 0) {
+        Throw "An error occured while restoring NuGet tools."
+    }
+    else
+    {
+        $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
+    }
+    Write-Verbose -Message ($NuGetOutput | out-string)
+    Pop-Location
+}
+
+# Make sure that Cake has been installed.
+if (!(Test-Path $CAKE_EXE)) {
+    Throw "Could not find Cake.exe at $CAKE_EXE"
+}
+
+# Start Cake
+Write-Host "Running build script..."
+Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -platform=`"$Platform`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseSkipTests $UseMono $UseDryRun $UseExperimental $ScriptArgs"
+exit $LASTEXITCODE

+ 105 - 0
build.sh

@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+##########################################################################
+# This is the Cake bootstrapper script for Linux and OS X.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
+
+# Define directories.
+SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+TOOLS_DIR=$SCRIPT_DIR/tools
+NUGET_EXE=$TOOLS_DIR/nuget.exe
+CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
+PACKAGES_CONFIG=$TOOLS_DIR/packages.config
+PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
+
+# Define md5sum or md5 depending on Linux/OSX
+MD5_EXE=
+if [[ "$(uname -s)" == "Darwin" ]]; then
+    MD5_EXE="md5 -r"
+else
+    MD5_EXE="md5sum"
+fi
+
+# Define default arguments.
+SCRIPT="build.cake"
+TARGET="Default"
+CONFIGURATION="Release"
+PLATFORM="Any CPU"
+VERBOSITY="verbose"
+DRYRUN=
+SKIP_TESTS=
+SHOW_VERSION=false
+SCRIPT_ARGUMENTS=()
+
+# Parse arguments.
+for i in "$@"; do
+    case $1 in
+        -s|--script) SCRIPT="$2"; shift ;;
+        -t|--target) TARGET="$2"; shift ;;
+        -p|--platform) PLATFORM="$2"; shift ;;
+        -c|--configuration) CONFIGURATION="$2"; shift ;;
+        --skip-tests) SKIP_TESTS="-skip-tests"; shift ;;
+        -v|--verbosity) VERBOSITY="$2"; shift ;;
+        -d|--dryrun) DRYRUN="-dryrun" ;;
+        --version) SHOW_VERSION=true ;;
+        --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;;
+        *) SCRIPT_ARGUMENTS+=("$1") ;;
+    esac
+    shift
+done
+
+# Make sure the tools folder exist.
+if [ ! -d "$TOOLS_DIR" ]; then
+  mkdir "$TOOLS_DIR"
+fi
+
+# Make sure that packages.config exist.
+if [ ! -f "$TOOLS_DIR/packages.config" ]; then
+    echo "Downloading packages.config..."
+    curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages
+    if [ $? -ne 0 ]; then
+        echo "An error occured while downloading packages.config."
+        exit 1
+    fi
+fi
+
+# Download NuGet if it does not exist.
+if [ ! -f "$NUGET_EXE" ]; then
+    echo "Downloading NuGet..."
+    curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
+    if [ $? -ne 0 ]; then
+        echo "An error occured while downloading nuget.exe."
+        exit 1
+    fi
+fi
+
+# Restore tools from NuGet.
+pushd "$TOOLS_DIR" >/dev/null
+if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then
+    find . -type d ! -name . | xargs rm -rf
+fi
+
+mono "$NUGET_EXE" install -ExcludeVersion
+if [ $? -ne 0 ]; then
+    echo "Could not restore NuGet packages."
+    exit 1
+fi
+
+$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5
+
+popd >/dev/null
+
+# Make sure that Cake has been installed.
+if [ ! -f "$CAKE_EXE" ]; then
+    echo "Could not find Cake.exe at '$CAKE_EXE'."
+    exit 1
+fi
+
+# Start Cake
+if $SHOW_VERSION; then
+    exec mono "$CAKE_EXE" -version
+else
+    exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -platform="$PLATFORM" -configuration="$CONFIGURATION" -target=$TARGET $DRYRUN $SKIP_TESTS "${SCRIPT_ARGUMENTS[@]}"
+fi

+ 86 - 0
docs/tutorial/nuget.md

@@ -0,0 +1,86 @@
+# Avalonia NuGet Packages
+
+Avalonia is divided into several `NuGet` packages. 
+
+* The `Avalonia` package contains core portable class libraries.
+* The `Dekstop` and `Mobile` packages contain platform specific windowing and rendering back-ends.
+* The `Avalonia.Desktop` package is intended to be used by the end users targeting multiple desktop platforms (`Windows`, `Linux` and `OSX`).
+* The `Avalonia.iOS` and `Avalonia.Android` packages are intended to be used by the end users targeting specific mobile platforms. 
+* The `Avalonia.Mobile` package is intended to be used by the end users targeting multiple mobile platforms (`Android` and `iOS`).
+
+## Core
+
+* Avalonia (.nupkg)
+  - Avalonia.Animation (.dll)
+  - Avalonia.Base (.dll)
+  - Avalonia.Controls (.dll)
+  - Avalonia.DesignerSupport (.dll)
+  - Avalonia.Diagnostics (.dll)
+  - Avalonia.Input (.dll)
+  - Avalonia.Interactivity (.dll)
+  - Avalonia.Layout (.dll)
+  - Avalonia.Logging.Serilog (.dll)
+  - Avalonia.SceneGraph (.dll)
+  - Avalonia.Styling (.dll)
+  - Avalonia.ReactiveUI (.dll)
+  - Avalonia.Themes.Default (.dll)
+  - Avalonia.Markup (.dll)
+  - Avalonia.Markup.Xaml (.dll)
+  - Serilog (.nupkg)
+  - Splat (.nupkg)
+  - Sprache (.nupkg)
+  - System.Reactive (.nupkg)
+
+* Avalonia.HtmlRenderer (.nupkg)
+  - Avalonia (.nupkg)
+
+## Desktop
+
+* Avalonia.Win32 (.nupkg)
+  - Avalonia.Win32 (.dll)
+  - Avalonia (.nupkg)
+
+* Avalonia.Direct2D1 (.nupkg)
+  - Avalonia.Direct2D1 (.dll)
+  - Avalonia (.nupkg)
+  - SharpDX (.nupkg)
+  - SharpDX.Direct2D1 (.nupkg)
+  - SharpDX.DXGI (.nupkg)
+
+* Avalonia.Gtk (.nupkg)
+  - Avalonia.Gtk (.dll)
+  - Avalonia (.nupkg)
+
+* Avalonia.Cairo (.nupkg)
+  - Avalonia.Cairo (.dll)
+  - Avalonia (.nupkg)
+
+* Avalonia.Skia.Desktop (.nupkg)
+  - Avalonia.Skia.Desktop (.dll)
+  - Avalonia (.nupkg)
+  - SkiaSharp (.nupkg)
+
+* Avalonia.Desktop (.nupkg)
+  - Avalonia.Win32 (.nupkg)
+  - Avalonia.Direct2D1 (.nupkg)
+  - Avalonia.Gtk (.nupkg)
+  - Avalonia.Cairo (.nupkg)
+  - Avalonia.Skia.Desktop (.nupkg)
+
+## Mobile
+
+* Avalonia.Android (.nupkg)
+  - Avalonia.Android (.dll)
+  - Avalonia.Skia.Android (.dll)
+  - Avalonia (.nupkg)
+  - SkiaSharp (.nupkg)
+
+* Avalonia.iOS (.nupkg)
+  - Avalonia.iOS (.dll)
+  - Avalonia.Skia.iOS (.dll)
+  - Avalonia (.nupkg)
+  - SkiaSharp (.nupkg)
+
+* Avalonia.Mobile (.nupkg)
+  - Avalonia.Android (.nupkg)
+  - Avalonia.iOS (.nupkg)

+ 4 - 0
docs/tutorial/toc.yml

@@ -1,2 +1,6 @@
 - name: Getting Started
   href: gettingstarted.md
+- name: Avalonia NuGet Packages
+  href: nuget.md
+- name: Avalonia for WPF Developers
+  href: from-wpf.md

+ 0 - 2
nuget/.gitignore

@@ -1,2 +0,0 @@
-Avalonia
-*.nupkg

+ 0 - 35
nuget/build-appveyor.ps1

@@ -1,35 +0,0 @@
-$ErrorActionPreference = "Stop"
-$scriptpath = $MyInvocation.MyCommand.Path
-$dir = Split-Path $scriptpath
-Push-Location $dir
-
-
-sv version $env:APPVEYOR_BUILD_NUMBER
-#sv version "1-debug"
-
-sv version 0.4.1-build$version-alpha
-sv key $env:myget_key
-
-. ".\include.ps1"
-.\build-version.ps1 $version
-
-sv reponame $env:APPVEYOR_REPO_NAME
-sv repobranch $env:APPVEYOR_REPO_BRANCH
-sv pullreq $env:APPVEYOR_PULL_REQUEST_NUMBER
-
-echo "Checking for publishing"
-echo "$reponame $repobranch $pullreq"
-if ([string]::IsNullOrWhiteSpace($pullreq))
-{
-    echo "Build is not a PR"
-    if($repobranch -eq "master")
-    {
-        echo "Repo branch matched"
-        foreach($pkg in $Packages)
-        {
-            nuget.exe push "$($pkg).$($version).nupkg" $key -Source https://www.myget.org/F/avalonia-ci/api/v2/package
-        }
-    }
-}
-
-

+ 0 - 84
nuget/build-version.ps1

@@ -1,84 +0,0 @@
-$ErrorActionPreference = "Stop"
-
-. ".\include.ps1"
-
-foreach($pkg in $Packages) 
-{
-    rm -Force -Recurse .\$pkg -ErrorAction SilentlyContinue
-}
-
-rm -Force -Recurse *.nupkg -ErrorAction SilentlyContinue
-Copy-Item template Avalonia -Recurse
-sv lib "Avalonia\lib\portable-windows8+net45"
-sv build "Avalonia.Desktop\lib\net45"
-
-sv skia_root "Avalonia.Skia.Desktop"
-sv skia_lib "Avalonia.Skia.Desktop\lib\net45"
-sv android "Avalonia.Android\lib\MonoAndroid10"
-sv ios "Avalonia.iOS\lib\Xamarin.iOS10"
-
-mkdir $lib -ErrorAction SilentlyContinue
-mkdir $build -ErrorAction SilentlyContinue
-mkdir $skia_lib
-mkdir $android
-mkdir $ios
-
-
-Copy-Item ..\src\Avalonia.Animation\bin\Release\Avalonia.Animation.dll $lib
-Copy-Item ..\src\Avalonia.Animation\bin\Release\Avalonia.Animation.xml $lib
-Copy-Item ..\src\Avalonia.Base\bin\Release\Avalonia.Base.dll $lib
-Copy-Item ..\src\Avalonia.Base\bin\Release\Avalonia.Base.xml $lib
-Copy-Item ..\src\Avalonia.Controls\bin\Release\Avalonia.Controls.dll $lib
-Copy-Item ..\src\Avalonia.Controls\bin\Release\Avalonia.Controls.xml $lib
-Copy-Item ..\src\Avalonia.DesignerSupport\bin\Release\Avalonia.DesignerSupport.dll $lib
-Copy-Item ..\src\Avalonia.DesignerSupport\bin\Release\Avalonia.DesignerSupport.xml $lib
-Copy-Item ..\src\Avalonia.Diagnostics\bin\Release\\Avalonia.Diagnostics.dll $lib
-Copy-Item ..\src\Avalonia.Diagnostics\bin\Release\\Avalonia.Diagnostics.xml $lib
-Copy-Item ..\src\Avalonia.Input\bin\Release\Avalonia.Input.dll $lib
-Copy-Item ..\src\Avalonia.Input\bin\Release\Avalonia.Input.xml $lib
-Copy-Item ..\src\Avalonia.Interactivity\bin\Release\Avalonia.Interactivity.dll $lib
-Copy-Item ..\src\Avalonia.Interactivity\bin\Release\Avalonia.Interactivity.xml $lib
-Copy-Item ..\src\Avalonia.Layout\bin\Release\Avalonia.Layout.dll $lib
-Copy-Item ..\src\Avalonia.Layout\bin\Release\Avalonia.Layout.xml $lib
-Copy-Item ..\src\Avalonia.Logging.Serilog\bin\Release\Avalonia.Logging.Serilog.dll $lib
-Copy-Item ..\src\Avalonia.Logging.Serilog\bin\Release\Avalonia.Logging.Serilog.xml $lib
-Copy-Item ..\src\Avalonia.SceneGraph\bin\Release\Avalonia.SceneGraph.dll $lib
-Copy-Item ..\src\Avalonia.SceneGraph\bin\Release\Avalonia.SceneGraph.xml $lib
-Copy-Item ..\src\Avalonia.Styling\bin\Release\Avalonia.Styling.dll $lib
-Copy-Item ..\src\Avalonia.Styling\bin\Release\Avalonia.Styling.xml $lib
-Copy-Item ..\src\Avalonia.Themes.Default\bin\Release\Avalonia.Themes.Default.dll $lib
-Copy-Item ..\src\Avalonia.Themes.Default\bin\Release\Avalonia.Themes.Default.xml $lib
-Copy-Item ..\src\Markup\Avalonia.Markup\bin\Release\Avalonia.Markup.dll $lib
-Copy-Item ..\src\Markup\Avalonia.Markup\bin\Release\Avalonia.Markup.xml $lib
-Copy-Item ..\src\Markup\Avalonia.Markup.Xaml\bin\Release\Avalonia.Markup.Xaml.dll $lib
-Copy-Item ..\src\Markup\Avalonia.Markup.Xaml\bin\Release\Avalonia.Markup.Xaml.xml $lib
-Copy-Item ..\src\Avalonia.HtmlRenderer\bin\Release\Avalonia.HtmlRenderer.dll $lib
-Copy-Item ..\src\Avalonia.ReactiveUI\bin\Release\Avalonia.ReactiveUI.dll $lib
-
-Copy-Item ..\src\Windows\Avalonia.Direct2D1\bin\Release\Avalonia.Direct2D1.dll $build
-Copy-Item ..\src\Windows\Avalonia.Win32\bin\Release\Avalonia.Win32.dll $build
-Copy-Item ..\src\Gtk\Avalonia.Gtk\bin\Release\Avalonia.Gtk.dll $build
-Copy-Item ..\src\Gtk\Avalonia.Cairo\bin\Release\Avalonia.Cairo.dll $build
-
-Copy-Item ..\src\Skia\Avalonia.Skia.Desktop\bin\x86\Release\Avalonia.Skia.Desktop.dll $skia_lib
-
-Copy-Item ..\src\Android\Avalonia.Android\bin\Release\Avalonia.Android.dll $android
-Copy-Item ..\src\Skia\Avalonia.Skia.Android\bin\Release\Avalonia.Skia.Android.dll $android
-
-Copy-Item ..\src\iOS\Avalonia.iOS\bin\iPhone\Release\Avalonia.iOS.dll $ios
-Copy-Item ..\src\Skia\Avalonia.Skia.iOS\bin\iPhone\Release\Avalonia.Skia.iOS.dll $ios
-
-foreach($pkg in $Packages)
-{
-    (gc Avalonia\$pkg.nuspec).replace('#VERSION#', $args[0]) | sc $pkg\$pkg.nuspec
-}
-
-foreach($pkg in $Packages)
-{
-    nuget.exe pack $pkg\$pkg.nuspec
-}
-
-foreach($pkg in $Packages)
-{
-    rm -Force -Recurse .\$pkg
-}

+ 0 - 1
nuget/build.ps1

@@ -1 +0,0 @@
-.\build-version.ps1 0.4.1

+ 0 - 1
nuget/include.ps1

@@ -1 +0,0 @@
-$Packages = @("Avalonia", "Avalonia.Desktop",  "Avalonia.Skia.Desktop", "Avalonia.Android", "Avalonia.iOS")

+ 0 - 28
nuget/template/Avalonia.Android.nuspec

@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-<package>
-  <metadata>
-    <id>Avalonia.Android</id>
-    <version>#VERSION#</version>
-    <authors>Avalonia Team</authors>
-    <owners>stevenk</owners>
-    <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
-    <projectUrl>https://github.com/AvaloniaUI/Avalonia/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <description>The Avalonia UI framework</description>
-    <releaseNotes></releaseNotes>
-    <copyright>Copyright 2015</copyright>
-    <tags>Avalonia</tags>
-    <dependencies>
-      <dependency id="Serilog" version="1.5.14" />
-      <dependency id="Splat" version="1.6.2" />
-      <dependency id="Sprache" version="2.0.0.50" />
-      <dependency id="System.Reactive" version="3.0.0" />
-      <dependency id="System.Reactive.Core" version="3.0.0" />
-      <dependency id="System.Reactive.Interfaces" version="3.0.0" />
-      <dependency id="System.Reactive.Linq" version="3.0.0" />
-      <dependency id="System.Reactive.PlatformServices" version="3.0.0" />
-      <dependency id="SkiaSharp" version="1.53.0"/>
-      <dependency id="Avalonia" version="#VERSION#" />
-    </dependencies>
-  </metadata>
-</package>

+ 0 - 30
nuget/template/Avalonia.Desktop.nuspec

@@ -1,30 +0,0 @@
-<?xml version="1.0"?>
-<package>
-  <metadata>
-    <id>Avalonia.Desktop</id>
-    <version>#VERSION#</version>
-    <authors>Avalonia Team</authors>
-    <owners>stevenk</owners>
-    <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
-    <projectUrl>https://github.com/AvaloniaUI/Avalonia/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <description>The Avalonia UI framework</description>
-    <releaseNotes></releaseNotes>
-    <copyright>Copyright 2015</copyright>
-    <tags>Avalonia</tags>
-    <dependencies>
-      <dependency id="Serilog" version="1.5.14" />
-      <dependency id="Splat" version="1.6.2" />
-      <dependency id="Sprache" version="2.0.0.50" />
-      <dependency id="System.Reactive" version="3.0.0" />
-      <dependency id="System.Reactive.Core" version="3.0.0" />
-      <dependency id="System.Reactive.Interfaces" version="3.0.0" />
-      <dependency id="System.Reactive.Linq" version="3.0.0" />
-      <dependency id="System.Reactive.PlatformServices" version="3.0.0" />
-      <dependency id="SharpDX" version="3.0.2"/>
-      <dependency id="SharpDX.Direct2D1" version="3.0.2"/>
-      <dependency id="SharpDX.DXGI" version="3.0.2"/>
-      <dependency id="Avalonia" version="#VERSION#" />
-    </dependencies>
-  </metadata>
-</package>

+ 0 - 20
nuget/template/Avalonia.Skia.Desktop.nuspec

@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-<package>
-  <metadata>
-    <id>Avalonia.Skia.Desktop</id>
-    <version>#VERSION#</version>
-    <authors>Avalonia Team</authors>
-    <owners>stevenk</owners>
-    <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
-    <projectUrl>https://github.com/AvaloniaUI/Avalonia/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <description>The Avalonia UI framework</description>
-    <releaseNotes></releaseNotes>
-    <copyright>Copyright 2015</copyright>
-    <tags>Avalonia</tags>
-    <dependencies>
-      <dependency id="SkiaSharp" version="1.53.0"/>
-      <dependency id="Avalonia" version="#VERSION#" />
-    </dependencies>
-  </metadata>
-</package>

+ 0 - 27
nuget/template/Avalonia.iOS.nuspec

@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<package>
-  <metadata>
-    <id>Avalonia.iOS</id>
-    <version>#VERSION#</version>
-    <authors>Avalonia Team</authors>
-    <owners>stevenk</owners>
-    <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
-    <projectUrl>https://github.com/AvaloniaUI/Avalonia/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <description>The Avalonia UI framework</description>
-    <releaseNotes></releaseNotes>
-    <copyright>Copyright 2015</copyright>
-    <tags>Avalonia</tags>
-    <dependencies>
-      <dependency id="Serilog" version="1.5.14" />
-      <dependency id="Splat" version="1.6.2" />
-      <dependency id="Sprache" version="2.0.0.50" />
-      <dependency id="System.Reactive" version="3.0.0" />
-      <dependency id="System.Reactive.Core" version="3.0.0" />
-      <dependency id="System.Reactive.Interfaces" version="3.0.0" />
-      <dependency id="System.Reactive.Linq" version="3.0.0" />
-      <dependency id="System.Reactive.PlatformServices" version="3.0.0" />
-      <dependency id="Avalonia" version="#VERSION#" />
-    </dependencies>
-  </metadata>
-</package>

+ 0 - 26
nuget/template/Avalonia.nuspec

@@ -1,26 +0,0 @@
-<?xml version="1.0"?>
-<package>
-  <metadata>
-    <id>Avalonia</id>
-    <version>#VERSION#</version>
-    <authors>Avalonia Team</authors>
-    <owners>stevenk</owners>
-    <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
-    <projectUrl>https://github.com/AvaloniaUI/Avalonia/</projectUrl>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <description>The Avalonia UI framework</description>
-    <releaseNotes>Initial alpha release.</releaseNotes>
-    <copyright>Copyright 2015</copyright>
-    <tags>Avalonia</tags>
-    <dependencies>
-      <dependency id="Serilog" version="1.5.14" />
-      <dependency id="Splat" version="1.6.2" />
-      <dependency id="Sprache" version="2.0.0.50" />
-      <dependency id="System.Reactive" version="3.0.0" />
-      <dependency id="System.Reactive.Core" version="3.0.0" />
-      <dependency id="System.Reactive.Interfaces" version="3.0.0" />
-      <dependency id="System.Reactive.Linq" version="3.0.0" />
-      <dependency id="System.Reactive.PlatformServices" version="3.0.0" />
-    </dependencies>
-  </metadata>
-</package>

+ 4 - 0
samples/BindingTest/BindingTest.csproj

@@ -93,6 +93,10 @@
     <EmbeddedResource Include="TestItemView.xaml" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
       <Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
       <Name>Avalonia.Markup.Xaml</Name>

+ 4 - 4
samples/ControlCatalog.Desktop/App.config

@@ -1,13 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
     </startup>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
+        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
       </dependentAssembly>
     </assemblyBinding>
   </runtime>

+ 4 - 0
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@@ -64,6 +64,10 @@
       <Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
       <Name>Avalonia.DesignerSupport</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Gtk\Avalonia.Cairo\Avalonia.Cairo.csproj">
       <Project>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</Project>
       <Name>Avalonia.Cairo</Name>

+ 4 - 0
samples/TestApplication/TestApplication.csproj

@@ -83,6 +83,10 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Gtk\Avalonia.Cairo\Avalonia.Cairo.csproj">
       <Project>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</Project>
       <Name>Avalonia.Cairo</Name>

+ 4 - 4
samples/VirtualizationTest/App.config

@@ -1,13 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
     </startup>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral"/>
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
+        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
       </dependentAssembly>
     </assemblyBinding>
   </runtime>

+ 4 - 0
samples/VirtualizationTest/VirtualizationTest.csproj

@@ -103,6 +103,10 @@
       <Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
       <Name>Avalonia.Diagnostics</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
       <Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
       <Name>Avalonia.Input</Name>

+ 6 - 2
samples/XamlTestApplication/XamlTestApplication.csproj

@@ -48,8 +48,8 @@
       <HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="Sprache, Version=2.0.0.50, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Sprache.2.0.0.50\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
+    <Reference Include="Sprache, Version=2.0.0.51, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System" />
@@ -91,6 +91,10 @@
     <None Include="App.config" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>

+ 1 - 1
samples/XamlTestApplication/packages.config

@@ -2,7 +2,7 @@
 <packages>
   <package id="Serilog" version="1.5.14" targetFramework="net45" />
   <package id="Splat" version="1.6.2" targetFramework="net45" />
-  <package id="Sprache" version="2.0.0.50" targetFramework="net45" />
+  <package id="Sprache" version="2.0.0.51" targetFramework="net45" />
   <package id="System.Reactive" version="3.0.0" targetFramework="net45" />
   <package id="System.Reactive.Core" version="3.0.0" targetFramework="net45" />
   <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net45" />

+ 1 - 1
src/Android/Avalonia.Android/AndroidPlatform.cs

@@ -49,7 +49,7 @@ namespace Avalonia.Android
 
         public void Init(Type applicationType)
         {
-            SharedPlatform.Register(applicationType.Assembly);
+            StandardRuntimePlatformServices.Register(applicationType.Assembly);
         }
 
         public IWindowImpl CreateWindow()

+ 1 - 0
src/Android/Avalonia.Android/Avalonia.Android.csproj

@@ -77,6 +77,7 @@
     <Compile Include="Platform\AndroidTopLevelRenderer.cs" />
     <Compile Include="Resources\Resource.Designer.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RuntimeInfo.cs" />
     <Compile Include="SystemDialogImpl.cs" />
   </ItemGroup>
   <ItemGroup>

+ 18 - 0
src/Android/Avalonia.Android/RuntimeInfo.cs

@@ -0,0 +1,18 @@
+using Avalonia.Platform;
+
+namespace Avalonia.Shared.PlatformSupport
+{
+    internal partial class StandardRuntimePlatform
+    {
+        public RuntimePlatformInfo GetRuntimeInfo() => new RuntimePlatformInfo
+        {
+            IsCoreClr = false,
+            IsDesktop = false,
+            IsMobile = true,
+            IsDotNetFramework = false,
+            IsMono = true,
+            IsUnix = true,
+            OperatingSystem = OperatingSystemType.Android
+        };
+    }
+}

+ 3 - 3
src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj

@@ -65,15 +65,15 @@
     <Reference Include="Mono.Android" />
     <Reference Include="mscorlib" />
     <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
+      <HintPath>..\..\..\packages\Serilog.1.5.14\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="Sprache, Version=2.0.0.47, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll</HintPath>
+    <Reference Include="Sprache, Version=2.0.0.51, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System" />

+ 2 - 2
src/Android/Avalonia.AndroidTestApplication/packages.config

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Serilog" version="1.5.9" targetFramework="monoandroid51" />
+  <package id="Serilog" version="1.5.14" targetFramework="monoandroid44" />
   <package id="Splat" version="1.6.2" targetFramework="monoandroid51" />
-  <package id="Sprache" version="2.0.0.47" targetFramework="monoandroid51" />
+  <package id="Sprache" version="2.0.0.51" targetFramework="monoandroid44" />
   <package id="System.Collections" version="4.0.11" targetFramework="monoandroid44" />
   <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="monoandroid44" />
   <package id="System.ComponentModel" version="4.0.1" targetFramework="monoandroid44" />

+ 1 - 1
src/Avalonia.Base/Avalonia.Base.csproj

@@ -85,7 +85,7 @@
     <Compile Include="AvaloniaPropertyRegistry.cs" />
     <Compile Include="AvaloniaProperty`1.cs" />
     <Compile Include="Platform\IAssetLoader.cs" />
-    <Compile Include="Platform\IPclPlatformWrapper.cs" />
+    <Compile Include="Platform\IRuntimePlatform.cs" />
     <Compile Include="Data\BindingPriority.cs" />
     <Compile Include="PriorityBindingEntry.cs" />
     <Compile Include="Collections\IAvaloniaList.cs" />

+ 1 - 1
src/Avalonia.Base/AvaloniaDisposable.cs

@@ -20,7 +20,7 @@ namespace Avalonia
         {
             IsDisposed = true;
 #if DEBUG_DISPOSE
-            DisposedAt = AvaloniaLocator.Current.GetService<IPclPlatformWrapper>().GetStackTrace();
+            DisposedAt = AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetStackTrace();
 #endif
             DoDispose();
         }

+ 0 - 17
src/Avalonia.Base/Platform/IPclPlatformWrapper.cs

@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Avalonia.Platform
-{
-    public interface IPclPlatformWrapper
-    {
-        Assembly[] GetLoadedAssemblies();
-        void PostThreadPoolItem(Action cb);
-        IDisposable StartSystemTimer(TimeSpan interval, Action tick);
-        string GetStackTrace();
-    }
-}

+ 39 - 0
src/Avalonia.Base/Platform/IRuntimePlatform.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Platform
+{
+    public interface IRuntimePlatform
+    {
+        Assembly[] GetLoadedAssemblies();
+        void PostThreadPoolItem(Action cb);
+        IDisposable StartSystemTimer(TimeSpan interval, Action tick);
+        string GetStackTrace();
+        RuntimePlatformInfo GetRuntimeInfo();
+    }
+
+    public struct RuntimePlatformInfo
+    {
+        public OperatingSystemType OperatingSystem { get; set; }
+        public bool IsDesktop { get; set; }
+        public bool IsMobile { get; set; }
+        public bool IsCoreClr { get; set; }
+        public bool IsMono { get; set; }
+        public bool IsDotNetFramework { get; set; }
+        public bool IsUnix { get; set; }
+    }
+
+    public enum OperatingSystemType
+    {
+        Unknown,
+        WinNT,
+        Linux,
+        OSX,
+        Android,
+        iOS
+    }
+}

+ 2 - 2
src/Avalonia.Base/Threading/SingleThreadDispatcher.cs

@@ -33,7 +33,7 @@ namespace Avalonia.Threading
             }
 
             public IDisposable StartTimer(TimeSpan interval, Action tick)
-                => AvaloniaLocator.Current.GetService<IPclPlatformWrapper>().StartSystemTimer(interval,
+                => AvaloniaLocator.Current.GetService<IRuntimePlatform>().StartSystemTimer(interval,
                     () => _timerJobRunner.Post(tick, DispatcherPriority.Normal));
 
             public void Signal() => _evnt.Set();
@@ -50,7 +50,7 @@ namespace Avalonia.Threading
         public static Dispatcher StartNew(CancellationToken token)
         {
             var dispatcher = new SingleThreadDispatcher();
-            AvaloniaLocator.Current.GetService<IPclPlatformWrapper>().PostThreadPoolItem(() =>
+            AvaloniaLocator.Current.GetService<IRuntimePlatform>().PostThreadPoolItem(() =>
             {
                 dispatcher.MainLoop(token);
             });

+ 31 - 23
src/Avalonia.Controls/AppBuilder.cs

@@ -3,14 +3,25 @@
 
 using System;
 using System.Reflection;
+using Avalonia.Platform;
 
 namespace Avalonia.Controls
 {
     /// <summary>
     /// Initializes up platform-specific services for an <see cref="Application"/>.
     /// </summary>
-    public class AppBuilder
+    public abstract class AppBuilderBase<AppBuilder> where AppBuilder : AppBuilderBase<AppBuilder>, new()
     {
+        /// <summary>
+        /// Gets or sets the <see cref="IRuntimePlatform"/> instance.
+        /// </summary>
+        public IRuntimePlatform RuntimePlatform { get; set; }
+
+        /// <summary>
+        /// Gets or sets a method to call the initialize the runtime platform services (e. g. AssetLoader)
+        /// </summary>
+        public Action RuntimePlatformServices { get; set; }
+
         /// <summary>
         /// Gets or sets the <see cref="Application"/> instance being initialized.
         /// </summary>
@@ -32,6 +43,12 @@ namespace Avalonia.Controls
         /// </summary>
         public Action<AppBuilder> BeforeStartCallback { get; set; }
 
+        protected AppBuilderBase(IRuntimePlatform platform, Action platformSevices)
+        {
+            RuntimePlatform = platform;
+            RuntimePlatformServices = platformSevices;
+        }
+
         /// <summary>
         /// Begin configuring an <see cref="Application"/>.
         /// </summary>
@@ -57,6 +74,8 @@ namespace Avalonia.Controls
             };
         }
 
+        protected AppBuilder Self => (AppBuilder) this;
+
         /// <summary>
         /// Registers a callback to call before <see cref="Start{TMainWindow}"/> is called on the
         /// <see cref="Application"/>.
@@ -66,7 +85,7 @@ namespace Avalonia.Controls
         public AppBuilder BeforeStarting(Action<AppBuilder> callback)
         {
             BeforeStartCallback = callback;
-            return this;
+            return Self;
         }
 
         /// <summary>
@@ -77,7 +96,7 @@ namespace Avalonia.Controls
             where TMainWindow : Window, new()
         {
             Setup();
-            BeforeStartCallback?.Invoke(this);
+            BeforeStartCallback?.Invoke(Self);
 
             var window = new TMainWindow();
             window.Show();
@@ -91,7 +110,7 @@ namespace Avalonia.Controls
         public AppBuilder SetupWithoutStarting()
         {
             Setup();
-            return this;
+            return Self;
         }
 
         /// <summary>
@@ -102,7 +121,7 @@ namespace Avalonia.Controls
         public AppBuilder UseWindowingSubsystem(Action initializer)
         {
             WindowingSubsystem = initializer;
-            return this;
+            return Self;
         }
 
         /// <summary>
@@ -120,7 +139,7 @@ namespace Avalonia.Controls
         public AppBuilder UseRenderingSubsystem(Action initializer)
         {
             RenderingSubsystem = initializer;
-            return this;
+            return Self;
         }
 
         /// <summary>
@@ -140,23 +159,6 @@ namespace Avalonia.Controls
             init.Invoke(null, null);
         };
 
-        public AppBuilder UsePlatformDetect()
-        {
-            var platformId = (int)
-                ((dynamic) Type.GetType("System.Environment").GetRuntimeProperty("OSVersion").GetValue(null)).Platform;
-            if (platformId == 4 || platformId == 6)
-            {
-                UseRenderingSubsystem("Avalonia.Cairo");
-                UseWindowingSubsystem("Avalonia.Gtk");
-            }
-            else
-            {
-                UseRenderingSubsystem("Avalonia.Direct2D1");
-                UseWindowingSubsystem("Avalonia.Win32");
-            }
-            return this;
-        }
-
         /// <summary>
         /// Sets up the platform-speciic services for the <see cref="Application"/>.
         /// </summary>
@@ -167,6 +169,11 @@ namespace Avalonia.Controls
                 throw new InvalidOperationException("No App instance configured.");
             }
 
+            if (RuntimePlatformServices == null)
+            {
+                throw new InvalidOperationException("No runtime platform services configured.");
+            }
+
             if (WindowingSubsystem == null)
             {
                 throw new InvalidOperationException("No windowing system configured.");
@@ -178,6 +185,7 @@ namespace Avalonia.Controls
             }
 
             Instance.RegisterServices();
+            RuntimePlatformServices();
             WindowingSubsystem();
             RenderingSubsystem();
             Instance.Initialize();

+ 11 - 3
src/Avalonia.DesignerSupport/DesignerAssist.cs

@@ -37,8 +37,11 @@ namespace Avalonia.DesignerSupport
         {
             Design.IsDesignMode = true;
             Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, UpdateXaml2 = UpdateXaml2, SetScalingFactor = SetScalingFactor};
-            var plat = (IPclPlatformWrapper) Activator.CreateInstance(Assembly.Load(new AssemblyName("Avalonia.Win32"))
-                .DefinedTypes.First(typeof (IPclPlatformWrapper).GetTypeInfo().IsAssignableFrom).AsType());
+
+            var runtimeAssembly = Assembly.Load(new AssemblyName("Avalonia.DotNetFrameworkRuntime"));
+
+            var plat = (IRuntimePlatform) Activator.CreateInstance(runtimeAssembly
+                .DefinedTypes.First(typeof (IRuntimePlatform).GetTypeInfo().IsAssignableFrom).AsType());
             
             TypeInfo app = null;
             var asms = plat.GetLoadedAssemblies();
@@ -58,7 +61,12 @@ namespace Avalonia.DesignerSupport
                     //Ignore, Assembly.DefinedTypes threw an exception, we can't do anything about that
                 }
             }
-            AppBuilder.Configure(app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType()))
+
+            var builderType = runtimeAssembly.GetType("Avalonia.AppBuilder");
+
+            var builder = (dynamic)Activator.CreateInstance(builderType,
+                app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType()));
+            builder
                 .UseWindowingSubsystem("Avalonia.Win32")
                 .UseRenderingSubsystem("Avalonia.Direct2D1")
                 .SetupWithoutStarting();

+ 40 - 0
src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs

@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia.Controls;
+using Avalonia.Platform;
+using Avalonia.Shared.PlatformSupport;
+
+namespace Avalonia
+{
+    public sealed class AppBuilder : AppBuilderBase<AppBuilder>
+    {
+        public AppBuilder() : base(new StandardRuntimePlatform(), () => StandardRuntimePlatformServices.Register())
+        {
+        }
+
+        public AppBuilder(Application app) : this()
+        {
+            Instance = app;
+        }
+
+        public AppBuilder UsePlatformDetect()
+        {
+            var platformId = (int)Environment.OSVersion.Platform;
+            if (platformId == 4 || platformId == 6)
+            {
+                UseRenderingSubsystem("Avalonia.Cairo");
+                UseWindowingSubsystem("Avalonia.Gtk");
+            }
+            else
+            {
+                UseRenderingSubsystem("Avalonia.Direct2D1");
+                UseWindowingSubsystem("Avalonia.Win32");
+            }
+            return this;
+        }
+    }
+}

+ 84 - 0
src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Avalonia.DotNetFrameworkRuntime</RootNamespace>
+    <AssemblyName>Avalonia.DotNetFrameworkRuntime</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;FULLDOTNET</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Avalonia.DotNetFrameworkRuntime.xml</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE;FULLDOTNET</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Avalonia.DotNetFrameworkRuntime.xml</DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AppBuilder.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RuntimeInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj">
+      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
+      <Name>Avalonia.Base</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj">
+      <Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
+      <Name>Avalonia.Controls</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj">
+      <Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
+      <Name>Avalonia.Styling</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 36 - 0
src/Avalonia.DotNetFrameworkRuntime/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Avalonia.DotNetFrameworkRuntime")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Avalonia.DotNetFrameworkRuntime")]
+[assembly: AssemblyCopyright("Copyright ©  2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4a1abb09-9047-4bd5-a4ad-a055e52c5ee0")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 44 - 0
src/Avalonia.DotNetFrameworkRuntime/RuntimeInfo.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Runtime.InteropServices;
+using Avalonia.Platform;
+
+namespace Avalonia.Shared.PlatformSupport
+{
+    internal partial class StandardRuntimePlatform
+    {
+        private static readonly Lazy<RuntimePlatformInfo> Info = new Lazy<RuntimePlatformInfo>(() =>
+        {
+            var isMono = Type.GetType("Mono.Runtime") != null;
+            var isUnix = Environment.OSVersion.Platform == PlatformID.Unix ||
+                         Environment.OSVersion.Platform == PlatformID.MacOSX;
+            return new RuntimePlatformInfo
+            {
+                IsCoreClr = false,
+                IsDesktop = true,
+                IsDotNetFramework = !isMono,
+                IsMono = isMono,
+                IsMobile = false,
+                IsUnix = isUnix,
+                OperatingSystem = isUnix ? DetectUnix() : OperatingSystemType.WinNT,
+            };
+        });
+
+        [DllImport("libc")]
+        static extern int uname(IntPtr buf);
+
+        static OperatingSystemType DetectUnix()
+        {
+            var buffer = Marshal.AllocHGlobal(0x1000);
+            uname(buffer);
+            var unixName = Marshal.PtrToStringAnsi(buffer);
+            Marshal.FreeHGlobal(buffer);
+            if(unixName=="Darwin")
+                return OperatingSystemType.OSX;
+            if (unixName == "Linux")
+                return OperatingSystemType.Linux;
+            return OperatingSystemType.Unknown;
+        }
+
+        public RuntimePlatformInfo GetRuntimeInfo() => Info.Value;
+    }
+}

+ 5 - 0
src/Avalonia.DotNetFrameworkRuntime/packages.config

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="System.Reactive.Core" version="3.0.0" targetFramework="net45" />
+  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net45" />
+</packages>

+ 1 - 1
src/Gtk/Avalonia.Cairo/CairoPlatform.cs

@@ -12,7 +12,7 @@ namespace Avalonia
 {
     public static class GtkApplicationExtensions
     {
-        public static AppBuilder UseCairo(this AppBuilder builder)
+        public static T UseCairo<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.RenderingSubsystem = Avalonia.Cairo.CairoPlatform.Initialize;
             return builder;

+ 0 - 1
src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj

@@ -103,5 +103,4 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
 </Project>

+ 1 - 3
src/Gtk/Avalonia.Gtk/GtkPlatform.cs

@@ -8,14 +8,13 @@ using Avalonia.Controls.Platform;
 using Avalonia.Input.Platform;
 using Avalonia.Input;
 using Avalonia.Platform;
-using Avalonia.Shared.PlatformSupport;
 using Avalonia.Controls;
 
 namespace Avalonia
 {
     public static class GtkApplicationExtensions
     {
-        public static AppBuilder UseGtk(this AppBuilder builder)
+        public static T UseGtk<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.WindowingSubsystem = Avalonia.Gtk.GtkPlatform.Initialize;
             return builder;
@@ -56,7 +55,6 @@ namespace Avalonia.Gtk
                 .Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
                 .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
                 .Bind<IPlatformIconLoader>().ToConstant(s_instance);
-            SharedPlatform.Register();
             _uiThread = Thread.CurrentThread;
         }
 

+ 3 - 2
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@@ -60,6 +60,7 @@
     <Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
     <Compile Include="Converters\CursorTypeConverter.cs" />
     <Compile Include="Converters\DateTimeTypeConverter.cs" />
+    <Compile Include="Converters\FontWeightConverter.cs" />
     <Compile Include="Converters\GeometryTypeConverter.cs" />
     <Compile Include="Converters\GridLengthTypeConverter.cs" />
     <Compile Include="Converters\IconTypeConverter.cs" />
@@ -321,8 +322,8 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="Sprache, Version=2.0.0.50, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Sprache.2.0.0.50\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
+    <Reference Include="Sprache, Version=2.0.0.51, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs

@@ -168,7 +168,7 @@ namespace Avalonia.Markup.Xaml.Context
         private void ScanNewAssemblies()
         {
             IEnumerable<Assembly> assemblies = AvaloniaLocator.Current
-                .GetService<IPclPlatformWrapper>()
+                .GetService<IRuntimePlatform>()
                 ?.GetLoadedAssemblies();
 
             if (assemblies != null)

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs

@@ -174,6 +174,7 @@ namespace Avalonia.Markup.Xaml.Context
             RegisterTypeConverter(typeof(Uri), new UriTypeConverter());
             RegisterTypeConverter(typeof(Cursor), new CursorTypeConverter());
             RegisterTypeConverter(typeof(WindowIcon), new IconTypeConverter());
+            RegisterTypeConverter(typeof(FontWeight), new FontWeightConverter());
         }
     }
 }

+ 39 - 0
src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs

@@ -0,0 +1,39 @@
+namespace Avalonia.Markup.Xaml.Converters
+{
+    using Avalonia.Media;
+    using OmniXaml.TypeConversion;
+    using System;
+    using System.Globalization;
+
+    public class FontWeightConverter : ITypeConverter
+    {
+        public bool CanConvertFrom(IValueContext context, Type sourceType)
+        {
+            return sourceType == typeof(string);
+        }
+
+        public bool CanConvertTo(IValueContext context, Type destinationType)
+        {
+            return false;
+        }
+
+        public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
+        {
+            FontWeight result;
+            
+            if (Enum.TryParse(value as string, out result))
+            {
+                return result;
+            }
+            else
+            {
+                throw new ArgumentException("unable to convert parameter to FontWeight");
+            }
+        }
+
+        public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/packages.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Sprache" version="2.0.0.50" targetFramework="portable45-net45+win8" />
+  <package id="Sprache" version="2.0.0.51" targetFramework="portable45-net45+win8" />
   <package id="System.Reactive" version="3.0.0" targetFramework="portable45-net45+win8" />
   <package id="System.Reactive.Core" version="3.0.0" targetFramework="portable45-net45+win8" />
   <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="portable45-net45+win8" />

+ 3 - 3
src/Shared/PlatformSupport/PlatformSupport.projitems

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
@@ -10,7 +10,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="$(MSBuildThisFileDirectory)AssetLoader.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)PclPlatformWrapper.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)SharedPlatform.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)StandardRuntimePlatform.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)StandardRuntimePlatformServices.cs" />
   </ItemGroup>
 </Project>

+ 3 - 1
src/Shared/PlatformSupport/PclPlatformWrapper.cs → src/Shared/PlatformSupport/StandardRuntimePlatform.cs

@@ -10,7 +10,7 @@ using Avalonia.Platform;
 
 namespace Avalonia.Shared.PlatformSupport
 {
-    internal class PclPlatformWrapper : IPclPlatformWrapper
+    internal partial class StandardRuntimePlatform : IRuntimePlatform
     {
         public Assembly[] GetLoadedAssemblies() => AppDomain.CurrentDomain.GetAssemblies();
         public void PostThreadPoolItem(Action cb) => ThreadPool.UnsafeQueueUserWorkItem(_ => cb(), null);
@@ -23,6 +23,8 @@ namespace Avalonia.Shared.PlatformSupport
             return Disposable.Create(() => timer.Dispose());
         }
 
+
+
         public string GetStackTrace() => Environment.StackTrace;
     }
 }

+ 2 - 2
src/Shared/PlatformSupport/SharedPlatform.cs → src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs

@@ -6,12 +6,12 @@ using Avalonia.Platform;
 
 namespace Avalonia.Shared.PlatformSupport
 {
-    static class SharedPlatform
+    static class StandardRuntimePlatformServices
     {
         public static void Register(Assembly assembly = null)
         {
             AvaloniaLocator.CurrentMutable
-                .Bind<IPclPlatformWrapper>().ToSingleton<PclPlatformWrapper>()
+                .Bind<IRuntimePlatform>().ToSingleton<StandardRuntimePlatform>()
                 .Bind<IAssetLoader>().ToConstant(new AssetLoader(assembly));
         }
     }

+ 3 - 3
src/Shared/SharedAssemblyInfo.cs

@@ -13,6 +13,6 @@ using System.Resources;
 [assembly: AssemblyTrademark("")]
 [assembly: NeutralResourcesLanguage("en")]
 
-[assembly: AssemblyVersion("0.4.0")]
-[assembly: AssemblyFileVersion("0.4.0")]
-[assembly: AssemblyInformationalVersion("0.4.0")]
+[assembly: AssemblyVersion("0.4.1")]
+[assembly: AssemblyFileVersion("0.4.1")]
+[assembly: AssemblyInformationalVersion("0.4.1")]

+ 1 - 1
src/Skia/Avalonia.Skia/SkiaPlatform.cs

@@ -8,7 +8,7 @@ namespace Avalonia
 {
     public static class SkiaApplicationExtensions
     {
-        public static AppBuilder UseSkia(this AppBuilder builder)
+        public static T UseSkia<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.RenderingSubsystem = Avalonia.Skia.SkiaPlatform.Initialize;
             return builder;

+ 1 - 1
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@@ -12,7 +12,7 @@ namespace Avalonia
 {
     public static class Direct2DApplicationExtensions
     {
-        public static AppBuilder UseDirect2D1(this AppBuilder builder)
+        public static T UseDirect2D1<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.RenderingSubsystem = Avalonia.Direct2D1.Direct2D1Platform.Initialize;
             return builder;

+ 0 - 1
src/Windows/Avalonia.Win32/Avalonia.Win32.csproj

@@ -123,7 +123,6 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 2 - 4
src/Windows/Avalonia.Win32/Win32Platform.cs

@@ -12,7 +12,6 @@ using System.Threading;
 using Avalonia.Controls.Platform;
 using Avalonia.Input;
 using Avalonia.Platform;
-using Avalonia.Shared.PlatformSupport;
 using Avalonia.Win32.Input;
 using Avalonia.Win32.Interop;
 using Avalonia.Controls;
@@ -22,7 +21,7 @@ namespace Avalonia
 {
     public static class Win32ApplicationExtensions
     {
-        public static AppBuilder UseWin32(this AppBuilder builder)
+        public static T UseWin32<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.WindowingSubsystem = Avalonia.Win32.Win32Platform.Initialize;
             return builder;
@@ -69,8 +68,7 @@ namespace Avalonia.Win32
                 .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogImpl>()
                 .Bind<IWindowingPlatform>().ToConstant(s_instance)
                 .Bind<IPlatformIconLoader>().ToConstant(s_instance);
-
-            SharedPlatform.Register();
+            
             _uiThread = Thread.CurrentThread;
         }
 

+ 1 - 0
src/iOS/Avalonia.iOS/Avalonia.iOS.csproj

@@ -43,6 +43,7 @@
     <Compile Include="PlatformSettings.cs" />
     <Compile Include="PlatformThreadingInterface.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RuntimeInfo.cs" />
     <Compile Include="Specific\KeyboardEventsHelper.cs" />
     <Compile Include="WindowingPlatformImpl.cs" />
   </ItemGroup>

+ 17 - 0
src/iOS/Avalonia.iOS/RuntimeInfo.cs

@@ -0,0 +1,17 @@
+using Avalonia.Platform;
+namespace Avalonia.Shared.PlatformSupport
+{
+    internal partial class StandardRuntimePlatform
+    {
+        public RuntimePlatformInfo GetRuntimeInfo() => new RuntimePlatformInfo
+        {
+            IsCoreClr = false,
+            IsDesktop = false,
+            IsMobile = true,
+            IsDotNetFramework = false,
+            IsMono = true,
+            IsUnix = true,
+            OperatingSystem = OperatingSystemType.Android
+        };
+    }
+}

+ 3 - 3
src/iOS/Avalonia.iOS/iOSPlatform.cs

@@ -13,14 +13,14 @@ namespace Avalonia
 {
     public static class iOSApplicationExtensions
     {
-        public static AppBuilder UseiOS(this AppBuilder builder)
+        public static T UseiOS<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             builder.WindowingSubsystem = Avalonia.iOS.iOSPlatform.Initialize;
             return builder;
         }
 
         // TODO: Can we merge this with UseSkia somehow once HW/platform cleanup is done?
-        public static AppBuilder UseSkiaViewHost(this AppBuilder builder)
+        public static T UseSkiaViewHost<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
             var window = new UIWindow(UIScreen.MainScreen.Bounds);
             var controller = new AvaloniaViewController(window);
@@ -53,7 +53,7 @@ namespace Avalonia.iOS
             KeyboardDevice = new KeyboardDevice();
 
             AvaloniaLocator.CurrentMutable
-                .Bind<IPclPlatformWrapper>().ToSingleton<PclPlatformWrapper>()
+                .Bind<IRuntimePlatform>().ToSingleton<StandardRuntimePlatform>()
                 .Bind<IClipboard>().ToTransient<Clipboard>()
                 // TODO: what does this look like for iOS??
                 //.Bind<ISystemDialogImpl>().ToTransient<SystemDialogImpl>()

+ 4 - 0
tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj

@@ -101,6 +101,10 @@
       <Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
       <Name>Avalonia.DesignerSupport</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
       <Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
       <Name>Avalonia.Input</Name>

+ 4 - 1
tests/Avalonia.Layout.UnitTests/Avalonia.Layout.UnitTests.csproj

@@ -109,6 +109,10 @@
       <Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
       <Name>Avalonia.Diagnostics</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
       <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
       <Name>Avalonia.Input</Name>
@@ -149,7 +153,6 @@
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
-  <Import Project="..\..\src\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Choose>
     <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
       <ItemGroup>

+ 1 - 1
tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs

@@ -149,7 +149,7 @@ namespace Avalonia.Layout.UnitTests
                 .Bind<IInputManager>().ToConstant(new Mock<IInputManager>().Object)
                 .Bind<IGlobalStyles>().ToConstant(globalStyles.Object)
                 .Bind<ILayoutManager>().ToConstant(new LayoutManager())
-                .Bind<IPclPlatformWrapper>().ToConstant(new PclPlatformWrapper())
+                .Bind<IRuntimePlatform>().ToConstant(new AppBuilder().RuntimePlatform)
                 .Bind<IPlatformRenderInterface>().ToConstant(renderInterface)
                 .Bind<IRenderQueueManager>().ToConstant(renderManager)
                 .Bind<IStyler>().ToConstant(new Styler())

+ 4 - 1
tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj

@@ -105,6 +105,10 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
       <Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
       <Name>Avalonia.Markup.Xaml</Name>
@@ -164,7 +168,6 @@
   <ItemGroup>
     <Content Include="Readme.txt" />
   </ItemGroup>
-  <Import Project="..\..\src\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 2 - 2
tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj

@@ -50,8 +50,8 @@
       <HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="Sprache, Version=2.0.0.50, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Sprache.2.0.0.50\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
+    <Reference Include="Sprache, Version=2.0.0.51, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System" />

+ 1 - 1
tests/Avalonia.Markup.Xaml.UnitTests/packages.config

@@ -2,7 +2,7 @@
 <packages>
   <package id="Moq" version="4.2.1510.2205" targetFramework="net451" />
   <package id="Splat" version="1.6.2" targetFramework="net451" />
-  <package id="Sprache" version="2.0.0.50" targetFramework="net451" />
+  <package id="Sprache" version="2.0.0.51" targetFramework="net451" />
   <package id="System.Reactive.Core" version="3.0.0" targetFramework="net451" />
   <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net451" />
   <package id="System.Reactive.Linq" version="3.0.0" targetFramework="net451" />

+ 4 - 1
tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj

@@ -64,6 +64,10 @@
     <Compile Include="MockWindowingPlatform.cs" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
+      <Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project>
+      <Name>Avalonia.DotNetFrameworkRuntime</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
       <Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
       <Name>Avalonia.Markup.Xaml</Name>
@@ -113,7 +117,6 @@
     <None Include="app.config" />
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\..\src\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 7 - 7
tests/Avalonia.UnitTests/TestServices.cs

@@ -19,7 +19,7 @@ namespace Avalonia.UnitTests
         public static readonly TestServices StyledWindow = new TestServices(
             assetLoader: new AssetLoader(),
             layoutManager: new LayoutManager(),
-            platformWrapper: new PclPlatformWrapper(),
+            platform: new AppBuilder().RuntimePlatform,
             renderInterface: CreateRenderInterfaceMock(),
             standardCursorFactory: Mock.Of<IStandardCursorFactory>(),
             styler: new Styler(),
@@ -31,7 +31,7 @@ namespace Avalonia.UnitTests
             renderInterface: CreateRenderInterfaceMock());
 
         public static readonly TestServices MockPlatformWrapper = new TestServices(
-            platformWrapper: Mock.Of<IPclPlatformWrapper>());
+            platform: Mock.Of<IRuntimePlatform>());
 
         public static readonly TestServices MockStyler = new TestServices(
             styler: Mock.Of<IStyler>());
@@ -56,7 +56,7 @@ namespace Avalonia.UnitTests
             IInputManager inputManager = null,
             Func<IKeyboardDevice> keyboardDevice = null,
             ILayoutManager layoutManager = null,
-            IPclPlatformWrapper platformWrapper = null,
+            IRuntimePlatform platform = null,
             IPlatformRenderInterface renderInterface = null,
             IStandardCursorFactory standardCursorFactory = null,
             IStyler styler = null,
@@ -70,7 +70,7 @@ namespace Avalonia.UnitTests
             InputManager = inputManager;
             KeyboardDevice = keyboardDevice;
             LayoutManager = layoutManager;
-            PlatformWrapper = platformWrapper;
+            Platform = platform;
             RenderInterface = renderInterface;
             StandardCursorFactory = standardCursorFactory;
             Styler = styler;
@@ -85,7 +85,7 @@ namespace Avalonia.UnitTests
         public IFocusManager FocusManager { get; }
         public Func<IKeyboardDevice> KeyboardDevice { get; }
         public ILayoutManager LayoutManager { get; }
-        public IPclPlatformWrapper PlatformWrapper { get; }
+        public IRuntimePlatform Platform { get; }
         public IPlatformRenderInterface RenderInterface { get; }
         public IStandardCursorFactory StandardCursorFactory { get; }
         public IStyler Styler { get; }
@@ -100,7 +100,7 @@ namespace Avalonia.UnitTests
             IInputManager inputManager = null,
             Func<IKeyboardDevice> keyboardDevice = null,
             ILayoutManager layoutManager = null,
-            IPclPlatformWrapper platformWrapper = null,
+            IRuntimePlatform platform = null,
             IPlatformRenderInterface renderInterface = null,
             IStandardCursorFactory standardCursorFactory = null,
             IStyler styler = null,
@@ -115,7 +115,7 @@ namespace Avalonia.UnitTests
                 inputManager: inputManager ?? InputManager,
                 keyboardDevice: keyboardDevice ?? KeyboardDevice,
                 layoutManager: layoutManager ?? LayoutManager,
-                platformWrapper: platformWrapper ?? PlatformWrapper,
+                platform: platform ?? Platform,
                 renderInterface: renderInterface ?? RenderInterface,
                 standardCursorFactory: standardCursorFactory ?? StandardCursorFactory,
                 styler: styler ?? Styler,

+ 1 - 1
tests/Avalonia.UnitTests/UnitTestApplication.cs

@@ -41,7 +41,7 @@ namespace Avalonia.UnitTests
                 .Bind<IInputManager>().ToConstant(Services.InputManager)
                 .Bind<IKeyboardDevice>().ToConstant(Services.KeyboardDevice?.Invoke())
                 .Bind<ILayoutManager>().ToConstant(Services.LayoutManager)
-                .Bind<IPclPlatformWrapper>().ToConstant(Services.PlatformWrapper)
+                .Bind<IRuntimePlatform>().ToConstant(Services.Platform)
                 .Bind<IPlatformRenderInterface>().ToConstant(Services.RenderInterface)
                 .Bind<IPlatformThreadingInterface>().ToConstant(Services.ThreadingInterface)
                 .Bind<IStandardCursorFactory>().ToConstant(Services.StandardCursorFactory)