class PushNotificationSubscriptionProcessingServiceImpl implements PushNotificationSubscriptionProcessingService {

    @Override
    public PushNotificationRecipient processPushNotificationSubscriptionChange(@Nonnull final PushNotificationSubscriptionProcessingParameters parameters) {
        Assert.notNull(parameters, "Push notification subscription processing parameters should not be null");
        Assert.notNull(parameters.getUserId(), "User id should not be null");
        Assert.notNull(parameters.getUserMobileDeviceId(), "User device id should not be null");
        Assert.notNull(parameters.getDeviceToken(), "Device token should not be null");
        Assert.notNull(parameters.getApplicationType(), "Application type should not be null");
        Assert.notNull(parameters.getPushNotificationProviderType(), "PushNotificationProviderType should not be null");
        LOGGER.debug("Processing push notification subscription for parameters - {}", parameters);
        final User user = userService.getUserById(parameters.getUserId());
        final UserDevice userDevice = userMobileDeviceService.getUserDeviceById(parameters.getUserMobileDeviceId());
        assertUserDeviceAndUser(user, userDevice);
        final DeviceOperatingSystemType operatingSystemType = userDevice.getOsType();
        final String applicationType = parameters.getApplicationType();
        // Retrieve push notification subscription for user
        final PushNotificationSubscription subscription = getOrCreateSubscriptionForUser(user);
        // Determine current token data to be used
        final Pair<PushNotificationProviderType, String> currentTokenData = determineCurrentNotificationData(
                parameters.getCurrentPushNotificationProviderType(),
                parameters.getCurrentProviderToken(),
                parameters.getPushNotificationProviderType()
        );
        final String oldProviderToken = currentTokenData.getValue();
        // Get user device token processor for provider type
        // Register user device token with provider
        final String newlyRegisteredProviderToken = pushNotificationUserDeviceTokenProcessor.registerUserDeviceToken(
                parameters.getDeviceToken(),
                operatingSystemType,
                applicationType,
                oldProviderToken,
                parameters.getPushNotificationProviderType()
        );
        // Disable all push notification recipients with same token
        disableAllRecipientsWithProviderTokenExceptCurrentSubscriptionIfProvided(subscription, newlyRegisteredProviderToken, parameters.getPushNotificationProviderType(), operatingSystemType, applicationType);
        // Enable or create push notification recipient
        PushNotificationRecipient recipient = getOrCreateRecipientForProviderToken(subscription, newlyRegisteredProviderToken, parameters.getPushNotificationProviderType(), operatingSystemType, applicationType);
        // Update push notification status
        recipient = updatePushNotificationRecipientStatus(recipient, parameters.isSubscribe());
        // Update user device for recipient
        recipient = pushNotificationRecipientService.updatePushNotificationRecipientUserDevice(recipient.getId(), userDevice.getId());
        // Verify and if required disable olf provider token
        verifyAndDisableOldProviderTokenIfRequired(oldProviderToken, newlyRegisteredProviderToken, parameters.getPushNotificationProviderType(), operatingSystemType, applicationType);
        LOGGER.debug("Successfully finalized push notification subscription processing for parameters - {}, processing result recipient - {}", parameters, recipient);
        return recipient;
    }

      PushNotificationSubscriptionProcessingServiceImpl();

}