Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix.sln
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix.sln	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix.sln	(revision 14933)
@@ -0,0 +1,34 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistenceCodeFix", "PersistenceCodeFix\PersistenceCodeFix\PersistenceCodeFix.csproj", "{5D74C4E0-52B2-4F01-B024-307EF52BAE35}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistenceCodeFix.Test", "PersistenceCodeFix\PersistenceCodeFix.Test\PersistenceCodeFix.Test.csproj", "{40425A71-F399-4C15-8651-AA343E78568F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistenceCodeFix.Vsix", "PersistenceCodeFix\PersistenceCodeFix.Vsix\PersistenceCodeFix.Vsix.csproj", "{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{5D74C4E0-52B2-4F01-B024-307EF52BAE35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5D74C4E0-52B2-4F01-B024-307EF52BAE35}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5D74C4E0-52B2-4F01-B024-307EF52BAE35}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5D74C4E0-52B2-4F01-B024-307EF52BAE35}.Release|Any CPU.Build.0 = Release|Any CPU
+		{40425A71-F399-4C15-8651-AA343E78568F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{40425A71-F399-4C15-8651-AA343E78568F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{40425A71-F399-4C15-8651-AA343E78568F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{40425A71-F399-4C15-8651-AA343E78568F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/CodeFixVerifier.Helper.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/CodeFixVerifier.Helper.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/CodeFixVerifier.Helper.cs	(revision 14933)
@@ -0,0 +1,75 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Simplification;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+
+namespace TestHelper {
+  /// <summary>
+  /// Diagnostic Producer class with extra methods dealing with applying codefixes
+  /// All methods are static
+  /// </summary>
+  public abstract partial class CodeFixVerifier : DiagnosticVerifier {
+    /// <summary>
+    /// Apply the inputted CodeAction to the inputted document.
+    /// Meant to be used to apply codefixes.
+    /// </summary>
+    /// <param name="document">The Document to apply the fix on</param>
+    /// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
+    /// <returns>A Document with the changes from the CodeAction</returns>
+    private static Document ApplyFix(Document document, CodeAction codeAction) {
+      var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
+      var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
+      return solution.GetDocument(document.Id);
+    }
+
+    /// <summary>
+    /// Compare two collections of Diagnostics,and return a list of any new diagnostics that appear only in the second collection.
+    /// Note: Considers Diagnostics to be the same if they have the same Ids.  In the case of multiple diagnostics with the same Id in a row,
+    /// this method may not necessarily return the new one.
+    /// </summary>
+    /// <param name="diagnostics">The Diagnostics that existed in the code before the CodeFix was applied</param>
+    /// <param name="newDiagnostics">The Diagnostics that exist in the code after the CodeFix was applied</param>
+    /// <returns>A list of Diagnostics that only surfaced in the code after the CodeFix was applied</returns>
+    private static IEnumerable<Diagnostic> GetNewDiagnostics(IEnumerable<Diagnostic> diagnostics, IEnumerable<Diagnostic> newDiagnostics) {
+      var oldArray = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
+      var newArray = newDiagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
+
+      int oldIndex = 0;
+      int newIndex = 0;
+
+      while (newIndex < newArray.Length) {
+        if (oldIndex < oldArray.Length && oldArray[oldIndex].Id == newArray[newIndex].Id) {
+          ++oldIndex;
+          ++newIndex;
+        } else {
+          yield return newArray[newIndex++];
+        }
+      }
+    }
+
+    /// <summary>
+    /// Get the existing compiler diagnostics on the inputted document.
+    /// </summary>
+    /// <param name="document">The Document to run the compiler diagnostic analyzers on</param>
+    /// <returns>The compiler diagnostics that were found in the code</returns>
+    private static IEnumerable<Diagnostic> GetCompilerDiagnostics(Document document) {
+      return document.GetSemanticModelAsync().Result.GetDiagnostics();
+    }
+
+    /// <summary>
+    /// Given a document, turn it into a string based on the syntax root
+    /// </summary>
+    /// <param name="document">The Document to be converted to a string</param>
+    /// <returns>A string containing the syntax of the Document after formatting</returns>
+    private static string GetStringFromDocument(Document document) {
+      var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
+      var root = simplifiedDoc.GetSyntaxRootAsync().Result;
+      root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
+      return root.GetText().ToString();
+    }
+  }
+}
+
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticResult.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticResult.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticResult.cs	(revision 14933)
@@ -0,0 +1,71 @@
+﻿using Microsoft.CodeAnalysis;
+using System;
+
+namespace TestHelper {
+  /// <summary>
+  /// Location where the diagnostic appears, as determined by path, line number, and column number.
+  /// </summary>
+  public struct DiagnosticResultLocation {
+    public DiagnosticResultLocation(string path, int line, int column) {
+      if (line < -1) {
+        throw new ArgumentOutOfRangeException(nameof(line), "line must be >= -1");
+      }
+
+      if (column < -1) {
+        throw new ArgumentOutOfRangeException(nameof(column), "column must be >= -1");
+      }
+
+      this.Path = path;
+      this.Line = line;
+      this.Column = column;
+    }
+
+    public string Path { get; }
+    public int Line { get; }
+    public int Column { get; }
+  }
+
+  /// <summary>
+  /// Struct that stores information about a Diagnostic appearing in a source
+  /// </summary>
+  public struct DiagnosticResult {
+    private DiagnosticResultLocation[] locations;
+
+    public DiagnosticResultLocation[] Locations {
+      get {
+        if (this.locations == null) {
+          this.locations = new DiagnosticResultLocation[] { };
+        }
+        return this.locations;
+      }
+
+      set {
+        this.locations = value;
+      }
+    }
+
+    public DiagnosticSeverity Severity { get; set; }
+
+    public string Id { get; set; }
+
+    public string Message { get; set; }
+
+    public string Path {
+      get {
+        return this.Locations.Length > 0 ? this.Locations[0].Path : "";
+      }
+    }
+
+    public int Line {
+      get {
+        return this.Locations.Length > 0 ? this.Locations[0].Line : -1;
+      }
+    }
+
+    public int Column {
+      get {
+        return this.Locations.Length > 0 ? this.Locations[0].Column : -1;
+      }
+    }
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticVerifier.Helper.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticVerifier.Helper.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Helpers/DiagnosticVerifier.Helper.cs	(revision 14933)
@@ -0,0 +1,151 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Text;
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+
+namespace TestHelper {
+  /// <summary>
+  /// Class for turning strings into documents and getting the diagnostics on them
+  /// All methods are static
+  /// </summary>
+  public abstract partial class DiagnosticVerifier {
+    private static readonly MetadataReference CorlibReference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
+    private static readonly MetadataReference SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location);
+    private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location);
+    private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location);
+
+    internal static string DefaultFilePathPrefix = "Test";
+    internal static string CSharpDefaultFileExt = "cs";
+    internal static string VisualBasicDefaultExt = "vb";
+    internal static string TestProjectName = "TestProject";
+
+    #region  Get Diagnostics
+
+    /// <summary>
+    /// Given classes in the form of strings, their language, and an IDiagnosticAnlayzer to apply to it, return the diagnostics found in the string after converting it to a document.
+    /// </summary>
+    /// <param name="sources">Classes in the form of strings</param>
+    /// <param name="language">The language the source classes are in</param>
+    /// <param name="analyzer">The analyzer to be run on the sources</param>
+    /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location</returns>
+    private static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer) {
+      return GetSortedDiagnosticsFromDocuments(analyzer, GetDocuments(sources, language));
+    }
+
+    /// <summary>
+    /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it.
+    /// The returned diagnostics are then ordered by location in the source document.
+    /// </summary>
+    /// <param name="analyzer">The analyzer to run on the documents</param>
+    /// <param name="documents">The Documents that the analyzer will be run on</param>
+    /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location</returns>
+    protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents) {
+      var projects = new HashSet<Project>();
+      foreach (var document in documents) {
+        projects.Add(document.Project);
+      }
+
+      var diagnostics = new List<Diagnostic>();
+      foreach (var project in projects) {
+        var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer));
+        var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result;
+        foreach (var diag in diags) {
+          if (diag.Location == Location.None || diag.Location.IsInMetadata) {
+            diagnostics.Add(diag);
+          } else {
+            for (int i = 0; i < documents.Length; i++) {
+              var document = documents[i];
+              var tree = document.GetSyntaxTreeAsync().Result;
+              if (tree == diag.Location.SourceTree) {
+                diagnostics.Add(diag);
+              }
+            }
+          }
+        }
+      }
+
+      var results = SortDiagnostics(diagnostics);
+      diagnostics.Clear();
+      return results;
+    }
+
+    /// <summary>
+    /// Sort diagnostics by location in source document
+    /// </summary>
+    /// <param name="diagnostics">The list of Diagnostics to be sorted</param>
+    /// <returns>An IEnumerable containing the Diagnostics in order of Location</returns>
+    private static Diagnostic[] SortDiagnostics(IEnumerable<Diagnostic> diagnostics) {
+      return diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
+    }
+
+    #endregion
+
+    #region Set up compilation and documents
+    /// <summary>
+    /// Given an array of strings as sources and a language, turn them into a project and return the documents and spans of it.
+    /// </summary>
+    /// <param name="sources">Classes in the form of strings</param>
+    /// <param name="language">The language the source code is in</param>
+    /// <returns>A Tuple containing the Documents produced from the sources and their TextSpans if relevant</returns>
+    private static Document[] GetDocuments(string[] sources, string language) {
+      if (language != LanguageNames.CSharp && language != LanguageNames.VisualBasic) {
+        throw new ArgumentException("Unsupported Language");
+      }
+
+      var project = CreateProject(sources, language);
+      var documents = project.Documents.ToArray();
+
+      if (sources.Length != documents.Length) {
+        throw new SystemException("Amount of sources did not match amount of Documents created");
+      }
+
+      return documents;
+    }
+
+    /// <summary>
+    /// Create a Document from a string through creating a project that contains it.
+    /// </summary>
+    /// <param name="source">Classes in the form of a string</param>
+    /// <param name="language">The language the source code is in</param>
+    /// <returns>A Document created from the source string</returns>
+    protected static Document CreateDocument(string source, string language = LanguageNames.CSharp) {
+      return CreateProject(new[] { source }, language).Documents.First();
+    }
+
+    /// <summary>
+    /// Create a project using the inputted strings as sources.
+    /// </summary>
+    /// <param name="sources">Classes in the form of strings</param>
+    /// <param name="language">The language the source code is in</param>
+    /// <returns>A Project created out of the Documents created from the source strings</returns>
+    private static Project CreateProject(string[] sources, string language = LanguageNames.CSharp) {
+      string fileNamePrefix = DefaultFilePathPrefix;
+      string fileExt = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt;
+
+      var projectId = ProjectId.CreateNewId(debugName: TestProjectName);
+
+      var solution = new AdhocWorkspace()
+          .CurrentSolution
+          .AddProject(projectId, TestProjectName, TestProjectName, language)
+          .AddMetadataReference(projectId, CorlibReference)
+          .AddMetadataReference(projectId, SystemCoreReference)
+          .AddMetadataReference(projectId, CSharpSymbolsReference)
+          .AddMetadataReference(projectId, CodeAnalysisReference);
+
+      int count = 0;
+      foreach (var source in sources) {
+        var newFileName = fileNamePrefix + count + "." + fileExt;
+        var documentId = DocumentId.CreateNewId(projectId, debugName: newFileName);
+        solution = solution.AddDocument(documentId, newFileName, SourceText.From(source));
+        count++;
+      }
+      return solution.GetProject(projectId);
+    }
+    #endregion
+  }
+}
+
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/PersistenceCodeFix.Test.csproj
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/PersistenceCodeFix.Test.csproj	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/PersistenceCodeFix.Test.csproj	(revision 14933)
@@ -0,0 +1,128 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c)  Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+    <Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{40425A71-F399-4C15-8651-AA343E78568F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PersistenceCodeFix.Test</RootNamespace>
+    <AssemblyName>PersistenceCodeFix.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</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>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </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>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CodeAnalysis, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.Common.1.0.1\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.1.0.1\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.0.1\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.VisualBasic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.0.1\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.0.1\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.1\lib\net452\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.1\lib\net452\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Composition.AttributedModel, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Composition.Convention, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Composition.Hosting, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Composition.Runtime, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Composition.TypedParts, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Reflection.Metadata, Version=1.0.21.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.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.Xml" />
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework">
+      <Private>false</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Verifiers\CodeFixVerifier.cs" />
+    <Compile Include="Verifiers\DiagnosticVerifier.cs" />
+    <Compile Include="Helpers\CodeFixVerifier.Helper.cs" />
+    <Compile Include="Helpers\DiagnosticResult.cs" />
+    <Compile Include="Helpers\DiagnosticVerifier.Helper.cs" />
+    <Compile Include="UnitTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\PersistenceCodeFix\PersistenceCodeFix.csproj">
+      <Project>{5D74C4E0-52B2-4F01-B024-307EF52BAE35}</Project>
+      <Name>PersistenceCodeFix</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Properties/AssemblyInfo.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Properties/AssemblyInfo.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Properties/AssemblyInfo.cs	(revision 14933)
@@ -0,0 +1,32 @@
+﻿using System.Reflection;
+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("PersistenceCodeFix.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("PersistenceCodeFix.Test")]
+[assembly: AssemblyCopyright("Copyright © FH-Hagenberg 2017")]
+[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)]
+
+// 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")]
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/UnitTests.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/UnitTests.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/UnitTests.cs	(revision 14933)
@@ -0,0 +1,52 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using TestHelper;
+using PersistenceCodeFix;
+
+namespace PersistenceCodeFix.Test {
+  [TestClass]
+  public class UnitTest : CodeFixVerifier {
+
+    //No diagnostics expected to show up
+    [TestMethod]
+    public void TestMethod1() {
+      var test = @"";
+
+      VerifyCSharpDiagnostic(test);
+    }
+
+    //Diagnostic and CodeFix both triggered and checked for
+    [TestMethod]
+    public void TestMethod2() {
+      var test = @"
+    namespace ConsoleApplication1 {
+      
+      [Item(""XXX""), NonDiscoverable]
+      class TypeName {   
+        class InnerClass {   
+        }
+      }
+    }";
+
+
+      var fixtest = @"
+    namespace ConsoleApplication1 {
+        [StorableType(Guid = ""XXX"")]
+        class TypeName {   
+        }
+    }";
+      VerifyCSharpFix(test, fixtest);
+    }
+
+    protected override CodeFixProvider GetCSharpCodeFixProvider() {
+      return new PersistenceCodeFixProvider();
+    }
+
+    protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() {
+      return new MissingStorableTypeAnalyzer();
+    }
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/CodeFixVerifier.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/CodeFixVerifier.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/CodeFixVerifier.cs	(revision 14933)
@@ -0,0 +1,116 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+
+namespace TestHelper {
+  /// <summary>
+  /// Superclass of all Unit tests made for diagnostics with codefixes.
+  /// Contains methods used to verify correctness of codefixes
+  /// </summary>
+  public abstract partial class CodeFixVerifier : DiagnosticVerifier {
+    /// <summary>
+    /// Returns the codefix being tested (C#) - to be implemented in non-abstract class
+    /// </summary>
+    /// <returns>The CodeFixProvider to be used for CSharp code</returns>
+    protected virtual CodeFixProvider GetCSharpCodeFixProvider() {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the codefix being tested (VB) - to be implemented in non-abstract class
+    /// </summary>
+    /// <returns>The CodeFixProvider to be used for VisualBasic code</returns>
+    protected virtual CodeFixProvider GetBasicCodeFixProvider() {
+      return null;
+    }
+
+    /// <summary>
+    /// Called to test a C# codefix when applied on the inputted string as a source
+    /// </summary>
+    /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
+    /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
+    /// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
+    /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
+    protected void VerifyCSharpFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) {
+      VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics);
+    }
+
+    /// <summary>
+    /// Called to test a VB codefix when applied on the inputted string as a source
+    /// </summary>
+    /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
+    /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
+    /// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
+    /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
+    protected void VerifyBasicFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) {
+      VerifyFix(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics);
+    }
+
+    /// <summary>
+    /// General verifier for codefixes.
+    /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes.
+    /// Then gets the string after the codefix is applied and compares it with the expected result.
+    /// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true.
+    /// </summary>
+    /// <param name="language">The language the source code is in</param>
+    /// <param name="analyzer">The analyzer to be applied to the source code</param>
+    /// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param>
+    /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
+    /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
+    /// <param name="codeFixIndex">Index determining which codefix to apply if there are multiple</param>
+    /// <param name="allowNewCompilerDiagnostics">A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied</param>
+    private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) {
+      var document = CreateDocument(oldSource, language);
+      var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
+      var compilerDiagnostics = GetCompilerDiagnostics(document);
+      var attempts = analyzerDiagnostics.Length;
+
+      for (int i = 0; i < attempts; ++i) {
+        var actions = new List<CodeAction>();
+        var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
+        codeFixProvider.RegisterCodeFixesAsync(context).Wait();
+
+        if (!actions.Any()) {
+          break;
+        }
+
+        if (codeFixIndex != null) {
+          document = ApplyFix(document, actions.ElementAt((int)codeFixIndex));
+          break;
+        }
+
+        document = ApplyFix(document, actions.ElementAt(0));
+        analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document });
+
+        var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
+
+        //check if applying the code fix introduced any new compiler diagnostics
+        if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) {
+          // Format and get the compiler diagnostics again so that the locations make sense in the output
+          document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
+          newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document));
+
+          Assert.IsTrue(false,
+              string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
+                  string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())),
+                  document.GetSyntaxRootAsync().Result.ToFullString()));
+        }
+
+        //check if there are analyzer diagnostics left after the code fix
+        if (!analyzerDiagnostics.Any()) {
+          break;
+        }
+      }
+
+      //after applying all of the code fixes, compare the resulting string to the inputted one
+      var actual = GetStringFromDocument(document);
+      Assert.AreEqual(newSource, actual);
+    }
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/DiagnosticVerifier.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/DiagnosticVerifier.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/Verifiers/DiagnosticVerifier.cs	(revision 14933)
@@ -0,0 +1,236 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace TestHelper {
+  /// <summary>
+  /// Superclass of all Unit Tests for DiagnosticAnalyzers
+  /// </summary>
+  public abstract partial class DiagnosticVerifier {
+    #region To be implemented by Test classes
+    /// <summary>
+    /// Get the CSharp analyzer being tested - to be implemented in non-abstract class
+    /// </summary>
+    protected virtual DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() {
+      return null;
+    }
+
+    /// <summary>
+    /// Get the Visual Basic analyzer being tested (C#) - to be implemented in non-abstract class
+    /// </summary>
+    protected virtual DiagnosticAnalyzer GetBasicDiagnosticAnalyzer() {
+      return null;
+    }
+    #endregion
+
+    #region Verifier wrappers
+
+    /// <summary>
+    /// Called to test a C# DiagnosticAnalyzer when applied on the single inputted string as a source
+    /// Note: input a DiagnosticResult for each Diagnostic expected
+    /// </summary>
+    /// <param name="source">A class in the form of a string to run the analyzer on</param>
+    /// <param name="expected"> DiagnosticResults that should appear after the analyzer is run on the source</param>
+    protected void VerifyCSharpDiagnostic(string source, params DiagnosticResult[] expected) {
+      VerifyDiagnostics(new[] { source }, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected);
+    }
+
+    /// <summary>
+    /// Called to test a VB DiagnosticAnalyzer when applied on the single inputted string as a source
+    /// Note: input a DiagnosticResult for each Diagnostic expected
+    /// </summary>
+    /// <param name="source">A class in the form of a string to run the analyzer on</param>
+    /// <param name="expected">DiagnosticResults that should appear after the analyzer is run on the source</param>
+    protected void VerifyBasicDiagnostic(string source, params DiagnosticResult[] expected) {
+      VerifyDiagnostics(new[] { source }, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected);
+    }
+
+    /// <summary>
+    /// Called to test a C# DiagnosticAnalyzer when applied on the inputted strings as a source
+    /// Note: input a DiagnosticResult for each Diagnostic expected
+    /// </summary>
+    /// <param name="sources">An array of strings to create source documents from to run the analyzers on</param>
+    /// <param name="expected">DiagnosticResults that should appear after the analyzer is run on the sources</param>
+    protected void VerifyCSharpDiagnostic(string[] sources, params DiagnosticResult[] expected) {
+      VerifyDiagnostics(sources, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected);
+    }
+
+    /// <summary>
+    /// Called to test a VB DiagnosticAnalyzer when applied on the inputted strings as a source
+    /// Note: input a DiagnosticResult for each Diagnostic expected
+    /// </summary>
+    /// <param name="sources">An array of strings to create source documents from to run the analyzers on</param>
+    /// <param name="expected">DiagnosticResults that should appear after the analyzer is run on the sources</param>
+    protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] expected) {
+      VerifyDiagnostics(sources, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected);
+    }
+
+    /// <summary>
+    /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run, 
+    /// then verifies each of them.
+    /// </summary>
+    /// <param name="sources">An array of strings to create source documents from to run the analyzers on</param>
+    /// <param name="language">The language of the classes represented by the source strings</param>
+    /// <param name="analyzer">The analyzer to be run on the source code</param>
+    /// <param name="expected">DiagnosticResults that should appear after the analyzer is run on the sources</param>
+    private void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) {
+      var diagnostics = GetSortedDiagnostics(sources, language, analyzer);
+      VerifyDiagnosticResults(diagnostics, analyzer, expected);
+    }
+
+    #endregion
+
+    #region Actual comparisons and verifications
+    /// <summary>
+    /// Checks each of the actual Diagnostics found and compares them with the corresponding DiagnosticResult in the array of expected results.
+    /// Diagnostics are considered equal only if the DiagnosticResultLocation, Id, Severity, and Message of the DiagnosticResult match the actual diagnostic.
+    /// </summary>
+    /// <param name="actualResults">The Diagnostics found by the compiler after running the analyzer on the source code</param>
+    /// <param name="analyzer">The analyzer that was being run on the sources</param>
+    /// <param name="expectedResults">Diagnostic Results that should have appeared in the code</param>
+    private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResults, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expectedResults) {
+      int expectedCount = expectedResults.Count();
+      int actualCount = actualResults.Count();
+
+      if (expectedCount != actualCount) {
+        string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : "    NONE.";
+
+        Assert.IsTrue(false,
+            string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
+      }
+
+      for (int i = 0; i < expectedResults.Length; i++) {
+        var actual = actualResults.ElementAt(i);
+        var expected = expectedResults[i];
+
+        if (expected.Line == -1 && expected.Column == -1) {
+          if (actual.Location != Location.None) {
+            Assert.IsTrue(false,
+                string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}",
+                FormatDiagnostics(analyzer, actual)));
+          }
+        } else {
+          VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Locations.First());
+          var additionalLocations = actual.AdditionalLocations.ToArray();
+
+          if (additionalLocations.Length != expected.Locations.Length - 1) {
+            Assert.IsTrue(false,
+                string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n    {2}\r\n",
+                    expected.Locations.Length - 1, additionalLocations.Length,
+                    FormatDiagnostics(analyzer, actual)));
+          }
+
+          for (int j = 0; j < additionalLocations.Length; ++j) {
+            VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Locations[j + 1]);
+          }
+        }
+
+        if (actual.Id != expected.Id) {
+          Assert.IsTrue(false,
+              string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+                  expected.Id, actual.Id, FormatDiagnostics(analyzer, actual)));
+        }
+
+        if (actual.Severity != expected.Severity) {
+          Assert.IsTrue(false,
+              string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+                  expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual)));
+        }
+
+        if (actual.GetMessage() != expected.Message) {
+          Assert.IsTrue(false,
+              string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+                  expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual)));
+        }
+      }
+    }
+
+    /// <summary>
+    /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult.
+    /// </summary>
+    /// <param name="analyzer">The analyzer that was being run on the sources</param>
+    /// <param name="diagnostic">The diagnostic that was found in the code</param>
+    /// <param name="actual">The Location of the Diagnostic found in the code</param>
+    /// <param name="expected">The DiagnosticResultLocation that should have been found</param>
+    private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) {
+      var actualSpan = actual.GetLineSpan();
+
+      Assert.IsTrue(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")),
+          string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+              expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic)));
+
+      var actualLinePosition = actualSpan.StartLinePosition;
+
+      // Only check line position if there is an actual line in the real diagnostic
+      if (actualLinePosition.Line > 0) {
+        if (actualLinePosition.Line + 1 != expected.Line) {
+          Assert.IsTrue(false,
+              string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+                  expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic)));
+        }
+      }
+
+      // Only check column position if there is an actual column position in the real diagnostic
+      if (actualLinePosition.Character > 0) {
+        if (actualLinePosition.Character + 1 != expected.Column) {
+          Assert.IsTrue(false,
+              string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
+                  expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic)));
+        }
+      }
+    }
+    #endregion
+
+    #region Formatting Diagnostics
+    /// <summary>
+    /// Helper method to format a Diagnostic into an easily readable string
+    /// </summary>
+    /// <param name="analyzer">The analyzer that this verifier tests</param>
+    /// <param name="diagnostics">The Diagnostics to be formatted</param>
+    /// <returns>The Diagnostics formatted as a string</returns>
+    private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics) {
+      var builder = new StringBuilder();
+      for (int i = 0; i < diagnostics.Length; ++i) {
+        builder.AppendLine("// " + diagnostics[i].ToString());
+
+        var analyzerType = analyzer.GetType();
+        var rules = analyzer.SupportedDiagnostics;
+
+        foreach (var rule in rules) {
+          if (rule != null && rule.Id == diagnostics[i].Id) {
+            var location = diagnostics[i].Location;
+            if (location == Location.None) {
+              builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
+            } else {
+              Assert.IsTrue(location.IsInSource,
+                  $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");
+
+              string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt";
+              var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;
+
+              builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
+                  resultMethodName,
+                  linePosition.Line + 1,
+                  linePosition.Character + 1,
+                  analyzerType.Name,
+                  rule.Id);
+            }
+
+            if (i != diagnostics.Length - 1) {
+              builder.Append(',');
+            }
+
+            builder.AppendLine();
+            break;
+          }
+        }
+      }
+      return builder.ToString();
+    }
+    #endregion
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/packages.config
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/packages.config	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Test/packages.config	(revision 14933)
@@ -0,0 +1,12 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Microsoft.CodeAnalysis.Common" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.CodeAnalysis.CSharp" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.CodeAnalysis.VisualBasic" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.CodeAnalysis.VisualBasic.Workspaces" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.CodeAnalysis.Workspaces.Common" version="1.0.1" targetFramework="net461" />
+  <package id="Microsoft.Composition" version="1.0.27" targetFramework="net461" />
+  <package id="System.Collections.Immutable" version="1.1.36" targetFramework="net461" />
+  <package id="System.Reflection.Metadata" version="1.0.21" targetFramework="net461" />
+</packages>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/PersistenceCodeFix.Vsix.csproj
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/PersistenceCodeFix.Vsix.csproj	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/PersistenceCodeFix.Vsix.csproj	(revision 14933)
@@ -0,0 +1,64 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c)  Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+  </PropertyGroup>
+  <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>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{6ACE10E7-BB87-479D-84EB-564B33FFFDDA}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PersistenceCodeFix.Vsix</RootNamespace>
+    <AssemblyName>PersistenceCodeFix.Vsix</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <GeneratePkgDefFile>false</GeneratePkgDefFile>
+    <IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
+    <IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
+    <IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
+    <CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
+    <CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
+    <VSSDKTargetPlatformRegRootSuffix>Roslyn</VSSDKTargetPlatformRegRootSuffix>
+  </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>
+  <PropertyGroup>
+    <StartAction>Program</StartAction>
+    <StartProgram>$(DevEnvDir)devenv.exe</StartProgram>
+    <StartArguments>/rootsuffix Roslyn</StartArguments>
+  </PropertyGroup>
+  <ItemGroup>
+    <None Include="source.extension.vsixmanifest">
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\PersistenceCodeFix\PersistenceCodeFix.csproj">
+      <Project>{5D74C4E0-52B2-4F01-B024-307EF52BAE35}</Project>
+      <Name>PersistenceCodeFix</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/source.extension.vsixmanifest
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/source.extension.vsixmanifest	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.Vsix/source.extension.vsixmanifest	(revision 14933)
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
+  <Metadata>
+    <Identity Id="PersistenceCodeFix.FH-Hagenberg.e880ba2c-6795-4f4c-88a1-777ab5af682f" Version="1.0" Language="en-US" Publisher="P24581"/>
+    <DisplayName>PersistenceCodeFix</DisplayName>
+    <Description xml:space="preserve">This is a sample diagnostic extension for the .NET Compiler Platform ("Roslyn").</Description>
+  </Metadata>
+  <Installation>
+    <InstallationTarget Version="[14.0,]" Id="Microsoft.VisualStudio.Pro" />
+  </Installation>
+  <Dependencies>
+    <Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
+  </Dependencies>
+  <Assets>
+    <Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="PersistenceCodeFix" Path="|PersistenceCodeFix|"/>
+    <Asset Type="Microsoft.VisualStudio.Analyzer" d:Source="Project" d:ProjectName="PersistenceCodeFix" Path="|PersistenceCodeFix|"/>
+  </Assets>
+  <Prerequisites>
+    <Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
+    <Prerequisite Id="Microsoft.VisualStudio.Component.Roslyn.LanguageServices" Version="[15.0,16.0)" DisplayName="Roslyn Language Services" />
+  </Prerequisites>
+</PackageManifest>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/CodeFixProvider.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/CodeFixProvider.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/CodeFixProvider.cs	(revision 14933)
@@ -0,0 +1,158 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Composition;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Text;
+
+
+namespace PersistenceCodeFix {
+  [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(PersistenceCodeFixProvider)), Shared]
+  public class PersistenceCodeFixProvider : CodeFixProvider {
+    private const string title = "Convert to Persistence-4.0";
+
+    public sealed override ImmutableArray<string> FixableDiagnosticIds {
+      get { return ImmutableArray.Create(MissingStorableTypeAnalyzer.DiagnosticId); }
+    }
+
+    public sealed override FixAllProvider GetFixAllProvider() {
+      // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers
+      return WellKnownFixAllProviders.BatchFixer;
+    }
+
+    public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) {
+      var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
+
+      var diagnostic = context.Diagnostics.First();
+      var diagnosticSpan = diagnostic.Location.SourceSpan;
+
+      // Find the type declaration identified by the diagnostic.
+      var typeDeclaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<BaseTypeDeclarationSyntax>().First();
+
+      // Register a code action that will invoke the fix.
+      context.RegisterCodeFix(
+        CodeAction.Create(
+          title: title,
+          createChangedSolution: c => AddStorableTypeAttribute(context.Document, typeDeclaration, c),
+          equivalenceKey: title),
+        diagnostic);
+    }
+
+
+    private async Task<Solution> AddStorableTypeAttribute(Document document, BaseTypeDeclarationSyntax typeDecl, CancellationToken cancellationToken) {
+      var newGuid = Guid.NewGuid();
+      var attributeLists = typeDecl.AttributeLists.ToDictionary(l => l, l => (AttributeListSyntax)null);
+      bool renamed = false;
+      AttributeListSyntax newAttrList = null;
+      SyntaxList<AttributeListSyntax> oldAttrList;
+
+      foreach (var kvp in attributeLists.ToArray()) {
+        var newList = SyntaxFactory.AttributeList();
+        foreach (var attr in kvp.Key.Attributes) {
+          if (attr.Name.WithoutTrivia().ToString() == "StorableClass") {
+            // rename
+            var guidArgument = SyntaxFactory.AttributeArgument(
+                SyntaxFactory.LiteralExpression(
+                  SyntaxKind.StringLiteralExpression,
+                  SyntaxFactory.Literal(newGuid.ToString())));
+
+            // collect existing arguments (if any) and append the GUID argument
+            var argumentList = new List<AttributeArgumentSyntax>();
+            if (attr.ArgumentList != null) argumentList.AddRange(attr.ArgumentList.Arguments);
+            argumentList.Add(guidArgument);
+
+            newList = newList.WithAttributes(
+              newList.Attributes.Add(
+                attr.WithName(SyntaxFactory.IdentifierName("StorableType"))
+                .WithLeadingTrivia(attr.GetLeadingTrivia())
+                .WithTrailingTrivia(attr.GetTrailingTrivia())
+                .WithArgumentList(SyntaxFactory.AttributeArgumentList(
+                SyntaxFactory.SeparatedList<AttributeArgumentSyntax>(argumentList)))));
+
+            renamed = true;
+          } else {
+            newList = newList.WithAttributes(newList.Attributes.Add(attr));
+          }
+        }
+
+        attributeLists[kvp.Key] = newList
+          .WithLeadingTrivia(kvp.Key.GetLeadingTrivia())
+          .WithTrailingTrivia(kvp.Key.GetTrailingTrivia());
+      }
+
+      if (!renamed) {
+        oldAttrList = typeDecl.AttributeLists;
+
+
+        newAttrList = SyntaxFactory.AttributeList(
+          SyntaxFactory.SingletonSeparatedList<AttributeSyntax>(
+            SyntaxFactory.Attribute(
+                SyntaxFactory.IdentifierName("StorableType"))
+              .WithArgumentList(
+                SyntaxFactory.AttributeArgumentList(
+                  SyntaxFactory.SingletonSeparatedList<AttributeArgumentSyntax>(
+                    SyntaxFactory.AttributeArgument(
+                        SyntaxFactory.LiteralExpression(
+                          SyntaxKind.StringLiteralExpression,
+                          SyntaxFactory.Literal(newGuid.ToString())))
+                      )))));
+
+      } else {
+        oldAttrList = SyntaxFactory.List(attributeLists.Values);
+      }
+
+      BaseTypeDeclarationSyntax newTypeDecl;
+      var classDecl = typeDecl as ClassDeclarationSyntax;
+      var structDecl = typeDecl as StructDeclarationSyntax;
+      var interfaceDecl = typeDecl as InterfaceDeclarationSyntax;
+      var enumDecl = typeDecl as EnumDeclarationSyntax;
+      if (classDecl != null) {
+        if (newAttrList != null) newTypeDecl = classDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList.Add(newAttrList));
+        else newTypeDecl = classDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList);
+      } else if (structDecl != null) {
+        if (newAttrList != null) newTypeDecl = structDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList.Add(newAttrList));
+        else newTypeDecl = structDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList);
+      } else if (interfaceDecl != null) {
+        if (newAttrList != null) newTypeDecl = interfaceDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList.Add(newAttrList));
+        else newTypeDecl = interfaceDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList);
+      } else if (enumDecl != null) {
+        if (newAttrList != null) newTypeDecl = enumDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList.Add(newAttrList));
+        else newTypeDecl = enumDecl.WithoutLeadingTrivia().WithoutTrailingTrivia().WithAttributeLists(oldAttrList);
+      } else throw new NotSupportedException();
+
+
+      var root = await document.GetSyntaxRootAsync(cancellationToken);
+
+      var oldUsings = (root as CompilationUnitSyntax).Usings;
+
+
+      var newRoot = root
+        .ReplaceNode(typeDecl, newTypeDecl
+          .WithAdditionalAnnotations(Formatter.Annotation)
+          .WithLeadingTrivia(typeDecl.GetLeadingTrivia())
+          .WithTrailingTrivia(typeDecl.GetTrailingTrivia())
+        ) as CompilationUnitSyntax;
+
+
+      // add using HeuristicLab.Persistence if something was changed or added and the document does already contain the using directive 
+      if ((newAttrList != null || renamed) &&
+        oldUsings.All(sn => sn.Name.WithoutTrivia().ToString() != "HeuristicLab.Persistence")) {
+        var newUsing = SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("HeuristicLab.Persistence"));
+        newRoot = newRoot.WithUsings(oldUsings.Add(newUsing));
+      }
+
+      return document
+        .WithSyntaxRoot(newRoot)
+        .Project.Solution;
+    }
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Diagnostic.nuspec
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Diagnostic.nuspec	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Diagnostic.nuspec	(revision 14933)
@@ -0,0 +1,27 @@
+﻿<?xml version="1.0"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
+  <metadata>
+    <id>PersistenceCodeFix</id>
+    <version>1.0.0.0</version>
+    <title>PersistenceCodeFix</title>
+    <authors>P24581</authors>
+    <owners>P24581</owners>
+    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
+    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
+    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
+    <requireLicenseAcceptance>false</requireLicenseAcceptance>
+    <description>PersistenceCodeFix</description>
+    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
+    <copyright>Copyright</copyright>
+    <tags>PersistenceCodeFix, analyzers</tags>
+    <frameworkAssemblies>
+      <frameworkAssembly assemblyName="System" targetFramework="" />
+    </frameworkAssemblies>
+    <developmentDependency>true</developmentDependency>
+  </metadata>
+  <!-- The convention for analyzers is to put language agnostic dlls in analyzers\portable50 and language specific analyzers in either analyzers\portable50\cs or analyzers\portable50\vb -->
+  <files>
+    <file src="*.dll" target="analyzers\dotnet\cs" exclude="**\Microsoft.CodeAnalysis.*;**\System.Collections.Immutable.*;**\System.Reflection.Metadata.*;**\System.Composition.*" />
+    <file src="tools\*.ps1" target="tools\" />
+  </files>
+</package>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/DiagnosticAnalyzer.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/DiagnosticAnalyzer.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/DiagnosticAnalyzer.cs	(revision 14933)
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace PersistenceCodeFix {
+  [DiagnosticAnalyzer(LanguageNames.CSharp)]
+  public class MissingStorableTypeAnalyzer : DiagnosticAnalyzer {
+    public const string DiagnosticId = "MissingStorableType";
+
+    private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.MissingStorableTypeAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
+    private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.MissingStorableTypeAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
+    private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.MissingStorableTypeAnalyzerDescription), Resources.ResourceManager, typeof(Resources));
+    private const string Category = "Persistence";
+
+    private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
+
+    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
+
+    public override void Initialize(AnalysisContext context) {
+      context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
+    }
+
+    private static void AnalyzeSymbol(SymbolAnalysisContext context) {
+      var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;
+      if (namedTypeSymbol.IsStatic) return;
+      if (namedTypeSymbol.TypeKind == TypeKind.Delegate) return;// don't trigger action for delegate types
+
+      var attr = context.Symbol.GetAttributes();
+      if (!attr.Any(a => a.AttributeClass.Name == "StorableTypeAttribute")) {
+        var diagnostic = Diagnostic.Create(Rule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name);
+        context.ReportDiagnostic(diagnostic);
+      }
+    }
+  }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.csproj
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.csproj	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix.csproj	(revision 14933)
@@ -0,0 +1,125 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c)  Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<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>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+    <Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ProjectGuid>{5D74C4E0-52B2-4F01-B024-307EF52BAE35}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PersistenceCodeFix</RootNamespace>
+    <AssemblyName>PersistenceCodeFix</AssemblyName>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </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>
+    <Compile Include="CodeFixProvider.cs" />
+    <Compile Include="DiagnosticAnalyzer.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Diagnostic.nuspec">
+      <SubType>Designer</SubType>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="packages.config" />
+    <None Include="tools\install.ps1">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="tools\uninstall.ps1">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
+    <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CodeAnalysis, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.Common.1.0.1\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.1.0.1\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.0.1\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.1\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Composition.AttributedModel, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Composition.Convention, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Composition.Hosting, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Composition.Runtime, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Composition.TypedParts, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Reflection.Metadata, Version=1.0.21.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+  <Target Name="AfterBuild">
+    <GetAssemblyIdentity AssemblyFiles="$(OutDir)\$(AssemblyName).dll">
+      <Output TaskParameter="Assemblies" ItemName="AnalyzerAssemblyInfo" />
+    </GetAssemblyIdentity>
+    <Exec Command="&quot;$(SolutionDir)packages\NuGet.CommandLine.2.8.5\tools\NuGet.exe&quot; pack Diagnostic.nuspec -NoPackageAnalysis -Version %(AnalyzerAssemblyInfo.Version) -OutputDirectory ." WorkingDirectory="$(OutDir)" LogStandardErrorAsError="true" ConsoleToMSBuild="true">
+      <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
+    </Exec>
+  </Target>
+</Project>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Properties/AssemblyInfo.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Properties/AssemblyInfo.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Properties/AssemblyInfo.cs	(revision 14933)
@@ -0,0 +1,31 @@
+﻿using System.Reflection;
+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("PersistenceCodeFix")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("PersistenceCodeFix")]
+[assembly: AssemblyCopyright("Copyright © FH-Hagenberg 2017")]
+[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)]
+
+// 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: AssemblyFileVersion("1.0.0.0")]
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/ReadMe.txt
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/ReadMe.txt	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/ReadMe.txt	(revision 14933)
@@ -0,0 +1,33 @@
+﻿
+Building this project will produce an analyzer .dll, as well as the
+following two ways you may wish to package that analyzer:
+ * A NuGet package (.nupkg file) that will add your assembly as a
+   project-local analyzer that participates in builds.
+ * A VSIX extension (.vsix file) that will apply your analyzer to all projects
+   and works just in the IDE.
+
+To debug your analyzer, make sure the default project is the VSIX project and
+start debugging.  This will deploy the analyzer as a VSIX into another instance
+of Visual Studio, which is useful for debugging, even if you intend to produce
+a NuGet package.
+
+
+TRYING OUT YOUR NUGET PACKAGE
+
+To try out the NuGet package:
+ 1. Create a local NuGet feed by following the instructions here:
+    > http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds
+ 2. Copy the .nupkg file into that folder.
+ 3. Open the target project in Visual Studio 2015.
+ 4. Right-click on the project node in Solution Explorer and choose Manage
+    NuGet Packages.
+ 5. Select the NuGet feed you created on the left.
+ 6. Choose your analyzer from the list and click Install.
+
+If you want to automatically deploy the .nupkg file to the local feed folder
+when you build this project, follow these steps:
+ 1. Right-click on this project in Solution Explorer and choose 'Unload Project'.
+ 2. Right-click on this project and click "Edit".
+ 3. Scroll down to the "AfterBuild" target.
+ 4. In the "Exec" task, change the value inside "Command" after the -OutputDirectory
+    path to point to your local NuGet feed folder.
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.Designer.cs
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.Designer.cs	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.Designer.cs	(revision 14933)
@@ -0,0 +1,91 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PersistenceCodeFix {
+    using System;
+    using System.Reflection;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PersistenceCodeFix.Resources", typeof(Resources).GetTypeInfo().Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to All types should be marked with a StorableType attribute.
+        /// </summary>
+        internal static string MissingStorableTypeAnalyzerDescription {
+            get {
+                return ResourceManager.GetString("MissingStorableTypeAnalyzerDescription", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Type &apos;{0}&apos; is not marked as StorableType.
+        /// </summary>
+        internal static string MissingStorableTypeAnalyzerMessageFormat {
+            get {
+                return ResourceManager.GetString("MissingStorableTypeAnalyzerMessageFormat", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Missing StorableTypeAttribute.
+        /// </summary>
+        internal static string MissingStorableTypeAnalyzerTitle {
+            get {
+                return ResourceManager.GetString("MissingStorableTypeAnalyzerTitle", resourceCulture);
+            }
+        }
+    }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.resx
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.resx	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/Resources.resx	(revision 14933)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="MissingStorableTypeAnalyzerDescription" xml:space="preserve">
+    <value>All types should be marked with a StorableType attribute</value>
+  </data>
+  <data name="MissingStorableTypeAnalyzerMessageFormat" xml:space="preserve">
+    <value>Type '{0}' is not marked as StorableType</value>
+  </data>
+  <data name="MissingStorableTypeAnalyzerTitle" xml:space="preserve">
+    <value>Missing StorableTypeAttribute</value>
+  </data>
+</root>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/packages.config
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/packages.config	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/packages.config	(revision 14933)
@@ -0,0 +1,12 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="portable45-net45+win8" />
+  <package id="Microsoft.CodeAnalysis.Common" version="1.0.1" targetFramework="portable45-net45+win8" />
+  <package id="Microsoft.CodeAnalysis.CSharp" version="1.0.1" targetFramework="portable45-net45+win8" />
+  <package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="1.0.1" targetFramework="portable45-net45+win8" />
+  <package id="Microsoft.CodeAnalysis.Workspaces.Common" version="1.0.1" targetFramework="portable45-net45+win8" />
+  <package id="Microsoft.Composition" version="1.0.27" targetFramework="portable45-net45+win8" />
+  <package id="NuGet.CommandLine" version="2.8.5" targetFramework="portable45-net45+win8" />
+  <package id="System.Collections.Immutable" version="1.1.36" targetFramework="portable45-net45+win8" />
+  <package id="System.Reflection.Metadata" version="1.0.21" targetFramework="portable45-net45+win8" />
+</packages>
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/install.ps1
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/install.ps1	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/install.ps1	(revision 14933)
@@ -0,0 +1,58 @@
+﻿param($installPath, $toolsPath, $package, $project)
+
+if($project.Object.SupportsPackageDependencyResolution)
+{
+    if($project.Object.SupportsPackageDependencyResolution())
+    {
+        # Do not install analyzers via install.ps1, instead let the project system handle it.
+        return
+    }
+}
+
+$analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve
+
+foreach($analyzersPath in $analyzersPaths)
+{
+    if (Test-Path $analyzersPath)
+    {
+        # Install the language agnostic analyzers.
+        foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll)
+        {
+            if($project.Object.AnalyzerReferences)
+            {
+                $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
+            }
+        }
+    }
+}
+
+# $project.Type gives the language name like (C# or VB.NET)
+$languageFolder = ""
+if($project.Type -eq "C#")
+{
+    $languageFolder = "cs"
+}
+if($project.Type -eq "VB.NET")
+{
+    $languageFolder = "vb"
+}
+if($languageFolder -eq "")
+{
+    return
+}
+
+foreach($analyzersPath in $analyzersPaths)
+{
+    # Install language specific analyzers.
+    $languageAnalyzersPath = join-path $analyzersPath $languageFolder
+    if (Test-Path $languageAnalyzersPath)
+    {
+        foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll)
+        {
+            if($project.Object.AnalyzerReferences)
+            {
+                $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
+            }
+        }
+    }
+}
Index: /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/uninstall.ps1
===================================================================
--- /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/uninstall.ps1	(revision 14933)
+++ /trunk/tools/PersistenceCodeFix/PersistenceCodeFix/PersistenceCodeFix/tools/uninstall.ps1	(revision 14933)
@@ -0,0 +1,65 @@
+﻿param($installPath, $toolsPath, $package, $project)
+
+if($project.Object.SupportsPackageDependencyResolution)
+{
+    if($project.Object.SupportsPackageDependencyResolution())
+    {
+        # Do not uninstall analyzers via uninstall.ps1, instead let the project system handle it.
+        return
+    }
+}
+
+$analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve
+
+foreach($analyzersPath in $analyzersPaths)
+{
+    # Uninstall the language agnostic analyzers.
+    if (Test-Path $analyzersPath)
+    {
+        foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll)
+        {
+            if($project.Object.AnalyzerReferences)
+            {
+                $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
+            }
+        }
+    }
+}
+
+# $project.Type gives the language name like (C# or VB.NET)
+$languageFolder = ""
+if($project.Type -eq "C#")
+{
+    $languageFolder = "cs"
+}
+if($project.Type -eq "VB.NET")
+{
+    $languageFolder = "vb"
+}
+if($languageFolder -eq "")
+{
+    return
+}
+
+foreach($analyzersPath in $analyzersPaths)
+{
+    # Uninstall language specific analyzers.
+    $languageAnalyzersPath = join-path $analyzersPath $languageFolder
+    if (Test-Path $languageAnalyzersPath)
+    {
+        foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll)
+        {
+            if($project.Object.AnalyzerReferences)
+            {
+                try
+                {
+                    $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
+                }
+                catch
+                {
+
+                }
+            }
+        }
+    }
+}
