private synchronized void retrieveMedia() {
    try {
      if (mCurrentState == State.NON_INITIALIZED) {
        mCurrentState = State.INITIALIZING;

        int slashPos = CATALOG_URL.lastIndexOf('/');
        String path = CATALOG_URL.substring(0, slashPos + 1);
        JSONObject jsonObj = fetchJSONFromUrl(CATALOG_URL);
        if (jsonObj == null) {
          return;
        }
        JSONArray tracks = jsonObj.getJSONArray(JSON_MUSIC);
        if (tracks != null) {
          for (int j = 0; j < tracks.length(); j++) {
            MediaMetadata item = buildFromJSON(tracks.getJSONObject(j), path);
            String musicId = item.getString(MediaMetadata.METADATA_KEY_MEDIA_ID);
            mMusicListById.put(musicId, new MutableMediaMetadata(musicId, item));
          }
          buildListsByGenre();
        }
        mCurrentState = State.INITIALIZED;
      }
    } catch (JSONException e) {
      LogHelper.e(TAG, e, "Could not retrieve music list");
    } finally {
      if (mCurrentState != State.INITIALIZED) {
        // Something bad happened, so we reset state to NON_INITIALIZED to allow
        // retries (eg if the network connection is temporary unavailable)
        mCurrentState = State.NON_INITIALIZED;
      }
    }
  }
  public synchronized void updateMusic(String musicId, MediaMetadata metadata) {
    MutableMediaMetadata track = mMusicListById.get(musicId);
    if (track == null) {
      return;
    }

    String oldGenre = track.metadata.getString(MediaMetadata.METADATA_KEY_GENRE);
    String newGenre = metadata.getString(MediaMetadata.METADATA_KEY_GENRE);

    track.metadata = metadata;

    // if genre has changed, we need to rebuild the list by genre
    if (!oldGenre.equals(newGenre)) {
      buildListsByGenre();
    }
  }