private ICodeEntity AnalyzeType(Type type, CodeAnalysisGraph graph)
        {
            if (false == ShouldBeIncluded(type))
            {
                return(null);
            }

            if (type.IsClass)
            {
                ClassEntity analyzedClass = new ClassEntity(type.Name, type.FullName, type.IsAbstract);
                analyzedClass = (ClassEntity)graph.GetEntity(analyzedClass);

                // skip already analyzed entities
                if (analyzedClass.AnalysisState != CodeEntityAnalysisState.NotAnalyzed)
                {
                    return(analyzedClass);
                }

                analyzedClass.AnalysisState = CodeEntityAnalysisState.InAnalysis;

                // find direct ancestor
                if (type.BaseType != null)
                {
                    ICodeEntity ancestor = AnalyzeType(type.BaseType, graph);

                    if (ancestor != null)
                    {
                        analyzedClass.AddAncestor(ancestor);
                    }
                }

                foreach (Type inheritedInterface in type.GetInterfaces())
                {
                    ICodeEntity ancestor = AnalyzeType(inheritedInterface, graph);

                    if (ancestor != null)
                    {
                        analyzedClass.AddAncestor(ancestor);
                    }
                }

                foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
                {
                    ICodeEntity association = AnalyzeType(field.FieldType, graph);
                    if (association != null)
                    {
                        analyzedClass.AddAssociation(association);
                    }
                }

                analyzedClass.AnalysisState = CodeEntityAnalysisState.Analyzed;

                return(analyzedClass);
            }
            else if (type.IsInterface)
            {
                InterfaceEntity analyzedInterface = new InterfaceEntity(type.Name, type.FullName);
                analyzedInterface = (InterfaceEntity)graph.GetEntity(analyzedInterface);

                // skip already analyzed entities
                if (analyzedInterface.AnalysisState != CodeEntityAnalysisState.NotAnalyzed)
                {
                    return(analyzedInterface);
                }

                analyzedInterface.AnalysisState = CodeEntityAnalysisState.InAnalysis;

                foreach (Type inheritedInterface in type.GetInterfaces())
                {
                    ICodeEntity ancestor = AnalyzeType(inheritedInterface, graph);

                    if (ancestor != null)
                    {
                        analyzedInterface.AddAncestor(ancestor);
                    }
                }

                analyzedInterface.AnalysisState = CodeEntityAnalysisState.Analyzed;

                return(analyzedInterface);
            }

            return(null);
        }
        public void GenerateDiagram(CodeAnalysisGraph graph, Stream outputStream)
        {
            using (StreamWriter writer = new StreamWriter(outputStream))
            {
                string fontName = "Tahoma";

                writer.WriteLine("digraph");
                writer.WriteLine("{");
                writer.WriteLine(@"node [shape = ""record"" fontsize=""7""]");

                foreach (ICodeEntity entity in graph.Entities.Values)
                {
                    if (entity is ClassEntity)
                    {
                        ClassEntity classEntity = (ClassEntity)entity;
                        writer.WriteLine(
                            "node{0} [label = \"{1}\" fontname=\"{2}\"]",
                            classEntity.UniqueId,
                            classEntity.EntityShortName,
                            fontName);

                        foreach (ICodeEntity association in classEntity.Associations)
                        {
                            writer.WriteLine(@"edge [arrowhead = ""none""]");

                            writer.WriteLine(
                                "\"node{0}\" -> \"node{1}\"",
                                association.UniqueId,
                                entity.UniqueId);
                        }
                    }
                    else if (entity is InterfaceEntity)
                    {
                        InterfaceEntity classEntity = (InterfaceEntity)entity;
                        writer.WriteLine(
                            "node{0} [label = \"{1}\" fontname=\"{2} Italic\"]",
                            classEntity.UniqueId,
                            classEntity.EntityShortName,
                            fontName);
                    }

                    foreach (ICodeEntity ancestor in entity.Ancestors)
                    {
                        if (entity is InterfaceEntity && ancestor is InterfaceEntity)
                        {
                            writer.WriteLine(@"edge [arrowhead = ""empty"" style=""dashed"" ]");
                        }
                        else
                        {
                            writer.WriteLine(@"edge [arrowhead = ""empty""]");
                        }

                        writer.WriteLine(
                            "\"node{0}\" -> \"node{1}\"",
                            ancestor.UniqueId,
                            entity.UniqueId);
                    }
                }

                writer.WriteLine("}");
            }
        }