Inheritance: HttpLogEntry, IComparable
        int IComparable.CompareTo(object obj)
        {
            //W3C_Extended_Log tempLog = obj is W3C_Extended_Log ? (W3C_Extended_Log)obj : null;
            W3C_Extended_Log tempLog = (W3C_Extended_Log)obj;

            if (tempLog == null)
            {
                throw new InvalidCastException();
            }

            //if less than zero then this instance is earlier than value, if zero its the same, and if greater then later
            return(this.Date.CompareTo(tempLog.Date));
        }
        public IEnumerable<W3C_Extended_Log> ParseW3CFormat()
        {
            //Use the findFields method to get only the supported columns from the log file
            if(!FoundFields)
            {
                FindFields();
            }

            //for parsing the time, the timezone for W3C extended is Greenwhich Standard Time
            TimeZoneInfo gmtZone = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
            TimeZoneInfo pstZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
            string line;
            //int count = 0;
            while ((line = _reader.ReadLine()) != null)
            {
                //count = 0;
                //if the line is not a directive line then its one of the HTTP log data
                bool isDirectiveLine = line.StartsWith("#", StringComparison.OrdinalIgnoreCase);
                if (!isDirectiveLine)
                {
                    _log = new W3C_Extended_Log();
                    //get the data and follow the Grammar
                    string[] data = line.Split(default(Char[]), StringSplitOptions.RemoveEmptyEntries);
                    //using a foreach loop and follow through the grammar
                    for (int i = 0; i < _fields.Count(); i++)
                    {
                        //check that the text fits the grammar
                        bool isValid = CheckGrammer(data[i], _fields[i].ToLower());

                        if (isValid)
                        {

                            switch (_fields[i].ToLower())
                            {
                                case W3C_ExtendedConstants.DATE:
                                    _log.Date = DateTime.Parse(data[i]);
                                    break;
                                case W3C_ExtendedConstants.TIME:
                                    _log.Time = DateTime.Parse(data[i]);
                                    break;
                                case W3C_ExtendedConstants.TIME_TAKEN:
                                    _log.TimeTaken = Convert.ToInt32(data[i]);
                                    break;
                                case W3C_ExtendedConstants.BYTES:
                                    _log.BytesSent = Convert.ToInt32(data[i]);
                                    break;
                                case W3C_ExtendedConstants.CACHED:
                                    //nothing
                                    break;
                                case W3C_ExtendedConstants.CLIENT_IP:
                                    try
                                    {

                                        _log.ClientIP = System.Net.IPAddress.Parse(data[i]);
                                    }
                                    catch (FormatException)
                                    {
                                        _log.ClientIP = System.Net.IPAddress.Parse("0");
                                    }
                                    break;
                                case W3C_ExtendedConstants.USER_NAME:
                                    _log.UserName = data[i];
                                    break;
                                case W3C_ExtendedConstants.SERVICE_NAME:
                                    _log.ServerSiteName = data[i];
                                    break;
                                case W3C_ExtendedConstants.SERVER_IP:
                                    try
                                    {
                                        _log.ServerIP = System.Net.IPAddress.Parse(data[i]);
                                    }
                                    catch (FormatException)
                                    {
                                        _log.ServerIP = System.Net.IPAddress.Parse("0");
                                    }
                                    break;
                                case W3C_ExtendedConstants.SERVER_PORT:
                                    _log.ServerPort = Convert.ToInt16(data[i]);
                                    break;
                                case W3C_ExtendedConstants.DNS:
                                    //nothing
                                    break;
                                case W3C_ExtendedConstants.STATUS:

                                    _log.StatusCode = Convert.ToInt16(data[i]);
                                    break;
                                case W3C_ExtendedConstants.WIN32_STATUS:
                                    _log.Win32_Status = Convert.ToUInt32(data[i]);
                                    break;
                                case W3C_ExtendedConstants.COMMENT:
                                    //nothing
                                    break;
                                case W3C_ExtendedConstants.METHOD:
                                    _log.TypeRequest = data[i];
                                    break;
                                case W3C_ExtendedConstants.URI:
                                    //nothing
                                    break;
                                case W3C_ExtendedConstants.URI_STEM:
                                    _log.UriStem = data[i];
                                    break;
                                case W3C_ExtendedConstants.URI_QUERY:
                                    _log.UriQuery = data[i];
                                    break;
                                case W3C_ExtendedConstants.BYTES_SENT:
                                    _log.BytesSent = Convert.ToInt32(data[i]);
                                    break;
                                case W3C_ExtendedConstants.BYTES_RECEIVED:
                                    _log.BytesSent = Convert.ToInt32(data[i]);
                                    break;
                                case W3C_ExtendedConstants.PROTOCOL_VERSION:
                                    _log.ProtocolVersion = data[i];
                                    break;
                                case W3C_ExtendedConstants.HOST:
                                    _log.Host = data[i];
                                    break;
                                case W3C_ExtendedConstants.USER_AGENT:
                                    _log.UserAgent = data[i];
                                    break;
                                case W3C_ExtendedConstants.COOKIE:
                                     CookieParser cookieParser = new CookieParser();
                                    _log.Cookies = cookieParser.ExtractServerHeaderResponseCookies(data[i]);
                                    break;
                                case W3C_ExtendedConstants.REFERRER:
                                    _log.Referrer = new Uri(data[i]);
                                    break;
                            }

                        }//end of if statement
                    }

                    string date = _log.Date.ToLongDateString();
                    string time = _log.Time.ToLongTimeString();

                    //we had earlier the time and date of a log as seperate instances of the date time object, to make querying of logs simple, merged the date and time
                    //into a single instance of DateTime.
                    _log.UTCLogDateTime = DateTime.Parse(date + " " + time);
                    //Trace.WriteLine(_log.UTCLogDateTime.ToString());
                    yield return _log;
                }

            }

            //After reading this file, set this back to false for the next file
            FoundFields = false;
            _reader.Close();
        }
 /// <summary>
 /// Used this function to perform metric computations between a start time and intermediate time
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end">The intermediate time</param>
 /// <param name="log">HttpLog that these metrics will use to compute data</param>
 private void HelperFunction(DateTime start, DateTime end, W3C_Extended_Log log)
 {
     if (log.UTCLogDateTime >= start && log.UTCLogDateTime < end)
     {
         foreach (IMetric job in _metricCollection)
         {
             job.ProcessEntry(log);
         }
     }
 }