/// <summary>
        /// Processes the file.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="fileId">The file id.</param>
        /// <param name="classWithNamespace">The class.</param>
        /// <param name="filePath">The file path.</param>
        /// <returns>The <see cref="CodeFile"/>.</returns>
        private static CodeFile ProcessFile(XElement module, string fileId, ClassWithNamespace classWithNamespace, string filePath)
        {
            var methods = module
                          .Elements("functions")
                          .Elements("function")
                          .Where(c => c.Attribute("namespace")?.Value == classWithNamespace.Namespace)
                          .Where(c => c.Attribute("type_name").Value.Equals(classWithNamespace.ClassName, StringComparison.Ordinal) ||
                                 c.Attribute("type_name").Value.StartsWith(classWithNamespace.ClassName + ".", StringComparison.Ordinal))
                          .Where(m => m.Elements("ranges").Elements("range").Any(r => r.Attribute("source_id").Value == fileId))
                          .ToArray();

            var linesOfFile = methods
                              .Elements("ranges")
                              .Elements("range")
                              .Where(l => l.Attribute("start_line").Value != "15732480")
                              .Select(l => new
            {
                LineNumberStart = int.Parse(l.Attribute("start_line").Value, CultureInfo.InvariantCulture),
                LineNumberEnd   = int.Parse(l.Attribute("end_line").Value, CultureInfo.InvariantCulture),
                Coverage        = l.Attribute("covered").Value.Equals("no") ? 0 : 1,
                Partial         = l.Attribute("covered").Value.Equals("partial")
            })
                              .OrderBy(seqpnt => seqpnt.LineNumberEnd)
                              .ToArray();

            int[]             coverage        = new int[] { };
            LineVisitStatus[] lineVisitStatus = new LineVisitStatus[] { };

            if (linesOfFile.Length > 0)
            {
                coverage        = new int[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1];
                lineVisitStatus = new LineVisitStatus[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1];

                for (int i = 0; i < coverage.Length; i++)
                {
                    coverage[i] = -1;
                }

                foreach (var seqpnt in linesOfFile)
                {
                    for (int lineNumber = seqpnt.LineNumberStart; lineNumber <= seqpnt.LineNumberEnd; lineNumber++)
                    {
                        coverage[lineNumber] = coverage[lineNumber] == -1 ? seqpnt.Coverage : Math.Min(coverage[lineNumber] + seqpnt.Coverage, 1);

                        if (lineVisitStatus[lineNumber] != LineVisitStatus.Covered)
                        {
                            LineVisitStatus statusOfLine = seqpnt.Partial ? LineVisitStatus.PartiallyCovered : (seqpnt.Coverage == 1 ? LineVisitStatus.Covered : LineVisitStatus.NotCovered);
                            lineVisitStatus[lineNumber] = (LineVisitStatus)Math.Max((int)lineVisitStatus[lineNumber], (int)statusOfLine);
                        }
                    }
                }
            }

            var codeFile = new CodeFile(filePath, coverage, lineVisitStatus);

            SetMethodMetrics(codeFile, methods);
            SetCodeElements(codeFile, methods);

            return(codeFile);
        }
            public override bool Equals(object obj)
            {
                if (obj == null || this.GetType() != obj.GetType())
                {
                    return(false);
                }

                ClassWithNamespace cwn = (ClassWithNamespace)obj;

                return(cwn.Namespace == this.Namespace &&
                       cwn.ClassName == this.ClassName);
            }
        /// <summary>
        /// Processes the given class.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="classWithNamespace">The class.</param>
        private void ProcessClass(XElement module, Assembly assembly, ClassWithNamespace classWithNamespace)
        {
            var fileIdsOfClass = module
                                 .Elements("functions")
                                 .Elements("function")
                                 .Where(c => c.Attribute("namespace")?.Value == classWithNamespace.Namespace)
                                 .Where(c => c.Attribute("type_name").Value.Equals(classWithNamespace.ClassName, StringComparison.Ordinal) ||
                                        c.Attribute("type_name").Value.StartsWith(classWithNamespace.ClassName + ".", StringComparison.Ordinal))
                                 .Elements("ranges")
                                 .Elements("range")
                                 .Select(r => r.Attribute("source_id").Value)
                                 .Distinct()
                                 .ToArray();

            var files = module
                        .Elements("source_files")
                        .Elements("source_file")
                        .ToArray();

            var filteredFilesOfClass = fileIdsOfClass
                                       .Select(fileId =>
                                               new
            {
                FileId   = fileId,
                FilePath = files.First(f => f.Attribute("id").Value == fileId).Attribute("path").Value
            })
                                       .Where(f => this.FileFilter.IsElementIncludedInReport(f.FilePath))
                                       .ToArray();

            // If all files are removed by filters, then the whole class is omitted
            if ((fileIdsOfClass.Length == 0 && !this.FileFilter.HasCustomFilters) || filteredFilesOfClass.Length > 0)
            {
                var @class = new Class(classWithNamespace.FullName, assembly);

                foreach (var file in filteredFilesOfClass)
                {
                    @class.AddFile(ProcessFile(module, file.FileId, classWithNamespace, file.FilePath));
                }

                assembly.AddClass(@class);
            }
        }