Inheritance: ConnectorAttribute
        public Uid UpdateAddAndVerifyUser(ActiveDirectoryConnector connector,
            ObjectClass oclass, Uid uid, ICollection<ConnectorAttribute> attributes,
            OperationOptions searchOptions)
        {
            // find the existing one, and save off all attributes
            Filter uidFilter = FilterBuilder.EqualTo(uid);
            ICollection<ConnectorObject> currentObjects = TestHelpers.SearchToList(
                connector, oclass, uidFilter, searchOptions);
            Assert.IsTrue(currentObjects.Count == 1);
            ICollection<ConnectorAttribute> currentAttributes =
                currentObjects.ElementAt(0).GetAttributes();

            // build a list that has the 'added' values added to the existing values
            ICollection<ConnectorAttribute> comparisonAttributes = new List<ConnectorAttribute>();
            foreach (ConnectorAttribute updateAttribute in attributes)
            {
                ConnectorAttribute existingAttribute = ConnectorAttributeUtil.Find(
                    updateAttribute.Name, currentAttributes);
                comparisonAttributes.Add(AttConcat(updateAttribute, existingAttribute));
            }

            // make sure the uid is present in the attributes
            attributes.Add(uid);
            // now update with ADD to add additional home phones
            Uid updatedUid = connector.Update(UpdateType.ADD, oclass,
                attributes, null);

            // find it back
            ICollection<ConnectorObject> updatedObjects = TestHelpers.SearchToList(
                connector, oclass, uidFilter, searchOptions);
            Assert.IsTrue(updatedObjects.Count == 1);

            VerifyObject(comparisonAttributes, updatedObjects.ElementAt(0));

            return updatedUid;
        }
Example #2
0
 public UnknownUidException(Uid uid, ObjectClass objclass)
     : base(String.Format(MSG, uid, objclass))
 {
 }
 public void TestUid()
 {
     Uid v1 = new Uid("test");
     Uid v2 = (Uid)CloneObject(v1);
     Assert.AreEqual(v1, v2);
 }
Example #4
0
 public ConnectorObject GetObject(ObjectClass objClass, Uid uid, OperationOptions options)
 {
     return ((GetApiOp)GetOperationCheckSupported(SafeType<APIOperation>.Get<GetApiOp>()))
             .GetObject(objClass, uid, options);
 }
Example #5
0
 public void SetUid(Uid uid)
 {
     AddAttribute(uid);
 }
Example #6
0
        /// <summary>
        /// Creates a SyncDelata
        /// </summary>
        /// <param name="token">The token. Must not be null.</param>
        /// <param name="deltaType">The delta. Must not be null.</param>
        /// <param name="uid">The uid. Must not be null.</param>
        /// <param name="object">The object that has changed. May be null for delete.</param>
        internal SyncDelta(SyncToken token, SyncDeltaType deltaType,
            Uid previousUid, Uid uid,
            ConnectorObject obj)
        {
            Assertions.NullCheck(token, "token");
            Assertions.NullCheck(deltaType, "deltaType");
            Assertions.NullCheck(uid, "uid");

            //do not allow previous Uid for anything else than create or update
            if (previousUid != null && deltaType != SyncDeltaType.CREATE_OR_UPDATE)
            {
                throw new ArgumentException("The previous Uid can only be specified for create or update.");
            }

            //only allow null object for delete
            if (obj == null &&
                 deltaType != SyncDeltaType.DELETE)
            {
                throw new ArgumentException("ConnectorObject must be specified for anything other than delete.");
            }

            //if object not null, make sure its Uid
            //matches
            if (obj != null)
            {
                if (!uid.Equals(obj.Uid))
                {
                    throw new ArgumentException("Uid does not match that of the object.");
                }
            }

            _token = token;
            _deltaType = deltaType;
            _previousUid = previousUid;
            _uid = uid;
            _object = obj;
        }
 public ConnectorObject GetConnectorObjectFromUid(
     ActiveDirectoryConnector connector, ObjectClass oclass, Uid uid,
     OperationOptions options)
 {
     // get sid to check permissions
     Filter uidFilter = FilterBuilder.EqualTo(uid);
     ICollection<ConnectorObject> objects = TestHelpers.SearchToList(connector,
         oclass, uidFilter, options);
     Assert.AreEqual(1, objects.Count);
     return objects.ElementAt(0);
 }
