diff --git a/osu.Desktop.Tests/BenchmarkTest.cs b/osu.Desktop.Tests/BenchmarkTest.cs
new file mode 100644
index 0000000000..c55b98aa57
--- /dev/null
+++ b/osu.Desktop.Tests/BenchmarkTest.cs
@@ -0,0 +1,33 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using NUnit.Framework;
+using osu.Desktop.VisualTests;
+using osu.Framework.Desktop.Platform;
+using osu.Game.Modes;
+using osu.Game.Modes.Catch;
+using osu.Game.Modes.Mania;
+using osu.Game.Modes.Osu;
+using osu.Game.Modes.Taiko;
+
+namespace osu.Desktop.Tests
+{
+    [TestFixture]
+    public class BenchmarkTest
+    {
+        [Test]
+        public void TestBenchmark()
+        {
+            using (var host = new HeadlessGameHost())
+            {
+                Ruleset.Register(new OsuRuleset());
+                Ruleset.Register(new TaikoRuleset());
+                Ruleset.Register(new ManiaRuleset());
+                Ruleset.Register(new CatchRuleset());
+
+                host.Add(new Benchmark());
+                host.Run();
+            }
+        }
+    }
+}
diff --git a/osu.Desktop.Tests/app.config b/osu.Desktop.Tests/app.config
new file mode 100644
index 0000000000..44ccc4b77a
--- /dev/null
+++ b/osu.Desktop.Tests/app.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
new file mode 100644
index 0000000000..8a6581ccab
--- /dev/null
+++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
@@ -0,0 +1,115 @@
+<?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>{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>osu.Desktop.Tests</RootNamespace>
+    <AssemblyName>osu.Desktop.Tests</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="SQLiteNetExtensions">
+      <HintPath>$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll</HintPath>
+    </Reference>
+    <Reference Include="SQLite.Net.Platform.Win32">
+      <HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
+    </Reference>
+    <Reference Include="SQLite.Net.Platform.Generic">
+      <HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
+    </Reference>
+    <Reference Include="OpenTK">
+      <HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1339\lib\net45\OpenTK.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BenchmarkTest.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
+      <Project>{65DC628F-A640-4111-AB35-3A5652BC1E17}</Project>
+      <Name>osu.Framework.Desktop</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
+      <Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
+      <Name>osu.Framework</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj">
+      <Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
+      <Name>osu.Game.Resources</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Desktop.VisualTests\osu.Desktop.VisualTests.csproj">
+      <Project>{69051C69-12AE-4E7D-A3E6-460D2E282312}</Project>
+      <Name>osu.Desktop.VisualTests</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Game.Modes.Catch\osu.Game.Modes.Catch.csproj">
+      <Project>{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}</Project>
+      <Name>osu.Game.Modes.Catch</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Game.Modes.Mania\osu.Game.Modes.Mania.csproj">
+      <Project>{48F4582B-7687-4621-9CBE-5C24197CB536}</Project>
+      <Name>osu.Game.Modes.Mania</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
+      <Project>{C92A607B-1FDD-4954-9F92-03FF547D9080}</Project>
+      <Name>osu.Game.Modes.Osu</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Game.Modes.Taiko\osu.Game.Modes.Taiko.csproj">
+      <Project>{F167E17A-7DE6-4AF5-B920-A5112296C695}</Project>
+      <Name>osu.Game.Modes.Taiko</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\osu.Game\osu.Game.csproj">
+      <Project>{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}</Project>
+      <Name>osu.Game</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <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>
\ No newline at end of file
diff --git a/osu.Desktop.Tests/packages.config b/osu.Desktop.Tests/packages.config
new file mode 100644
index 0000000000..05b53c019c
--- /dev/null
+++ b/osu.Desktop.Tests/packages.config
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+  <package id="NUnit" version="3.5.0" targetFramework="net45" />
+  <package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
+  <package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
+  <package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/Benchmark.cs b/osu.Desktop.VisualTests/Benchmark.cs
new file mode 100644
index 0000000000..506788e93c
--- /dev/null
+++ b/osu.Desktop.VisualTests/Benchmark.cs
@@ -0,0 +1,56 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using osu.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Desktop.Platform;
+using osu.Framework.GameModes.Testing;
+using osu.Game;
+using osu.Game.Modes;
+using osu.Game.Modes.Catch;
+using osu.Game.Modes.Mania;
+using osu.Game.Modes.Osu;
+using osu.Game.Modes.Taiko;
+
+namespace osu.Desktop.VisualTests
+{
+    public class Benchmark : OsuGameBase
+    {
+        private double timePerTest = 200;
+
+        [BackgroundDependencyLoader]
+        private void load(BaseGame game)
+        {
+            Host.MaximumDrawHz = int.MaxValue;
+            Host.MaximumUpdateHz = int.MaxValue;
+            Host.MaximumInactiveHz = int.MaxValue;
+        }
+
+        protected override void LoadComplete()
+        {
+            base.LoadComplete();
+
+            TestBrowser f = new TestBrowser();
+            Add(f);
+
+            Console.WriteLine($@"{Time}: Running {f.TestCount} tests for {timePerTest}ms each...");
+
+            for (int i = 1; i < f.TestCount; i++)
+            {
+                int loadableCase = i;
+                Scheduler.AddDelayed(delegate
+                {
+                    f.LoadTest(loadableCase);
+                    Console.WriteLine($@"{Time}: Switching to test #{loadableCase}");
+                }, loadableCase * timePerTest);
+            }
+
+            Scheduler.AddDelayed(Host.Exit, f.TestCount * timePerTest);
+        }
+    }
+}
diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs
index df54297812..b89c6bcf4d 100644
--- a/osu.Desktop.VisualTests/Program.cs
+++ b/osu.Desktop.VisualTests/Program.cs
@@ -18,6 +18,8 @@ namespace osu.Desktop.VisualTests
         [STAThread]
         public static void Main(string[] args)
         {
+            bool benchmark = args.Length > 0 && args[0] == @"-benchmark";
+
             using (BasicGameHost host = Host.GetSuitableHost(@"osu"))
             {
                 Ruleset.Register(new OsuRuleset());
@@ -25,7 +27,10 @@ namespace osu.Desktop.VisualTests
                 Ruleset.Register(new ManiaRuleset());
                 Ruleset.Register(new CatchRuleset());
 
-                host.Add(new VisualTestGame());
+                if (benchmark)
+                    host.Add(new Benchmark());
+                else
+                    host.Add(new VisualTestGame());
                 host.Run();
             }
         }
diff --git a/osu.Desktop.VisualTests/VisualTestGame.cs b/osu.Desktop.VisualTests/VisualTestGame.cs
index 7489559c98..952de4ab26 100644
--- a/osu.Desktop.VisualTests/VisualTestGame.cs
+++ b/osu.Desktop.VisualTests/VisualTestGame.cs
@@ -10,7 +10,6 @@ using osu.Framework.Desktop.Platform;
 using System.Reflection;
 using System.IO;
 using System.Collections.Generic;
-using SQLiteNetExtensions.Extensions;
 using osu.Framework.Allocation;
 
 namespace osu.Desktop.VisualTests
diff --git a/osu.Desktop.VisualTests/app.config b/osu.Desktop.VisualTests/app.config
new file mode 100644
index 0000000000..9bad888bf3
--- /dev/null
+++ b/osu.Desktop.VisualTests/app.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
+Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+-->
+
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index 6fa9ab604e..1ec48e3cdf 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -100,13 +100,12 @@
     <Reference Include="OpenTK">
       <HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1339\lib\net45\OpenTK.dll</HintPath>
     </Reference>
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\osu.licenseheader">
       <Link>osu.licenseheader</Link>
     </None>
+    <None Include="app.config" />
     <None Include="packages.config" />
     <None Include="OpenTK.dll.config" />
   </ItemGroup>
@@ -172,6 +171,7 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Benchmark.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Tests\TestCaseChatDisplay.cs" />
     <Compile Include="Tests\TestCaseGamefield.cs" />
diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config
index f39a585e49..75affafd35 100644
--- a/osu.Desktop.VisualTests/packages.config
+++ b/osu.Desktop.VisualTests/packages.config
@@ -1,13 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
-Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
--->
-
-<packages>
-  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
-  <package id="ppy.OpenTK" version="2.0.50727.1339" targetFramework="net45" />
-  <package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
-  <package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
-  <package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
+Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+-->
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+  <package id="ppy.OpenTK" version="2.0.50727.1339" targetFramework="net45" />
+  <package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
+  <package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
+  <package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/osu.Game/Graphics/Containers/ParallaxContainer.cs b/osu.Game/Graphics/Containers/ParallaxContainer.cs
index c5e53e14a5..fe3601a5f2 100644
--- a/osu.Game/Graphics/Containers/ParallaxContainer.cs
+++ b/osu.Game/Graphics/Containers/ParallaxContainer.cs
@@ -45,7 +45,8 @@ namespace osu.Game.Graphics.Containers
         {
             base.Update();
 
-            content.MoveTo((ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount, firstUpdate ? 0 : 1000, EasingTypes.OutQuint);
+            Vector2 offset = input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2;
+            content.MoveTo(offset * ParallaxAmount, firstUpdate ? 0 : 1000, EasingTypes.OutQuint);
             content.Scale = new Vector2(1 + ParallaxAmount);
 
             firstUpdate = false;
diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs
index a76cdbe99b..6d720569df 100644
--- a/osu.Game/Screens/Menu/ButtonSystem.cs
+++ b/osu.Game/Screens/Menu/ButtonSystem.cs
@@ -119,11 +119,11 @@ namespace osu.Game.Screens.Menu
             buttonFlow.Add(buttonsTopLevel);
         }
 
-        [BackgroundDependencyLoader]
-        private void load(AudioManager audio, OsuGame game)
+        [BackgroundDependencyLoader(true)]
+        private void load(AudioManager audio, OsuGame game = null)
         {
             sampleOsuClick = audio.Sample.Get(@"Menu/menuhit");
-            toolbar = game.Toolbar;
+            toolbar = game?.Toolbar;
         }
 
         protected override void LoadComplete()
diff --git a/osu.sln b/osu.sln
index f3736c16c0..588cabf6b6 100644
--- a/osu.sln
+++ b/osu.sln
@@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Modes.Taiko", "osu
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Modes.Mania", "osu.Game.Modes.Mania\osu.Game.Modes.Mania.csproj", "{48F4582B-7687-4621-9CBE-5C24197CB536}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.Tests", "osu.Desktop.Tests\osu.Desktop.Tests.csproj", "{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -79,6 +81,10 @@ Global
 		{48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.Build.0 = Release|Any CPU
+		{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -95,6 +101,7 @@ Global
 		{58F6C80C-1253-4A0E-A465-B8C85EBEADF3} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
 		{F167E17A-7DE6-4AF5-B920-A5112296C695} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
 		{48F4582B-7687-4621-9CBE-5C24197CB536} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
+		{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D} = {0D37A2AD-80A4-464F-A1DE-1560B70F1CE3}
 	EndGlobalSection
 	GlobalSection(MonoDevelopProperties) = preSolution
 		Policies = $0