title: Replacing a method node using Roslyn
body: <p>While exploring Roslyn I put together a small app that should include a trace statement as the first statement in every method found in a Visual Studio Solution. My code is buggy and is only updating the first method. </p>
  
  <p>The line that is not working as expected is flagged with a “TODO” comment. Please, advise.</p>
  
  <p>I also welcome style recommendations that would create a more streamlined/readable solution.</p>
  
  <p>Thanks in advance.</p>
  
  <p>...</p>
  
  <pre><code>    private void TraceBtn_Click(object sender, RoutedEventArgs e) {
          var myWorkSpace = new MyWorkspace("...Visual Studio 2012\Projects\Tests.sln"); 
          myWorkSpace.InjectTrace();
          myWorkSpace.ApplyChanges();
      }
  </code></pre>
  
  <p>...        </p>
  
  <pre><code>using System;
  using System.Linq;
  using Roslyn.Compilers;
  using Roslyn.Compilers.CSharp;
  using Roslyn.Services;
  
  namespace InjectTrace
  {
      public class MyWorkspace
      {
      private string solutionFile;
      public string SolutionFile {
          get { return solutionFile; }
          set { 
              if (string.IsNullOrEmpty(value)) throw new Exception("Invalid Solution File");
              solutionFile = value;
          }
      }
  
      private IWorkspace loadedWorkSpace;
      public IWorkspace LoadedWorkSpace { get { return loadedWorkSpace; } }
  
      public ISolution CurrentSolution { get; private set; }
      public IProject CurrentProject { get; private set; }
      public IDocument CurrentDocument { get; private set; }
      public ISolution NewSolution { get; private set; }
  
  
      public MyWorkspace(string solutionFile) {
          this.SolutionFile = solutionFile;
          this.loadedWorkSpace = Workspace.LoadSolution(SolutionFile);
      }
  
      public void InjectTrace()
      {
  
          int projectCtr = 0;
          int documentsCtr = 0;
          int transformedMembers = 0;
          int transformedClasses = 0;
          this.CurrentSolution = this.LoadedWorkSpace.CurrentSolution;
          this.NewSolution = this.CurrentSolution;
  
          //For Each Project...
          foreach (var projectId in LoadedWorkSpace.CurrentSolution.ProjectIds)
          {
              CurrentProject = NewSolution.GetProject(projectId);
  
              //..for each Document in the Project..
              foreach (var docId in CurrentProject.DocumentIds)
              {
                  CurrentDocument = NewSolution.GetDocument(docId);
                  var docRoot = CurrentDocument.GetSyntaxRoot();
                  var newDocRoot = docRoot;
                  var classes = docRoot.DescendantNodes().OfType&lt;ClassDeclarationSyntax&gt;();
                  IDocument newDocument = null;
  
                  //..for each Class in the Document..
                  foreach (var @class in classes) {
                      var methods = @class.Members.OfType&lt;MethodDeclarationSyntax&gt;();
  
                      //..for each Member in the Class..
                      foreach (var currMethod in methods) {
                          //..insert a Trace Statement
                          var newMethod = InsertTrace(currMethod);
                          transformedMembers++;
                          //TODO: PROBLEM IS HERE
                          newDocRoot = newDocRoot.ReplaceNode(currMethod, newMethod);                             
                      }
                      if (transformedMembers != 0) {
                          newDocument = CurrentDocument.UpdateSyntaxRoot(newDocRoot);
                          transformedMembers = 0;
                          transformedClasses++;
                      }
                  }
  
                  if (transformedClasses != 0) {
                      NewSolution = NewSolution.UpdateDocument(newDocument);
                      transformedClasses = 0;
                  }
  
                  documentsCtr++;
  
              }
              projectCtr++;
              if (projectCtr &gt; 2) return;
          }
      }
  
      public MethodDeclarationSyntax InsertTrace(MethodDeclarationSyntax currMethod) {
          var traceText =
          @"System.Diagnostics.Trace.WriteLine(""Tracing: '" + currMethod.Ancestors().OfType&lt;NamespaceDeclarationSyntax&gt;().Single().Name + "." + currMethod.Identifier.ValueText + "'\");";
          var traceStatement = Syntax.ParseStatement(traceText);
          var bodyStatementsWithTrace = currMethod.Body.Statements.Insert(0, traceStatement);
          var newBody = currMethod.Body.Update(Syntax.Token(SyntaxKind.OpenBraceToken), bodyStatementsWithTrace,
                                              Syntax.Token(SyntaxKind.CloseBraceToken));
          var newMethod = currMethod.ReplaceNode(currMethod.Body, newBody);
          return newMethod;
  
      }
  
      public void ApplyChanges() {
          LoadedWorkSpace.ApplyChanges(CurrentSolution, NewSolution);
      }
  
  
  }
  </code></pre>
  
  <p>}</p>