/// <summary>
        /// Add a device with strongly typed settings (could be usefull in some scenarios)
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public async Task <SIoT.Device> AddDeviceWithTagsAsync(string deviceId, SIoT.DeviceIoTSettings settings)
        {
            TwinJsonConverter converter = new TwinJsonConverter();
            Twin twin = null;

            if (settings != null && settings.Twins != null)
            {
                twin = new Twin(deviceId);

                string jsonTags = JsonConvert.SerializeObject(settings.Twins, new JsonSerializerSettings {
                    NullValueHandling = NullValueHandling.Ignore
                });
                twin.Tags = new TwinCollection(jsonTags);
            }

            BulkRegistryOperationResult result = await _registryManager.AddDeviceWithTwinAsync(new Device(deviceId), twin);

            if (result != null && result.IsSuccessful)
            {
                return(await GetDeviceAsync(deviceId));
            }
            else
            {
                throw new Exception(JsonConvert.SerializeObject(result.Errors, Formatting.Indented));
            }
        }
        /// <summary>
        /// Usefull for updating Twins properties (either tags or desired/reported properties).
        /// This first version does not include desired/reported properties serialization/deserialization but it could be added easily (additional properties in settings classes)
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public async Task <bool> UpdateDeviceSettings(string deviceId, Model.IoT.DeviceIoTSettings options)
        {
            if (string.IsNullOrEmpty(deviceId))
            {
                throw new ArgumentNullException("deviceId");
            }

            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (options.Twins != null && options.Twins.Tags != null)
            {
                try
                {
                    Twin twin = await _registryManager.GetTwinAsync(deviceId);

                    if (twin != null)
                    {
                        string jsonTags = JsonConvert.SerializeObject(options.Twins, new JsonSerializerSettings {
                            NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented
                        });
                        Twin updatedTwin = await _registryManager.UpdateTwinAsync(deviceId, jsonTags, twin.ETag);

                        return(updatedTwin != null);
                    }
                    else
                    {
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                    throw ex;
                }
            }
            else
            {
                return(false);
            }
        }
        public async Task <SIoT.Device> AddDeviceAsync(string deviceId, SIoT.DeviceIoTSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            Device device = await AddDeviceToIoTHubAsync(deviceId);

            bool twinUpdated = await UpdateDeviceSettings(deviceId, settings);

            if (device != null && twinUpdated)
            {
                return(_mapper.Map <SIoT.Device>(device));
            }
            else
            {
                throw new Exception("An error has occurred during the device creation or the twin updates.");
            }
        }