public static Node CreateNode([NotNull] SelectionRuleNode ruleNode, [NotNull] IThreatModel model) { var result = new Node(ruleNode.Name) { Image = GetImage(ruleNode.Scope), }; if (ruleNode is NaryRuleNode nary) { if (nary is AndRuleNode) { result.Image = Resources.logic_and; } else if (nary is OrRuleNode) { result.Image = Resources.logic_or; } result.Tag = new NaryItemContext(ruleNode.GetType()); } else if (ruleNode is UnaryRuleNode unary) { if (unary is NotRuleNode) { result.Image = Resources.logic_not; } result.Tag = new NaryItemContext(ruleNode.GetType()); } else if (ruleNode is CrossTrustBoundaryRuleNode crossRuleNode) { UpdateNode(result, crossRuleNode); result.Tag = new CrossTrustBoundaryItemContext(); } else if (ruleNode is ComparisonRuleNode comparisonRuleNode) { UpdateNode(result, comparisonRuleNode); var propertyType = GetPropertyType(comparisonRuleNode.Namespace, comparisonRuleNode.Schema, comparisonRuleNode.Name, model); if (propertyType == null) { result.Tag = new ComparisonItemContext(comparisonRuleNode.Scope); } else { result.Tag = new PropertyTypeItemContext(propertyType, comparisonRuleNode.Scope, PropertyTypeItemContextType.Comparison); } } else if (ruleNode is EnumValueRuleNode enumValueRuleNode) { UpdateNode(result, enumValueRuleNode); var propertyType = GetPropertyType(enumValueRuleNode.Namespace, enumValueRuleNode.Schema, enumValueRuleNode.Name, model); if (propertyType == null) { result.Tag = new EnumValueItemContext(enumValueRuleNode.Values, enumValueRuleNode.Scope); } else { result.Tag = new PropertyTypeItemContext(propertyType, enumValueRuleNode.Scope, PropertyTypeItemContextType.EnumValue); } } else if (ruleNode is BooleanRuleNode booleanRuleNode) { UpdateNode(result, booleanRuleNode); var propertyType = GetPropertyType(booleanRuleNode.Namespace, booleanRuleNode.Schema, booleanRuleNode.Name, model); if (propertyType == null) { result.Tag = new BooleanItemContext(booleanRuleNode.Scope); } else { result.Tag = new PropertyTypeItemContext(propertyType, booleanRuleNode.Scope, PropertyTypeItemContextType.Boolean); } } else if (ruleNode is HasIncomingRuleNode hasIncomingRuleNode) { var flowsItemContext = new FlowsItemContext(true, hasIncomingRuleNode.Scope); UpdateNode(result, flowsItemContext.Values, hasIncomingRuleNode); result.Tag = flowsItemContext; } else if (ruleNode is HasOutgoingRuleNode hasOutgoingRuleNode) { var flowsItemContext = new FlowsItemContext(false, hasOutgoingRuleNode.Scope); UpdateNode(result, flowsItemContext.Values, hasOutgoingRuleNode); result.Tag = flowsItemContext; } else if (ruleNode is TruismRuleNode) { result.Image = Resources.ok; result.Tag = new TruismItemContext(); } else if (ruleNode is ExternalInteractorTemplateRuleNode externalInteractorTemplateRuleNode) { var externalInteractorTemplateItemContext = new ExternalInteractorTemplateItemContext(model, externalInteractorTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.ExternalInteractor), externalInteractorTemplateRuleNode); result.Tag = externalInteractorTemplateItemContext; } else if (ruleNode is ProcessTemplateRuleNode processTemplateRuleNode) { var processTemplateContext = new ProcessTemplateItemContext(model, processTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.Process), processTemplateRuleNode); result.Tag = processTemplateContext; } else if (ruleNode is DataStoreTemplateRuleNode dataStoreTemplateRuleNode) { var dataStoreTemplateItemContext = new DataStoreTemplateItemContext(model, dataStoreTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.DataStore), dataStoreTemplateRuleNode); result.Tag = dataStoreTemplateItemContext; } else if (ruleNode is EntityTemplateRuleNode entityTemplateRuleNode) { var entityTemplate = model.GetEntityTemplate(entityTemplateRuleNode.EntityTemplate); switch (entityTemplate.EntityType) { case EntityType.ExternalInteractor: var eiTemplateItemContext = new ExternalInteractorTemplateItemContext(model, entityTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.ExternalInteractor), entityTemplateRuleNode); result.Tag = eiTemplateItemContext; break; case EntityType.Process: var pTemplateContext = new ProcessTemplateItemContext(model, entityTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.Process), entityTemplateRuleNode); result.Tag = pTemplateContext; break; case EntityType.DataStore: var dsTemplateItemContext = new DataStoreTemplateItemContext(model, entityTemplateRuleNode.Scope); UpdateNode(result, model.EntityTemplates?.Where(x => x.EntityType == EntityType.DataStore), entityTemplateRuleNode); result.Tag = dsTemplateItemContext; break; default: throw new ArgumentOutOfRangeException(); } } else if (ruleNode is TrustBoundaryTemplateRuleNode trustBoundaryTemplateRuleNode) { var trustBoundaryContext = new TrustBoundaryTemplateItemContext(model, trustBoundaryTemplateRuleNode.Scope); UpdateNode(result, model.TrustBoundaryTemplates, trustBoundaryTemplateRuleNode); result.Tag = trustBoundaryContext; } else if (ruleNode is FlowTemplateRuleNode flowTemplateRuleNode) { var flowTemplateContext = new FlowTemplateItemContext(model, flowTemplateRuleNode.Scope); UpdateNode(result, model.FlowTemplates, flowTemplateRuleNode); result.Tag = flowTemplateContext; } return(result); }