Example #8
0
 /// <summary>
 /// Finds a DirectoryEntry by it's uid
 /// </summary>
 /// <param name="serverName"></param>
 /// <param name="uid"></param>
 /// <param name="adminUserName"></param>
 /// <param name="adminPassword"></param>
 /// <returns></returns>
 internal static DirectoryEntry GetDirectoryEntryFromUid(String serverName,
     Uid uid, string adminUserName, string adminPassword)
 {
     DirectoryEntry foundDirectoryEntry = new DirectoryEntry(
         ActiveDirectoryUtils.GetLDAPPath(serverName, uid.GetUidValue()),
         adminUserName, adminPassword);
     string dn = (string)foundDirectoryEntry.Properties["distinguishedName"][0];
     foundDirectoryEntry.Dispose();
     foundDirectoryEntry = new DirectoryEntry(
         ActiveDirectoryUtils.GetLDAPPath(serverName, dn),
         adminUserName, adminPassword);
     return foundDirectoryEntry;
 }
 public void AddModUid(Uid uid, ICollection<ConnectorAttribute> attributes)
 {
     _mods[uid] = attributes;
 }
 public ConnectorObject GetConnectorObjectFromUid(
     ActiveDirectoryConnector connector, ObjectClass oclass, Uid uid)
 {
     return GetConnectorObjectFromUid(connector, oclass, uid, null);
 }
 public void AddDelUid(Uid uid)
 {
     _dels.Add(uid);
 }
 public void VerifyObject(ActiveDirectoryConnector connector, Uid uid,
     ObjectClass oclass, ICollection<ConnectorAttribute> attributes)
 {
     // verify the object
     VerifyObject(attributes, GetConnectorObjectFromUid(connector, oclass, uid));
 }
        public Uid UpdateReplaceAndVerifyObject(ActiveDirectoryConnector connector,
            ObjectClass oclass, Uid uid, ICollection<ConnectorAttribute> attributes)
        {
            attributes.Add(uid);
            Filter uidFilter = FilterBuilder.EqualTo(uid);

            // find the object ... can't update if it doesn't exist
            ICollection<ConnectorObject> currentConnectorObjects = TestHelpers.SearchToList(
                connector, oclass, uidFilter);
            Assert.AreEqual(1, currentConnectorObjects.Count);

            Uid updatedUid = connector.Update(UpdateType.REPLACE, oclass,
                attributes, null);

            Assert.IsNotNull(updatedUid);

            uidFilter = FilterBuilder.EqualTo(updatedUid);
            ICollection<ConnectorObject> updatedConnectorObjects = TestHelpers.SearchToList(
                connector, oclass, uidFilter);
            Assert.IsTrue(updatedConnectorObjects.Count == 1);
            VerifyObject(attributes, updatedConnectorObjects.ElementAt(0));
            return updatedUid;
        }
        /// <summary>
        /// Process the Hashtable result and convert it to a SyncDelta object
        /// ready to be processed by the sync handler 
        /// </summary>
        /// <remarks>
        /// The result Hashtable must follow a specific format and contain the following key/value:
        /// 
        /// "Token": (Object) token object (could be Integer, Date, String), [!! could be null]
        /// "DeltaType": (String) ("CREATE|UPDATE|CREATE_OR_UPDATE"|"DELETE"),
        /// "Uid": (String) uid  (uid of the entry),
        /// "PreviousUid": (String) previous uid (This is for rename ops),
        /// "Object": Hashtable(String,List) of attributes name/values describing the object
        /// "ObjectClass": (String) must be set if Operation = DELETE and Object = null
        /// </remarks>
        /// <param name="result"></param>
        /// <returns></returns>
        public Object Process(Hashtable result)
        {
            var syncbld = new SyncDeltaBuilder();
            var cobld = new ConnectorObjectBuilder();
            Uid uid;

            // SyncToken
            // Mandatory here
            if (result.ContainsKey(SyncTokenKeyName))
            {
                syncbld.Token = result[SyncTokenKeyName] == null ? new SyncToken(0L) : new SyncToken(result[SyncTokenKeyName]);
            }
            else
                throw new ArgumentException("SyncToken is missing in Sync result");

            // SyncDelta
            // Mandatory here
            if (isValidKeyAndValue(result,DeltaTypeKeyName))
            {
                var op = result[DeltaTypeKeyName];
                if (SyncDeltaType.CREATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.CREATE;
                else if (SyncDeltaType.UPDATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.UPDATE;
                else if (SyncDeltaType.DELETE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.DELETE;
                else if (SyncDeltaType.CREATE_OR_UPDATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.CREATE_OR_UPDATE;
                else
                    throw new ArgumentException("Unrecognized DeltaType in Sync result");
            }
            else
                throw new ArgumentException("DeltaType is missing in Sync result");

            // Uid
            // Mandatory
            if (isValidKeyAndValue(result, UidKeyName))
            {
                var value = result[UidKeyName];
                if (value is String)
                {
                    uid = new Uid(value as String);
                } else if (value is Uid)
                {
                    uid = value as Uid;
                }
                else
                {
                    throw new ArgumentException("Unrecognized Uid in Sync result");
                }
                syncbld.Uid = uid;
                cobld.SetUid(uid);
            }
            else
            {
                throw new ArgumentException("Uid is missing in Sync result");
            }

            // PreviousUid
            // Not valid if DELETE
            if (isValidKeyAndValue(result, PreviousUidKeyName))
            {
                var value = result[PreviousUidKeyName];
                Uid previousUid;
                if (value is String)
                {
                    previousUid = new Uid(value as String);
                }
                else if (value is Uid)
                {
                    previousUid = value as Uid;
                }
                else
                {
                    throw new ArgumentException("Unrecognized PreviousUid in Sync result");
                }
                syncbld.PreviousUid = previousUid;
            }
            if (syncbld.PreviousUid != null && syncbld.DeltaType == SyncDeltaType.DELETE)
            {
                throw new ArgumentException("PreviousUid can only be specified for Create or Update.");
            }

            // Connector object
            // Mandatory unless DELETE
            if (result.ContainsKey(ConnectorObjectKeyName) && result[ConnectorObjectKeyName] is Hashtable)
            {
                var attrs = result[ConnectorObjectKeyName] as Hashtable;

                if (!attrs.ContainsKey(Name.NAME))
                    throw new ArgumentException("The Object must contain a Name");

                foreach (DictionaryEntry attr in attrs)
                {
                    var attrName = attr.Key as String;
                    var attrValue = attr.Value;

                    if (Name.NAME.Equals(attrName))
                        cobld.SetName(attrValue as String);
                    else if (Uid.NAME.Equals((attrName)))
                    {
                        if (!uid.GetUidValue().Equals(attrValue))
                            throw new ArgumentException("Uid from Object is different than Uid from Sync result");
                    }
                    else if (OperationalAttributes.ENABLE_NAME.Equals((attrName)))
                        cobld.AddAttribute(ConnectorAttributeBuilder.BuildEnabled(attr.Value is bool && (bool) attr.Value));
                    else
                    {
                        if (attrValue == null)
                        {
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName));
                        }
                        else if (attrValue.GetType() == typeof(Object[]) || attrValue.GetType() == typeof(System.Collections.ICollection))
                        {
                            var list = new Collection<object>();
                            foreach (var val in (ICollection)attrValue)
                            {
                                list.Add(FrameworkUtil.IsSupportedAttributeType(val.GetType()) ? val : val.ToString());
                            }
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName, list));
                        }
                        else
                        {
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName, attrValue));
                        }
                    }
                }
                cobld.ObjectClass = _objectClass;
                syncbld.Object = cobld.Build();
            }
            // If operation is DELETE and the ConnectorObject is null,
            // we need to set the ObjectClass at the SyncDelta level
            else if ((SyncDeltaType.DELETE == syncbld.DeltaType) && isValidKeyAndValue(result, ObjectClassKeyName))
            {
                var objclass = result[ObjectClassKeyName];
                if (objclass is ObjectClass)
                {
                    syncbld.ObjectClass = objclass as ObjectClass;
                }
                else if (objclass is String)
                {
                    syncbld.ObjectClass = new ObjectClass(objclass as String);
                }
                else
                {
                    throw new ArgumentException("Unrecognized ObjectClass in Sync result");
                }
            }
            else
            {
                throw new ArgumentException("Object is missing in Sync result");
            }

            return _handler.Handle(syncbld.Build());
        }
