@Override
 public void onPendingIntentChanged(PendingIntent pending) {
   mHandler.removeTargettedMessages(CHANGES_COMPLETE_INTERNAL);
   if (shouldHandleMessage(INTENT_CHANGED)) {
     mPlugin.onPendingIntentChanged(pending);
   } else {
     mHandler.obtainTargettedMessage(INTENT_CHANGED, pending).sendToTarget();
   }
   mHandler.sendTargettedEmptyMessage(CHANGES_COMPLETE_INTERNAL);
 }
 @Override
 public boolean handleMessage(Message msg) {
   switch (msg.what) {
     case CHANGES_COMPLETE_INTERNAL:
       if (!mHandler.hasTargettedMessages(CHANGES_COMPLETE)) {
         mHandler.sendTargettedEmptyMessage(CHANGES_COMPLETE);
       }
       break;
     case SONG_CHANGED:
       mPlugin.onSongChanged((Song) msg.obj);
       break;
     case DURATION_CHANGED:
       mPlugin.onDurationChanged((Integer) msg.obj);
       break;
     case NEXT_TRACK_UNAVAILABLE:
       mPlugin.onNextSongUnavailable();
       break;
     case NEXT_TRACK_AVAILABLE:
       mPlugin.onNextSongAvailable((Song) msg.obj);
       break;
     case ART_CHANGED_URI:
       mPlugin.onAlbumArtChanged((Uri) msg.obj);
       break;
     case ALBUM_CHANGED:
       mPlugin.onAlbumTitleChanged((String) msg.obj);
       break;
     case ARTIST_CHANGED:
       mPlugin.onArtistChanged((String) msg.obj);
       break;
     case TITLE_CHANGED:
       mPlugin.onTitleChanged((String) msg.obj);
       break;
     case PLAYBACK_STOPPED:
       mPlugin.onAudioStopped();
       break;
     case PLAYBACK_STARTED:
       mPlugin.onAudioStarted();
       break;
     case PLAYBACK_RESUMED:
       mPlugin.onAudioResumed();
       break;
     case PLAYBACK_PAUSED:
       mPlugin.onAudioPaused();
       break;
     case AUDIO_LOADING:
       mPlugin.onAudioLoading();
       break;
     case INTENT_CHANGED:
       mPlugin.onPendingIntentChanged((PendingIntent) msg.obj);
       break;
     case SONG_FINISHED:
       mPlugin.onSongFinished((Song) msg.obj, msg.arg1);
       break;
     case PLAYER_HATER_LOADED:
       LoadedObject o = (LoadedObject) msg.obj;
       mPlugin.onPlayerHaterLoaded(o.context, o.playerHater);
       break;
     case TRANSPORT_CONTROL_FLAGS_CHANGED:
       mPlugin.onTransportControlFlagsChanged(msg.arg1);
       break;
     case CHANGES_COMPLETE:
       mPlugin.onChangesComplete();
       break;
     case SERVICE_STOPPING:
       mPlugin.onPlayerHaterShutdown();
       break;
     default:
       return false;
   }
   return true;
 }