already_AddRefed<nsIApplicationCache>
nsDOMOfflineResourceList::GetDocumentAppCache()
{
  nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
    GetDocumentAppCacheContainer();

  if (appCacheContainer) {
    nsCOMPtr<nsIApplicationCache> applicationCache;
    appCacheContainer->GetApplicationCache(
      getter_AddRefs(applicationCache));
    return applicationCache.forget();
  }

  return nsnull;
}
NS_IMETHODIMP
nsDOMOfflineResourceList::SwapCache()
{
  nsresult rv = Init();
  NS_ENSURE_SUCCESS(rv, rv);

  if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  nsCOMPtr<nsIApplicationCache> currentAppCache = GetDocumentAppCache();
  if (!currentAppCache) {
    return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  // Check the current and potentially newly available cache are not identical.
  if (mAvailableApplicationCache == currentAppCache) {
    return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  if (mAvailableApplicationCache) {
    nsCString currClientId, availClientId;
    currentAppCache->GetClientID(currClientId);
    mAvailableApplicationCache->GetClientID(availClientId);
    if (availClientId == currClientId)
      return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  ClearCachedKeys();

  nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
    GetDocumentAppCacheContainer();

  // In the case of an obsolete cache group, newAppCache might be null.
  // We will disassociate from the cache in that case.
  if (appCacheContainer) {
    rv = appCacheContainer->SetApplicationCache(mAvailableApplicationCache);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  mAvailableApplicationCache = nsnull;
  mStatus = nsIDOMOfflineResourceList::IDLE;

  return NS_OK;
}
NS_IMETHODIMP
nsDOMOfflineResourceList::SwapCache()
{
  nsresult rv = Init();
  NS_ENSURE_SUCCESS(rv, rv);

  if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  nsCOMPtr<nsIApplicationCacheService> serv =
    do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIApplicationCache> currentAppCache = GetDocumentAppCache();

  nsCOMPtr<nsIApplicationCache> newAppCache;
  rv = serv->GetActiveCache(mManifestSpec, getter_AddRefs(newAppCache));
  NS_ENSURE_SUCCESS(rv, rv);

  // In the case of an obsolete cache group, newAppCache might be null.
  // We will disassociate from the cache in that case.

  if (newAppCache == currentAppCache) {
    return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  ClearCachedKeys();

  nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
    GetDocumentAppCacheContainer();

  if (appCacheContainer) {
    rv = appCacheContainer->SetApplicationCache(newAppCache);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}