public IDictionary <Guid, int> GetProjectedThreatTypesResidualRisk(IThreatModel model, IEnumerable <Guid> mitigations)
        {
            IDictionary <Guid, int> result = null;

            var threatEvents = model.GetThreatEvents()?.ToArray();

            if (threatEvents?.Any() ?? false)
            {
                var dict = new Dictionary <Guid, int>();

                foreach (var threatEvent in threatEvents)
                {
                    var mitigationsStrength = threatEvent.Mitigations?
                                              .Where(x => (x.Status != MitigationStatus.Existing) &&
                                                     (x.Status != MitigationStatus.Implemented) &&
                                                     (mitigations?.Any(y => y == x.MitigationId) ?? false))
                                              .Sum(x => x.StrengthId);
                    var newSeverity = model.GetMappedSeverity(
                        Convert.ToInt32(((float)threatEvent.SeverityId) *
                                        (100f - Math.Min((mitigationsStrength ?? 0), 100f)) / 100f));

                    if (newSeverity != null)
                    {
                        var newSeverityId = newSeverity.Id == 0 ? (int)DefaultSeverity.Info : newSeverity.Id;
                        if (dict.ContainsKey(threatEvent.ThreatTypeId))
                        {
                            if (dict[threatEvent.ThreatTypeId] < newSeverityId)
                            {
                                dict[threatEvent.ThreatTypeId] = newSeverityId;
                            }
                        }
                        else
                        {
                            dict[threatEvent.ThreatTypeId] = newSeverityId;
                        }
                    }
                }

                result = dict;
            }

            return(result);
        }
        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++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }