public async Task <IActionResult> Run(
            [HttpTrigger(
                 "post",
                 Route = Routes.KontentClone
                 )] string body,
            string itemCodename,
            string languageCodename
            )
        {
            try
            {
                var stopwatch = new Stopwatch();

                stopwatch.Start();

                var oldItemReference  = new CodenameReference(itemCodename);
                var newItemReference  = new ExternalIdReference(kontentRepository.GetExternalId());
                var languageReference = new CodenameReference(languageCodename);
                var newItemVariants   = new Dictionary <Reference, ItemVariant>();

                await kontentRepository.PrepareDeepClone(new PrepareItemParameters
                {
                    ItemVariant = await kontentRepository.GetItemVariant(new GetItemVariantParameters
                    {
                        OldItemReference  = oldItemReference,
                        NewItemReference  = newItemReference,
                        LanguageReference = languageReference,
                        NewItemVariants   = newItemVariants
                    }),
                    LanguageReference = languageReference,
                    NewItemVariants   = newItemVariants
                });

                var newItems = new List <ContentItem>();

                foreach (var(newItem, newVariant) in newItemVariants.Values)
                {
                    newItems.Add(await kontentRepository.UpsertContentItem(newItem));

                    await kontentRepository.UpsertLanguageVariant(new UpsertLanguageVariantParameters
                    {
                        LanguageReference = languageReference,
                        Variant           = newVariant
                    });
                }

                stopwatch.Stop();

                return(LogOkObject(new
                {
                    TotalApiCalls = kontentRepository.ApiCalls,
                    TotalMilliseconds = stopwatch.ElapsedMilliseconds,
                    NewItems = newItems
                }));
            }
            catch (Exception ex)
            {
                return(LogException(ex));
            }
        }
        public async Task PrepareDeepClone(PrepareItemParameters prepareItemParameters)
        {
            var((item, variant), languageReference, newItemVariants) = prepareItemParameters;

            var descendantReferences = new HashSet <ItemVariant>();

            foreach (var element in variant.Elements !)
            {
                switch (element)
                {
                case RichTextElement richTextElement:

                    void ReplaceReferences(ref string richTextValue, string pattern, Func <string, Reference> getReference)
                    {
                        var matches = Regex.Matches(richTextValue, pattern);

                        foreach (Match?match in matches)
                        {
                            if (match?.Success == true)
                            {
                                var matchValue   = match.Groups[1];
                                var oldReference = getReference(matchValue.Value);

                                if (newItemVariants !.TryGetValue(oldReference, out var itemVariant) && itemVariant.Variant?.ItemReference != null)
                                {
                                    richTextValue = richTextValue.Replace(matchValue.Value, itemVariant.Variant.ItemReference.Value);
                                }
                                else
                                {
                                    var newReference = new ExternalIdReference(GetExternalId());

                                    descendantReferences !.Add(GetItemVariant(new GetItemVariantParameters
                                    {
                                        OldItemReference  = oldReference,
                                        NewItemReference  = newReference,
                                        LanguageReference = languageReference,
                                        NewItemVariants   = newItemVariants
                                    }).Result);

                                    richTextValue = richTextValue.Replace(matchValue.Value, newReference.Value);
                                }
                            }
                        }
                    }

                    if (richTextElement.Value != null)
                    {
                        if (richTextElement.Components != null)
                        {
                            foreach (var component in richTextElement.Components)
                            {
                                var newGuid = Guid.NewGuid();

                                richTextElement.Value = richTextElement.Value.Replace(component.Id.ToString(), newGuid.ToString());

                                component.Id = newGuid;
                            }
                        }

                        var newRichTextValue = richTextElement.Value;

                        ReplaceReferences(ref newRichTextValue, "(?<=data-type=\"item\" *)data-id=\"(.*?)\"", value => new IdReference(value));
                        ReplaceReferences(ref newRichTextValue, "(?<=data-type=\"item\" *)data-external-id=\"(.*?)\"", value => new ExternalIdReference(value));

                        newRichTextValue = Regex.Replace(newRichTextValue, "(?<=data-type=\"item\" *)data-id", "data-external-id");

                        ReplaceReferences(ref newRichTextValue, "data-item-id=\"(.*?)\"", value => new IdReference(value));
                        ReplaceReferences(ref newRichTextValue, "data-item-external-id=\"(.*?)\"", value => new ExternalIdReference(value));

                        newRichTextValue = newRichTextValue.Replace("data-item-id", "data-item-external-id");

                        richTextElement.Value = newRichTextValue;
                    }

                    break;