Example #15
0
 internal static Command GetCommand(PSExchangeConnector.CommandInfo cmdInfo, ICollection<ConnectorAttribute> attributes, Uid uidAttribute, ExchangeConfiguration config)
 {
     return GetCommand(cmdInfo, attributes, uidAttribute, null, config);
 }
Example #16
0
 public static String ConvertUIDToSearchString(Uid uid)
 {
     // e.g. <GUID=8184d4af97d9ed4c949c21665768881b>
     string uidValue = uid.GetUidValue().ToLowerInvariant();
     if (!uidValue.StartsWith("<guid=") || !uidValue.EndsWith(">") || uidValue.Length != 39)
     {
         throw new ArgumentException("Unsupported UID format: " + uidValue);
     }
     string raw = uidValue.Substring(6, 32);
     StringBuilder rv = new StringBuilder();
     for (int i = 0; i < raw.Length; i += 2)
     {
         rv.Append("\\").Append(raw.Substring(i, 2));
     }
     return rv.ToString();
 }
Example #17
0
        /// <summary>
        /// Creates command based on the commanf info, reading the calues from attributes
        /// </summary>
        /// <param name="cmdInfo">Command defition</param>
        /// <param name="attributes">Attribute values - UID in these is ignored! It should be passed as a separate parameter</param>
        /// <param name="config">Configuration object</param>
        /// <returns>
        /// Ready to execute Command
        /// </returns>
        /// <exception cref="ArgumentNullException">if some of the param is null</exception>
        internal static Command GetCommand(PSExchangeConnector.CommandInfo cmdInfo, ICollection<ConnectorAttribute> attributes, Uid uidAttribute, Name nameAttribute, ExchangeConfiguration config)
        {
            Assertions.NullCheck(cmdInfo, "cmdInfo");

            LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "GetCommand: cmdInfo name = {0}", cmdInfo.Name);

            ISet<string> parametersSet = new HashSet<string>();

            // create command
            Command cmd = new Command(cmdInfo.Name);

            if (!string.IsNullOrEmpty(cmdInfo.UidParameter) && !parametersSet.Contains(cmdInfo.UidParameter))
            {
                Uid uidAttr = uidAttribute != null ? uidAttribute : ConnectorAttributeUtil.GetUidAttribute(attributes);
                string uid = uidAttr != null ? uidAttr.GetUidValue() : null;
                if (uid != null)
                {
                    cmd.Parameters.Add(cmdInfo.UidParameter, ActiveDirectoryUtils.ConvertADGUIDtoObjectGUID(uid));
                    parametersSet.Add(cmdInfo.UidParameter);
                }
            }

            // map name attribute, if mapping specified
            if (!string.IsNullOrEmpty(cmdInfo.NameParameter) && !parametersSet.Contains(cmdInfo.NameParameter))
            {
                Name nameAttr = nameAttribute != null ? nameAttribute : ConnectorAttributeUtil.GetNameFromAttributes(attributes);
                string name = nameAttr != null ? nameAttr.GetNameValue() : null; ;
                if (name != null)
                {
                    cmd.Parameters.Add(cmdInfo.NameParameter, name);
                    parametersSet.Add(cmdInfo.NameParameter);
                }
            }

            if (cmdInfo.UsesConfirm)
            {
                cmd.Parameters.Add("confirm", false);
                parametersSet.Add("confirm");
            }

            if (cmdInfo.UsesDomainController)
            {
                cmd.Parameters.Add("DomainController", ActiveDirectoryUtils.GetDomainControllerName(config));
                parametersSet.Add("DomainController");
            }

            // TODO check this only for user-related operations
            bool emailAddressesPresent = GetAttValues(ExchangeConnectorAttributes.AttEmailAddresses, attributes) != null;
            bool primarySmtpAddressPresent = GetAttValues(ExchangeConnectorAttributes.AttPrimarySmtpAddress, attributes) != null;

            if (emailAddressesPresent && primarySmtpAddressPresent) {
                throw new ArgumentException(ExchangeConnectorAttributes.AttEmailAddresses + " and " + ExchangeConnectorAttributes.AttPrimarySmtpAddress + " cannot be both set.");
            }

            if (attributes != null) {

                foreach (string attName in cmdInfo.Parameters) {

                    object valueToSet = null;

                    ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes);
                    if (attribute != null) {
                        if (attribute.Value != null && attribute.Value.Count > 1) {
                            List<string> stringValues = new List<string>();
                            foreach (object val in attribute.Value) {
                                stringValues.Add(val.ToString());
                            }
                            valueToSet = stringValues.ToArray();
                        } else {
                            valueToSet = ConnectorAttributeUtil.GetSingleValue(attribute);
                        }
                        if (parametersSet.Contains(attName))
                        {
                            throw new InvalidOperationException("Parameter " + attName + " is already defined for command " + cmdInfo.Name);
                        }
                        cmd.Parameters.Add(attName, valueToSet);
                        parametersSet.Add(attName);
                    }
                }
            }

            LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "GetCommand exit: cmdInfo name = {0}", cmdInfo.Name);
            return cmd;
        }
