private async Task RegisterAsync(UserDetails user, DeviceDetails device, string appVersion, bool alreadyLocked = false)
        {
	        try
	        {
		        if (!alreadyLocked)
		        {
			        await _synchroniseLock.WaitAsync();
		        }

		        var isAnonymous = user == null || string.IsNullOrEmpty(user.UserId);

		        _logger.LogInformation("Starting registration for user: {0}",
			        isAnonymous ? "(anonymous)" : user.UserId);

		        var request = new RegistrationDetail
		        {
			        Client = CreateClientDetail(appVersion),
			        Device = await CreateServiceDevice(device),
			        User = user == null
				        ? null
				        : CreateServiceUser(user)
		        };

		        var response = await _publicRegistrationService.RegisterAsync(request);
		        await UpdateUserInContext(user, response.UserId, isAnonymous);

		        await UpdateDeviceInContext(device);
		        _registrationContext.NetworkId = response.NetworkId;

		        _serviceContext.UpdateFromAccessDetail(response.AccessDetails);
		        await _configurationManager.UpdateConfigurationAsync(
			        response.AccessDetails.Configuration.ConfigurationItems,
			        response.AccessDetails.Configuration.ConfigurationSets);

		        _logger.LogInformation("Registered successfully.  NetworkId: {0}",
			        response.NetworkId);

				PublishRegistrationChanged();

		        _logger.LogDebug("New token expiry time: {0}", response.AccessDetails.ExpiresOn);

	        }
	        finally
	        {
		        if (!alreadyLocked)
		        {
					_synchroniseLock.Release();
				}
			}
		}
		public async Task UpdateRegistrationAsync(RegistrationDetail registration)
		{
			await ExecuteAsync<RegistrationDetail, object>("registration", HttpMethod.Put, registration);
		}
		public async Task<RegistrationResult> RegisterAsync(RegistrationDetail registration)
		{
			return await ExecuteAsync<RegistrationDetail, RegistrationResult>("registration", HttpMethod.Post, registration);
		}