NS_IMETHODIMP
sbPlayQueueExternalLibraryListener::OnItemUpdated(sbIMediaList* aMediaList,
                                                  sbIMediaItem* aMediaItem,
                                                  sbIPropertyArray* aProperties,
                                                  PRBool* aNoMoreForBatch)
{
  TRACE(("%s[%p]", __FUNCTION__, this));

  nsresult rv;

  Updates updates;
  sbPropertyUpdate update(aMediaItem, aProperties);
  {
    nsAutoLock lock(mUpdateLock);

    UpdateIter it;
    it = std::find(mUpdates.begin(), mUpdates.end(), update);
    if (it != mUpdates.end()) {
      // This update is already being handled.
      return NS_OK;
    }

    rv = GenerateUpdates(aMediaItem, aProperties, updates);
    NS_ENSURE_SUCCESS(rv, rv);
    if (updates.size() == 0) {
      // No duplicates to update.
      return NS_OK;
    }

    for (it = updates.begin(); it != updates.end(); it++) {
      mUpdates.push_back(*it);
    }
  }

  // Get the updated properties from the item and apply them to the items we
  // need to update.
  nsCOMPtr<sbIPropertyArray> props;
  rv = aMediaItem->GetProperties(aProperties, getter_AddRefs(props));
  NS_ENSURE_SUCCESS(rv, rv);

  for (UpdateIter it = updates.begin(); it != updates.end(); it++) {
    rv = it->mItem->SetProperties(props);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  {
    nsAutoLock lock(mUpdateLock);

    for (UpdateIter it = updates.begin(); it != updates.end(); it++) {
      mUpdates.remove(*it);
    }
  }

  return NS_OK;
}