NullCheck() static private method

Localized null check
If the passed object is null
static private NullCheck ( object obj, string param, Configuration config ) : void
obj object Object to be check for null
param string Parameter name to be used in exception message
config Configuration Configuration used for localization purposes
return void
        public void Delete(ObjectClass objClass, Uid uid, OperationOptions options)
        {
            const string operation = "Delete";

            plugins.OnBeforeDelete(objClass, uid, options, _configuration);

            ExchangeUtility.NullCheck(objClass, "objClass", this._configuration);
            ExchangeUtility.NullCheck(uid, "uid", this._configuration);

            LOG.Info("Exchange.Delete method; uid:\n{0}", uid.GetUidValue());

            DeleteOpContext context = new DeleteOpContext()
            {
                Connector = this,
                ConnectorConfiguration = _configuration,
                ObjectClass            = objClass,
                OperationName          = operation,
                Uid     = uid,
                Options = options
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    DeleteMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);
            } catch (Exception e) {
                LOG.Error(e, "Exception while executing Delete operation: {0}");
                throw;
            }
        }
        /// <summary>
        /// helper method for searching object in AD by UID
        /// </summary>
        /// <param name="uid">Uid of the searched </param>
        /// <param name="oclass">Object class</param>
        /// <param name="options">Operation options</param>
        /// <returns>Connector object found by the Uid</returns>
        private ConnectorObject ADSearchByUid(Uid uid, ObjectClass oclass, OperationOptions options)
        {
            ExchangeUtility.NullCheck(uid, "uid", this.configuration);
            ExchangeUtility.NullCheck(oclass, "oclass", this.configuration);
            if (options == null)
            {
                options = new OperationOptionsBuilder().Build();
            }

            ConnectorObject ret        = null;
            Filter          filter     = FilterBuilder.EqualTo(uid);
            var             translator = base.CreateFilterTranslator(oclass, options);
            IList <string>  queries    = translator.Translate(filter);

            if (queries.Count == 1)
            {
                ResultsHandler handler = delegate(ConnectorObject cobject)
                {
                    ret = cobject;
                    return(false);
                };
                base.ExecuteQuery(oclass, queries[0], handler, options);
            }

            return(ret);
        }
        /// <summary>
        /// Implementation of SynOp.Sync
        /// </summary>
        /// <param name="objClass">Object class</param>
        /// <param name="token">Sync token</param>
        /// <param name="handler">Sync results handler</param>
        /// <param name="options">Operation options</param>
        public void Sync(
            ObjectClass oclass, SyncToken token, SyncResultsHandler handler, OperationOptions options)
        {
            const string operation = "Sync";

            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);

            LOG.Info("Exchange.Sync method; oclass = {0}, token = {1}", oclass, token);

            SyncOpContext context = new SyncOpContext()
            {
                Connector = this,
                ConnectorConfiguration = _configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options            = options,
                SyncToken          = token,
                SyncResultsHandler = handler
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);
                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    SyncMain(context);
                }
                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);
            } catch (Exception e) {
                LOG.Error(e, "Exception while executing Sync operation: {0}");
                throw;
            }

            // TODO what about executing a script on each returned item?
        }
Esempio n. 4
0
        // TODO move to appropriate place
        /// <summary>
        /// helper method for searching object in AD by UID
        /// </summary>
        /// <param name="uid">Uid of the searched </param>
        /// <param name="oclass">Object class</param>
        /// <param name="options">Operation options</param>
        /// <returns>Connector object found by the Uid</returns>
        internal ConnectorObject ADSearchByUid(ExchangeConnector connector, Uid uid, ObjectClass oclass, OperationOptions options)
        {
            ExchangeConfiguration configuration = connector.Configuration;

            ExchangeUtility.NullCheck(uid, "uid", configuration);
            ExchangeUtility.NullCheck(oclass, "oclass", configuration);
            if (options == null)
            {
                options = new OperationOptionsBuilder().Build();
            }

            ConnectorObject ret        = null;
            Filter          filter     = FilterBuilder.EqualTo(uid);
            var             translator = connector.ActiveDirectoryConnector.CreateFilterTranslator(oclass, options);
            IList <string>  queries    = translator.Translate(filter);

            if (queries.Count == 1)
            {
                ResultsHandler handler = new ResultsHandler()
                {
                    Handle = cobject =>
                    {
                        ret = cobject;
                        return(false);
                    }
                };
                connector.ActiveDirectoryConnector.ExecuteQuery(oclass, queries[0], handler, options);
            }

            return(ret);
        }
