private void Process(PublishedContentRequest request)
        {
            //Are we rendering a published content (sanity check)?
            if (request?.PublishedContent == null)
            {
                return;
            }

            //Are there any experiments running
            var experiments = new GetApplicableCachedExperiments
            {
                ContentId = request.PublishedContent.Id
            }.ExecuteAsync().Result;

            //variations of the same content will be applied in the order the experiments were created,
            //if they override the same property variation of the newest experiment wins
            var variationsToApply = new List <IPublishedContentVariation>();

            foreach (var experiment in experiments)
            {
                var eventArgs = new BeforeExperimentExecutedArgs(experiment, request.RoutingContext?.UmbracoContext?.HttpContext);
                OnBeforeExperimentExecuted(eventArgs);

                if (eventArgs.SkipExperiment) //allow the developer to opt out
                {
                    continue;
                }

                var experimentId = experiment.GoogleExperiment.Id;

                //Has the user been previously exposed to this experiment?
                var assignedVariationId = GetAssignedVariation(request, experiment.Id);
                if (assignedVariationId != null)
                {
                    if (ShouldApplyVariation(experiment, assignedVariationId.Value))
                    {
                        var variationContent = GetVariationContent(experiment, assignedVariationId.Value);
                        variationsToApply.Add(new PublishedContentVariation(variationContent, experimentId, assignedVariationId.Value));
                    }
                }
                //Should the user be included in the experiment?
                else if (ShouldVisitorParticipate(experiment))
                {
                    //Choose a variation for the user
                    var variationId = SelectVariation(experiment);
                    AssignVariationToUser(request, experiment.Id, variationId);
                    if (ShouldApplyVariation(experiment, variationId))
                    {
                        var variationContent = GetVariationContent(experiment, variationId);
                        variationsToApply.Add(new PublishedContentVariation(variationContent, experimentId, variationId));
                    }
                }
                else
                {
                    AssignVariationToUser(request, experiment.Id, -1);
                }
            }

            //the visitor is excluded or we didn't find the content needed for variations, just show original
            if (variationsToApply.Count <= 0)
            {
                return;
            }

            var variedContent = new VariedContent(request.PublishedContent, variationsToApply.ToArray());

            request.PublishedContent = variedContent;
            request.SetIsInitialPublishedContent();

            //Reset the published content now we have set the initial content
            request.PublishedContent = PublishedContentModelFactoryResolver.Current.Factory.CreateModel(variedContent);

            request.TrySetTemplate(variedContent.GetTemplateAlias());
        }
 private static void OnBeforeExperimentExecuted(BeforeExperimentExecutedArgs e)
 {
     BeforeExperimentExecuted?.Invoke(null, e);
 }