private void ImportThreats([NotNull] ThreatModel source, [NotNull] IThreatModel target, Func <IThreatModel, Threat, IThreatType, IPropertySchema, bool> unassignedThreatHandler, out int threatTypes, out int customThreatTypes, out int threats, out int missingThreats) { threatTypes = 0; customThreatTypes = 0; threats = 0; missingThreats = 0; var threatsPerType = source.ThreatsPerType; if (threatsPerType?.Any() ?? false) { var schema = new ThreatsPropertySchemaManager(target).GetSchema(); InitializeThreatsPropertySchema(schema, source.Properties); var schemaManager = new ObjectPropertySchemaManager(target); var defaultSeverity = target.GetMappedSeverity(0); foreach (var threatPerType in threatsPerType) { var tt = source.GetThreatType(threatPerType.Key); IThreatType threatType = null; if (!string.IsNullOrWhiteSpace(tt.Name)) { ISeverity severity; if (Enum.TryParse <DefaultSeverity>(tt.Priority, out var severityId)) { severity = target.GetMappedSeverity((int)severityId); } else { severity = target.GetMappedSeverity((int)DefaultSeverity.High); } threatType = target.AddThreatType(tt.Name, severity); if (threatType != null) { threatType.Description = tt.Description; var threatTypeProperties = tt.Properties?.ToArray(); if (threatTypeProperties?.Any() ?? false) { foreach (var property in threatTypeProperties) { switch (property.Name) { case "Title": break; case "UserThreatDescription": break; case "Priority": break; default: var propertyType = schema.GetPropertyType(property.Label); if (propertyType != null) { threatType.AddProperty(propertyType, property.Values.FirstOrDefault()); } break; } } } threatTypes++; } else { threatType = target.ThreatTypes? .FirstOrDefault(x => string.CompareOrdinal(x.Name, tt.Name) == 0); } } else { var internalThreats = threatPerType.Value; if (internalThreats.Any()) { foreach (var internalThreat in internalThreats) { threatType = target.AddThreatType(internalThreat.ToString(), defaultSeverity); if (threatType != null) { threatType.Description = internalThreat.GetValueFromLabel("Description"); customThreatTypes++; } else { threatType = target.ThreatTypes?.FirstOrDefault(x => string.CompareOrdinal(x.Name, internalThreat.ToString()) == 0); } break; } } } if (threatType != null) { CreateGenerationRule(source, tt, threatType); foreach (var threat in threatPerType.Value) { var flow = GetDataFlow(threat.FlowGuid.ToString(), target, schemaManager); if (flow != null) { var threatEvent = flow.AddThreatEvent(threatType); if (threatEvent != null) { AddProperties(threatEvent, threat, schema); threats++; } else { missingThreats++; } } else { if (unassignedThreatHandler != null) { if (unassignedThreatHandler(target, threat, threatType, schema)) { threats++; } else { missingThreats++; } } else { var threatEvent = target.AddThreatEvent(threatType); if (threatEvent != null) { AddProperties(threatEvent, threat, schema); threats++; } else { missingThreats++; } } } } } } } }