Esempio n. 5
0
        /// <summary>
        /// Gets the Exchange user using powershell Get-User command
        /// </summary>
        /// <param name="cmdInfo">command info to get the user</param>
        /// <param name="attributes">attributes containing the Name</param>
        /// <returns><see cref="PSObject"/> with user info</returns>
        private PSObject GetUser(ExchangeConnector connector, PSExchangeConnector.CommandInfo cmdInfo, Name nameAttribute)
        {
            ExchangeConfiguration configuration = connector.Configuration;
            // assert we have user name
            string name = nameAttribute.GetNameValue();

            ExchangeUtility.NullCheck(name, "User name", configuration);

            ICollection <ConnectorAttribute> attributes = new List <ConnectorAttribute>();

            attributes.Add(nameAttribute);
            Command cmdUser = ExchangeUtility.GetCommand(cmdInfo, attributes, configuration);
            ICollection <PSObject> users = _helper.InvokePipeline(connector, cmdUser);

            if (users.Count == 1)
            {
                foreach (PSObject obj in users)
                {
                    return(obj);
                }
            }

            throw new ArgumentException(
                      configuration.ConnectorMessages.Format(
                          "ex_bad_username", "Provided User name is not unique or not existing"));
        }
        /// <summary>
        /// Implementation of SearchOp.ExecuteQuery
        /// </summary>
        /// <param name="oclass">Object class</param>
        /// <param name="query">Query to execute</param>
        /// <param name="handler">Results handler</param>
        /// <param name="options">Operation options</param>
        public override void ExecuteQuery(
            ObjectClass oclass, string query, ResultsHandler handler, OperationOptions options)
        {
            ExchangeUtility.NullCheck(oclass, "oclass", this.configuration);

            // we handle accounts only
            if (!oclass.Is(ObjectClass.ACCOUNT_NAME))
            {
                base.ExecuteQuery(oclass, query, handler, options);
                return;
            }

            ICollection <string> attsToGet = null;

            if (options != null && options.AttributesToGet != null)
            {
                attsToGet = CollectionUtil.NewList(options.AttributesToGet);
            }

            // delegate to get the exchange attributes if requested
            ResultsHandler filter = delegate(ConnectorObject cobject)
            {
                ConnectorObject filtered = ExchangeUtility.ReplaceAttributes(
                    cobject, attsToGet, AttMapFromAD);
                filtered = this.AddExchangeAttributes(oclass, filtered, attsToGet);
                return(handler(filtered));
            };

            ResultsHandler   handler2use = handler;
            OperationOptions options2use = options;

            if (options != null && options.AttributesToGet != null)
            {
                if (attsToGet.Contains(AttDatabase) || attsToGet.Contains(AttExternalMail) ||
                    attsToGet.Contains(AttRecipientType))
                {
                    // replace Exchange attributes with AD names
                    var newAttsToGet = ExchangeUtility.FilterReplace(attsToGet, AttMap2AD);

                    // we have to remove recipient type, as it is unknown to AD
                    newAttsToGet.Remove(AttRecipientType);

                    // build new op options
                    var      builder         = new OperationOptionsBuilder(options);
                    string[] attributesToGet = new string[newAttsToGet.Count];
                    newAttsToGet.CopyTo(attributesToGet, 0);
                    builder.AttributesToGet = attributesToGet;
                    options2use             = builder.Build();
                    handler2use             = filter;
                }
            }

            base.ExecuteQuery(oclass, query, handler2use, options2use);
        }
        public Uid Update(UpdateType updateType, ObjectClass oclass, Uid uid, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            const string operation = "Update";

            ExchangeUtility.NullCheck(updateType, "updateType", this._configuration);
            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);
            ExchangeUtility.NullCheck(uid, "uid", this._configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this._configuration);

            LOG.Info("Exchange.Update method; oclass = {0}, uid = {1}, type = {2}, attributes:\n{3}", oclass, uid, updateType, CommonUtils.DumpConnectorAttributes(attributes));

            if (attributes == null || attributes.Count == 0)
            {
                LOG.Info("Returning immediately, as there are no attributes to modify.");
                return(uid);
            }

            String database = (String)ExchangeUtility.GetAttValue("Database", attributes);

            LOG.Info("Database attribute before plugins call: " + database);
            plugins.OnBeforeUpdate(oclass, uid, attributes, options, _configuration);
            database = (String)ExchangeUtility.GetAttValue("Database", attributes);
            LOG.Info("Database attribute after plugins call: " + database);

            UpdateOpContext context = new UpdateOpContext()
            {
                UpdateType             = updateType,
                Attributes             = attributes,
                Connector              = this,
                ConnectorConfiguration = this._configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options = options,
                Uid     = uid
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    UpdateMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);

                return(context.Uid);
            } catch (Exception e) {
                LOG.Error(e, "Exception while executing Update operation: {0}");
                throw;
            }
        }
        /// <summary>
        /// Implementation of SynOp.Sync
        /// </summary>
        /// <param name="objClass">Object class</param>
        /// <param name="token">Sync token</param>
        /// <param name="handler">Sync results handler</param>
        /// <param name="options">Operation options</param>
        public override void Sync(
            ObjectClass objClass, SyncToken token, SyncResultsHandler handler, OperationOptions options)
        {
            ExchangeUtility.NullCheck(objClass, "oclass", this.configuration);

            // we handle accounts only
            if (!objClass.Is(ObjectClass.ACCOUNT_NAME))
            {
                base.Sync(objClass, token, handler, options);
                return;
            }

            ICollection <string> attsToGet = null;

            if (options != null && options.AttributesToGet != null)
            {
                attsToGet = CollectionUtil.NewSet(options.AttributesToGet);
            }

            // delegate to get the exchange attributes if requested
            SyncResultsHandler xchangeHandler = delegate(SyncDelta delta)
            {
                if (delta.DeltaType == SyncDeltaType.DELETE)
                {
                    return(handler(delta));
                }

                // replace the ad attributes with exchange one and add recipient type
                ConnectorObject updated = ExchangeUtility.ReplaceAttributes(delta.Object, attsToGet, AttMapFromAD);
                updated = this.AddExchangeAttributes(objClass, updated, attsToGet);
                if (updated != delta.Object)
                {
                    // build new sync delta, cause we changed the object
                    SyncDeltaBuilder deltaBuilder = new SyncDeltaBuilder
                    {
                        DeltaType = delta.DeltaType,
                        Token     = delta.Token,
                        Uid       = delta.Uid,
                        Object    = updated
                    };
                    delta = deltaBuilder.Build();
                }

                return(handler(delta));
            };

            // call AD sync, use xchangeHandler
            base.Sync(objClass, token, xchangeHandler, options);
        }
