public SearchResultRS MappingSearchResult(HotelListResponse rawRs, HDSRequest request)
        {
            SearchResultRS rs = new SearchResultRS();

            //EAN warning and error
            if (rawRs.EanWsError != null)
            {
                if ((rawRs.EanWsError.handling == errorHandling.RECOVERABLE) && (rawRs.EanWsError.category == errorCategory.DATA_VALIDATION)){
                    //warning about location
                    rs.Warnings = new List<WarningAndError>();
                    WarningAndError warning = helper.GenerateWarningAndError(9002, rawRs.EanWsError);
                    rs.Warnings.Add(warning);
                }
                else{
                    //error! something has happened
                    rs.Errors = new List<WarningAndError>();
                    WarningAndError error = helper.GenerateWarningAndError(9001, rawRs.EanWsError);
                    rs.Errors.Add(error);
                }
            }

            //hotels
            if (rawRs.HotelList != null)
            {
                //pagination
                if (rawRs.moreResultsAvailableSpecified){
                    rs.IsMoreResultsAvailable = rawRs.moreResultsAvailable;
                    if (rawRs.moreResultsAvailable){
                        string tempQs = request.RequestQueryString;

                        if (tempQs.Contains("&cacheKey=") && request.Session.Expedia != null)         //remove old cacheKey from request query string
                            tempQs = tempQs.Replace("&cacheKey=" + HttpUtility.UrlEncode(request.Session.Expedia.CacheKey), "");

                        if (tempQs.Contains("&cacheLocation=") && request.Session.Expedia != null)    //remove old cacheLocation from request query string
                            tempQs = tempQs.Replace("&cacheLocation=" + HttpUtility.UrlEncode(request.Session.Expedia.CacheLocation), "");

                        rs.NextPageQueryString = tempQs + "&cacheKey="      + HttpUtility.UrlEncode(rawRs.cacheKey)
                                                        + "&cacheLocation=" + HttpUtility.UrlEncode(rawRs.cacheLocation);

                        //re-create new expedia session
                        rs.Session.Expedia = new ExpediaSpecific { CacheKey = rawRs.cacheKey, CacheLocation = rawRs.cacheLocation };
                    }

                }

                //popuplate each of every hotels
                rs.Hotels = new List<HDSInterfaces.Hotel>();
                foreach (HotelSummary rawHotel in rawRs.HotelList.HotelSummary)
                {
                    bool isHotelWithRate = false;

                    HDSInterfaces.Hotel hotel = new HDSInterfaces.Hotel();

                    /* ****************** for testing ****************** */
                    //if (hotel.Id == 356393) { string breakkkkkkk = ""; }
                    /* ****************** for testing ****************** */

                    //address and location
                    hotel.HotelInfo = new HotelInformation();
                    hotel.HotelInfo.Id = rawHotel.hotelId;
                    hotel.HotelInfo.Name = rawHotel.name;

                    hotel.HotelInfo.Address = helper.GenerateHotelAddress(rawHotel);

                    //star rating
                    if (rawHotel.hotelRatingSpecified) { hotel.HotelInfo.StarRating = rawHotel.hotelRating; }
                    if (rawHotel.tripAdvisorRatingSpecified) { hotel.HotelInfo.TripAdvisorRating = rawHotel.tripAdvisorRating; }

                    //description and image
                    hotel.HotelInfo.HotelDescription = rawHotel.shortDescription;
                    hotel.HotelInfo.Images = new List<HDSInterfaces.HotelImage>();
                    hotel.HotelInfo.Images.Add(new HDSInterfaces.HotelImage { UrlThumbnail = IMAGE_URL_PREFIX + rawHotel.thumbNailUrl });

                    //rooms and rates - some expedia hotel won't have rate (but still has all other information)
                    if (rawHotel.RoomRateDetailsList != null)
                    {
                        isHotelWithRate = true;
                        hotel.Rooms = new List<HDSInterfaces.Room>();
                        foreach (RoomRateDetails rawRoom in rawHotel.RoomRateDetailsList)
                        {

                            /*
                             * room identification code - do it later
                             */

                            //room info and promotion
                            HDSInterfaces.Room room = new HDSInterfaces.Room();
                            room.Description = rawRoom.roomDescription;
                            if (rawRoom.currentAllotment > 0) { room.NumberOfRoomAvailable = rawRoom.currentAllotment; }    //as per expedia document, 0 doesn't mean unavailable :(

                            //promotion
                            if (!string.IsNullOrEmpty(rawRoom.promoDescription)) {
                                room.Promotions = new List<Promotion>();
                                room.Promotions.Add(new Promotion { Code = rawRoom.promoId, Description = rawRoom.promoDescription });
                            }

                            //room rate total and nightly
                            room.Rates = helper.GenerateRoomRate(rawRoom.RateInfo);

                            //value adds
                            if (rawRoom.ValueAdds != null){
                                room.ValueAdds = new List<RoomValueAdd>();
                                foreach (valueAdd rawValueAdd in rawRoom.ValueAdds.ValueAdd){
                                    RoomValueAdd valueAdd = new RoomValueAdd { Id = rawValueAdd.id, Description = rawValueAdd.description };
                                    room.ValueAdds.Add(valueAdd);
                                }
                            }

                            hotel.Rooms.Add(room);
                        }

                    }

                    if (isHotelWithRate)        //populate hotel only if there is at least 1 rate
                        rs.Hotels.Add(hotel);
                }
            }

            //location suggestion
            if (rawRs.LocationInfos != null){
                rs.Locations = new List<Location>();
                foreach (LocationInfo rawLocation in rawRs.LocationInfos.LocationInfo) {
                    if (rawLocation.active){
                        Location location = new Location
                        {
                            Code = rawLocation.destinationId,
                            Name = rawLocation.code,
                            Address = new Address
                            {
                                State = new State { Name = rawLocation.stateProvinceCode },
                                City = new City { Name = rawLocation.city },
                                Country = new Country { Name = rawLocation.countryName, Code = rawLocation.countryCode },
                            }
                        };
                        rs.Locations.Add(location);
                    }
                }
            }

            return rs;
        }
        public SearchResultRS GetSearchResult(HDSRequest request)
        {
            //create hotel list request object(HotelListRequest)
            HotelListRequest rawRq = new HotelListRequest();
            rawRq = (HotelListRequest)commonHelper.GenerateBaseRequest(rawRq, request);

            if (request.Session.Expedia != null)
            {
                rawRq.cacheKey = request.Session.Expedia.CacheKey;
                rawRq.cacheLocation = request.Session.Expedia.CacheLocation;
            }
            else
            {

                //set max hotel return
                if (request.Session.PageSize != null)
                {
                    rawRq.numberOfResults = (int)request.Session.PageSize;
                    rawRq.numberOfResultsSpecified = true;
                }

                //star rating
                if (request.SearchCriteria != null)
                {
                    if (request.SearchCriteria.MinStarRating != null)
                    {
                        rawRq.minStarRating = (float)request.SearchCriteria.MinStarRating;
                        rawRq.minStarRatingSpecified = true;
                    }
                    if (request.SearchCriteria.MaxStarRating != null)
                    {
                        rawRq.maxStarRating = (float)request.SearchCriteria.MaxStarRating;
                        rawRq.maxStarRatingSpecified = true;
                    }
                }

                //stay date
                rawRq.arrivalDate = request.StayDate.GetCheckInUSFormat();
                rawRq.departureDate = request.StayDate.GetCheckOutUSFormat();

                //room and num adults-children
                rawRq.numberOfBedRooms = request.Itineraries.Count;
                rawRq.maxRatePlanCount = DEFAULT_MAX_NUMBER_OF_ROOM;
                rawRq.RoomGroup = commonHelper.GenerateRoomGroup(request.Itineraries);

                //location keyword or location(s) or list of hotelid
                switch (request.RequestType)
                {
                    case HDSRequestType.SearchByHotelIds:
                        int index = 0;
                        rawRq.hotelIdList = new long[request.Hotels.Count];
                        foreach (HDSInterfaces.Hotel hotel in request.Hotels)
                        {
                            rawRq.hotelIdList[index] = (long)hotel.Id;
                            index = index + 1;
                        }

                        break;
                    case HDSRequestType.SearchByLocationIds:
                        rawRq.destinationId = request.SearchCriteria.Location.Code;

                        break;
                    case HDSRequestType.SearchByLocationKeyword:
                        rawRq.destinationString = request.SearchCriteria.LocationKeyword;

                        break;
                }

                //addition filter - by hotel name keyword ( **** NOTE: this is excluded to search by list of hotel ID as expedia will ignore this on this search type ***** )
                if (request.SearchCriteria.HotelNameKeyword != null){
                    rawRq.propertyName = request.SearchCriteria.HotelNameKeyword;
                }

                //addition filter - by amenities (NOTE: tested and it's working with search by location keyword, location id and list of hotel id)
                if (request.SearchCriteria.Amenities != null) {
                    if (request.SearchCriteria.Amenities.Count > 0) {
                        int index = 0;
                        rawRq.amenities = new int[request.SearchCriteria.Amenities.Count];
                        foreach (HDSInterfaces.Amenity amenity in request.SearchCriteria.Amenities) {
                            rawRq.amenities[index] = int.Parse(amenity.Code);
                            index = index + 1;
                        }
                    }
                }

                //additon filter - by property type (e.g. hotel, motel, apartment)
                if (request.SearchCriteria.PropertyTypes != null)
                {
                    if (request.SearchCriteria.PropertyTypes.Count > 0)
                    {
                        int index = 0;
                        rawRq.propertyCategory = new PropertyCategory[request.SearchCriteria.PropertyTypes.Count];
                        foreach (HDSInterfaces.PropertyType propertyType in request.SearchCriteria.PropertyTypes)
                        {
                            PropertyCategory pc = PropertyCategory.Item0;
                            switch (propertyType.Code.Trim())
                            {
                                case "1":
                                    pc = PropertyCategory.Item1;
                                    break;
                                case "2":
                                    pc = PropertyCategory.Item2;
                                    break;
                                case "3":
                                    pc = PropertyCategory.Item3;
                                    break;
                                case "4":
                                    pc = PropertyCategory.Item4;
                                    break;
                                case "5":
                                    pc = PropertyCategory.Item5;
                                    break;
                                case "6":
                                    pc = PropertyCategory.Item6;
                                    break;
                            }
                            rawRq.propertyCategory[index] = pc;
                            index = index + 1;
                        }
                    }
                }

            }

            //submit soap request to expedia
            HotelListResponse rawRs;
            try
            {
                serviceObjShop = new Expedia.HotelShoppingServiceReference.HotelServicesClient();
                rawRs = serviceObjShop.getList(rawRq);
            }
            catch (Exception e1)
            {
                SearchResultRS error = new SearchResultRS();
                error.Errors = new List<WarningAndError>();
                error.Errors.Add(new WarningAndError { Id = 9003, Message = "Error return from provider", DetailDescription = e1.ToString() });
                return error;
            }

            try
            {
                return objMapping.MappingSearchResult(rawRs, request);
            }
            catch (Exception e2)
            {
                SearchResultRS error = new SearchResultRS();
                error.Errors = new List<WarningAndError>();
                error.Errors.Add(new WarningAndError { Id = 9110, Message = "Search Result mapping exception", DetailDescription = e2.ToString() });
                return error;
            }
        }