protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var service = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            // the model that we want to add the association to
            var model = artifact.StorageModel();

            // check for uniqueness
            var assocName = Name;
            var assocSetName = assocName;
            if (UniquifyNames)
            {
                assocName = ModelHelper.GetUniqueName(typeof(Association), model, assocName);
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);
            }
            else
            {
                // check for uniqueness of the association name
                string msg = null;
                if (ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg) == false)
                {
                    throw new InvalidOperationException(msg);
                }

                // check for uniqueness of the association set name
                if (ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg) == false)
                {
                    throw new InvalidOperationException(msg);
                }
            }

            // create the new item in our model
            var association = new Association(model, null);
            association.LocalName.Value = assocName;
            model.AddAssociation(association);
            XmlModelHelper.NormalizeAndResolve(association);

            // create the ends of the association
            var fkEnd = new AssociationEnd(association, null);
            fkEnd.Type.SetRefName(FkTable);
            fkEnd.Role.Value = FkRoleNameOverride ?? ModelHelper.CreateFKAssociationEndName(FkTable.LocalName.Value);
            if (FkMultiplicityOverride != null)
            {
                fkEnd.Multiplicity.Value = FkMultiplicityOverride;
            }
            else
            {
                fkEnd.Multiplicity.Value = DoesFkFormPk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_Many;
            }
            association.AddAssociationEnd(fkEnd);
            XmlModelHelper.NormalizeAndResolve(fkEnd);

            var pkEnd = new AssociationEnd(association, null);
            pkEnd.Type.SetRefName(PkTable);
            pkEnd.Role.Value = PkRoleNameOverride ?? ModelHelper.CreatePKAssociationEndName(PkTable.LocalName.Value);
            if (PkMultiplicityOverride != null)
            {
                pkEnd.Multiplicity.Value = PkMultiplicityOverride;
            }
            else
            {
                pkEnd.Multiplicity.Value = IsNullableFk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_One;
            }
            association.AddAssociationEnd(pkEnd);
            XmlModelHelper.NormalizeAndResolve(pkEnd);

            var cmd = new CreateAssociationSetCommand(assocSetName, association, ModelSpace.Storage);
            CommandProcessor.InvokeSingleCommand(cpc, cmd);
            var set = cmd.AssociationSet;
            Debug.Assert(set != null, "failed to create an AssociationSet");

            Association = association;
            _createdAssociationFkEnd = fkEnd;
            _createdAssociationPkEnd = pkEnd;
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var service = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            // the model that we want to add the association to
            var model = artifact.ConceptualModel();

            // check for uniqueness of the assocation and association set names
            // if uniquifyNames is true then make them unique, otherwise throw
            // an exception if they're not (always uniquify associationSetName
            // regardless as we get bugs if not)
            var assocName = Name;
            var assocSetName = assocName;
            if (UniquifyNames)
            {
                assocName = ModelHelper.GetUniqueName(typeof(Association), model, assocName);
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);

                // ensure unique NavigationProperty names
                if (ShouldCreateNavigationPropertyEnd1
                    && !ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true)
                    || NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value)
                {
                    var namesToAvoid = new HashSet<string>();
                    namesToAvoid.Add(End1Entity.LocalName.Value);
                    namesToAvoid.Add(NavigationPropertyInEnd2Entity);
                    NavigationPropertyInEnd1Entity = ModelHelper.GetUniqueConceptualPropertyName(
                        NavigationPropertyInEnd1Entity, End1Entity, namesToAvoid);
                }

                if (ShouldCreateNavigationPropertyEnd2
                    && !ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true)
                    || NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value)
                {
                    var namesToAvoid = new HashSet<string> { End2Entity.LocalName.Value, NavigationPropertyInEnd1Entity };
                    NavigationPropertyInEnd2Entity = ModelHelper.GetUniqueConceptualPropertyName(
                        NavigationPropertyInEnd2Entity, End2Entity, namesToAvoid);
                }
            }
            else
            {
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);

                string msg = null;
                if (!ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg))
                {
                    throw new InvalidOperationException(msg);
                }
                else if (!ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg))
                {
                    throw new InvalidOperationException(msg);
                }
                else if (ShouldCreateNavigationPropertyEnd1
                         && (!ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true)))
                {
                    msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd1Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (ShouldCreateNavigationPropertyEnd2
                         && (!ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true)))
                {
                    msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd2Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value)
                {
                    msg = string.Format(
                        CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd1Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value)
                {
                    msg = string.Format(
                        CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd2Entity);
                    throw new InvalidOperationException(msg);
                }
            }

            // create the new item in our model
            var association = new Association(model, null);
            association.LocalName.Value = assocName;
            model.AddAssociation(association);
            XmlModelHelper.NormalizeAndResolve(association);

            // create the first end
            _end1 = new AssociationEnd(association, null);
            _end1.Type.SetRefName(End1Entity);
            _end1.Role.Value = End1Entity.LocalName.Value;
            _end1.Multiplicity.Value = End1Multiplicity;
            association.AddAssociationEnd(_end1);
            XmlModelHelper.NormalizeAndResolve(_end1);

            // create the second end
            _end2 = new AssociationEnd(association, null);
            _end2.Type.SetRefName(End2Entity);
            var endRoleValue = End2Entity.LocalName.Value;
            if (_end1.Role.Value.Equals(endRoleValue))
            {
                // avoid duplicate Role values between the two ends. This will occur in self-associations.
                // Appending "1" is consistent with how model-gen chooses a unique name.
                endRoleValue = endRoleValue + "1";
            }
            _end2.Role.Value = endRoleValue;
            _end2.Multiplicity.Value = End2Multiplicity;
            association.AddAssociationEnd(_end2);
            XmlModelHelper.NormalizeAndResolve(_end2);

            // create the association set for this association
            var cmd = new CreateAssociationSetCommand(assocSetName, association);
            CommandProcessor.InvokeSingleCommand(cpc, cmd);
            var set = cmd.AssociationSet;
            Debug.Assert(set != null, "unable to create association set");

            CreateNavigationPropertyCommand navcmd;

            if (ShouldCreateNavigationPropertyEnd1)
            {
                navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd1Entity, End1Entity, association, _end1, _end2);
                CommandProcessor.InvokeSingleCommand(cpc, navcmd);
            }

            if (ShouldCreateNavigationPropertyEnd2)
            {
                navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd2Entity, End2Entity, association, _end2, _end1);
                CommandProcessor.InvokeSingleCommand(cpc, navcmd);
            }

            if (ShouldCreateForeignKeyProperties)
            {
                CreateForeignKeyProperties.AddRule(cpc, association);
            }

            CreatedAssociation = association;
        }