Esempio n. 9
0
        public Uid Update(UpdateType updateType, ObjectClass oclass, Uid uid, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            const string operation = "Update";

            ExchangeUtility.NullCheck(updateType, "updateType", this._configuration);
            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);
            ExchangeUtility.NullCheck(uid, "uid", this._configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this._configuration);

            LOGGER_API.TraceEvent(TraceEventType.Information, CAT_DEFAULT,
                                  "Exchange.Update method; oclass = {0}, uid = {1}, type = {2}, attributes:\n{3}", oclass, uid, updateType, CommonUtils.DumpConnectorAttributes(attributes));

            if (attributes == null || attributes.Count == 0)
            {
                LOGGER_API.TraceEvent(TraceEventType.Information, CAT_DEFAULT,
                                      "Returning immediately, as there are no attributes to modify.");
                return(uid);
            }

            UpdateOpContext context = new UpdateOpContext()
            {
                UpdateType             = updateType,
                Attributes             = attributes,
                Connector              = this,
                ConnectorConfiguration = this._configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options = options,
                Uid     = uid
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    UpdateMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);

                return(context.Uid);
            } catch (Exception e) {
                LOGGER.TraceEvent(TraceEventType.Error, CAT_DEFAULT, "Exception while executing Update operation: {0}", e);
                throw;
            }
        }
        /// <summary>
        /// Implementation of CreateOp.Create
        /// </summary>
        /// <param name="oclass">Object class</param>
        /// <param name="attributes">Object attributes</param>
        /// <param name="options">Operation options</param>
        /// <returns>Uid of the created object</returns>
        public Uid Create(ObjectClass oclass, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            const string operation = "Create";

            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this._configuration);

            LOG.Info("Exchange.Create method for {0}; attributes:\n{1}", oclass.GetObjectClassValue(), CommonUtils.DumpConnectorAttributes(attributes));

            String database = (String)ExchangeUtility.GetAttValue("Database", attributes);

            LOG.Info("Database attribute before plugins call: " + database);
            plugins.OnBeforeCreate(oclass, attributes, options, _configuration);
            database = (String)ExchangeUtility.GetAttValue("Database", attributes);
            LOG.Info("Database attribute after plugins call: " + database);

            CreateOpContext context = new CreateOpContext()
            {
                Attributes             = attributes,
                Connector              = this,
                ConnectorConfiguration = this._configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options = options
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    CreateMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);

                return(context.Uid);
            } catch (Exception e) {
                LOG.Error(e, "Exception while executing Create operation: {0}");
                throw;
            }
        }
        /// <summary>
        /// Gets the Exchange user using powershell Get-User command
        /// </summary>
        /// <param name="cmdInfo">command info to get the user</param>
        /// <param name="attributes">attributes containing the Name</param>
        /// <returns><see cref="PSObject"/> with user info</returns>
        private PSObject GetUser(PSExchangeConnector.CommandInfo cmdInfo, ICollection <ConnectorAttribute> attributes)
        {
            // assert we have user name
            string name = ExchangeUtility.GetAttValue(Name.NAME, attributes) as string;

            ExchangeUtility.NullCheck(name, "User name", this.configuration);

            Command cmdUser = ExchangeUtility.GetCommand(cmdInfo, attributes, this.configuration);
            ICollection <PSObject> users = this.InvokePipeline(cmdUser);

            if (users.Count == 1)
            {
                foreach (PSObject obj in users)
                {
                    return(obj);
                }
            }

            throw new ArgumentException(
                      this.configuration.ConnectorMessages.Format(
                          "ex_bad_username", "Provided User name is not unique or not existing"));
        }
