@Override
  public Status pushMessage(PushoverMessage msg) throws PushoverException {

    final HttpPost post = new HttpPost(PUSH_MESSAGE_URL);

    final List<NameValuePair> nvps = new ArrayList<NameValuePair>();

    nvps.add(new BasicNameValuePair("token", msg.getApiToken()));
    nvps.add(new BasicNameValuePair("user", msg.getUserId()));
    nvps.add(new BasicNameValuePair("message", msg.getMessage()));

    addPairIfNotNull(nvps, "title", msg.getTitle());

    addPairIfNotNull(nvps, "url", msg.getUrl());
    addPairIfNotNull(nvps, "url_title", msg.getTitleForURL());

    addPairIfNotNull(nvps, "device", msg.getDevice());
    addPairIfNotNull(nvps, "timestamp", msg.getTimestamp());
    addPairIfNotNull(nvps, "sound", msg.getSound());
    addPairIfNotNull(nvps, "expire", msg.getExpire());
    addPairIfNotNull(nvps, "retry", msg.getRetry());

    if (!MessagePriority.NORMAL.equals(msg.getPriority())) {
      addPairIfNotNull(nvps, "priority", msg.getPriority());
    }

    post.setEntity(new UrlEncodedFormEntity(nvps, Charset.defaultCharset()));

    try {
      HttpResponse response = httpClient.execute(post);
      return PushoverResponseFactory.createStatus(response);
    } catch (Exception e) {
      throw new PushoverException(e.getMessage(), e.getCause());
    }
  }
  @Override
  public Set<PushOverSound> getSounds() throws PushoverException {

    Set<PushOverSound> cachedSounds = SOUND_CACHE.get();
    if (cachedSounds == null) {
      try {
        cachedSounds =
            PushoverResponseFactory.createSoundSet(httpClient.execute(SOUND_LIST_REQUEST));
      } catch (Exception e) {
        throw new PushoverException(e.getMessage(), e.getCause());
      }
      SOUND_CACHE.set(cachedSounds);
    }
    return cachedSounds;
  }