Example #18
0
 /// <summary>
 /// Returns a mutable copy of the original set with the uid attribute added.
 /// </summary>
 /// <param name="attrs">The original set. Must not be null.</param>
 /// <param name="uid">The uid. Must not be null.</param>
 /// <returns>A mutable copy of the original set with the uid attribute added.</returns>
 public static ICollection<ConnectorAttribute> AddUid(ICollection<ConnectorAttribute> attrs, Uid uid)
 {
     Assertions.NullCheck(attrs, "attrs");
     Assertions.NullCheck(uid, "uid");
     HashSet<ConnectorAttribute> ret = new HashSet<ConnectorAttribute>(attrs);
     ret.Add(uid);
     return ret;
 }
        public void TestScriptOnConnectorWithCache()
        {
            var builder = new ScriptContextBuilder();
            builder.ScriptLanguage = "POWERShell";
            builder.ScriptText = "$Connector.Configuration.PropertyBag['cache'] = $Connector.Arguments.uid.GetUidValue()";
            var uid = new Uid("foo", "12345");
            builder.AddScriptArgument("uid", uid);
            GetFacade().RunScriptOnConnector(builder.Build(), null);

            builder.ScriptText = "return $Connector.Configuration.PropertyBag['cache']";
            var res = GetFacade().RunScriptOnConnector(builder.Build(), null) as List<object>;
            if (res != null)
            {
                Assert.AreEqual(res[0], uid.GetUidValue());
            }
            else
            {
                throw new ConnectorException("Not the expected result");
            }
        }