Esempio n. 12
0
        /// <summary>
        /// Implementation of SearchOp.ExecuteQuery
        /// </summary>
        /// <param name="oclass">Object class</param>
        /// <param name="query">Query to execute</param>
        /// <param name="handler">Results handler</param>
        /// <param name="options">Operation options</param>
        public void ExecuteQuery(ObjectClass oclass, string query, ResultsHandler handler, OperationOptions options)
        {
            const string operation = "ExecuteQuery";

            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);
            if (options == null)
            {
                options = new OperationOptions(new Dictionary <string, object>());
            }

            LOGGER_API.TraceEvent(TraceEventType.Information, CAT_DEFAULT,
                                  "Exchange.ExecuteQuery method; oclass = {0}, query = {1}", oclass, query);

            ExecuteQueryContext context = new ExecuteQueryContext()
            {
                Connector = this,
                ConnectorConfiguration = _configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options        = options,
                Query          = query,
                ResultsHandler = handler
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);
                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    ExecuteQueryMain(context);
                }
                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);
            } catch (Exception e) {
                LOGGER.TraceEvent(TraceEventType.Error, CAT_DEFAULT, "Exception while executing ExecuteQuery operation: {0}", e);
                throw;
            }

            // TODO what about executing a script on each returned item?
        }
Esempio n. 13
0
        /// <summary>
        /// Implementation of CreateOp.Create
        /// </summary>
        /// <param name="oclass">Object class</param>
        /// <param name="attributes">Object attributes</param>
        /// <param name="options">Operation options</param>
        /// <returns>Uid of the created object</returns>
        public Uid Create(ObjectClass oclass, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            const string operation = "Create";

            ExchangeUtility.NullCheck(oclass, "oclass", this._configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this._configuration);

            LOGGER_API.TraceEvent(TraceEventType.Information, CAT_DEFAULT,
                                  "Exchange.Create method for {0}; attributes:\n{1}", oclass.GetObjectClassValue(), CommonUtils.DumpConnectorAttributes(attributes));

            CreateOpContext context = new CreateOpContext()
            {
                Attributes             = attributes,
                Connector              = this,
                ConnectorConfiguration = this._configuration,
                ObjectClass            = oclass,
                OperationName          = operation,
                Options = options
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    CreateMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);

                return(context.Uid);
            } catch (Exception e) {
                LOGGER.TraceEvent(TraceEventType.Error, CAT_DEFAULT, "Exception while executing Create operation: {0}", e);
                throw;
            }
        }
        /// <summary>
        /// Gets Recipient Type/Database from Exchange database, this method can be more general, but it is ok
        /// for out needs
        /// </summary>
        /// <param name="oc">object class, currently the moethod works for <see cref="ObjectClass.ACCOUNT"/> only</param>
        /// <param name="cobject">connector object to get the recipient type/database for</param>
        /// <param name="attToGet">attributes to get</param>
        /// <returns>Connector Object with recipient type added</returns>
        /// <exception cref="ConnectorException">In case of some troubles in powershell (if the
        /// user is not found we get this exception too)</exception>
        private ConnectorObject AddExchangeAttributes(ObjectClass oc, ConnectorObject cobject, IEnumerable <string> attToGet)
        {
            ExchangeUtility.NullCheck(oc, "name", this.configuration);
            ExchangeUtility.NullCheck(oc, "cobject", this.configuration);

            // we support ACCOUNT only or there is nothing to add
            if (!oc.Is(ObjectClass.ACCOUNT_NAME) || attToGet == null)
            {
                return(cobject);
            }

            // check it is not deleted object
            bool?deleted = ExchangeUtility.GetAttValue(AttIsDeleted, cobject.GetAttributes()) as bool?;

            if (deleted != null && deleted == true)
            {
                // do nothing, it is deleted object
                return(cobject);
            }

            ICollection <string> lattToGet = CollectionUtil.NewCaseInsensitiveSet();

            CollectionUtil.AddAll(lattToGet, attToGet);
            foreach (string att in attToGet)
            {
                if (cobject.GetAttributeByName(att) != null && att != AttDatabase)
                {
                    lattToGet.Remove(att);
                }
            }

            if (lattToGet.Count == 0)
            {
                return(cobject);
            }

            ConnectorObjectBuilder cobjBuilder = new ConnectorObjectBuilder();

            cobjBuilder.AddAttributes(cobject.GetAttributes());

            PSExchangeConnector.CommandInfo cmdInfo = PSExchangeConnector.CommandInfo.GetUser;

            // prepare the connector attribute list to get the command
            ICollection <ConnectorAttribute> attributes = new Collection <ConnectorAttribute> {
                cobject.Name
            };

            // get the command
            Command cmd = ExchangeUtility.GetCommand(cmdInfo, attributes, this.configuration);
            ICollection <PSObject> foundObjects = this.InvokePipeline(cmd);
            PSObject user = null;

            if (foundObjects != null && foundObjects.Count == 1)
            {
                user = GetFirstElement(foundObjects);
                foreach (var info in user.Properties)
                {
                    ConnectorAttribute att = GetAsAttribute(info);
                    if (att != null && lattToGet.Contains(att.Name))
                    {
                        cobjBuilder.AddAttribute(att);
                        lattToGet.Remove(att.Name);
                    }
                }

                if (lattToGet.Count == 0)
                {
                    return(cobjBuilder.Build());
                }
            }

            if (user == null)
            {
                // nothing to do
                return(cobject);
            }

            string rcptType = user.Members[AttRecipientType].Value.ToString();

            foundObjects = null;

            // get detailed information
            if (rcptType == RcptTypeMailBox)
            {
                foundObjects = this.InvokePipeline(ExchangeUtility.GetCommand(PSExchangeConnector.CommandInfo.GetMailbox, attributes, this.configuration));
            }
            else if (rcptType == RcptTypeMailUser)
            {
                foundObjects = this.InvokePipeline(ExchangeUtility.GetCommand(PSExchangeConnector.CommandInfo.GetMailUser, attributes, this.configuration));
            }

            if (foundObjects != null && foundObjects.Count == 1)
            {
                PSObject userDetails = GetFirstElement(foundObjects);
                foreach (var info in userDetails.Properties)
                {
                    ConnectorAttribute att = GetAsAttribute(info);
                    if (att != null && lattToGet.Contains(att.Name))
                    {
                        cobjBuilder.AddAttribute(att);
                        lattToGet.Remove(att.Name);
                    }
                }
            }

            return(cobjBuilder.Build());
        }
        /// <summary>
        /// Implementation of UpdateOp.Update
        /// </summary>
        /// <param name="type">Update type</param>
        /// <param name="oclass">Object class</param>
        /// <param name="attributes">Object attributes</param>
        /// <param name="options">Operation options</param>
        /// <returns>Uid of the updated object</returns>
        public override Uid Update(
            UpdateType type,
            ObjectClass oclass,
            ICollection <ConnectorAttribute> attributes,
            OperationOptions options)
        {
            const string METHOD = "Update";

            Debug.WriteLine(METHOD + ":entry", ClassName);

            ExchangeUtility.NullCheck(type, "updatetype", this.configuration);
            ExchangeUtility.NullCheck(oclass, "oclass", this.configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this.configuration);

            // we handle accounts only
            if (!oclass.Is(ObjectClass.ACCOUNT_NAME))
            {
                return(base.Update(type, oclass, attributes, options));
            }

            // get recipient type and database
            string rcptType = ExchangeUtility.GetAttValue(AttRecipientType, attributes) as string;
            string database = ExchangeUtility.GetAttValue(AttDatabase, attributes) as string;

            // update in AD first
            var filtered = FilterOut(
                attributes,
                PSExchangeConnector.CommandInfo.EnableMailbox,
                PSExchangeConnector.CommandInfo.EnableMailUser,
                PSExchangeConnector.CommandInfo.SetMailbox,
                PSExchangeConnector.CommandInfo.SetMailUser);
            Uid uid = base.Update(type, oclass, filtered, options);

            ConnectorObject aduser = this.ADSearchByUid(uid, oclass, ExchangeUtility.AddAttributeToOptions(options, AttDatabaseADName));

            attributes.Add(aduser.Name);
            PSExchangeConnector.CommandInfo cmdInfo = PSExchangeConnector.CommandInfo.GetUser;
            if (aduser.GetAttributeByName(AttDatabaseADName) != null)
            {
                // we can be sure it is user mailbox type
                cmdInfo = PSExchangeConnector.CommandInfo.GetMailbox;
            }

            PSObject psuser       = this.GetUser(cmdInfo, attributes);
            string   origRcptType = psuser.Members[AttRecipientType].Value.ToString();

            if (String.IsNullOrEmpty(rcptType))
            {
                rcptType = origRcptType;
            }

            if (rcptType == RcptTypeMailUser)
            {
                if (type == UpdateType.REPLACE)
                {
                    if (origRcptType != rcptType)
                    {
                        Command cmdEnable = ExchangeUtility.GetCommand(
                            PSExchangeConnector.CommandInfo.EnableMailUser, attributes, this.configuration);
                        this.InvokePipeline(cmdEnable);
                    }

                    Command cmdSet = ExchangeUtility.GetCommand(PSExchangeConnector.CommandInfo.SetMailUser, attributes, this.configuration);
                    this.InvokePipeline(cmdSet);
                }
                else
                {
                    throw new ConnectorException(this.configuration.ConnectorMessages.Format(
                                                     "ex_wrong_update_type", "Update type [{0}] not supported", type));
                }
            }
            else if (rcptType == RcptTypeMailBox)
            {
                // we should execute something like this here:
                // get-user -identity id|?{$_.RecipientType -eq "User"}|enable-mailbox -database "db"
                // unfortunately I was not able to get it working with the pipeline... that's why there are two commands
                // executed :-(
                // alternatively there can be something like:
                // get-user -identity id -RecipientTypeDetails User|enable-mailbox -database "db", but we have then trouble
                // with detecting attempt to change the database attribute
                string origDatabase = psuser.Members[AttDatabase] != null ? psuser.Members[AttDatabase].Value.ToString() : null;
                if (origRcptType != rcptType)
                {
                    Command cmdEnable = ExchangeUtility.GetCommand(PSExchangeConnector.CommandInfo.EnableMailbox, attributes, this.configuration);
                    this.InvokePipeline(cmdEnable);
                }
                else
                {
                    // trying to update the database?
                    if (database != null && database != origDatabase)
                    {
                        throw new ArgumentException(
                                  this.configuration.ConnectorMessages.Format(
                                      "ex_not_updatable", "Update of [{0}] attribute is not supported", AttDatabase));
                    }
                }

                Command cmdSet = ExchangeUtility.GetCommand(PSExchangeConnector.CommandInfo.SetMailbox, attributes, this.configuration);
                this.InvokePipeline(cmdSet);
            }
            else if (rcptType == RcptTypeUser && origRcptType != rcptType)
            {
                throw new ArgumentException(
                          this.configuration.ConnectorMessages.Format(
                              "ex_update_notsupported", "Update of [{0}] to [{1}] is not supported", AttRecipientType, rcptType));
            }
            else if (rcptType != RcptTypeUser)
            {
                // unsupported rcpt type
                throw new ArgumentException(
                          this.configuration.ConnectorMessages.Format(
                              "ex_bad_rcpt", "Recipient type [{0}] is not supported", rcptType));
            }

            Debug.WriteLine(METHOD + ":exit", ClassName);
            return(uid);
        }
        /// <summary>
        /// Implementation of CreateOp.Create
        /// </summary>
        /// <param name="oclass">Object class</param>(oc
        /// <param name="attributes">Object attributes</param>
        /// <param name="options">Operation options</param>
        /// <returns>Uid of the created object</returns>
        public override Uid Create(
            ObjectClass oclass, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            ExchangeUtility.NullCheck(oclass, "oclass", this.configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this.configuration);

            // we handle accounts only
            if (!oclass.Is(ObjectClass.ACCOUNT_NAME))
            {
                return(base.Create(oclass, attributes, options));
            }

            const string METHOD = "Create";

            Debug.WriteLine(METHOD + ":entry", ClassName);

            // get recipient type
            string rcptType = ExchangeUtility.GetAttValue(AttRecipientType, attributes) as string;

            PSExchangeConnector.CommandInfo cmdInfoEnable = null;
            PSExchangeConnector.CommandInfo cmdInfoSet    = null;
            switch (rcptType)
            {
            case RcptTypeMailBox:
                cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailbox;
                cmdInfoSet    = PSExchangeConnector.CommandInfo.SetMailbox;
                break;

            case RcptTypeMailUser:
                cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailUser;
                cmdInfoSet    = PSExchangeConnector.CommandInfo.SetMailUser;
                break;

            case RcptTypeUser:
                break;

            default:
                throw new ArgumentException(
                          this.configuration.ConnectorMessages.Format(
                              "ex_bad_rcpt", "Recipient type [{0}] is not supported", rcptType));
            }

            // first create the object in AD
            Uid uid = base.Create(oclass, FilterOut(attributes, cmdInfoEnable, cmdInfoSet), options);

            if (rcptType == RcptTypeUser)
            {
                // AD account only, we do nothing
                return(uid);
            }

            // prepare the command
            Command cmdEnable = ExchangeUtility.GetCommand(cmdInfoEnable, attributes, this.configuration);
            Command cmdSet    = ExchangeUtility.GetCommand(cmdInfoSet, attributes, this.configuration);

            try
            {
                this.InvokePipeline(cmdEnable);
                this.InvokePipeline(cmdSet);
            }
            catch
            {
                Trace.TraceWarning("Rolling back AD create for UID: " + uid.GetUidValue());

                // rollback AD create
                try
                {
                    Delete(oclass, uid, options);
                }
                catch
                {
                    Trace.TraceWarning("Not able to rollback AD create for UID: " + uid.GetUidValue());

                    // note: this is not perfect, we hide the original exception
                    throw;
                }

                // rethrow original exception
                throw;
            }

            Debug.WriteLine(METHOD + ":exit", ClassName);
            return(uid);
        }