diff --git a/.gitignore b/.gitignore
index d1fcfc4e..4c997e2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,270 @@
-bin
-obj
-project.lock.json
\ No newline at end of file
+syntax: glob
+
+### VisualStudio ###
+
+# Project.json lock file
+project.lock.json
+
+# Tool Runtime Dir
+/[Tt]ools/
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+msbuild.log
+msbuild.err
+msbuild.wrn
+
+
+
+# Cross building rootfs
+cross/rootfs/
+
+# Visual Studio 2015
+.vs/
+
+# Visual Studio 2015 Pre-CTP6
+*.sln.ide
+*.ide/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+#NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding addin-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nuget.props
+*.nuget.targets
+*.nupkg
+**/packages/*
+
+# NuGet package restore lockfiles
+project.lock.json
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+*.metaproj
+*.metaproj.tmp
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+### MonoDevelop ###
+
+*.pidb
+*.userprefs
+
+### Windows ###
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+### Linux ###
+
+*~
+
+# KDE directory preferences
+.directory
+
+### OSX ###
+
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# vim temporary files
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+
+# Visual Studio Code
+.vscode/
diff --git a/ServiceHost/.vscode/launch.json b/ServiceHost/.vscode/launch.json
deleted file mode 100644
index 18ebbb27..00000000
--- a/ServiceHost/.vscode/launch.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- "name": ".NET Core Launch (console)",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/servicehost.dll",
- "args": [],
- "cwd": "${workspaceRoot}",
- "externalConsole": true,
- "requireExactSource": false,
- "stopAtEntry": false
- },
- {
- "name": ".NET Core Attach",
- "type": "coreclr",
- "request": "attach",
- "requireExactSource": false,
- "processId": 17264
- }
- ]
-}
\ No newline at end of file
diff --git a/ServiceHost/.vscode/tasks.json b/ServiceHost/.vscode/tasks.json
deleted file mode 100644
index 67d6eb75..00000000
--- a/ServiceHost/.vscode/tasks.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "version": "0.1.0",
- "command": "dotnet",
- "isShellCommand": true,
- "args": [],
- "tasks": [
- {
- "taskName": "build",
- "args": [],
- "isBuildCommand": true,
- "problemMatcher": "$msCompile"
- }
- ]
-}
\ No newline at end of file
diff --git a/global.json b/global.json
new file mode 100644
index 00000000..db6ba19b
--- /dev/null
+++ b/global.json
@@ -0,0 +1,5 @@
+{
+ "projects": [ "src", "test" ]
+}
+
+
diff --git a/ServiceHost/LanguageServer/ClientCapabilities.cs b/src/ServiceHost/LanguageServer/ClientCapabilities.cs
similarity index 100%
rename from ServiceHost/LanguageServer/ClientCapabilities.cs
rename to src/ServiceHost/LanguageServer/ClientCapabilities.cs
diff --git a/ServiceHost/LanguageServer/Completion.cs b/src/ServiceHost/LanguageServer/Completion.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Completion.cs
rename to src/ServiceHost/LanguageServer/Completion.cs
diff --git a/ServiceHost/LanguageServer/Configuration.cs b/src/ServiceHost/LanguageServer/Configuration.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Configuration.cs
rename to src/ServiceHost/LanguageServer/Configuration.cs
diff --git a/ServiceHost/LanguageServer/Definition.cs b/src/ServiceHost/LanguageServer/Definition.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Definition.cs
rename to src/ServiceHost/LanguageServer/Definition.cs
diff --git a/ServiceHost/LanguageServer/Diagnostics.cs b/src/ServiceHost/LanguageServer/Diagnostics.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Diagnostics.cs
rename to src/ServiceHost/LanguageServer/Diagnostics.cs
diff --git a/ServiceHost/LanguageServer/DocumentHighlight.cs b/src/ServiceHost/LanguageServer/DocumentHighlight.cs
similarity index 100%
rename from ServiceHost/LanguageServer/DocumentHighlight.cs
rename to src/ServiceHost/LanguageServer/DocumentHighlight.cs
diff --git a/ServiceHost/LanguageServer/ExpandAliasRequest.cs b/src/ServiceHost/LanguageServer/ExpandAliasRequest.cs
similarity index 100%
rename from ServiceHost/LanguageServer/ExpandAliasRequest.cs
rename to src/ServiceHost/LanguageServer/ExpandAliasRequest.cs
diff --git a/ServiceHost/LanguageServer/FindModuleRequest.cs b/src/ServiceHost/LanguageServer/FindModuleRequest.cs
similarity index 100%
rename from ServiceHost/LanguageServer/FindModuleRequest.cs
rename to src/ServiceHost/LanguageServer/FindModuleRequest.cs
diff --git a/ServiceHost/LanguageServer/Hover.cs b/src/ServiceHost/LanguageServer/Hover.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Hover.cs
rename to src/ServiceHost/LanguageServer/Hover.cs
diff --git a/ServiceHost/LanguageServer/Initialize.cs b/src/ServiceHost/LanguageServer/Initialize.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Initialize.cs
rename to src/ServiceHost/LanguageServer/Initialize.cs
diff --git a/ServiceHost/LanguageServer/InstallModuleRequest.cs b/src/ServiceHost/LanguageServer/InstallModuleRequest.cs
similarity index 100%
rename from ServiceHost/LanguageServer/InstallModuleRequest.cs
rename to src/ServiceHost/LanguageServer/InstallModuleRequest.cs
diff --git a/ServiceHost/LanguageServer/References.cs b/src/ServiceHost/LanguageServer/References.cs
similarity index 100%
rename from ServiceHost/LanguageServer/References.cs
rename to src/ServiceHost/LanguageServer/References.cs
diff --git a/ServiceHost/LanguageServer/ServerCapabilities.cs b/src/ServiceHost/LanguageServer/ServerCapabilities.cs
similarity index 100%
rename from ServiceHost/LanguageServer/ServerCapabilities.cs
rename to src/ServiceHost/LanguageServer/ServerCapabilities.cs
diff --git a/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs b/src/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs
similarity index 100%
rename from ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs
rename to src/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs
diff --git a/ServiceHost/LanguageServer/Shutdown.cs b/src/ServiceHost/LanguageServer/Shutdown.cs
similarity index 100%
rename from ServiceHost/LanguageServer/Shutdown.cs
rename to src/ServiceHost/LanguageServer/Shutdown.cs
diff --git a/ServiceHost/LanguageServer/SignatureHelp.cs b/src/ServiceHost/LanguageServer/SignatureHelp.cs
similarity index 100%
rename from ServiceHost/LanguageServer/SignatureHelp.cs
rename to src/ServiceHost/LanguageServer/SignatureHelp.cs
diff --git a/ServiceHost/LanguageServer/TextDocument.cs b/src/ServiceHost/LanguageServer/TextDocument.cs
similarity index 100%
rename from ServiceHost/LanguageServer/TextDocument.cs
rename to src/ServiceHost/LanguageServer/TextDocument.cs
diff --git a/ServiceHost/LanguageServer/WorkspaceSymbols.cs b/src/ServiceHost/LanguageServer/WorkspaceSymbols.cs
similarity index 100%
rename from ServiceHost/LanguageServer/WorkspaceSymbols.cs
rename to src/ServiceHost/LanguageServer/WorkspaceSymbols.cs
diff --git a/ServiceHost/LanguageSupport/LanguageService.cs b/src/ServiceHost/LanguageSupport/LanguageService.cs
similarity index 100%
rename from ServiceHost/LanguageSupport/LanguageService.cs
rename to src/ServiceHost/LanguageSupport/LanguageService.cs
diff --git a/ServiceHost/MessageProtocol/Channel/ChannelBase.cs b/src/ServiceHost/MessageProtocol/Channel/ChannelBase.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Channel/ChannelBase.cs
rename to src/ServiceHost/MessageProtocol/Channel/ChannelBase.cs
diff --git a/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs b/src/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs
rename to src/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs
diff --git a/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs b/src/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs
rename to src/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs
diff --git a/ServiceHost/MessageProtocol/Constants.cs b/src/ServiceHost/MessageProtocol/Constants.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Constants.cs
rename to src/ServiceHost/MessageProtocol/Constants.cs
diff --git a/ServiceHost/MessageProtocol/EventContext.cs b/src/ServiceHost/MessageProtocol/EventContext.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/EventContext.cs
rename to src/ServiceHost/MessageProtocol/EventContext.cs
diff --git a/ServiceHost/MessageProtocol/EventType.cs b/src/ServiceHost/MessageProtocol/EventType.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/EventType.cs
rename to src/ServiceHost/MessageProtocol/EventType.cs
diff --git a/ServiceHost/MessageProtocol/IMessageSender.cs b/src/ServiceHost/MessageProtocol/IMessageSender.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/IMessageSender.cs
rename to src/ServiceHost/MessageProtocol/IMessageSender.cs
diff --git a/ServiceHost/MessageProtocol/IMessageSerializer.cs b/src/ServiceHost/MessageProtocol/IMessageSerializer.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/IMessageSerializer.cs
rename to src/ServiceHost/MessageProtocol/IMessageSerializer.cs
diff --git a/ServiceHost/MessageProtocol/Message.cs b/src/ServiceHost/MessageProtocol/Message.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Message.cs
rename to src/ServiceHost/MessageProtocol/Message.cs
diff --git a/ServiceHost/MessageProtocol/MessageDispatcher.cs b/src/ServiceHost/MessageProtocol/MessageDispatcher.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/MessageDispatcher.cs
rename to src/ServiceHost/MessageProtocol/MessageDispatcher.cs
diff --git a/ServiceHost/MessageProtocol/MessageParseException.cs b/src/ServiceHost/MessageProtocol/MessageParseException.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/MessageParseException.cs
rename to src/ServiceHost/MessageProtocol/MessageParseException.cs
diff --git a/ServiceHost/MessageProtocol/MessageProtocolType.cs b/src/ServiceHost/MessageProtocol/MessageProtocolType.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/MessageProtocolType.cs
rename to src/ServiceHost/MessageProtocol/MessageProtocolType.cs
diff --git a/ServiceHost/MessageProtocol/MessageReader.cs b/src/ServiceHost/MessageProtocol/MessageReader.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/MessageReader.cs
rename to src/ServiceHost/MessageProtocol/MessageReader.cs
diff --git a/ServiceHost/MessageProtocol/MessageWriter.cs b/src/ServiceHost/MessageProtocol/MessageWriter.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/MessageWriter.cs
rename to src/ServiceHost/MessageProtocol/MessageWriter.cs
diff --git a/ServiceHost/MessageProtocol/ProtocolEndpoint.cs b/src/ServiceHost/MessageProtocol/ProtocolEndpoint.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/ProtocolEndpoint.cs
rename to src/ServiceHost/MessageProtocol/ProtocolEndpoint.cs
diff --git a/ServiceHost/MessageProtocol/RequestContext.cs b/src/ServiceHost/MessageProtocol/RequestContext.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/RequestContext.cs
rename to src/ServiceHost/MessageProtocol/RequestContext.cs
diff --git a/ServiceHost/MessageProtocol/RequestType.cs b/src/ServiceHost/MessageProtocol/RequestType.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/RequestType.cs
rename to src/ServiceHost/MessageProtocol/RequestType.cs
diff --git a/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs b/src/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
rename to src/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
diff --git a/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs b/src/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
similarity index 100%
rename from ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
rename to src/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
diff --git a/ServiceHost/Program.cs b/src/ServiceHost/Program.cs
similarity index 100%
rename from ServiceHost/Program.cs
rename to src/ServiceHost/Program.cs
diff --git a/ServiceHost/Properties/AssemblyInfo.cs b/src/ServiceHost/Properties/AssemblyInfo.cs
similarity index 100%
rename from ServiceHost/Properties/AssemblyInfo.cs
rename to src/ServiceHost/Properties/AssemblyInfo.cs
diff --git a/ServiceHost/Server/LanguageServer.cs b/src/ServiceHost/Server/LanguageServer.cs
similarity index 100%
rename from ServiceHost/Server/LanguageServer.cs
rename to src/ServiceHost/Server/LanguageServer.cs
diff --git a/ServiceHost/Server/LanguageServerBase.cs b/src/ServiceHost/Server/LanguageServerBase.cs
similarity index 100%
rename from ServiceHost/Server/LanguageServerBase.cs
rename to src/ServiceHost/Server/LanguageServerBase.cs
diff --git a/ServiceHost/Server/LanguageServerEditorOperations.cs b/src/ServiceHost/Server/LanguageServerEditorOperations.cs
similarity index 100%
rename from ServiceHost/Server/LanguageServerEditorOperations.cs
rename to src/ServiceHost/Server/LanguageServerEditorOperations.cs
diff --git a/ServiceHost/Server/LanguageServerSettings.cs b/src/ServiceHost/Server/LanguageServerSettings.cs
similarity index 100%
rename from ServiceHost/Server/LanguageServerSettings.cs
rename to src/ServiceHost/Server/LanguageServerSettings.cs
diff --git a/ServiceHost/Session/EditorSession.cs b/src/ServiceHost/Session/EditorSession.cs
similarity index 100%
rename from ServiceHost/Session/EditorSession.cs
rename to src/ServiceHost/Session/EditorSession.cs
diff --git a/ServiceHost/Session/HostDetails.cs b/src/ServiceHost/Session/HostDetails.cs
similarity index 100%
rename from ServiceHost/Session/HostDetails.cs
rename to src/ServiceHost/Session/HostDetails.cs
diff --git a/ServiceHost/Session/OutputType.cs b/src/ServiceHost/Session/OutputType.cs
similarity index 100%
rename from ServiceHost/Session/OutputType.cs
rename to src/ServiceHost/Session/OutputType.cs
diff --git a/ServiceHost/Session/OutputWrittenEventArgs.cs b/src/ServiceHost/Session/OutputWrittenEventArgs.cs
similarity index 100%
rename from ServiceHost/Session/OutputWrittenEventArgs.cs
rename to src/ServiceHost/Session/OutputWrittenEventArgs.cs
diff --git a/ServiceHost/Session/ProfilePaths.cs b/src/ServiceHost/Session/ProfilePaths.cs
similarity index 100%
rename from ServiceHost/Session/ProfilePaths.cs
rename to src/ServiceHost/Session/ProfilePaths.cs
diff --git a/ServiceHost/Session/SqlToolsContext.cs b/src/ServiceHost/Session/SqlToolsContext.cs
similarity index 100%
rename from ServiceHost/Session/SqlToolsContext.cs
rename to src/ServiceHost/Session/SqlToolsContext.cs
diff --git a/ServiceHost/Utility/AsyncContext.cs b/src/ServiceHost/Utility/AsyncContext.cs
similarity index 100%
rename from ServiceHost/Utility/AsyncContext.cs
rename to src/ServiceHost/Utility/AsyncContext.cs
diff --git a/ServiceHost/Utility/AsyncContextThread.cs b/src/ServiceHost/Utility/AsyncContextThread.cs
similarity index 100%
rename from ServiceHost/Utility/AsyncContextThread.cs
rename to src/ServiceHost/Utility/AsyncContextThread.cs
diff --git a/ServiceHost/Utility/AsyncLock.cs b/src/ServiceHost/Utility/AsyncLock.cs
similarity index 100%
rename from ServiceHost/Utility/AsyncLock.cs
rename to src/ServiceHost/Utility/AsyncLock.cs
diff --git a/ServiceHost/Utility/AsyncQueue.cs b/src/ServiceHost/Utility/AsyncQueue.cs
similarity index 100%
rename from ServiceHost/Utility/AsyncQueue.cs
rename to src/ServiceHost/Utility/AsyncQueue.cs
diff --git a/ServiceHost/Utility/Extensions.cs b/src/ServiceHost/Utility/Extensions.cs
similarity index 100%
rename from ServiceHost/Utility/Extensions.cs
rename to src/ServiceHost/Utility/Extensions.cs
diff --git a/ServiceHost/Utility/Logger.cs b/src/ServiceHost/Utility/Logger.cs
similarity index 100%
rename from ServiceHost/Utility/Logger.cs
rename to src/ServiceHost/Utility/Logger.cs
diff --git a/ServiceHost/Utility/ThreadSynchronizationContext.cs b/src/ServiceHost/Utility/ThreadSynchronizationContext.cs
similarity index 100%
rename from ServiceHost/Utility/ThreadSynchronizationContext.cs
rename to src/ServiceHost/Utility/ThreadSynchronizationContext.cs
diff --git a/ServiceHost/Utility/Validate.cs b/src/ServiceHost/Utility/Validate.cs
similarity index 100%
rename from ServiceHost/Utility/Validate.cs
rename to src/ServiceHost/Utility/Validate.cs
diff --git a/ServiceHost/Workspace/BufferPosition.cs b/src/ServiceHost/Workspace/BufferPosition.cs
similarity index 100%
rename from ServiceHost/Workspace/BufferPosition.cs
rename to src/ServiceHost/Workspace/BufferPosition.cs
diff --git a/ServiceHost/Workspace/BufferRange.cs b/src/ServiceHost/Workspace/BufferRange.cs
similarity index 100%
rename from ServiceHost/Workspace/BufferRange.cs
rename to src/ServiceHost/Workspace/BufferRange.cs
diff --git a/ServiceHost/Workspace/FileChange.cs b/src/ServiceHost/Workspace/FileChange.cs
similarity index 100%
rename from ServiceHost/Workspace/FileChange.cs
rename to src/ServiceHost/Workspace/FileChange.cs
diff --git a/ServiceHost/Workspace/FilePosition.cs b/src/ServiceHost/Workspace/FilePosition.cs
similarity index 100%
rename from ServiceHost/Workspace/FilePosition.cs
rename to src/ServiceHost/Workspace/FilePosition.cs
diff --git a/ServiceHost/Workspace/ScriptFile.cs b/src/ServiceHost/Workspace/ScriptFile.cs
similarity index 100%
rename from ServiceHost/Workspace/ScriptFile.cs
rename to src/ServiceHost/Workspace/ScriptFile.cs
diff --git a/ServiceHost/Workspace/ScriptFileMarker.cs b/src/ServiceHost/Workspace/ScriptFileMarker.cs
similarity index 100%
rename from ServiceHost/Workspace/ScriptFileMarker.cs
rename to src/ServiceHost/Workspace/ScriptFileMarker.cs
diff --git a/ServiceHost/Workspace/ScriptRegion.cs b/src/ServiceHost/Workspace/ScriptRegion.cs
similarity index 100%
rename from ServiceHost/Workspace/ScriptRegion.cs
rename to src/ServiceHost/Workspace/ScriptRegion.cs
diff --git a/ServiceHost/Workspace/Workspace.cs b/src/ServiceHost/Workspace/Workspace.cs
similarity index 100%
rename from ServiceHost/Workspace/Workspace.cs
rename to src/ServiceHost/Workspace/Workspace.cs
diff --git a/ServiceHost/project.json b/src/ServiceHost/project.json
similarity index 91%
rename from ServiceHost/project.json
rename to src/ServiceHost/project.json
index 28565355..11340892 100644
--- a/ServiceHost/project.json
+++ b/src/ServiceHost/project.json
@@ -5,7 +5,7 @@
"emitEntryPoint": true
},
"dependencies": {
- "Newtonsoft.Json": "9.0.1",
+ "Newtonsoft.Json": "9.0.1"
},
"frameworks": {
"netcoreapp1.0": {
diff --git a/test/ServiceHost.Test/App.config b/test/ServiceHost.Test/App.config
new file mode 100644
index 00000000..570b96df
--- /dev/null
+++ b/test/ServiceHost.Test/App.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/ServiceHost.Test/LanguageServer/JsonRpcMessageSerializerTests.cs b/test/ServiceHost.Test/LanguageServer/JsonRpcMessageSerializerTests.cs
new file mode 100644
index 00000000..9ec341c5
--- /dev/null
+++ b/test/ServiceHost.Test/LanguageServer/JsonRpcMessageSerializerTests.cs
@@ -0,0 +1,144 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
+using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers;
+using Newtonsoft.Json.Linq;
+using Xunit;
+
+namespace Microsoft.SqlTools.EditorServices.Test.Protocol.LanguageServer
+{
+ public class TestMessageContents
+ {
+ public const string SomeFieldValue = "Some value";
+ public const int NumberValue = 42;
+
+ public string SomeField { get; set; }
+
+ public int Number { get; set; }
+
+ public TestMessageContents()
+ {
+ this.SomeField = SomeFieldValue;
+ this.Number = NumberValue;
+ }
+ }
+
+ public class JsonRpcMessageSerializerTests
+ {
+ private IMessageSerializer messageSerializer;
+
+ private const string MessageId = "42";
+ private const string MethodName = "testMethod";
+ private static readonly JToken MessageContent = JToken.FromObject(new TestMessageContents());
+
+ public JsonRpcMessageSerializerTests()
+ {
+ this.messageSerializer = new JsonRpcMessageSerializer();
+ }
+
+ [Fact]
+ public void SerializesRequestMessages()
+ {
+ var messageObj =
+ this.messageSerializer.SerializeMessage(
+ Message.Request(
+ MessageId,
+ MethodName,
+ MessageContent));
+
+ AssertMessageFields(
+ messageObj,
+ checkId: true,
+ checkMethod: true,
+ checkParams: true);
+ }
+
+ [Fact]
+ public void SerializesEventMessages()
+ {
+ var messageObj =
+ this.messageSerializer.SerializeMessage(
+ Message.Event(
+ MethodName,
+ MessageContent));
+
+ AssertMessageFields(
+ messageObj,
+ checkMethod: true,
+ checkParams: true);
+ }
+
+ [Fact]
+ public void SerializesResponseMessages()
+ {
+ var messageObj =
+ this.messageSerializer.SerializeMessage(
+ Message.Response(
+ MessageId,
+ null,
+ MessageContent));
+
+ AssertMessageFields(
+ messageObj,
+ checkId: true,
+ checkResult: true);
+ }
+
+ [Fact]
+ public void SerializesResponseWithErrorMessages()
+ {
+ var messageObj =
+ this.messageSerializer.SerializeMessage(
+ Message.ResponseError(
+ MessageId,
+ null,
+ MessageContent));
+
+ AssertMessageFields(
+ messageObj,
+ checkId: true,
+ checkError: true);
+ }
+
+ private static void AssertMessageFields(
+ JObject messageObj,
+ bool checkId = false,
+ bool checkMethod = false,
+ bool checkParams = false,
+ bool checkResult = false,
+ bool checkError = false)
+ {
+ JToken token = null;
+
+ Assert.True(messageObj.TryGetValue("jsonrpc", out token));
+ Assert.Equal("2.0", token.ToString());
+
+ if (checkId)
+ {
+ Assert.True(messageObj.TryGetValue("id", out token));
+ Assert.Equal(MessageId, token.ToString());
+ }
+
+ if (checkMethod)
+ {
+ Assert.True(messageObj.TryGetValue("method", out token));
+ Assert.Equal(MethodName, token.ToString());
+ }
+
+ if (checkError)
+ {
+ // TODO
+ }
+ else
+ {
+ string contentField = checkParams ? "params" : "result";
+ Assert.True(messageObj.TryGetValue(contentField, out token));
+ Assert.True(JToken.DeepEquals(token, MessageContent));
+ }
+ }
+ }
+}
+
diff --git a/test/ServiceHost.Test/Message/MessageReaderWriterTests.cs b/test/ServiceHost.Test/Message/MessageReaderWriterTests.cs
new file mode 100644
index 00000000..82e619f5
--- /dev/null
+++ b/test/ServiceHost.Test/Message/MessageReaderWriterTests.cs
@@ -0,0 +1,177 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
+using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers;
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Microsoft.SqlTools.EditorServices.Test.Protocol.MessageProtocol
+{
+ public class MessageReaderWriterTests
+ {
+ const string TestEventString = "{\"type\":\"event\",\"event\":\"testEvent\",\"body\":null}";
+ const string TestEventFormatString = "{{\"event\":\"testEvent\",\"body\":{{\"someString\":\"{0}\"}},\"seq\":0,\"type\":\"event\"}}";
+ readonly int ExpectedMessageByteCount = Encoding.UTF8.GetByteCount(TestEventString);
+
+ private IMessageSerializer messageSerializer;
+
+ public MessageReaderWriterTests()
+ {
+ this.messageSerializer = new V8MessageSerializer();
+ }
+
+ [Fact]
+ public async Task WritesMessage()
+ {
+ MemoryStream outputStream = new MemoryStream();
+
+ MessageWriter messageWriter =
+ new MessageWriter(
+ outputStream,
+ this.messageSerializer);
+
+ // Write the message and then roll back the stream to be read
+ // TODO: This will need to be redone!
+ await messageWriter.WriteMessage(Message.Event("testEvent", null));
+ outputStream.Seek(0, SeekOrigin.Begin);
+
+ string expectedHeaderString =
+ string.Format(
+ Constants.ContentLengthFormatString,
+ ExpectedMessageByteCount);
+
+ byte[] buffer = new byte[128];
+ await outputStream.ReadAsync(buffer, 0, expectedHeaderString.Length);
+
+ Assert.Equal(
+ expectedHeaderString,
+ Encoding.ASCII.GetString(buffer, 0, expectedHeaderString.Length));
+
+ // Read the message
+ await outputStream.ReadAsync(buffer, 0, ExpectedMessageByteCount);
+
+ Assert.Equal(
+ TestEventString,
+ Encoding.UTF8.GetString(buffer, 0, ExpectedMessageByteCount));
+
+ outputStream.Dispose();
+ }
+
+ [Fact]
+ public void ReadsMessage()
+ {
+ MemoryStream inputStream = new MemoryStream();
+ MessageReader messageReader =
+ new MessageReader(
+ inputStream,
+ this.messageSerializer);
+
+ // Write a message to the stream
+ byte[] messageBuffer = this.GetMessageBytes(TestEventString);
+ inputStream.Write(
+ this.GetMessageBytes(TestEventString),
+ 0,
+ messageBuffer.Length);
+
+ inputStream.Flush();
+ inputStream.Seek(0, SeekOrigin.Begin);
+
+ Message messageResult = messageReader.ReadMessage().Result;
+ Assert.Equal("testEvent", messageResult.Method);
+
+ inputStream.Dispose();
+ }
+
+ [Fact]
+ public void ReadsManyBufferedMessages()
+ {
+ MemoryStream inputStream = new MemoryStream();
+ MessageReader messageReader =
+ new MessageReader(
+ inputStream,
+ this.messageSerializer);
+
+ // Get a message to use for writing to the stream
+ byte[] messageBuffer = this.GetMessageBytes(TestEventString);
+
+ // How many messages of this size should we write to overflow the buffer?
+ int overflowMessageCount =
+ (int)Math.Ceiling(
+ (MessageReader.DefaultBufferSize * 1.5) / messageBuffer.Length);
+
+ // Write the necessary number of messages to the stream
+ for (int i = 0; i < overflowMessageCount; i++)
+ {
+ inputStream.Write(messageBuffer, 0, messageBuffer.Length);
+ }
+
+ inputStream.Flush();
+ inputStream.Seek(0, SeekOrigin.Begin);
+
+ // Read the written messages from the stream
+ for (int i = 0; i < overflowMessageCount; i++)
+ {
+ Message messageResult = messageReader.ReadMessage().Result;
+ Assert.Equal("testEvent", messageResult.Method);
+ }
+
+ inputStream.Dispose();
+ }
+
+ [Fact]
+ public void ReaderResizesBufferForLargeMessages()
+ {
+ MemoryStream inputStream = new MemoryStream();
+ MessageReader messageReader =
+ new MessageReader(
+ inputStream,
+ this.messageSerializer);
+
+ // Get a message with content so large that the buffer will need
+ // to be resized to fit it all.
+ byte[] messageBuffer =
+ this.GetMessageBytes(
+ string.Format(
+ TestEventFormatString,
+ new String('X', (int)(MessageReader.DefaultBufferSize * 3))));
+
+ inputStream.Write(messageBuffer, 0, messageBuffer.Length);
+ inputStream.Flush();
+ inputStream.Seek(0, SeekOrigin.Begin);
+
+ Message messageResult = messageReader.ReadMessage().Result;
+ Assert.Equal("testEvent", messageResult.Method);
+
+ inputStream.Dispose();
+ }
+
+ private byte[] GetMessageBytes(string messageString, Encoding encoding = null)
+ {
+ if (encoding == null)
+ {
+ encoding = Encoding.UTF8;
+ }
+
+ byte[] messageBytes = Encoding.UTF8.GetBytes(messageString);
+ byte[] headerBytes =
+ Encoding.ASCII.GetBytes(
+ string.Format(
+ Constants.ContentLengthFormatString,
+ messageBytes.Length));
+
+ // Copy the bytes into a single buffer
+ byte[] finalBytes = new byte[headerBytes.Length + messageBytes.Length];
+ Buffer.BlockCopy(headerBytes, 0, finalBytes, 0, headerBytes.Length);
+ Buffer.BlockCopy(messageBytes, 0, finalBytes, headerBytes.Length, messageBytes.Length);
+
+ return finalBytes;
+ }
+ }
+}
+
diff --git a/test/ServiceHost.Test/Message/TestMessageTypes.cs b/test/ServiceHost.Test/Message/TestMessageTypes.cs
new file mode 100644
index 00000000..cc5981dc
--- /dev/null
+++ b/test/ServiceHost.Test/Message/TestMessageTypes.cs
@@ -0,0 +1,56 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
+using System;
+using System.Threading.Tasks;
+
+namespace Microsoft.SqlTools.EditorServices.Test.Protocol.MessageProtocol
+{
+ #region Request Types
+
+ internal class TestRequest
+ {
+ public Task ProcessMessage(
+ EditorSession editorSession,
+ MessageWriter messageWriter)
+ {
+ return Task.FromResult(false);
+ }
+ }
+
+ internal class TestRequestArguments
+ {
+ public string SomeString { get; set; }
+ }
+
+ #endregion
+
+ #region Response Types
+
+ internal class TestResponse
+ {
+ }
+
+ internal class TestResponseBody
+ {
+ public string SomeString { get; set; }
+ }
+
+ #endregion
+
+ #region Event Types
+
+ internal class TestEvent
+ {
+ }
+
+ internal class TestEventBody
+ {
+ public string SomeString { get; set; }
+ }
+
+ #endregion
+}
diff --git a/test/ServiceHost.Test/PowerShellEditorServices.Test.Protocol.csproj b/test/ServiceHost.Test/PowerShellEditorServices.Test.Protocol.csproj
new file mode 100644
index 00000000..54e20896
--- /dev/null
+++ b/test/ServiceHost.Test/PowerShellEditorServices.Test.Protocol.csproj
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ Debug
+ AnyCPU
+ {E3A5CF5D-6E41-44AC-AE0A-4C227E4BACD4}
+ Library
+ Properties
+ Microsoft.SqlTools.EditorServices.Test.Protocol
+ Microsoft.SqlTools.EditorServices.Test.Protocol
+ v4.6.1
+ 512
+ 69e9ba79
+ ..\..\
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+
+
+
+ ..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
+ True
+
+
+ ..\..\packages\xunit.assert.2.1.0\lib\portable-net45+win8+wp8+wpa81\xunit.assert.dll
+ True
+
+
+ ..\..\packages\xunit.extensibility.core.2.1.0\lib\portable-net45+win8+wp8+wpa81\xunit.core.dll
+ True
+
+
+ ..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {f8a0946a-5d25-4651-8079-b8d5776916fb}
+ SqlToolsEditorServices.Protocol
+
+
+ {81e8cbcd-6319-49e7-9662-0475bd0791f4}
+ SqlToolsEditorServices
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/ServiceHost.Test/Properties/AssemblyInfo.cs b/test/ServiceHost.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..5cf54b90
--- /dev/null
+++ b/test/ServiceHost.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,42 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+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("SqlToolsEditorServices.Test.Transport.Stdio")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SqlToolsEditorServices.Test.Transport.Stdio")]
+[assembly: AssemblyCopyright("Copyright � 2015")]
+[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("07137FCA-76D0-4CE7-9764-C21DB7A57093")]
+
+// 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")]
+
diff --git a/test/ServiceHost.Test/packages.config b/test/ServiceHost.Test/packages.config
new file mode 100644
index 00000000..d01e8969
--- /dev/null
+++ b/test/ServiceHost.Test/packages.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/ServiceHost.Test/project.json b/test/ServiceHost.Test/project.json
new file mode 100644
index 00000000..b7f00724
--- /dev/null
+++ b/test/ServiceHost.Test/project.json
@@ -0,0 +1,30 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable"
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "9.0.1",
+ "System.Runtime.Serialization.Primitives": "4.1.1",
+ "xunit": "2.1.0",
+ "dotnet-test-xunit": "1.0.0-rc2-192208-24",
+ "ServiceHost": {
+ "target": "project"
+ }
+ },
+ "testRunner": "xunit",
+ "frameworks": {
+ "netcoreapp1.0": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ },
+ "imports": [
+ "dotnet5.4",
+ "portable-net451+win8"
+ ]
+ }
+ }
+}