Example #20
0
 /// <summary>
 /// Create a QualifiedUid.
 /// </summary>
 /// <param name="objectClass">The object class. May not be null.</param>
 /// <param name="uid">The uid. May not be null.</param>
 public QualifiedUid(ObjectClass objectClass,
     Uid uid)
 {
     Assertions.NullCheck(objectClass, "objectClass");
     Assertions.NullCheck(uid, "uid");
     _objectClass = objectClass;
     _uid = uid;
 }
 public void TestScriptOnConnector()
 {
     var builder = new ScriptContextBuilder();
     builder.ScriptLanguage = "POWERShell";
     builder.ScriptText = "Write-Warning \"Test\"; return $Connector.Arguments.uid.GetUidValue()";
     var uid = new Uid("foo", "12345");
     builder.AddScriptArgument("uid", uid);
     var res = GetFacade().RunScriptOnConnector(builder.Build(), null) as Collection<object>;
     if (res != null)
     {
         Assert.AreEqual(res[0], uid.GetUidValue());
     }
 }
Example #22
0
 /// <summary>
 /// Creates a new <code>SyncDeltaBuilder</code> whose
 /// values are initialized to those of the delta.
 /// </summary>
 /// <param name="delta">The original delta.</param>
 public SyncDeltaBuilder(SyncDelta delta)
 {
     _token = delta.Token;
     _deltaType = delta.DeltaType;
     _previousUid = delta.PreviousUid;
     _uid = delta.Uid;
     _object = delta.Object;
 }
