public static void MoveCriteriaModel(this ICriteriaModelContainer criteriaModelContainer, CriteriaModel criteriaModel, CriteriaModel targetCriteriaModel, bool insertAtEnd)
        {
            var index = criteriaModelContainer.IndexOfCriteriaModel(criteriaModel);

            if (index == -1)
            {
                throw new ArgumentOutOfRangeException(criteriaModel.ToString());
            }

            var targetIndex = criteriaModelContainer.IndexOfCriteriaModel(targetCriteriaModel);

            if (targetIndex > index && !insertAtEnd)
            {
                targetIndex -= 1;
            }
            if (targetIndex == -1)
            {
                throw new ArgumentOutOfRangeException(targetCriteriaModel.ToString());
            }

            Undo.RegisterCompleteObjectUndo(criteriaModelContainer.SerializableAsset, "Move Criteria Model");

            criteriaModelContainer.RemoveCriteriaModelNoUndo(criteriaModel);
            criteriaModelContainer.InsertCriteriaModelNoUndo(targetIndex, criteriaModel);
        }
        public static CriteriaModel DuplicateCriteriaModel(this ICriteriaModelContainer criteriaModelContainer,
                                                           CriteriaModel criteriaModel,
                                                           ICriteriaModelContainer targetCriteriaModelContainer,
                                                           CriteriaModel targetCriteriaModel,
                                                           bool insertAtEnd)
        {
            Assert.AreNotEqual(criteriaModelContainer, targetCriteriaModelContainer);

            var index = criteriaModelContainer.IndexOfCriteriaModel(criteriaModel);

            if (index == -1)
            {
                throw new ArgumentOutOfRangeException(criteriaModel.ToString());
            }

            Undo.RegisterCompleteObjectUndo(targetCriteriaModelContainer.SerializableAsset, "Duplicate Criteria Model");
            CriteriaModel clone = criteriaModel.Clone();

            foreach (var criterion in clone.Criteria)
            {
                Utility.SaveAssetIntoObject(criterion.Value.NodeAssetReference, (Object)clone.GraphModel.AssetModel);
            }
            clone.GraphModel         = targetCriteriaModelContainer.GraphModel;
            clone.UniqueNameProvider = targetCriteriaModelContainer;
            clone.SetUniqueName(clone.Name);

            if (insertAtEnd)
            {
                targetCriteriaModelContainer.AddCriteriaModelNoUndo(clone);
            }
            else
            {
                var targetIndex = targetCriteriaModelContainer.IndexOfCriteriaModel(targetCriteriaModel);
                if (targetIndex == -1)
                {
                    throw new ArgumentOutOfRangeException(targetCriteriaModel.ToString());
                }

                targetCriteriaModelContainer.InsertCriteriaModelNoUndo(targetIndex, clone);
            }

            Utility.SaveAssetIntoObject(clone, (Object)((VSGraphModel)clone.GraphModel).AssetModel);

            return(clone);
        }