public bool TryParse(string queryString, char keyValueSeparator = '=', char groupSeparator = '&')
        {
            if (String.IsNullOrWhiteSpace(queryString) || queryString.IndexOf(keyValueSeparator) == -1)
            {
                return(false);
            }

            // Remove the /action/[AdvertiserId]? part from QueryString
            var ei = queryString.IndexOf(QSParameterAdvertiserId_end);

            if (!ExtractKeyValuePairs(queryString.Substring(ei + 1), keyValueSeparator, groupSeparator))
            {
                return(false);
            }

            // Extract AdvertiserId to be used for Version 1 logs to lookup (TagName, AdvertiserId) -> TagId map file.
            var bi = queryString.IndexOf(QSParameterAdvertiserId_begin);

            if (bi != -1 && ei > bi)
            {
                bi += QSParameterAdvertiserId_begin.Length;
                var advertiserIdStr = queryString.Substring(bi, ei - bi);
                int advertiserIdInt;
                AdvertiserId = int.TryParse(advertiserIdStr, out advertiserIdInt) ? advertiserIdInt : (int?)null;
            }

            // Enumerate string columns
            Version   = LookupKeyString(QsParameterVersion);
            PageTitle = LookupKeyString(QsParameterPageTitle);

            // QueryString for AppInstall events start with /action/aips?
            if (queryString.IndexOf(QSParameterAppInstallPS) != -1)
            {
                AppInstallClickId = LookupKeyString(QSParameterBCLID);
            }

            // decode NavigatedFromURL and ReferrerURL
            NavigatedFromURL = WebUtility.UrlDecode(LookupKeyString(QsParameterNavigatedFromUrl));
            ReferrerURL      = WebUtility.UrlDecode(LookupKeyString(QSParameterReferrerURL));
            EventCategory    = WebUtility.UrlDecode(LookupKeyString(QsParameterEventCategory));
            EventAction      = WebUtility.UrlDecode(LookupKeyString(QsParameterEventAction));
            EventLabel       = WebUtility.UrlDecode(LookupKeyString(QsParameterEventLabel));
            EventType        = LookupKeyString(QsParameterEventType);

            // If the event type is not specified, but the key "ec" exist in the query string, then set type to custom event.
            if (String.IsNullOrEmpty(EventType) && !String.IsNullOrWhiteSpace(EventCategory))
            {
                EventType = "custom";
            }

            TagName = WebUtility.UrlDecode(LookupKeyString(QsParameterTagName));

            UETMatchingGuid = CommonUtils.ParseGuid(LookupKeyString(QSParameterUETMatchingMUID));
            rn = LookupKeyString(QSParameterRandomNumber);

            // Enumerate nullable number columns
            EventValue = LookupKeyDouble(QsParameterEventValue);
            TagId      = LookupKeyInt(QsParameterTagId);
            PageLoad   = LookupKeySByte(QsParameterPageLoad);
            GoalValue  = LookupKeyDouble(QsParameterGoalValue);
            iframe     = LookupKeyString(QSParameterIframe) == "1";

            return(true);
        }