public override void VisitClassDeclaration(ClassDeclarationSyntax node)
		{
			if (node.ShouldBeHidden()) return;

			++ClassDepth;
			if (ClassDepth == 1)
			{
				base.VisitClassDeclaration(node);
			}				
			else if (node.ChildNodes().All(childNode => childNode is PropertyDeclarationSyntax || childNode is AttributeListSyntax))
			{
				// simple nested POCO	
				var line = node.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;
				var walker = new CodeWithDocumentationWalker(ClassDepth - 2, line);
				walker.Visit(node);
				this.Blocks.AddRange(walker.Blocks);
			}
			else
			{
				var methods = node.ChildNodes().OfType<MethodDeclarationSyntax>();
				if (!methods.Any(m => m.AttributeLists.SelectMany(a => a.Attributes).Any()))
				{
					// nested class with methods that are not unit or integration tests e.g. example PropertyVisitor in Automap.doc.cs
					var line = node.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;
					var walker = new CodeWithDocumentationWalker(ClassDepth - 2, line);
					walker.Visit(node);
					this.Blocks.AddRange(walker.Blocks);
				}
			}
			--ClassDepth;
		}
        public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            var typeList = node.ChildNodes().OfType<TypeParameterListSyntax>();

            if (typeList.Any())
                return node.RemoveNodes(typeList, SyntaxRemoveOptions.KeepEndOfLine);

            return node;
        }
		public override void VisitClassDeclaration(ClassDeclarationSyntax node)
		{
			++ClassDepth;
			if (ClassDepth == 1)
			{
				base.VisitClassDeclaration(node);
			}
			// are we dealing with a simple nested POCO?
			else if (node.ChildNodes().All(childNode => childNode is PropertyDeclarationSyntax || childNode is AttributeListSyntax))
			{ 
				var line = node.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;
				var walker = new CodeWithDocumentationWalker(ClassDepth - 2, line);
				walker.Visit(node);
				this.Blocks.AddRange(walker.Blocks);
			}
			--ClassDepth;
		}
        public override void VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            // generate empty ctor if necessary
              if (node.HasInitializableMembers(model) && !node.HasDefaultConstructor())
              {
            cb.AppendWithIndent(node.Identifier.ToString())
              .Append("::")
              .Append(node.Identifier.ToString())
              .AppendLine("() :");

            //cb.Indent(() =>
            //{
            //  AppendFieldInitializers(node);
            //});

            cb.AppendLine("{}").AppendLine();
              }

              // generate static initialization
              foreach (var fields in node.ChildNodes().OfType<FieldDeclarationSyntax>())
              {
            foreach (var v in fields.Declaration.Variables)
            {
              var z = (IFieldSymbol)model.GetDeclaredSymbol(v);
              if (z.IsStatic && v.Initializer != null)
              {
            cb.AppendWithIndent("extern ")
              .Append(node.Identifier.ToString())
              .Append("::")
              .Append(v.Identifier.ToString())
              .Append(" = ")
              .Append(v.Initializer.Value.ToString())
              .AppendLine(";").AppendLine();
              }
            }
              }

              base.VisitClassDeclaration(node);
        }
 public SyntaxTree UnWeave(ClassDeclarationSyntax c)
 {
     var foundMethods = c.ChildNodes().OfType<MethodDeclarationSyntax>().Where(HasBeenWeaved);
     return WeaveOrUnWeave(foundMethods, UnWeaveMethod);
 }
        /// <summary>
        /// Tries to get the list of potential methods that can override the given virtual call.
        /// If it cannot find such methods then it returns false.
        /// </summary>
        /// <param name="overriders">List of overrider methods</param>
        /// <param name="virtualCall">Virtual call</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="originalMachine">Original machine</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        internal static bool TryGetPotentialMethodOverriders(out HashSet<MethodDeclarationSyntax> overriders,
            InvocationExpressionSyntax virtualCall, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
            ClassDeclarationSyntax originalMachine, SemanticModel model, AnalysisContext context)
        {
            overriders = new HashSet<MethodDeclarationSyntax>();

            ISymbol calleeSymbol = null;
            SimpleNameSyntax callee = null;
            bool isThis = false;

            if (virtualCall.Expression is MemberAccessExpressionSyntax)
            {
                var expr = virtualCall.Expression as MemberAccessExpressionSyntax;
                var identifier = expr.Expression.DescendantNodesAndSelf().
                    OfType<IdentifierNameSyntax>().Last();
                calleeSymbol = model.GetSymbolInfo(identifier).Symbol;
                
                if (expr.Expression is ThisExpressionSyntax ||
                    context.IsMachineType(identifier, model))
                {
                    callee = expr.Name;
                    isThis = true;
                }
            }
            else
            {
                callee = virtualCall.Expression as IdentifierNameSyntax;
                isThis = true;
            }

            if (isThis)
            {
                foreach (var nestedClass in originalMachine.ChildNodes().OfType<ClassDeclarationSyntax>())
                {
                    foreach (var method in nestedClass.ChildNodes().OfType<MethodDeclarationSyntax>())
                    {
                        if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                        {
                            overriders.Add(method);
                            return true;
                        }
                    }
                }

                foreach (var method in originalMachine.ChildNodes().OfType<MethodDeclarationSyntax>())
                {
                    if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                    {
                        overriders.Add(method);
                        return true;
                    }
                }

                return false;
            }

            if (calleeSymbol == null)
            {
                return false;
            }

            Dictionary<ISymbol, HashSet<ITypeSymbol>> objectTypeMap = null;
            if (!cfgNode.Summary.DataFlowMap.TryGetObjectTypeMapForSyntaxNode(
                syntaxNode, cfgNode, out objectTypeMap))
            {
                return false;
            }

            if (!objectTypeMap.ContainsKey(calleeSymbol))
            {
                return false;
            }

            foreach (var objectType in objectTypeMap[calleeSymbol])
            {
                MethodDeclarationSyntax m = null;
                if (InheritanceAnalysis.TryGetMethodFromType(out m, objectType, virtualCall, context))
                {
                    overriders.Add(m);
                }
            }

            return true;
        }
        public override void VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            // be sure to add the includes
              cb.AppendLine($"#include <{node.Identifier.Text}.h>")
            .AppendLine();

              // generate empty ctor if necessary
              if (node.HasInitializableMembers(model) && !node.HasDefaultConstructor())
              {
            cb.AppendWithIndent(node.Identifier.ToString())
              .Append("::")
              .Append(node.Identifier.ToString())
              .AppendLine("() :");

            //cb.Indent(() =>
            //{
            //  AppendFieldInitializers(node);
            //});

            cb.AppendLine("{}").AppendLine();
              }

              // generate static initialization
              foreach (var fields in node.ChildNodes().OfType<FieldDeclarationSyntax>())
              {
            foreach (var v in fields.Declaration.Variables)
            {
              var z = (IFieldSymbol)model.GetDeclaredSymbol(v);
              if (z.IsStatic && v.Initializer != null)
              {
            var cppType = z.Type.ToCppType();

            string initExpression;
            if (cppType.Contains("shared_ptr"))
            {
              var argumentList = new StringBuilder();

              var evcs = v.Initializer as EqualsValueClauseSyntax;
              if (evcs != null)
              {
                var oces = evcs.Value as ObjectCreationExpressionSyntax;
                if (oces != null)
                {
                  var count = oces.ArgumentList.Arguments.Count;
                  for (int i = 0; i < count; i++)
                  {
                    var a = oces.ArgumentList.Arguments[i];
                    argumentList.Append(a.ToFullString());
                    if (i + 1 != count)
                      argumentList.Append(",");
                  }
                }
              }

              initExpression = $"std::make_shared<{z.Type.Name}>({argumentList})";
            }
            else
            {
              initExpression = v.Initializer.Value.ToString();
            }

            cb.AppendWithIndent("extern ")
              .Append(node.Identifier.ToString())
              .Append("::")
              .Append(v.Identifier.ToString())
              .Append(" = ")
              .Append(initExpression)
              .AppendLine(";").AppendLine();
              }
            }
              }

              base.VisitClassDeclaration(node);
        }
 private void AppendFieldInitializers(ClassDeclarationSyntax node)
 {
     foreach (var fields in node.ChildNodes().OfType<FieldDeclarationSyntax>()
     .Where(f => f.RequiresInitialization(model)))
       {
     var vs = new List<Tuple<VariableDeclaratorSyntax, IFieldSymbol>>();
     foreach (var v in fields.Declaration.Variables)
     {
       var z = (IFieldSymbol) model.GetDeclaredSymbol(v);
       if (!z.IsStatic)
       {
     vs.Add(new Tuple<VariableDeclaratorSyntax, IFieldSymbol>(v,z));
       }
     }
     for (int i = 0; i < vs.Count; ++i)
     {
       var v = vs[i].Item1;
       var symbol = vs[i].Item2;
       cb.AppendWithIndent(v.Identifier.ToString()).Append("(");
       // if the field has an initer, use that instead
       if (v.Initializer != null)
       {
     cb.Append(v.Initializer.Value.ToString());
       }
       else
       {
     cb.Append(symbol.Type.GetDefaultValue());
       }
       cb.Append(")");
       if (i + 1 != vs.Count)
     cb.Append(",");
       cb.AppendLine();
     }
       }
 }
        /// <summary>
        /// Checks if the given name is a state of the given machine.
        /// </summary>
        /// <param name="name">string</param>
        /// <param name="machine">Machine</param>
        /// <returns>Boolean value</returns>
        private static bool IsStateOfTheMachine(string name, ClassDeclarationSyntax machine)
        {
            List<string> stateNames = new List<string>();

            foreach (var nestedClass in machine.ChildNodes().OfType<ClassDeclarationSyntax>())
            {
                stateNames.Add(nestedClass.Identifier.ValueText);
            }

            if (stateNames.Any(str => str.Equals(name)))
            {
                return true;
            }

            return false;
        }
        /// <summary>
        /// Computes the summary for the given method.
        /// </summary>
        /// <param name="method">Method</param>
        /// <param name="machine">Machine</param>
        /// <param name="state">State</param>
        private void ComputeSummaryForMethod(MethodDeclarationSyntax method,
            ClassDeclarationSyntax machine, ClassDeclarationSyntax state)
        {
            List<InvocationExpressionSyntax> givesUpSources = new List<InvocationExpressionSyntax>();
            foreach (var call in method.DescendantNodes().OfType<InvocationExpressionSyntax>())
            {
                var model = this.AnalysisContext.Compilation.GetSemanticModel(call.SyntaxTree);

                var callSymbol = model.GetSymbolInfo(call).Symbol;
                if (callSymbol == null)
                {
                    continue;
                }

                var definition = SymbolFinder.FindSourceDefinitionAsync(callSymbol,
                    this.AnalysisContext.Solution).Result;
                if (definition == null)
                {
                    continue;
                }

                var callee = this.AnalysisContext.GetCallee(call);
                var calleeMethod = definition.DeclaringSyntaxReferences.First().GetSyntax()
                    as BaseMethodDeclarationSyntax;

                if (this.AnalysisContext.IsSourceOfGivingUpOwnership(call, model, callee) ||
                    this.AnalysisContext.Summaries.ContainsKey(calleeMethod))
                {
                    givesUpSources.Add(call);
                }
                else if (machine.ChildNodes().OfType<BaseMethodDeclarationSyntax>().Contains(calleeMethod) &&
                    !this.AnalysisContext.Summaries.ContainsKey(calleeMethod) &&
                    !calleeMethod.Modifiers.Any(SyntaxKind.AbstractKeyword))
                {
                    return;
                }
            }

            MethodSummary summary = MethodSummary.Factory.Summarize(this.AnalysisContext, method, machine, state);
            foreach (var givesUpNode in summary.GivesUpNodes)
            {
                this.TryComputeGivesUpSetForSendControlFlowGraphNode(givesUpNode, summary);
                this.TryComputeGivesUpSetForCreateControlFlowGraphNode(givesUpNode, summary);
                this.TryComputeGivesUpSetForGenericControlFlowGraphNode(givesUpNode, summary);
            }
        }
        /// <summary>
        /// Analyses all the eligible methods of the given machine to compute each
        /// method summary. This process continues until it reaches a fix point.
        /// </summary>
        /// <param name="machine">Machine</param>
        private void AnalyseMethodsInMachine(ClassDeclarationSyntax machine)
        {
            int fixPoint = 0;

            foreach (var nestedClass in machine.ChildNodes().OfType<ClassDeclarationSyntax>())
            {
                foreach (var method in nestedClass.ChildNodes().OfType<MethodDeclarationSyntax>())
                {
                    if (!this.AnalysisContext.ShouldAnalyseMethod(method) ||
                        this.AnalysisContext.Summaries.ContainsKey(method))
                    {
                        continue;
                    }

                    this.ComputeSummaryForMethod(method, machine, nestedClass);
                    if (!this.AnalysisContext.Summaries.ContainsKey(method))
                    {
                        fixPoint++;
                    }
                }
            }

            foreach (var method in machine.ChildNodes().OfType<MethodDeclarationSyntax>())
            {
                if (!this.AnalysisContext.ShouldAnalyseMethod(method) ||
                    this.AnalysisContext.Summaries.ContainsKey(method))
                {
                    continue;
                }

                this.ComputeSummaryForMethod(method, machine, null);
                if (!this.AnalysisContext.Summaries.ContainsKey(method))
                {
                    fixPoint++;
                }
            }

            if (fixPoint > 0)
            {
                this.AnalyseMethodsInMachine(machine);
            }
        }
        /// <summary>
        /// Tries to parse and return the state transitions for the given machine.
        /// </summary>
        /// <param name="stateTransitions">State transitions</param>
        /// <param name="machine">Machine</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Boolean value</returns>
        private bool TryParseStateTransitions(out Dictionary<ClassDeclarationSyntax,
            HashSet<ClassDeclarationSyntax>> stateTransitions, ClassDeclarationSyntax machine,
            SemanticModel model)
        {
            stateTransitions = new Dictionary<ClassDeclarationSyntax, HashSet<ClassDeclarationSyntax>>();

            var defineGotoStateTransitionsMethod = machine.ChildNodes().
                OfType<MethodDeclarationSyntax>().FirstOrDefault(v
                => v.Identifier.ValueText.Equals("DefineGotoStateTransitions") &&
                v.Modifiers.Any(SyntaxKind.OverrideKeyword) && v.ReturnType.ToString().
                Equals("System.Collections.Generic.Dictionary<Type, GotoStateTransitions>"));
            if (defineGotoStateTransitionsMethod == null)
            {
                return false;
            }

            var returnStmt = defineGotoStateTransitionsMethod.DescendantNodes().
                OfType<ReturnStatementSyntax>().First();
            var returnSymbol = model.GetSymbolInfo(returnStmt.Expression).Symbol;
            Dictionary<ClassDeclarationSyntax, IdentifierNameSyntax> stateMap = null;
            if (!this.TryParseStateMap(out stateMap, returnSymbol,
                defineGotoStateTransitionsMethod, model))
            {
                return false;
            }

            foreach (var state in stateMap)
            {
                if (state.Value == null)
                {
                    continue;
                }

                var dictionarySymbol = model.GetSymbolInfo(state.Value).Symbol;
                var dictionaryInvocations = this.GetInvocationsFromSymbol(
                    dictionarySymbol, defineGotoStateTransitionsMethod);

                var transitions = ParseTransitions(dictionarySymbol,
                    defineGotoStateTransitionsMethod, model);
                if (transitions.Count == 0)
                {
                    continue;
                }

                stateTransitions.Add(state.Key, transitions);
            }

            return true;
        }
        public Class TraverseClass(ClassDeclarationSyntax cds)
        {
            Class retClass = new Class();
            //public List<Delegate> Delegates { get; set; }
            //public List<Method> FunctionDefs { get; set; }
            //public Inheritance Inheritance { get; set; }
            //public List<Module> Modules { get; set; }
            //public List<Preprocessor> Preprocessors { get; set; }
            //public List<Property> Properties { get; set; }
            //public List<Union> Unions { get; set; }
            retClass.Name = cds.Identifier.ValueText;
            if (cds.HasLeadingTrivia)
            {
                SetOuterComments(retClass, cds.GetLeadingTrivia().ToFullString());
            }

            if (cds.HasTrailingTrivia)
            {
                SetInnerComments(retClass, cds.GetTrailingTrivia().ToFullString());
            }
            foreach (SyntaxToken st in cds.Modifiers)
            {
                string modifier = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(st.ValueText);
                Encapsulation encap;
                Qualifiers qual;
                if (System.Enum.TryParse<Encapsulation>( modifier, out encap))
                {
                    retClass.Encapsulation.Add(encap);
                }
                else if (System.Enum.TryParse<Qualifiers>(modifier, out qual))
                {
                    retClass.Qualifiers.Add(qual);
                }
            }

            var enums = from aEnu in cds.ChildNodes().OfType<EnumDeclarationSyntax>() select aEnu;
            foreach (EnumDeclarationSyntax eds in enums)
            {
                retClass.Enums.Add(TraverseEnums(eds));
            }

            var structs = from aStruct in cds.ChildNodes().OfType<StructDeclarationSyntax>() select aStruct;
            foreach (StructDeclarationSyntax sds in structs)
            {
                retClass.Structs.Add(TransverseStructs(sds));
            }

            var methods = from aMethod in cds.ChildNodes().OfType<MethodDeclarationSyntax>() select aMethod;
            foreach (MethodDeclarationSyntax mds in methods)
            {
                retClass.Methods.Add(TransverseMethods(mds));
            }

            var Fields = from aField in cds.ChildNodes().OfType<FieldDeclarationSyntax>() select aField;
            foreach (FieldDeclarationSyntax fds in Fields)
            {
                retClass.Fields.Add(TransverseVariables(fds));
            }

            //var properties = from aProperty in cds.ChildNodes().OfType<PropertyDeclarationSyntax>() select aProperty;
            //foreach (PropertyDeclarationSyntax pds in properties)
            //{
            //    //traverse attributes
            //}

            var constructors = from aConstructor in cds.ChildNodes().OfType<ConstructorDeclarationSyntax>() select aConstructor;
            foreach (ConstructorDeclarationSyntax cods in constructors)
            {
                retClass.Constructors.Add(TransverseConstructors(cods));
            }

            var destructors = from aDestructor in cds.ChildNodes().OfType<DestructorDeclarationSyntax>() select aDestructor;
            foreach (DestructorDeclarationSyntax dds in destructors)
            {
                retClass.Destructors.Add(TransverseDestructors(dds));
            }

            var classes = from aClass in cds.ChildNodes().OfType<ClassDeclarationSyntax>() select aClass;
            foreach (ClassDeclarationSyntax cds2 in classes)
            {
                retClass.Classes.Add(TraverseClass(cds2));
            }

            return retClass;
        }