protected override void OnHandleIntent(Intent intent)
        {
            try
            {
                var context = this.ApplicationContext;
                var action  = intent.Action;

                if (action.Equals(Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK))
                {
                    handleRegistration(context, intent);
                }
                else if (action.Equals(Constants.INTENT_FROM_GCM_MESSAGE))
                {
                    // checks for special messages
                    var messageType = intent.GetStringExtra(Constants.EXTRA_SPECIAL_MESSAGE);
                    if (messageType != null)
                    {
                        if (messageType.Equals(Constants.VALUE_DELETED_MESSAGES))
                        {
                            var sTotal = intent.GetStringExtra(Constants.EXTRA_TOTAL_DELETED);
                            if (!string.IsNullOrEmpty(sTotal))
                            {
                                int nTotal = 0;
                                if (int.TryParse(sTotal, out nTotal))
                                {
                                    Logger.Debug("Received deleted messages notification: " + nTotal);
                                    OnDeletedMessages(context, nTotal);
                                }
                                else
                                {
                                    Logger.Debug("GCM returned invalid number of deleted messages: " + sTotal);
                                }
                            }
                        }
                        else
                        {
                            // application is not using the latest GCM library
                            Logger.Debug("Received unknown special message: " + messageType);
                        }
                    }
                    else
                    {
                        OnMessage(context, intent);
                    }
                }
                else if (action.Equals(Constants.INTENT_FROM_GCM_LIBRARY_RETRY))
                {
                    var token = intent.GetStringExtra(EXTRA_TOKEN);

                    if (!string.IsNullOrEmpty(token) && !TOKEN.Equals(token))
                    {
                        // make sure intent was generated by this class, not by a
                        // malicious app.
                        Logger.Debug("Received invalid token: " + token);
                        return;
                    }

                    // retry last call
                    if (GcmClient.IsRegistered(context))
                    {
                        GcmClient.internalUnRegister(context);
                    }
                    else
                    {
                        GcmClient.internalRegister(context, SenderIds);
                    }
                }
            }
            finally
            {
                // Release the power lock, so phone can get back to sleep.
                // The lock is reference-counted by default, so multiple
                // messages are ok.

                // If OnMessage() needs to spawn a thread or do something else,
                // it should use its own lock.
                lock (LOCK)
                {
                    //Sanity check for null as this is a public method
                    if (sWakeLock != null)
                    {
                        Logger.Debug("Releasing Wakelock");
                        sWakeLock.Release();
                    }
                    else
                    {
                        //Should never happen during normal workflow
                        Logger.Debug("Wakelock reference is null");
                    }
                }
            }
        }
        private void handleRegistration(Context context, Intent intent)
        {
            var registrationId = intent.GetStringExtra(Constants.EXTRA_REGISTRATION_ID);
            var error          = intent.GetStringExtra(Constants.EXTRA_ERROR);
            var unregistered   = intent.GetStringExtra(Constants.EXTRA_UNREGISTERED);

            Logger.Debug("handleRegistration: registrationId = " + registrationId + ", error = " + error + ", unregistered = " + unregistered);

            // registration succeeded
            if (registrationId != null)
            {
                GcmClient.ResetBackoff(context);
                GcmClient.SetRegistrationId(context, registrationId);
                OnRegistered(context, registrationId);
                return;
            }

            // unregistration succeeded
            if (unregistered != null)
            {
                // Remember we are unregistered
                GcmClient.ResetBackoff(context);
                var oldRegistrationId = GcmClient.ClearRegistrationId(context);
                OnUnRegistered(context, oldRegistrationId);
                return;
            }

            // last operation (registration or unregistration) returned an error;
            Logger.Debug("Registration error: " + error);
            // Registration failed
            if (Constants.ERROR_SERVICE_NOT_AVAILABLE.Equals(error))
            {
                var retry = OnRecoverableError(context, error);

                if (retry)
                {
                    int backoffTimeMs = GcmClient.GetBackoff(context);
                    int nextAttempt   = backoffTimeMs / 2 + sRandom.Next(backoffTimeMs);

                    Logger.Debug("Scheduling registration retry, backoff = " + nextAttempt + " (" + backoffTimeMs + ")");

                    var retryIntent = new Intent(Constants.INTENT_FROM_GCM_LIBRARY_RETRY);
                    retryIntent.PutExtra(EXTRA_TOKEN, TOKEN);

                    var retryPendingIntent = PendingIntent.GetBroadcast(context, 0, retryIntent, PendingIntentFlags.OneShot);

                    var am = AlarmManager.FromContext(context);
                    am.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + nextAttempt, retryPendingIntent);

                    // Next retry should wait longer.
                    if (backoffTimeMs < MAX_BACKOFF_MS)
                    {
                        GcmClient.SetBackoff(context, backoffTimeMs * 2);
                    }
                }
                else
                {
                    Logger.Debug("Not retrying failed operation");
                }
            }
            else
            {
                // Unrecoverable error, notify app
                OnError(context, error);
            }
        }