private void ParseTimingDataFile(string ParsedFileName)
        {
            // Convert input file back into summary objects.
            using (BinaryReader Reader = new BinaryReader(File.Open(ParsedFileName, FileMode.Open, FileAccess.Read)))
            {
                TimingData ParsedTimingData = new TimingData(Reader);

                Task CompressDataTask = Task.Run(() =>
                {
                    Reader.BaseStream.Seek(0, SeekOrigin.Begin);
                    using (MemoryStream CompressedMemoryStream = new MemoryStream())
                    {
                        using (GZipStream CompressionStream = new GZipStream(CompressedMemoryStream, CompressionMode.Compress))
                        {
                            Reader.BaseStream.CopyTo(CompressionStream);
                        }

                        CompressedFiles.TryAdd(ParsedTimingData.Name, CompressedMemoryStream.ToArray());
                        DecompressedFileSizes.TryAdd(ParsedTimingData.Name, (int)Reader.BaseStream.Length);
                    }
                });

                TimingData SummarizedTimingData = new TimingData()
                {
                    Name = ParsedTimingData.Name, Parent = FileTimingData, Type = TimingDataType.Summary
                };
                foreach (TimingData Include in ParsedTimingData.Children["IncludeTimings"].Children.Values)
                {
                    SummarizedTimingData.AddChild(Include.Clone());
                }
                SummarizedTimingData.ExclusiveDuration += ParsedTimingData.Children["ClassTimings"].Children.Values.Sum(d => d.InclusiveDuration);
                SummarizedTimingData.ExclusiveDuration += ParsedTimingData.Children["FunctionTimings"].Children.Values.Sum(d => d.InclusiveDuration);

                // Gather and update child timing data.
                Task QueueIncludesTask = Task.Run(() =>
                {
                    // Flatten the includes for aggregation.
                    IEnumerable <TimingData> Includes = ParsedTimingData.Children["IncludeTimings"].Children.Values;
                    Dictionary <string, TimingData> FlattenedIncludes = new Dictionary <string, TimingData>();
                    FlattenIncludes(FlattenedIncludes, Includes);
                    foreach (TimingData Include in FlattenedIncludes.Values)
                    {
                        AggregateIncludes.Add(Include);
                    }
                });

                Task QueueClassesTask = Task.Run(() =>
                {
                    // Collapse templates into single entries.
                    IEnumerable <TimingData> CollapsedClasses = GroupChildren(ParsedTimingData.Children["ClassTimings"].Children.Values, TimingDataType.Class);
                    foreach (TimingData Class in CollapsedClasses)
                    {
                        AggregateClasses.Add(new TimingData()
                        {
                            Name = Class.Name, Type = TimingDataType.Class, ExclusiveDuration = Class.InclusiveDuration
                        });
                    }
                });

                Task QueueFunctionsTask = Task.Run(() =>
                {
                    // Collapse templates into single entries.
                    IEnumerable <TimingData> CollapsedFunctions = GroupChildren(ParsedTimingData.Children["FunctionTimings"].Children.Values, TimingDataType.Function);
                    foreach (TimingData Function in CollapsedFunctions)
                    {
                        AggregateFunctions.Add(new TimingData()
                        {
                            Name = Function.Name, Type = TimingDataType.Function, ExclusiveDuration = Function.InclusiveDuration
                        });
                    }
                });

                while (!CompressDataTask.IsCompleted || !QueueIncludesTask.IsCompleted || !QueueClassesTask.IsCompleted || !QueueFunctionsTask.IsCompleted)
                {
                    Thread.Sleep(TimeSpan.FromMilliseconds(50));
                }

                lock (AddFileLock)
                {
                    FileTimingData.AddChild(SummarizedTimingData);
                }
            }
        }