public static OperationMapInfo GetOperationMapInfo(Type type) { var operations = OperationLogic.TypeOperationsAndConstructors(type); var stateTypes = operations.Select(a => a.StateType).Distinct().NotNull().PreAnd(typeof(DefaultState)).ToList(); Dictionary <Type, LambdaExpression> expressions = stateTypes .ToDictionary(t => t, t => type == typeof(DefaultState) ? null : giGetGraphGetter.GetInvoker(type, t)()); Dictionary <Type, Dictionary <Enum, int> > counts = expressions.SelectDictionary(t => t.UnNullify(), exp => exp == null ? giCount.GetInvoker(type)() : giCountGroupBy.GetInvoker(type, exp.Body.Type)(exp)); Dictionary <Type, string> tokens = expressions.SelectDictionary(t => t.UnNullify(), exp => exp == null ? null : GetToken(exp)); var symbols = operations.Select(a => a.OperationSymbol).ToList(); var operationCounts = Database.Query <OperationLogEntity>() .Where(log => symbols.Contains(log.Operation)) .GroupBy(log => log.Operation) .Select(a => KVP.Create(a.Key, a.Count())) .ToDictionary(); return(new OperationMapInfo { states = (from t in stateTypes from e in Enum.GetValues(t.UnNullify()).Cast <Enum>() let ignored = e.GetType().GetField(e.ToString(), BindingFlags.Static | BindingFlags.Public).HasAttribute <IgnoreAttribute>() select new MapState { count = counts.GetOrThrow(e.GetType()).TryGet(e, 0), ignored = ignored, key = e.ToString(), niceName = e.NiceToString(), isSpecial = t == typeof(DefaultState), color = Engine.Chart.ChartColorLogic.ColorFor(EnumEntity.FromEnumUntyped(e)).TryToHtml(), token = tokens.GetOrThrow(e.GetType()), }).ToList(), operations = (from o in operations select new MapOperation { niceName = o.OperationSymbol.NiceToString(), key = o.OperationSymbol.Key, count = operationCounts.TryGet(o.OperationSymbol, 0), fromStates = WithDefaultStateArray(o.UntypedFromStates, DefaultState.Start).Select(a => a.ToString()).ToArray(), toStates = WithDefaultStateArray(o.UntypedToStates, DefaultState.End).Select(a => a.ToString()).ToArray(), }).ToList() }); }