diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index d148c0a..7f40494 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -165,8 +165,6 @@
 
     private SensorManager mSensorManager = null;
 
-    private WebStorage.QuotaUpdater mWebStorageQuotaUpdater = null;
-
     // These are single-character shortcuts for searching popular sources.
     private static final int SHORTCUT_INVALID = 0;
     private static final int SHORTCUT_GOOGLE_SEARCH = 1;
@@ -3850,36 +3848,38 @@
         }
 
         /**
-         * The origin has exceeded it's database quota.
+         * The origin has exceeded its database quota.
          * @param url the URL that exceeded the quota
          * @param databaseIdentifier the identifier of the database on
          *     which the transaction that caused the quota overflow was run
          * @param currentQuota the current quota for the origin.
+         * @param totalUsedQuota is the sum of all origins' quota.
          * @param quotaUpdater The callback to run when a decision to allow or
          *     deny quota has been made. Don't forget to call this!
          */
         @Override
         public void onExceededDatabaseQuota(String url,
-            String databaseIdentifier, long currentQuota,
+            String databaseIdentifier, long currentQuota, long totalUsedQuota,
             WebStorage.QuotaUpdater quotaUpdater) {
-            if(LOGV_ENABLED) {
-                Log.v(LOGTAG,
-                      "BrowserActivity received onExceededDatabaseQuota for "
-                      + url +
-                      ":"
-                      + databaseIdentifier +
-                      "(current quota: "
-                      + currentQuota +
-                      ")");
-            }
-            mWebStorageQuotaUpdater = quotaUpdater;
-            String DIALOG_PACKAGE = "com.android.browser";
-            String DIALOG_CLASS = DIALOG_PACKAGE + ".PermissionDialog";
-            Intent intent = new Intent();
-            intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS);
-            intent.putExtra(PermissionDialog.PARAM_ORIGIN, url);
-            intent.putExtra(PermissionDialog.PARAM_QUOTA, currentQuota);
-            startActivityForResult(intent, WEBSTORAGE_QUOTA_DIALOG);
+            mSettings.getWebStorageSizeManager().onExceededDatabaseQuota(
+                    url, databaseIdentifier, currentQuota, totalUsedQuota,
+                    quotaUpdater);
+        }
+
+        /**
+         * The Application Cache has exceeded its max size.
+         * @param spaceNeeded is the amount of disk space that would be needed
+         * in order for the last appcache operation to succeed.
+         * @param totalUsedQuota is the sum of all origins' quota.
+         * @param quotaUpdater A callback to inform the WebCore thread that a new
+         * app cache size is available. This callback must always be executed at
+         * some point to ensure that the sleeping WebCore thread is woken up.
+         */
+        @Override
+        public void onReachedMaxAppCacheSize(long spaceNeeded,
+                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
+            mSettings.getWebStorageSizeManager().onReachedMaxAppCacheSize(
+                    spaceNeeded, totalUsedQuota, quotaUpdater);
         }
 
         /* Adds a JavaScript error message to the system log.
@@ -4616,14 +4616,6 @@
                     }
                 }
                 break;
-            case WEBSTORAGE_QUOTA_DIALOG:
-                long currentQuota = 0;
-                if (resultCode == RESULT_OK && intent != null) {
-                    currentQuota = intent.getLongExtra(
-                        PermissionDialog.PARAM_QUOTA, currentQuota);
-                }
-                mWebStorageQuotaUpdater.updateQuota(currentQuota);
-                break;
             default:
                 break;
         }
@@ -5169,7 +5161,6 @@
     final static int COMBO_PAGE                 = 1;
     final static int DOWNLOAD_PAGE              = 2;
     final static int PREFERENCES_PAGE           = 3;
-    final static int WEBSTORAGE_QUOTA_DIALOG    = 4;
 
     // the frenquency of checking whether system memory is low
     final static int CHECK_MEMORY_INTERVAL = 30000;     // 30 seconds
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index d2371cd..3074d2b 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -25,7 +25,6 @@
 import android.content.SharedPreferences.Editor;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
-import android.os.StatFs;
 import android.webkit.CookieManager;
 import android.webkit.WebView;
 import android.webkit.WebViewDatabase;
@@ -79,6 +78,7 @@
     private boolean appCacheEnabled = true;
     private String appCachePath;  // default value set in loadFromDb().
     private long appCacheMaxSize = Long.MAX_VALUE;
+    private WebStorageSizeManager webStorageSizeManager;
     private boolean domStorageEnabled = true;
     private String jsFlags = "";
 
@@ -238,7 +238,9 @@
         // Set the default value for the Application Caches path.
         appCachePath = ctx.getDir("appcache", 0).getPath();
         // Determine the maximum size of the application cache.
-        appCacheMaxSize = getAppCacheMaxSize();
+        webStorageSizeManager = WebStorageSizeManager.getInstance(appCachePath,
+                ctx);
+        appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
         // Set the default value for the Database path.
         databasePath = ctx.getDir("databases", 0).getPath();
 
@@ -363,6 +365,10 @@
         return jsFlags;
     }
 
+    public WebStorageSizeManager getWebStorageSizeManager() {
+        return webStorageSizeManager;
+    }
+
     public void setHomePage(Context context, String url) {
         Editor ed = PreferenceManager.
                 getDefaultSharedPreferences(context).edit();
@@ -532,6 +538,8 @@
                 true);
         // reset homeUrl
         setHomePage(ctx, getFactoryResetHomeUrl(ctx));
+        // reset appcache max size
+        appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
     }
 
     private String getFactoryResetHomeUrl(Context context) {
@@ -543,35 +551,6 @@
         return url;
     }
 
-    private long getAppCacheMaxSize() {
-        StatFs dataPartition = new StatFs(appCachePath);
-        long freeSpace = dataPartition.getAvailableBlocks()
-            * dataPartition.getBlockSize();
-        long fileSystemSize = dataPartition.getBlockCount()
-            * dataPartition.getBlockSize();
-        return calculateAppCacheMaxSize(fileSystemSize, freeSpace);
-    }
-
-    /*package*/ static long calculateAppCacheMaxSize(long fileSystemSizeBytes,
-            long freeSpaceBytes) {
-        if (fileSystemSizeBytes <= 0
-                || freeSpaceBytes <= 0
-                || freeSpaceBytes > fileSystemSizeBytes) {
-            return 0;
-        }
-
-        long fileSystemSizeRatio =
-            4 << ((int) Math.floor(Math.log10(fileSystemSizeBytes / (1024 * 1024))));
-        long maxSizeBytes = (long) Math.min(Math.floor(fileSystemSizeBytes / fileSystemSizeRatio),
-                Math.floor(freeSpaceBytes / 4));
-        // Round maxSizeBytes up to a multiple of 512KB (except when freeSpaceBytes < 1MB).
-        long maxSizeStepBytes = 512 * 1024;
-        if (freeSpaceBytes < maxSizeStepBytes * 2) {
-            return 0;
-        }
-        return (maxSizeStepBytes * ((maxSizeBytes / maxSizeStepBytes) + 1));
-    }
-
     // Private constructor that does nothing.
     private BrowserSettings() {
     }
