private void AnalyzeCompilation(CompilationAnalysisContext context)
        {
            Trace.WriteLine("AnalyzeCompilation");

            try
            {
                INamedTypeSymbol dbContextTypeSymbol;
                IEnumerable<INamedTypeSymbol> entityTypeSymbols = SymbolHelper.GetAllEntityTypesFromDbContext(context.Compilation, out dbContextTypeSymbol);
                if (!entityTypeSymbols.Any())
                {
                    return;
                }

                var allTypeSymbols = context.Compilation.GetSymbolsWithName(s => !s.EndsWith("DbContext"), SymbolFilter.Type).Cast<INamedTypeSymbol>();
                var allMemberSymbols = allTypeSymbols.SelectMany(t => t.GetMembers().Where(m => m.Kind == SymbolKind.Property));
                Trace.WriteLine("Class count: " + allTypeSymbols.Count());
                Trace.WriteLine("Property count: " + allMemberSymbols.Count());

                var efRoslynTheorem = new EFRoslynTheorem();
                var result = efRoslynTheorem.Solve(entityTypeSymbols);
                if (result.Status == Status.Unsatisfiable)
                {
                    var classAssumptions = efRoslynTheorem.ClassAssumptions.ToList();
                    var propertyAssumptions = efRoslynTheorem.PropertyAssumptions.OrderBy(pa => pa.Rank).ToList();

                    do
                    {
                        result = TryToRemoveWrongAssumption(efRoslynTheorem, result, classAssumptions, propertyAssumptions);
                    } while (result != null && result.Status != Status.Satisfiable);

                    if (result == null || result.Status != Status.Satisfiable)
                    {
                        var diagnostic2 = Diagnostic.Create(UnsatisfiableRule, dbContextTypeSymbol.Locations[0], dbContextTypeSymbol.Name);
                        Trace.WriteLine("ReportDiagnostic " + diagnostic2.Descriptor.Id);
                        context.ReportDiagnostic(diagnostic2);
                        return;
                    }

                    var cacheId = EFRoslynTheoremCache.Add(context.Compilation, efRoslynTheorem, result);

                    var props = ImmutableDictionary.Create<string, string>();
                    props = props.Add("CacheId", cacheId);

                    var diagnostic = Diagnostic.Create(SatisfiableRule, dbContextTypeSymbol.Locations[0], props, dbContextTypeSymbol.Name);
                    Trace.WriteLine("ReportDiagnostic " + diagnostic.Descriptor.Id);
                    context.ReportDiagnostic(diagnostic);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                throw;
            }
        }
 public Item(Compilation compilation, EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult objectTheoremResult)
 {
     Compilation = compilation;
     EFRoslynTheorem = efRoslynTheorem;
     ObjectTheoremResult = objectTheoremResult;
 }
 public static string Add(Compilation compilation, EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult objectTheoremResult)
 {
     var cacheId = compilation.AssemblyName;
     _cache[cacheId] = new Item(compilation, efRoslynTheorem, objectTheoremResult);
     return cacheId;
 }
        private ObjectTheoremResult TryToRemoveWrongAssumption(EFRoslynTheorem efRoslynTheorem, ObjectTheoremResult result,
            List<IClassAssumption> classAssumptions, List<IPropertyAssumption> propertyAssumptions)
        {
            foreach (var assumes in classAssumptions)
            {
                if (result.IsAssumptionWrong(assumes.Assumption))
                {
                    classAssumptions.Remove(assumes);
                    efRoslynTheorem.RemoveAssumption(assumes.Assumption);
                    return efRoslynTheorem.ReSolve();
                }
            }

            foreach (var assumes in propertyAssumptions)
            {
                if (result.IsAssumptionWrong(assumes.Assumption))
                {
                    propertyAssumptions.Remove(assumes);
                    efRoslynTheorem.RemoveAssumption(assumes.Assumption);
                    return efRoslynTheorem.ReSolve();
                }
            }

            return null;
        }