/// <summary>
        /// Used by the event processor to update the initial data for the device
        /// without deleting the CommandHistory and the original created date
        /// This assumes the device controls and has full knowledge of its metadata except for:
        /// - CreatedTime
        /// - CommandHistory
        /// </summary>
        /// <param name="device">Device information to save to the backend Device Registry</param>
        /// <returns>Combined device that was saved to registry</returns>
        public async Task <dynamic> UpdateDeviceFromDeviceInfoPacketAsync(dynamic device)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }

            dynamic existingDevice = await GetDeviceAsync(DeviceSchemaHelper.GetDeviceID(device));

            // Save the command history, original created date, and system properties (if any) of the existing device
            if (DeviceSchemaHelper.GetDeviceProperties(existingDevice) != null)
            {
                dynamic deviceProperties = DeviceSchemaHelper.GetDeviceProperties(device);
                deviceProperties.CreatedTime = DeviceSchemaHelper.GetCreatedTime(existingDevice);
            }

            device.CommandHistory = existingDevice.CommandHistory;

            // Copy the existing system properties, or initialize them if they do not exist
            if (existingDevice.SystemProperties != null)
            {
                device.SystemProperties = existingDevice.SystemProperties;
            }
            else
            {
                DeviceSchemaHelper.InitializeSystemProperties(device, null);
            }

            return(await _deviceRegistryCrudRepository.UpdateDeviceAsync(device));
        }
        /// <summary>
        /// Used by the event processor to update the initial data for the device
        /// without deleting the CommandHistory and the original created date
        /// This assumes the device controls and has full knowledge of its metadata except for:
        /// - CreatedTime
        /// - CommandHistory
        /// </summary>
        /// <param name="device">Device information to save to the backend Device Registry</param>
        /// <returns>Combined device that was saved to registry</returns>
        public async Task <dynamic> UpdateDeviceFromDeviceInfoPacketAsync(dynamic device)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }

            // Get original device document
            var     connectionDeviceId = DeviceSchemaHelper.GetConnectionDeviceId(device);
            dynamic existingDevice     = await GetDeviceAsync(connectionDeviceId);

            // Save the command history, original created date, and system properties (if any) of the existing device
            if (DeviceSchemaHelper.GetDeviceProperties(existingDevice) != null)
            {
                dynamic deviceProperties = DeviceSchemaHelper.GetDeviceProperties(device);
                deviceProperties.CreatedTime = DeviceSchemaHelper.GetCreatedTime(existingDevice);
            }

            device.CommandHistory = existingDevice.CommandHistory;

            // Copy the existing system properties, or initialize them if they do not exist
            if (existingDevice.SystemProperties != null)
            {
                device.SystemProperties = existingDevice.SystemProperties;
            }
            else
            {
                DeviceSchemaHelper.InitializeSystemProperties(device, null);
            }

            // Merge device back to existing so we don't drop missing data
            if (existingDevice is JObject)
            {
                //merge union of objects to avoid duplicates
                var MergeSetting = new JsonMergeSettings
                {
                    MergeArrayHandling = MergeArrayHandling.Union
                };

                existingDevice.Merge(device, MergeSetting);
            }

            // If there is Telemetry or Command objects from device, replace instead of merge
            if (device.Telemetry != null)
            {
                existingDevice.Telemetry = device.Telemetry;
            }
            if (device.Commands != null)
            {
                existingDevice.Commands = device.Commands;
            }


            return(await _deviceRegistryCrudRepository.UpdateDeviceAsync(existingDevice));
        }