public static Opportunity ToOpportunity(this OpportunityInfo opportunityInfo)
        {
            int id = int.TryParse(opportunityInfo.OpportunityId, out id) ? id : 0;

            Venue  venue  = null;
            string region = null;

            try
            {
                venue = ((VenueInfo)opportunityInfo.Item).ToVenue();
            }
            catch (InvalidCastException)
            {
                try
                {
                    region = opportunityInfo.Item.ToString();
                }
                catch (InvalidCastException)
                {
                    // Unbale to cast to a Venue or a Region
                }
            }

            return(new Opportunity(
                       id,
                       opportunityInfo.StudyMode.ToStudyMode(),
                       opportunityInfo.AttendanceMode.ToAttendanceMode(),
                       opportunityInfo.AttendancePattern.ToAttendancePattern(),
                       opportunityInfo.DFE1619Funded,
                       opportunityInfo.StartDate.ToDescriptionDate(),
                       venue,
                       region,
                       opportunityInfo.Duration.ToDuration()));
        }
        /// <summary>
        /// Build CourseListResponseStructure object from CourseListResponse data and original CourseListRequestStructure.
        /// </summary>
        /// <param name="response">CourseListResponse data.</param>
        /// <param name="request">Original CourseListRequestStructure.</param>
        /// <returns>Populated CourseListResponseStructure object.</returns>
        private static CourseListResponseStructure BuildCourseListResponseStructure(CourseListResponse response, CourseListRequestStructure request)
        {
            CourseListResponseStructure courseListResponse = new CourseListResponseStructure();

            // Create matching Ldcs collection
            List <CourseListResponseStructureMatchingLDCS> matchingLdcss =
                new List <CourseListResponseStructureMatchingLDCS>();

            foreach (LdcsCode ldcsCode in response.LdcsCodes)
            {
                CourseListResponseStructureMatchingLDCS matchingLdcs = new CourseListResponseStructureMatchingLDCS();
                matchingLdcs.LDCS   = BuildLdcsInfoType(ldcsCode.LdcsCodeValue, ldcsCode.LdcsCodeDescription);
                matchingLdcs.Counts = ldcsCode.CourseCount.ToString();

                matchingLdcss.Add(matchingLdcs);
            }

            courseListResponse.MatchingLDCS = matchingLdcss.ToArray();

            // Create CourseStructure collection
            List <CourseStructure> courseStructures = new List <CourseStructure>();

            foreach (Course course in response.Courses)
            {
                // Get Course information
                CourseStructure courseStructure = new CourseStructure();

                courseStructure.Course               = new CourseInfo();
                courseStructure.Course.CourseID      = course.CourseId.ToString();
                courseStructure.Course.CourseSummary = course.CourseSummary;
                courseStructure.Course.CourseTitle   = course.CourseTitle;

                courseStructure.Course.LDCS               = new LDCSOutputType();
                courseStructure.Course.LDCS.CatCode1      = BuildLdcsInfoType(course.LdcsCode1, course.LdcsDesc1);
                courseStructure.Course.LDCS.CatCode2      = BuildLdcsInfoType(course.LdcsCode2, course.LdcsDesc2);
                courseStructure.Course.LDCS.CatCode3      = BuildLdcsInfoType(course.LdcsCode3, course.LdcsDesc3);
                courseStructure.Course.LDCS.CatCode4      = BuildLdcsInfoType(course.LdcsCode4, course.LdcsDesc4);
                courseStructure.Course.LDCS.CatCode5      = BuildLdcsInfoType(course.LdcsCode5, course.LdcsDesc5);
                courseStructure.Course.NoOfOpps           = course.NumberOfOpportunities.ToString();
                courseStructure.Course.QualificationLevel = course.QualificationLevel;
                courseStructure.Course.QualificationType  = course.QualificationType;

                // Get Opportunity information
                List <OpportunityInfo> opportunityInfos = new List <OpportunityInfo>();

                foreach (Opportunity opportunity in course.Opportunities)
                {
                    OpportunityInfo opportunityInfo = new OpportunityInfo();

                    opportunityInfo.AttendanceMode    = opportunity.AttendanceMode;
                    opportunityInfo.AttendancePattern = opportunity.AttendancePattern;
                    opportunityInfo.OpportunityId     = opportunity.OpportunityId;

                    StartDateType startDateType = BuildStartDateType(opportunity);

                    //StartDateType startDateType = new StartDateType();
                    //startDateType.ItemElementName = ItemChoiceType.Date;
                    //startDateType.Item = opportunity.StartDate;

                    // TODO: how do we add these in?  I suspect we need to change the contract.
                    //StartDateType startDateDescType = new StartDateType();
                    //startDateDescType.ItemElementName = ItemChoiceType.DateDesc;
                    //startDateDescType.Item = opportunity.StartDateDescription;

                    opportunityInfo.StartDate = startDateType;
                    opportunityInfo.Duration  = new DurationType();
                    opportunityInfo.Duration.DurationDescription = opportunity.DurationDescription;
                    opportunityInfo.Duration.DurationUnit        = opportunity.DurationUnit;

                    if (opportunity.DurationValue != 0)
                    {
                        opportunityInfo.Duration.DurationValue = opportunity.DurationValue.ToString();
                    }

                    opportunityInfo.EndDate                = opportunity.EndDate;
                    opportunityInfo.StudyMode              = opportunity.StudyMode;
                    opportunityInfo.DFE1619Funded          = opportunity.DfE1619Funded;
                    opportunityInfo.DFE1619FundedSpecified = true;

                    if (opportunity.Venue != null && !string.IsNullOrEmpty(opportunity.Venue.VenueName))
                    {
                        VenueInfo venueInfo = new VenueInfo();
                        if (!string.IsNullOrEmpty(opportunity.Distance))
                        {
                            venueInfo.DistanceSpecified = true;
                            venueInfo.Distance          = float.Parse(opportunity.Distance);
                        }
                        venueInfo.VenueName    = opportunity.Venue.VenueName;
                        venueInfo.VenueAddress =
                            BuildAddressType(opportunity.Venue.AddressLine1, opportunity.Venue.AddressLine2,
                                             opportunity.Venue.Town, opportunity.Venue.County, opportunity.Venue.Postcode, opportunity.Venue.Latitude, opportunity.Venue.Longitude);

                        opportunityInfo.Item = venueInfo;
                    }
                    else
                    {
                        opportunityInfo.Item = opportunity.RegionName;
                    }

                    opportunityInfos.Add(opportunityInfo);
                }

                // pick out the first opportunity (expecting there to be only one looking at the java web service's design).
                // if there is more than one here - then current site cannot deal with it.
                courseStructure.Opportunity = opportunityInfos.ElementAt(0);

                courseStructure.Provider = new ProviderInfo();
                courseStructure.Provider.ProviderName           = course.Provider.ProviderName;
                courseStructure.Provider.TFPlusLoans            = course.Provider.TFPlusLoans;
                courseStructure.Provider.TFPlusLoansSpecified   = true;
                courseStructure.Provider.DFE1619Funded          = course.Provider.DFE1619Funded;
                courseStructure.Provider.DFE1619FundedSpecified = true;

                if (course.Provider.FEChoices_EmployerSatisfaction.HasValue)
                {
                    courseStructure.Provider.FEChoices_EmployerSatisfaction = course.Provider.FEChoices_EmployerSatisfaction.Value;
                }
                courseStructure.Provider.FEChoices_EmployerSatisfactionSpecified = course.Provider.FEChoices_EmployerSatisfaction.HasValue;
                if (course.Provider.FEChoices_LearnerSatisfaction.HasValue)
                {
                    courseStructure.Provider.FEChoices_LearnerSatisfaction = course.Provider.FEChoices_LearnerSatisfaction.Value;
                }
                courseStructure.Provider.FEChoices_LearnerSatisfactionSpecified = course.Provider.FEChoices_LearnerSatisfaction.HasValue;
                if (course.Provider.FEChoices_LearnerDestination.HasValue)
                {
                    courseStructure.Provider.FEChoices_LearnerDestination = course.Provider.FEChoices_LearnerDestination.Value;
                }
                courseStructure.Provider.FEChoices_LearnerDestinationSpecified = course.Provider.FEChoices_LearnerDestination.HasValue;


                courseStructures.Add(courseStructure);
            }

            courseListResponse.CourseDetails = courseStructures.ToArray();

            // Get Result information, i.e. page number etc.
            courseListResponse.ResultInfo = new ResultInfoType();

            int requestRecordsPerPage = 0;

            if (!string.IsNullOrEmpty(request.RecordsPerPage))
            {
                requestRecordsPerPage = Int32.Parse(request.RecordsPerPage);
            }

            int responseRecordsPerPage = (requestRecordsPerPage > 0) ? requestRecordsPerPage : 50;
            int totalRecords           = response.NumberOfRecords;
            int numberOfPages          =
                (totalRecords / responseRecordsPerPage) + ((totalRecords % responseRecordsPerPage == 0) ? 0 : 1);

            int currentPage = 1;

            if (!string.IsNullOrEmpty(request.PageNo))
            {
                currentPage = Int32.Parse(request.PageNo);
            }

            courseListResponse.ResultInfo.NoOfRecords = response.NumberOfRecords.ToString();
            courseListResponse.ResultInfo.PageNo      = (currentPage > 0) ? currentPage.ToString() : "1";
            courseListResponse.ResultInfo.NoOfPages   = numberOfPages.ToString();

            // Get original Request details
            courseListResponse.RequestDetails = request;

            return(courseListResponse);
        }