internal Run CreateRun(RunVersionOne v1Run)
        {
            Run run = null;

            if (v1Run != null)
            {
                if (v1Run.TryGetProperty("sarifv2/run", out run))
                {
                    return(run);
                }
                else
                {
                    _currentV1Run = v1Run;

                    _v1FileKeytoV2IndexMap = CreateFileKeyToIndexMapping(v1Run.Files);
                    _v1RuleKeyToV2IndexMap = CreateRuleKeyToIndexMapping(v1Run.Rules);

                    RunAutomationDetails   id           = null;
                    RunAutomationDetails[] aggregateIds = null;

                    if (v1Run.Id != null || v1Run.StableId != null)
                    {
                        id = new RunAutomationDetails
                        {
                            InstanceGuid = v1Run.Id,
                            InstanceId   = v1Run.StableId != null ? v1Run.StableId + "/" : null
                        };
                    }

                    if (v1Run.AutomationId != null)
                    {
                        aggregateIds = new[] { new RunAutomationDetails {
                                                   InstanceId = v1Run.AutomationId + "/"
                                               } };
                    }

                    run = new Run()
                    {
                        Id                   = id,
                        AggregateIds         = aggregateIds,
                        BaselineInstanceGuid = v1Run.BaselineId,
                        Properties           = v1Run.Properties,
                        Tool                 = CreateTool(v1Run.Tool),
                        ColumnKind           = ColumnKind.Utf16CodeUnits
                    };

                    _currentRun = run;

                    if (v1Run.Rules != null)
                    {
                        run.Tool.Driver.RuleDescriptors = new List <ReportingDescriptor>();

                        foreach (var pair in v1Run.Rules)
                        {
                            run.Tool.Driver.RuleDescriptors.Add(CreateRule(pair.Value));
                        }
                    }

                    if (v1Run.Files != null)
                    {
                        run.Artifacts = new List <Artifact>();

                        foreach (KeyValuePair <string, FileDataVersionOne> pair in v1Run.Files)
                        {
                            FileDataVersionOne fileDataVersionOne = pair.Value;
                            if (fileDataVersionOne.Uri == null)
                            {
                                fileDataVersionOne.Uri = new Uri(pair.Key, UriKind.RelativeOrAbsolute);
                            }

                            run.Artifacts.Add(CreateFileData(fileDataVersionOne, pair.Key));
                        }
                    }

                    if (v1Run.LogicalLocations != null)
                    {
                        // Pass 1 over results. In this phase, we're simply collecting fully qualified names that
                        // may be duplicated in the logical locations dictionary. We're doing this so that we
                        // can properly construct the v2 logical instances in the converted array (i.e., we can't
                        // populate the v2 logicalLocation.FullyQualifiedName property in cases where the
                        // v1 key is a synthesized value and not actually the fully qualified name)
                        var visitor = new VersionOneLogicalLocationKeyToLogicalLocationDataVisitor();
                        visitor.VisitRunVersionOne(v1Run);

                        _v1KeyToFullyQualifiedNameMap           = visitor.LogicalLocationKeyToFullyQualifiedNameMap;
                        _v1LogicalLocationKeyToDecoratedNameMap = visitor.LogicalLocationKeyToDecoratedNameMap;

                        run.LogicalLocations = new List <LogicalLocation>();
                        HashSet <string> populatedKeys = new HashSet <string>();

                        foreach (KeyValuePair <string, LogicalLocationVersionOne> pair in v1Run.LogicalLocations)
                        {
                            PopulateLogicalLocation(
                                run,
                                v1Run.LogicalLocations,
                                _v1LogicalLocationKeyToDecoratedNameMap,
                                _v1KeyToFullyQualifiedNameMap,
                                pair.Key,
                                pair.Value,
                                populatedKeys);
                        }
                    }

                    // Even if there is no v1 invocation, there may be notifications
                    // in which case we will need a v2 invocation to contain them
                    Invocation invocation = CreateInvocation(v1Run.Invocation,
                                                             v1Run.ToolNotifications,
                                                             v1Run.ConfigurationNotifications);

                    if (invocation != null)
                    {
                        run.Invocations = new List <Invocation>()
                        {
                            invocation
                        };
                    }

                    if (v1Run.Results != null)
                    {
                        run.Results = new List <Result>();

                        foreach (ResultVersionOne v1Result in v1Run.Results)
                        {
                            Result result = CreateResult(v1Result);
                            run.Results.Add(result);
                        }
                    }

                    // Stash the entire v1 run in this v2 run's property bag
                    if (EmbedVersionOneContentInPropertyBag)
                    {
                        run.SetProperty($"{FromPropertyBagPrefix}/run", v1Run);
                    }
                }
            }

            _currentRun = null;

            return(run);
        }
        internal Run CreateRun(RunVersionOne v1Run)
        {
            Run run = null;

            if (v1Run != null)
            {
                if (v1Run.TryGetProperty("sarifv2/run", out run))
                {
                    return(run);
                }
                else
                {
                    _currentV1Run = v1Run;

                    run = new Run()
                    {
                        Architecture         = v1Run.Architecture,
                        AutomationLogicalId  = v1Run.AutomationId,
                        BaselineInstanceGuid = v1Run.BaselineId,
                        InstanceGuid         = v1Run.Id,
                        Properties           = v1Run.Properties,
                        Results   = new List <Result>(),
                        LogicalId = v1Run.StableId,
                        Tool      = CreateTool(v1Run.Tool)
                    };

                    _currentRun = run;

                    if (v1Run.Rules != null)
                    {
                        run.Resources = new Resources
                        {
                            Rules = new Dictionary <string, Rule>()
                        };

                        foreach (var pair in v1Run.Rules)
                        {
                            run.Resources.Rules.Add(pair.Key, CreateRule(pair.Value));
                        }
                    }

                    if (v1Run.Files != null)
                    {
                        run.Files = new Dictionary <string, FileData>();

                        foreach (var pair in v1Run.Files)
                        {
                            run.Files.Add(pair.Key, CreateFileData(pair.Value));
                        }
                    }

                    if (v1Run.LogicalLocations != null)
                    {
                        run.LogicalLocations = new Dictionary <string, LogicalLocation>();

                        foreach (var pair in v1Run.LogicalLocations)
                        {
                            run.LogicalLocations.Add(pair.Key, CreateLogicalLocation(pair.Value));
                        }

                        RemoveRedundantLogicalLocationProperties();
                    }

                    // Even if there is no v1 invocation, there may be notifications
                    // in which case we will need a v2 invocation to contain them
                    Invocation invocation = CreateInvocation(v1Run.Invocation,
                                                             v1Run.ToolNotifications,
                                                             v1Run.ConfigurationNotifications);

                    if (invocation != null)
                    {
                        run.Invocations = new List <Invocation>()
                        {
                            invocation
                        };
                    }

                    foreach (ResultVersionOne v1Result in v1Run.Results)
                    {
                        run.Results.Add(CreateResult(v1Result));
                    }

                    // Stash the entire v1 run in this v2 run's property bag
                    run.SetProperty($"{FromPropertyBagPrefix}/run", v1Run);
                }
            }

            return(run);
        }