diff --git a/CodeLensOopSample/LICENSE b/CodeLensOopSample/LICENSE
new file mode 100644
index 0000000..49d2166
--- /dev/null
+++ b/CodeLensOopSample/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Microsoft
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/CodeLensOopSample/README.md b/CodeLensOopSample/README.md
new file mode 100644
index 0000000..a5b994f
--- /dev/null
+++ b/CodeLensOopSample/README.md
@@ -0,0 +1,23 @@
+# CodeLensOopProvider example
+A example for demonstrating how to use the public CodeLens API to create an out-of-proc extesnion that provides a CodeLens indictor showing most recent Git commits made to the source code.
+
+* Technologies: Visual Studio 2017 SDK
+* Topics: CodeLens
+
+**Description**
+
+This example generates a VSIX extension that packs two components:
+* CodeLensOopProvider.dll: This assembly contains a CodeLens data point provider that retrieves most recent commits from git repo where the source code are commited. This assembly is loaded by the CodeLens service which runs out of the Visual Studio process.
+* CodeLensOopProvidervsix.dll: This assembly provides a VSPackage which handles the command invoked when a users clicks on a commit from the commit indicator detail pane. This assembly is loaded by the Visual Studio process.
+
+![image](src/CodeLensOopProvider.jpg)
+
+**Getting Started**
+1. Clone the repo
+ `git clone https://github.com/Microsoft/VSSDK-Extensibility-Samples.git`
+2. To run the example, hit F5 or choose the **Debug > Start Debugging** menu command. A new instance of Visual Studio will launch under the experimental hive.
+3. Open a solution from a local git repo, for example, this example solution.
+4. Open a source code file, you will see the git commit lens indictor along with other CodeLens indicators in the editor.
+
+**How it works**
+1.
diff --git a/CodeLensOopSample/nuget.config b/CodeLensOopSample/nuget.config
new file mode 100644
index 0000000..d01fbb3
--- /dev/null
+++ b/CodeLensOopSample/nuget.config
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CodeLensOopSample/src/CodeLensOopProvider.jpg b/CodeLensOopSample/src/CodeLensOopProvider.jpg
new file mode 100644
index 0000000..c207b14
Binary files /dev/null and b/CodeLensOopSample/src/CodeLensOopProvider.jpg differ
diff --git a/CodeLensOopSample/src/CodeLensOopProvider/CodeLensOopProvider.csproj b/CodeLensOopSample/src/CodeLensOopProvider/CodeLensOopProvider.csproj
new file mode 100644
index 0000000..ec95898
--- /dev/null
+++ b/CodeLensOopSample/src/CodeLensOopProvider/CodeLensOopProvider.csproj
@@ -0,0 +1,112 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {31EB1B96-34E8-4E37-872D-4ED7363C95D9}
+ Library
+ Properties
+ CodeLensOopProvider
+ CodeLensOopProvider
+ v4.6.1
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\packages\LibGit2Sharp.0.24.1\lib\net40\LibGit2Sharp.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.CoreUtility.15.8.414-preview\lib\net46\Microsoft.VisualStudio.CoreUtility.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Language.15.8.414-preview\lib\net46\Microsoft.VisualStudio.Language.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Text.Data.15.8.414-preview\lib\net46\Microsoft.VisualStudio.Text.Data.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Text.Logic.15.8.414-preview\lib\net46\Microsoft.VisualStudio.Text.Logic.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Text.UI.15.8.414-preview\lib\net46\Microsoft.VisualStudio.Text.UI.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Threading.15.3.23\lib\net45\Microsoft.VisualStudio.Threading.dll
+
+
+ ..\..\packages\Microsoft.VisualStudio.Validation.15.3.15\lib\net45\Microsoft.VisualStudio.Validation.dll
+
+
+ ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\..\packages\StreamJsonRpc.1.3.6\lib\net45\StreamJsonRpc.dll
+
+
+ ..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
+
+
+ ..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ Designer
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use 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/CodeLensOopSample/src/CodeLensOopProvider/GitCommitDataPointProvider.cs b/CodeLensOopSample/src/CodeLensOopProvider/GitCommitDataPointProvider.cs
new file mode 100644
index 0000000..d2337f5
--- /dev/null
+++ b/CodeLensOopSample/src/CodeLensOopProvider/GitCommitDataPointProvider.cs
@@ -0,0 +1,191 @@
+using LibGit2Sharp;
+using Microsoft.VisualStudio.Core.Imaging;
+using Microsoft.VisualStudio.Language.CodeLens.Remoting;
+using Microsoft.VisualStudio.Threading;
+using Microsoft.VisualStudio.Utilities;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace CodeLensOopProvider
+{
+ [Export(typeof(IAsyncCodeLensDataPointProvider))]
+ [Name(Id)]
+ [ContentType("code")]
+ [LocalizedName(typeof(Resources), "GitCommitCodeLensProvider")]
+ [Priority(200)]
+ internal class GitCommitDataPointProvider : IAsyncCodeLensDataPointProvider
+ {
+ internal const string Id = "GitCommit";
+
+ public Task CanCreateDataPointAsync(CodeLensDescriptor descriptor, CancellationToken token)
+ {
+ Debug.Assert(descriptor != null);
+ var gitRepo = GitUtil.ProbeGitRepository(descriptor.FilePath, out string repoRoot);
+ return Task.FromResult(gitRepo != null);
+ }
+
+ public Task CreateDataPointAsync(CodeLensDescriptor descriptor, CancellationToken token)
+ {
+ return Task.FromResult(new GitCommitDataPoint(descriptor));
+ }
+
+ private class GitCommitDataPoint : IAsyncCodeLensDataPoint
+ {
+ private readonly CodeLensDescriptor descriptor;
+ private readonly Repository gitRepo;
+ private readonly string gitRepoRootPath;
+
+ public GitCommitDataPoint(CodeLensDescriptor descriptor)
+ {
+ this.descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor));
+ this.gitRepo = GitUtil.ProbeGitRepository(descriptor.FilePath, out this.gitRepoRootPath);
+ }
+
+ public event AsyncEventHandler InvalidatedAsync;
+
+ public CodeLensDescriptor Descriptor => this.descriptor;
+
+ public Task GetDataAsync(CancellationToken token)
+ {
+ // get the most recent commit
+ Commit commit = GitUtil.GetCommits(this.gitRepo, this.descriptor.FilePath, 1).FirstOrDefault();
+ if (commit == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ CodeLensDataPointDescriptor response = new CodeLensDataPointDescriptor()
+ {
+ Description = commit.Author.Name,
+ TooltipText = $"Last change committed by {commit.Author.Name} at {commit.Author.When.ToString(CultureInfo.CurrentCulture)}",
+ IntValue = null, // no int value
+ ImageId = GetCommitTypeIcon(commit),
+ };
+
+ return Task.FromResult(response);
+ }
+
+ public Task GetDetailsAsync(CancellationToken token)
+ {
+ // get the most recent 5 commits
+ var commits = GitUtil.GetCommits(this.gitRepo, this.descriptor.FilePath, 5).AsEnumerable();
+ if (commits == null || commits.Count() == 0)
+ {
+ return Task.FromResult(null);
+ }
+
+ var headers = new List()
+ {
+ new CodeLensDetailHeaderDescriptor()
+ {
+ UniqueName = "CommitType",
+ Width = 22,
+ },
+ new CodeLensDetailHeaderDescriptor()
+ {
+ UniqueName = "CommitId",
+ DisplayName = "Commit Id",
+ Width = 100, // fixed width
+ },
+ new CodeLensDetailHeaderDescriptor()
+ {
+ UniqueName = "CommitDescription",
+ DisplayName = "Description",
+ Width = 0.66666, // use 2/3 of the remaining width
+ },
+ new CodeLensDetailHeaderDescriptor()
+ {
+ UniqueName = "CommitAuthor",
+ DisplayName = "Author",
+ Width = 0.33333, // use 1/3 of the remaining width
+ },
+ new CodeLensDetailHeaderDescriptor()
+ {
+ UniqueName = "CommitDate",
+ DisplayName = "Date",
+ Width = 85, // fixed width
+ }
+ };
+
+ var entries = commits.Select(
+ commit => new CodeLensDetailEntryDescriptor()
+ {
+ Fields = new List()
+ {
+ new CodeLensDetailEntryField()
+ {
+ ImageId = GetCommitTypeIcon(commit),
+ },
+ new CodeLensDetailEntryField()
+ {
+ Text = commit.Id.Sha.Substring(0, 8),
+ },
+ new CodeLensDetailEntryField()
+ {
+ Text = commit.MessageShort,
+ },
+ new CodeLensDetailEntryField()
+ {
+ Text = commit.Author.Name,
+ },
+ new CodeLensDetailEntryField()
+ {
+ Text = commit.Author.When.ToString(@"MM\/dd\/yyyy", CultureInfo.CurrentCulture),
+ },
+ },
+ Tooltip = commit.Message,
+ NavigationCommand = new CodeLensDetailEntryCommand()
+ {
+ CommandSet = new Guid("f3cb9f10-281b-444f-a14e-de5de36177cd"),
+ CommandId = 0x0100,
+ CommandName = "Git.NavigateToCommit",
+ },
+ NavigationCommandArgs = new List