/**
   * Returns the last jid that the party with the specified <tt>address</tt> contacted us from or
   * <tt>null</tt>(or bare jid) if we don't have a jid for the specified <tt>address</tt> yet. The
   * method would also purge all entries that haven't seen any activity (i.e. no one has tried to
   * get or remap it) for a delay longer than <tt>JID_INACTIVITY_TIMEOUT</tt>.
   *
   * @param jid the <tt>jid</tt> that we'd like to obtain a threadID for.
   * @return the last jid that the party with the specified <tt>address</tt> contacted us from or
   *     <tt>null</tt> if we don't have a jid for the specified <tt>address</tt> yet.
   */
  String getThreadIDForAddress(String jid) {
    synchronized (jids) {
      purgeOldJids();
      StoredThreadID ta = jids.get(jid);

      if (ta == null) return null;

      ta.lastUpdatedTime = System.currentTimeMillis();

      return ta.threadID;
    }
  }
  /**
   * Remove from our <tt>jids</tt> map all entries that have not seen any activity (i.e. neither
   * outgoing nor incoming messags) for more than JID_INACTIVITY_TIMEOUT. Note that this method is
   * not synchronous and that it is only meant for use by the {@link #getThreadIDForAddress(String)}
   * and {@link #putJidForAddress(String, String)}
   */
  private void purgeOldJids() {
    long currentTime = System.currentTimeMillis();

    Iterator<Map.Entry<String, StoredThreadID>> entries = jids.entrySet().iterator();

    while (entries.hasNext()) {
      Map.Entry<String, StoredThreadID> entry = entries.next();
      StoredThreadID target = entry.getValue();

      if (currentTime - target.lastUpdatedTime > JID_INACTIVITY_TIMEOUT) entries.remove();
    }
  }
  /**
   * Maps the specified <tt>address</tt> to <tt>jid</tt>. The point of this method is to allow us to
   * send all messages destined to the contact with the specified <tt>address</tt> to the
   * <tt>jid</tt> that they last contacted us from.
   *
   * @param threadID the threadID of conversation.
   * @param jid the jid (i.e. address/resource) that the contact with the specified <tt>address</tt>
   *     last contacted us from.
   */
  private void putJidForAddress(String jid, String threadID) {
    synchronized (jids) {
      purgeOldJids();

      StoredThreadID ta = jids.get(jid);

      if (ta == null) {
        ta = new StoredThreadID();
        jids.put(jid, ta);
      }

      recentJIDForAddress.put(StringUtils.parseBareAddress(jid), jid);

      ta.lastUpdatedTime = System.currentTimeMillis();
      ta.threadID = threadID;
    }
  }