diff --git a/src/com/android/browser/PermissionDialog.java b/src/com/android/browser/PermissionDialog.java
deleted file mode 100644
index b71261a..0000000
--- a/src/com/android/browser/PermissionDialog.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.Window;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-/**
- * Permission dialog for HTML5
- * @hide
- */
-public class PermissionDialog extends Activity {
-
-    private static final String TAG = "PermissionDialog";
-    public static final String PARAM_ORIGIN = "origin";
-    public static final String PARAM_QUOTA = "quota";
-
-    private String mWebStorageOrigin;
-    private long mWebStorageQuota = 0;
-    private int mNotification = 0;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        getParameters();
-        setupDialog();
-    }
-
-    private void getParameters() {
-        Intent intent = getIntent();
-        mWebStorageOrigin = intent.getStringExtra(PARAM_ORIGIN);
-        mWebStorageQuota = intent.getLongExtra(PARAM_QUOTA, 0);
-    }
-
-    private void setupDialog() {
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-        setContentView(R.layout.permission_dialog);
-
-        setIcon(R.id.icon, android.R.drawable.ic_popup_disk_full);
-        setText(R.id.dialog_title, R.string.query_storage_quota_prompt);
-        setText(R.id.dialog_message, R.string.query_storage_quota_message);
-        setCharSequence(R.id.origin, mWebStorageOrigin);
-
-        setupButton(R.id.button_allow, R.string.permission_button_allow,
-            new View.OnClickListener() {
-                public void onClick(View v) { allow(); }
-            });
-        setupButton(R.id.button_alwaysdeny, R.string.permission_button_alwaysdeny,
-            new View.OnClickListener() {
-                public void onClick(View v) { alwaysdeny(); }
-            });
-        setupButton(R.id.button_deny, R.string.permission_button_deny,
-            new View.OnClickListener() {
-                public void onClick(View v) { deny(); }
-            });
-    }
-
-    private void setText(int viewID, int stringID) {
-        setCharSequence(viewID, getString(stringID));
-    }
-
-    private void setCharSequence(int viewID, CharSequence string) {
-        View view = findViewById(viewID);
-        if (view == null) {
-            return;
-        }
-        view.setVisibility(View.VISIBLE);
-        TextView textView = (TextView) view;
-        textView.setText(string);
-    }
-
-    private void setIcon(int viewID, int imageID) {
-        View view = findViewById(viewID);
-        if (view == null) {
-            return;
-        }
-        view.setVisibility(View.VISIBLE);
-        ImageView icon = (ImageView) view;
-        icon.setImageResource(imageID);
-    }
-
-    private void setupButton(int viewID, int stringID,
-                             View.OnClickListener listener) {
-        View view = findViewById(viewID);
-        if (view == null) {
-            return;
-        }
-        setText(viewID, stringID);
-        view.setOnClickListener(listener);
-    }
-
-    private void useNextQuota() {
-        CharSequence[] values = getResources().getTextArray(
-            R.array.webstorage_quota_entries_values);
-        for (int i=0; i<values.length; i++) {
-            long value = Long.parseLong(values[i].toString());
-            value *= (1024 * 1024); // the string array is expressed in MB
-            if (value > mWebStorageQuota) {
-                mWebStorageQuota = value;
-                break;
-            }
-        }
-    }
-
-    private void allow() {
-        // If somehow there is no "next quota" in the ladder,
-        // we'll add 1MB anyway.
-        mWebStorageQuota += 1024*1024;
-        useNextQuota();
-        mNotification = R.string.webstorage_notification;
-        closeDialog();
-    }
-
-    private void alwaysdeny() {
-        // Setting the quota to 0 will prevent any new data to be
-        // added, but the existing data will not be deleted.
-        mWebStorageQuota = 0;
-        mNotification = R.string.webstorage_notification;
-        closeDialog();
-    }
-
-    private void deny() {
-        closeDialog();
-    }
-
-    private void closeDialog() {
-        Intent intent = new Intent();
-        intent.putExtra(PARAM_QUOTA, mWebStorageQuota);
-        setResult(RESULT_OK, intent);
-        showToast();
-        finish();
-    }
-
-    private void showToast() {
-        if (mNotification != 0) {
-            Toast toast = Toast.makeText(this, mNotification, Toast.LENGTH_LONG);
-            toast.setGravity(Gravity.BOTTOM, 0, 0);
-            toast.show();
-        }
-    }
-
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
-              && (event.getAction() == KeyEvent.ACTION_DOWN)) {
-            closeDialog();
-            return true; // event consumed
-        }
-        return super.dispatchKeyEvent(event);
-    }
-
-}
diff --git a/src/com/android/browser/WebStorageSizeManager.java b/src/com/android/browser/WebStorageSizeManager.java
new file mode 100644
index 0000000..e524f4c
--- /dev/null
+++ b/src/com/android/browser/WebStorageSizeManager.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.content.Context;
+import android.os.StatFs;
+import android.util.Log;
+import android.webkit.WebStorage;
+
+import java.io.File;
+import java.util.Set;
+
+
+/**
+ * Package level class for managing the disk size consumed by the WebDatabase
+ * and ApplicationCaches APIs (henceforth called Web storage).
+ *
+ * Currently, the situation on the WebKit side is as follows:
+ *  - WebDatabase enforces a quota for each origin.
+ *  - Session/LocalStorage do not enforce any disk limits.
+ *  - ApplicationCaches enforces a maximum size for all origins.
+ *
+ * The WebStorageSizeManager maintains a global limit for the disk space
+ * consumed by the WebDatabase and ApplicationCaches. As soon as WebKit will
+ * have a limit for Session/LocalStorage, this class will manage the space used
+ * by those APIs as well.
+ *
+ * The global limit is computed as a function of the size of the partition where
+ * these APIs store their data (they must store it on the same partition for
+ * this to work) and the size of the available space on that partition.
+ * The global limit is not subject to user configuration but we do provide
+ * a debug-only setting.
+ * TODO(andreip): implement the debug setting.
+ *
+ * The size of the disk space used for Web storage is initially divided between
+ * WebDatabase and ApplicationCaches as follows:
+ *
+ * 75% for WebDatabase
+ * 25% for ApplicationCaches
+ *
+ * When an origin's database usage reaches its current quota, WebKit invokes
+ * the following callback function:
+ * - exceededDatabaseQuota(Frame* frame, const String& database_name);
+ * Note that the default quota for a new origin is 0, so we will receive the
+ * 'exceededDatabaseQuota' callback before a new origin gets the chance to
+ * create its first database.
+ *
+ * When the total ApplicationCaches usage reaches its current quota, WebKit
+ * invokes the following callback function:
+ * - void reachedMaxAppCacheSize(int64_t spaceNeeded);
+ *
+ * The WebStorageSizeManager's main job is to respond to the above two callbacks
+ * by inspecting the amount of unused Web storage quota (i.e. global limit -
+ * sum of all other origins' quota) and deciding if a quota increase for the
+ * out-of-space origin is allowed or not.
+ *
+ * The default quota for an origin is min(ORIGIN_DEFAULT_QUOTA, unused_quota).
+ * Quota increases are done in steps, where the increase step is
+ * min(QUOTA_INCREASE_STEP, unused_quota).
+ *
+ * This approach has the drawback that space may remain unused if there
+ * are many websites that store a lot less content than ORIGIN_DEFAULT_QUOTA.
+ * We deal with this by picking a value for ORIGIN_DEFAULT_QUOTA that is smaller
+ * than what the HTML 5 spec recommends. At the same time, picking a very small
+ * value for ORIGIN_DEFAULT_QUOTA may create performance problems since it's
+ * more likely for origins to have to rollback and restart transactions as a
+ * result of reaching the quota more often.
+ *
+ * When all the Web storage space is used, the WebStorageSizeManager creates
+ * a system notification that will guide the user to the WebSettings UI. There,
+ * the user can free some of the Web storage space by deleting all the data used
+ * by an origin.
+ * TODO(andreip): implement the notification.
+ */
+class WebStorageSizeManager {
+    // Logging flags.
+    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
+    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
+    private final static String LOGTAG = "browser";
+    // The default quota value for an origin.
+    private final static long ORIGIN_DEFAULT_QUOTA = 4 * 1024 * 1024;  // 4MB
+    // The default value for quota increases.
+    private final static long QUOTA_INCREASE_STEP = 2 * 1024 * 1024;  // 2MB
+    // The name of the application cache file. Keep in sync with
+    // WebCore/loader/appcache/ApplicationCacheStorage.cpp
+    private final static String APPCACHE_FILE = "ApplicationCache.db";
+    // The WebStorageSizeManager singleton.
+    private static WebStorageSizeManager mManager;
+    // The application context.
+    private Context mContext;
+    // The global Web storage limit.
+    private long mGlobalLimit;
+    // The maximum size of the application cache file.
+    private long mAppCacheMaxSize;
+
+    /**
+     * Factory method.
+     * @param path is a path on the partition where the app cache data is kept.
+     * @param ctx is the browser application context.
+     * @param storage is the WebStorage singleton.
+     *
+     */
+    public static WebStorageSizeManager getInstance(String appCachePath,
+            Context ctx) {
+       if (mManager == null) {
+           mManager = new WebStorageSizeManager(appCachePath, ctx);
+       }
+       return mManager;
+    }
+
+    /**
+     * Returns the maximum size of the application cache.
+     */
+    public long getAppCacheMaxSize() {
+        return mAppCacheMaxSize;
+    }
+
+    /**
+     * The origin has exceeded its database quota.
+     * @param url the URL that exceeded the quota
+     * @param databaseIdentifier the identifier of the database on
+     *     which the transaction that caused the quota overflow was run
+     * @param currentQuota the current quota for the origin.
+     * @param totalUsedQuota is the sum of all origins' quota.
+     * @param quotaUpdater The callback to run when a decision to allow or
+     *     deny quota has been made. Don't forget to call this!
+     */
+    public void onExceededDatabaseQuota(String url,
+        String databaseIdentifier, long currentQuota, long totalUsedQuota,
+        WebStorage.QuotaUpdater quotaUpdater) {
+        if(LOGV_ENABLED) {
+            Log.v(LOGTAG,
+                  "Received onExceededDatabaseQuota for "
+                  + url
+                  + ":"
+                  + databaseIdentifier
+                  + "(current quota: "
+                  + currentQuota
+                  + ")");
+        }
+        long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize;
+
+        if (totalUnusedQuota < QUOTA_INCREASE_STEP) {
+            // There definitely isn't any more space. Fire notifications
+            // and exit.
+            scheduleOutOfSpaceNotification();
+            quotaUpdater.updateQuota(currentQuota);
+            if(LOGV_ENABLED) {
+                Log.v(LOGTAG, "onExceededDatabaseQuota: out of space.");
+            }
+            return;
+        }
+        // We have enough space inside mGlobalLimit.
+        long newOriginQuota = currentQuota;
+        if (newOriginQuota == 0) {
+            // This is a new origin. It wants an initial quota. It is guaranteed
+            // to get at least ORIGIN_INCREASE_STEP bytes.
+            newOriginQuota =
+                Math.min(ORIGIN_DEFAULT_QUOTA, totalUnusedQuota);
+        } else {
+            // This is an origin we have seen before. It wants a quota
+            // increase.
+            newOriginQuota +=
+                Math.min(QUOTA_INCREASE_STEP, totalUnusedQuota);
+        }
+        quotaUpdater.updateQuota(newOriginQuota);
+
+        if(LOGV_ENABLED) {
+            Log.v(LOGTAG, "onExceededDatabaseQuota set new quota to "
+                    + newOriginQuota);
+        }
+    }
+
+    /**
+     * The Application Cache has exceeded its max size.
+     * @param spaceNeeded is the amount of disk space that would be needed
+     * in order for the last appcache operation to succeed.
+     * @param totalUsedQuota is the sum of all origins' quota.
+     * @param quotaUpdater A callback to inform the WebCore thread that a new
+     * app cache size is available. This callback must always be executed at
+     * some point to ensure that the sleeping WebCore thread is woken up.
+     */
+    public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota,
+            WebStorage.QuotaUpdater quotaUpdater) {
+        if(LOGV_ENABLED) {
+            Log.v(LOGTAG, "Received onReachedMaxAppCacheSize with spaceNeeded "
+                  + spaceNeeded + " bytes.");
+        }
+
+        long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize;
+
+        if (totalUnusedQuota < spaceNeeded) {
+            // There definitely isn't any more space. Fire notifications
+            // and exit.
+            scheduleOutOfSpaceNotification();
+            quotaUpdater.updateQuota(0);
+            if(LOGV_ENABLED) {
+                Log.v(LOGTAG, "onReachedMaxAppCacheSize: out of space.");
+            }
+            return;
+        }
+        // There is enough space to accommodate spaceNeeded bytes.
+        mAppCacheMaxSize += spaceNeeded;
+        quotaUpdater.updateQuota(mAppCacheMaxSize);
+
+        if(LOGV_ENABLED) {
+            Log.v(LOGTAG, "onReachedMaxAppCacheSize set new max size to "
+                    + mAppCacheMaxSize);
+        }
+    }
+
+    // Computes the global limit as a function of the size of the data
+    // partition and the amount of free space on that partition.
+    private long getGlobalLimit(String path) {
+        StatFs dataPartition = new StatFs(path);
+        long freeSpace = dataPartition.getAvailableBlocks()
+            * dataPartition.getBlockSize();
+        long fileSystemSize = dataPartition.getBlockCount()
+            * dataPartition.getBlockSize();
+        return calculateGlobalLimit(fileSystemSize, freeSpace);
+    }
+
+    // Returns the current size (in bytes) of the application cache file.
+    private long getCurrentAppCacheSize(String path) {
+        File file = new File(path + File.separator + APPCACHE_FILE);
+        return file.length();
+    }
+
+    /*package*/ static long calculateGlobalLimit(long fileSystemSizeBytes,
+            long freeSpaceBytes) {
+        if (fileSystemSizeBytes <= 0
+                || freeSpaceBytes <= 0
+                || freeSpaceBytes > fileSystemSizeBytes) {
+            return 0;
+        }
+
+        long fileSystemSizeRatio =
+            2 << ((int) Math.floor(Math.log10(
+                    fileSystemSizeBytes / (1024 * 1024))));
+        long maxSizeBytes = (long) Math.min(Math.floor(
+                fileSystemSizeBytes / fileSystemSizeRatio),
+                Math.floor(freeSpaceBytes / 2));
+        // Round maxSizeBytes up to a multiple of 1024KB (but only if
+        // maxSizeBytes > 1MB).
+        long maxSizeStepBytes = 1024 * 1024;
+        if (maxSizeBytes < maxSizeStepBytes) {
+            return 0;
+        }
+        long roundingExtra = maxSizeBytes % maxSizeStepBytes == 0 ? 0 : 1;
+        return (maxSizeStepBytes
+                * ((maxSizeBytes / maxSizeStepBytes) + roundingExtra));
+    }
+
+    // Schedules a system notification that takes the user to the WebSettings
+    // activity when clicked.
+    private void scheduleOutOfSpaceNotification() {
+        // TODO(andreip): implement.
+    }
+    // Private ctor.
+    private WebStorageSizeManager(String appCachePath, Context ctx) {
+        mContext = ctx;
+        mGlobalLimit = getGlobalLimit(appCachePath);
+        // The initial max size of the app cache is either 25% of the global
+        // limit or the current size of the app cache file, whichever is bigger.
+        mAppCacheMaxSize = Math.max(mGlobalLimit / 4,
+                getCurrentAppCacheSize(appCachePath));
+    }
+}
\ No newline at end of file
