private void SearchFolders(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
		{
			using (var repository = _repositoryFactory())
			{
				var query = repository.Folders.Where(x => x.ParentFolderId == criteria.FolderId);
				var folderIds = query.Select(x => x.Id).ToArray();

				result.ContentFolders = new List<coreModel.DynamicContentFolder>();
				foreach(var folderId in folderIds)
				{
					var folder = repository.GetContentFolderById(folderId);
					result.ContentFolders.Add(folder.ToCoreModel());
				}

				//Populate folder for all founded places and items
				if (criteria.FolderId != null)
				{
					var searchedFolder = repository.GetContentFolderById(criteria.FolderId);
					if(searchedFolder != null)
					{
						var hasfolderItems = result.ContentPlaces.OfType<coreModel.IsHasFolder>().Concat(result.ContentItems);
						foreach(var hasfolderItem in hasfolderItems)
						{
							hasfolderItem.Folder = searchedFolder.ToCoreModel();
						}
					}
				}

			}
		}
		public coreModel.MarketingSearchResult SearchResources(coreModel.MarketingSearchCriteria criteria)
		{
			var retVal = new coreModel.MarketingSearchResult();
			var count = criteria.Count;
			
			if ((criteria.ResponseGroup & coreModel.SearchResponseGroup.WithPromotions) == coreModel.SearchResponseGroup.WithPromotions)
			{
				SearchPromotions(criteria, retVal);
				criteria.Count -= retVal.Promotions.Count();
			}
			if ((criteria.ResponseGroup & coreModel.SearchResponseGroup.WithContentItems) == coreModel.SearchResponseGroup.WithContentItems)
			{
				SearchContentItems(criteria, retVal);
				criteria.Count -= retVal.ContentItems.Count();
			}
			if ((criteria.ResponseGroup & coreModel.SearchResponseGroup.WithContentPlaces) == coreModel.SearchResponseGroup.WithContentPlaces)
			{
				SearchContentPlaces(criteria, retVal);
				criteria.Count -= retVal.ContentPlaces.Count();
			}
			if ((criteria.ResponseGroup & coreModel.SearchResponseGroup.WithContentPublications) == coreModel.SearchResponseGroup.WithContentPublications)
			{
				SearchContentPublications(criteria, retVal);
				criteria.Count -= retVal.ContentPublications.Count();
			}
			if ((criteria.ResponseGroup & coreModel.SearchResponseGroup.WithFolders) == coreModel.SearchResponseGroup.WithFolders)
			{
				SearchFolders(criteria, retVal);
			}
			
			return retVal;
		}
 public void UpdateContents(coreModel.DynamicContentItem[] contents)
 {
     var pkMap = new PrimaryKeyResolvingMap();
     using (var repository = _repositoryFactory())
     using (var changeTracker = GetChangeTracker(repository))
     {
         foreach (var content in contents)
         {
             var sourceEntity = content.ToDataModel(pkMap);
             var targetEntity = repository.GetContentItemById(content.Id);
             if (targetEntity == null)
             {
                 repository.Add(sourceEntity);
             }
             else
             {
                 changeTracker.Attach(targetEntity);
                 sourceEntity.Patch(targetEntity);
             }
         }
         CommitChanges(repository);
         pkMap.ResolvePrimaryKeys();
     }
     foreach (var content in contents)
     {
         _dynamicPropertyService.SaveDynamicPropertyValues(content);
     }
 }
		public IHttpActionResult EvaluatePromotions(coreModel.PromotionEvaluationContext context)
		{
            // DOESN'T WORK
			//var cacheKey = CacheKey.Create("MarketingController.EvaluatePromotions", context.GetHash<MD5CryptoServiceProvider>());
			//var retVal = _cacheManager.Get(cacheKey, () => _promotionEvaluator.EvaluatePromotion(context));
		    var retVal = _promotionEvaluator.EvaluatePromotion(context);
			return Ok(retVal.Rewards.Select(x => x.ToWebModel()).ToArray());
		}
		public coreModel.DynamicContentItem CreateContent(coreModel.DynamicContentItem content)
		{
			var entity = content.ToDataModel();
			coreModel.DynamicContentItem retVal = null;
			using (var repository = _repositoryFactory())
			{
				repository.Add(entity);
				CommitChanges(repository);
			}
			retVal = GetContentItemById(entity.Id);
			return retVal;
		}
        public IHttpActionResult Search(coreModel.MarketingSearchCriteria criteria)
        {
            var retVal = new webModel.MarketingSearchResult();
            var coreResult = _marketingSearchService.SearchResources(criteria);

            retVal.Promotions = coreResult.Promotions.Select(x => x.ToWebModel()).ToList();
            retVal.ContentPlaces = coreResult.ContentPlaces.Select(x => x.ToWebModel()).ToList();
            retVal.ContentItems = coreResult.ContentItems.Select(x => x.ToWebModel()).ToList();
            retVal.ContentPublications = coreResult.ContentPublications.Select(x => x.ToWebModel()).ToList();
            retVal.ContentFolders = coreResult.ContentFolders.Select(x => x.ToWebModel()).ToList();
            retVal.TotalCount = coreResult.TotalCount;

            return Ok(retVal);
        }
        public coreModel.DynamicContentItem CreateContent(coreModel.DynamicContentItem content)
        {
            var entity = content.ToDataModel();

            using (var repository = _repositoryFactory())
            {
                repository.Add(entity);
                CommitChanges(repository);
            }

            content.SetObjectId(entity.Id);
            _dynamicPropertyService.SaveDynamicPropertyValues(content);

            var retVal = GetContentItemById(entity.Id);
            return retVal;
        }
        public coreModel.DynamicContentItem CreateContent(coreModel.DynamicContentItem content)
        {
            var pkMap = new PrimaryKeyResolvingMap();
            var entity = content.ToDataModel(pkMap);

            using (var repository = _repositoryFactory())
            {
                repository.Add(entity);
                CommitChanges(repository);
                pkMap.ResolvePrimaryKeys();
            }

            _dynamicPropertyService.SaveDynamicPropertyValues(content);

            var retVal = GetContentItemById(entity.Id);
            return retVal;
        }
		public void UpdateContents(coreModel.DynamicContentItem[] contents)
		{
			using (var repository = _repositoryFactory())
			using (var changeTracker = base.GetChangeTracker(repository))
			{
				foreach (var content in contents)
				{
					var sourceEntity = content.ToDataModel();
					var targetEntity = repository.GetContentItemById(content.Id);
					if (targetEntity == null)
					{
						repository.Add(sourceEntity);
					}
					else
					{
						changeTracker.Attach(targetEntity);
						sourceEntity.Patch(targetEntity);
					}
				}
				CommitChanges(repository);
			}
		}
		private static void SetPropertyValue(dataModel.DynamicContentItemProperty retVal, coreModel.Property property)
		{
			switch (property.ValueType)
			{
				case coreModel.PropertyValueType.Boolean:
					retVal.BooleanValue = Convert.ToBoolean(property.Value);
					break;
				case coreModel.PropertyValueType.DateTime:
					retVal.DateTimeValue = Convert.ToDateTime(property.Value);
					break;
				case coreModel.PropertyValueType.Decimal:
					retVal.DecimalValue = Convert.ToDecimal(property.Value);
					break;
				case coreModel.PropertyValueType.Integer:
					retVal.IntegerValue = Convert.ToInt32(property.Value);
					break;
				case coreModel.PropertyValueType.LongText:
					retVal.LongTextValue = Convert.ToString(property.Value);
					break;
				case coreModel.PropertyValueType.ShortText:
					retVal.ShortTextValue = Convert.ToString(property.Value);
					break;
			}
		}
		private void SearchContentItems(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
		{
			using (var repository = _repositoryFactory())
			{
				var query = repository.Items.Where(x => x.FolderId == criteria.FolderId);
				result.TotalCount += query.Count();
				var ids = query.OrderBy(x => x.Id)
							   .Select(x => x.Id)
							   .Skip(criteria.Start)
							   .Take(criteria.Count).ToArray();
				result.ContentItems = ids.Select(x => _dynamicContentService.GetContentItemById(x)).ToList();
			}

		}
		public coreModel.DynamicContentPlace CreatePlace(coreModel.DynamicContentPlace place)
		{
			var entity = place.ToDataModel();
			coreModel.DynamicContentPlace retVal = null;
			using (var repository = _repositoryFactory())
			{
				repository.Add(entity);
				CommitChanges(repository);
			}
			retVal = GetPlaceById(entity.Id);
			return retVal;
		}
        private void SearchPromotions(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
        {
            var promotions = new List<coreModel.Promotion>();
            var totalCount = 0;
            using (var repository = _repositoryFactory())
            {
                var query = repository.Promotions;
                if (!string.IsNullOrEmpty(criteria.Keyword))
                {
                    query = query.Where(x => x.Name.Contains(criteria.Keyword) || x.Description.Contains(criteria.Keyword));
                }

                promotions = query.OrderBy(x => x.Id)
                                              .Skip(criteria.Start)
                                              .Take(criteria.Count)
                                              .ToArray()
                                              .Select(x => x.ToCoreModel())
                                              .ToList();
                totalCount = query.Count();
            }


            promotions.AddRange(_customPromotionManager.Promotions.Skip(criteria.Start).Take(criteria.Count));
            totalCount += _customPromotionManager.Promotions.Count();

            result.Promotions = promotions;
            result.TotalCount += totalCount;
        }
 public void UpdatePlace(coreModel.DynamicContentPlace place)
 {
     using (var repository = _repositoryFactory())
     using (var changeTracker = GetChangeTracker(repository))
     {
         var sourceEntity = place.ToDataModel();
         var targetEntity = repository.GetContentPlaceById(place.Id);
         if (targetEntity == null)
         {
             repository.Add(sourceEntity);
         }
         else
         {
             changeTracker.Attach(targetEntity);
             sourceEntity.Patch(targetEntity);
         }
         CommitChanges(repository);
     }
 }
		private void SearchContentPublications(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
		{
			using (var repository = _repositoryFactory())
			{
				var query = repository.PublishingGroups;
				result.TotalCount += query.Count();

				var ids = query.OrderBy(x => x.Id)
						   .Select(x => x.Id)
						   .Skip(criteria.Start)
						   .Take(criteria.Count).ToArray();
				result.ContentPublications = ids.Select(x => _dynamicContentService.GetPublicationById(x)).ToList();
			}

		}
		private void SearchPromotions(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
		{
			var promotions = new List<coreModel.Promotion>();
			var totalCount = 0;
			using (var repository = _repositoryFactory())
			{
				promotions = repository.Promotions.OrderBy(x => x.Id)
											  .Skip(criteria.Start)
											  .Take(criteria.Count)
											  .ToArray()
											  .Select(x => x.ToCoreModel())
											  .ToList();
				totalCount = repository.Promotions.Count();
			}


			promotions.AddRange(_customPromotionManager.Promotions.Skip(criteria.Start).Take(criteria.Count));
			totalCount += _customPromotionManager.Promotions.Count();

			result.Promotions = promotions;
			result.TotalCount += totalCount;
		}
 public IHttpActionResult EvaluateDynamicContent(coreModel.DynamicContent.DynamicContentEvaluationContext evalContext)
 {
     var retVal = _dynamicContentEvaluator.EvaluateItems(evalContext).Select(x => x.ToWebModel()).ToArray();
     return Ok(retVal);
 }
		public void UpdateFolder(coreModel.DynamicContentFolder folder)
		{
			using (var repository = _repositoryFactory())
			using (var changeTracker = base.GetChangeTracker(repository))
			{
				var sourceEntity = folder.ToDataModel();
				var targetEntity = repository.GetContentFolderById(folder.Id);
				if (targetEntity == null)
				{
					repository.Add(sourceEntity);
				}
				else
				{
					changeTracker.Attach(targetEntity);
					sourceEntity.Patch(targetEntity);
				}
				CommitChanges(repository);
			}
		}
		public coreModel.DynamicContentFolder CreateFolder(coreModel.DynamicContentFolder folder)
		{
			var entity = folder.ToDataModel();
			coreModel.DynamicContentFolder retVal = null;
			using (var repository = _repositoryFactory())
			{
				repository.Add(entity);
				CommitChanges(repository);
			}
			retVal = GetFolderById(entity.Id);
			return retVal;
		}
		private void SearchContentItems(coreModel.MarketingSearchCriteria criteria, coreModel.MarketingSearchResult result)
		{
			using (var repository = _repositoryFactory())
			{
				var query = repository.Items.Include(x => x.PropertyValues).Where(x => x.FolderId == criteria.FolderId);
				result.TotalCount += query.Count();

				result.ContentItems = query.OrderBy(x => x.Id)
											  .Skip(criteria.Start)
											  .Take(criteria.Count)
											  .ToArray()
											  .Select(x => x.ToCoreModel())
											  .ToList();
			}

		}
		public IHttpActionResult ProcessMarketingEvent(coreModel.IMarketingEvent marketingEvent)
		{
			var retVal = _promotionEvaluator.ProcessEvent(marketingEvent);
			return Ok(retVal.Rewards.Select(x => x.ToWebModel()).ToArray());
		}
 public IHttpActionResult EvaluatePromotions(coreModel.PromotionEvaluationContext context)
 {
     var retVal = _promoEvaluator.EvaluatePromotion(context);
     return Ok(retVal.Rewards.Select(x => x.ToWebModel()).ToArray());
 }
		public coreModel.DynamicContentPublication CreatePublication(coreModel.DynamicContentPublication publication)
		{
			var entity = publication.ToDataModel();
			coreModel.DynamicContentPublication retVal = null;
			using (var repository = _repositoryFactory())
			{
				repository.Add(entity);
				CommitChanges(repository);
			}
			retVal = GetPublicationById(entity.Id);
			return retVal;
		}