Example #23
0
 /// <summary>
 /// Sets the Uid of existing Object.
 /// 
 /// Connectors who throw this exception from their
 /// <seealso cref="org.identityconnectors.framework.spi.operations.CreateOp"/> or
 /// <seealso cref="org.identityconnectors.framework.spi.operations.UpdateOp"/> should
 /// set the object's Uid if available.
 /// </summary>
 /// <param name="uid">
 ///            The uid. </param>
 /// <returns> A reference to this. </returns>
 public AlreadyExistsException InitUid(Uid uid)
 {
     this._uid = uid;
     return this;
 }
Example #24
0
 public void Delete(ObjectClass objClass, Uid uid, OperationOptions options)
 {
     ((DeleteApiOp)GetOperationCheckSupported(SafeType<APIOperation>.Get<DeleteApiOp>()))
         .Delete(objClass, uid, options);
 }
Example #25
0
 /// <summary>
 /// Constructs a new RetryableException which signals partial success of
 /// <code>create</code> operation.
 /// 
 /// This should be called inside
 /// <seealso cref="Org.IdentityConnectors.Framework.Spi.Operations.CreateOp#create(org.identityconnectors.framework.common.objects.ObjectClass, java.util.Set, org.identityconnectors.framework.common.objects.OperationOptions)"/>
 /// implementation to signal that the create was not completed but the object
 /// was created with <code>Uid</code> and Application should call the
 /// <seealso cref="Org.IdentityConnectors.Framework.Spi.Operations.UpdateOp#update(org.identityconnectors.framework.common.objects.ObjectClass, org.identityconnectors.framework.common.objects.Uid, java.util.Set, org.identityconnectors.framework.common.objects.OperationOptions)"/>
 /// method now.
 /// <p/>
 /// Use this only if the created object can not be deleted. The best-practice
 /// should always be the Connector implementation reverts the changes if the
 /// operation failed.
 /// </summary>
 /// <param name="message">
 ///            the detail message (which is saved for later retrieval by the
 ///            <seealso cref="#getMessage()"/> method).
 /// </param>
 /// <param name="uid">
 ///            the new object's Uid. </param>
 /// <returns> a <code>RetryableException</code> that either <i>is</i> the
 ///         specified exception or <i>contains</i> the specified exception. </returns>
 public static RetryableException Wrap(string message, Uid uid)
 {
     return new RetryableException(message, new AlreadyExistsException().InitUid(Assertions.NullChecked(uid, "Uid")));
 }
Example #26
0
 public Uid Update(ObjectClass objclass, Uid uid, ICollection<ConnectorAttribute> attrs, OperationOptions options)
 {
     return ((UpdateApiOp)GetOperationCheckSupported(SafeType<APIOperation>.Get<UpdateApiOp>()))
             .Update(objclass, uid, attrs, options);
 }
        public void DeleteAndVerifyObject(ActiveDirectoryConnector connector,
            ObjectClass oclass, Uid uid, bool verifyExists, bool verifyDeleted)
        {
            Filter uidFilter = FilterBuilder.EqualTo(uid);

            if (verifyExists)
            {
                // verify that object currently exists
                ICollection<ConnectorObject> foundObjects = TestHelpers.SearchToList(
                    connector, oclass, uidFilter);

                // verify that it was deleted
                Assert.AreEqual(1, foundObjects.Count);
            }

            // delete
            try
            {
                connector.Delete(oclass, uid, null);
            }
            catch
            {
                if (verifyDeleted)
                {
                    throw;
                }
            }

            if (verifyDeleted)
            {
                // verify that object was deleted
                ICollection<ConnectorObject> deletedObjects = TestHelpers.SearchToList(
                    connector, oclass, uidFilter);

                // verify that it was deleted
                Assert.AreEqual(0, deletedObjects.Count);
            }
        }