private static void MatchEvents(EtwEvent manifestEvent, TraceRecord record, List <ExtendedPropertyInfo> traceRecordMetadata)
        {
            // Validate the mapping which we maintain.
            var mappingValid = IsMappingValid(manifestEvent, record);

            if (!mappingValid)
            {
                throw new TraceManifestMismatchException(record, manifestEvent, MismatchKind.MappingMismatch, "Mapping Mismatch");
            }

            // Validate the Version.
            if (record.GetMinimumVersionOfProductWherePresent() > manifestEvent.Version)
            {
                throw new TraceManifestMismatchException(record, manifestEvent, MismatchKind.EventVersionMismatch, "Event Version Mismatch");
            }

            // Validate Field Count.
            var fields = manifestEvent.Fields;

            if (fields.Count() != traceRecordMetadata.Count())
            {
                throw new TraceManifestMismatchException(
                          record,
                          manifestEvent,
                          MismatchKind.FieldCountDiffer,
                          string.Format("Expected Count: {0}, Actual Count: {1}", traceRecordMetadata.Count, fields.Count));
            }

            // Validate Each Field Type.
            for (int i = 0; i < traceRecordMetadata.Count; ++i)
            {
                // Get the Matching Field.
                var matchingFieldFromManifest = fields.SingleOrDefault(oneField => oneField.Name == traceRecordMetadata[i].ManifestOriginalName);
                if (matchingFieldFromManifest == null)
                {
                    throw new TraceManifestMismatchException(
                              record,
                              manifestEvent,
                              MismatchKind.PropertyMissingInManifest,
                              string.Format("Property Missing. Friendly Name: {0}, Original Name: {1}", traceRecordMetadata[i].Name, traceRecordMetadata[i].ManifestOriginalName));
                }

                // It implies that field is actually an Enum
                if (matchingFieldFromManifest.Enumeration != null)
                {
                    if (!DoesEnumMatch(matchingFieldFromManifest, traceRecordMetadata[i]))
                    {
                        throw new TraceManifestMismatchException(
                                  record,
                                  manifestEvent,
                                  MismatchKind.EnumMismatch,
                                  string.Format("Property: {0} in TraceRecord is of Enum Type and has mismatch in manifest", traceRecordMetadata[i].Name));
                    }

                    continue;
                }

                // Validate Position of the Field.
                if (matchingFieldFromManifest.Position != i)
                {
                    throw new TraceManifestMismatchException(
                              record,
                              manifestEvent,
                              MismatchKind.FieldPositionMismatch,
                              string.Format("Expected Position: {0}, Real Position: {1}", i, matchingFieldFromManifest.Position));
                }

                // Validate the Type.
                var manifestDataType = ConvertToDataType(ConvertFromManifestTypeToRealType(matchingFieldFromManifest.Type));
                if (manifestDataType != traceRecordMetadata[i].Type)
                {
                    throw new TraceManifestMismatchException(
                              record,
                              manifestEvent,
                              MismatchKind.DataTypeMismatch,
                              string.Format("Expected type: {0}, Actual Type: {1}", traceRecordMetadata[i].Type, manifestDataType));
                }
            }
        }