Back out Bug 587797 due to test failures.
authorKyle Huey <khuey@kylehuey.com>
Tue, 03 Jan 2012 11:44:34 -0500
changeset 83696 695adbd228787b43d83d34f3e4cbe605c19ab607
parent 83695 4dd520a2dab09603a51919908379e89bdf0b9226
child 83697 c90dc56f83f0d52b61197b9ae93a5493a1f9f7dd
push id421
push usertim.taubert@gmx.de
push dateThu, 05 Jan 2012 09:22:55 +0000
treeherderfx-team@4795500b7c1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs587797
milestone12.0a1
Back out Bug 587797 due to test failures.
dom/base/nsDOMClassInfo.cpp
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/CheckPermissionsHelper.cpp
dom/indexedDB/CheckPermissionsHelper.h
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/IndexedDatabaseManager.h
dom/indexedDB/Makefile.in
dom/indexedDB/OpenDatabaseHelper.cpp
dom/indexedDB/nsIIndexedDatabaseManager.idl
dom/indexedDB/test/Makefile.in
dom/indexedDB/test/helpers.js
dom/indexedDB/test/test_add_put.html
dom/indexedDB/test/test_add_twice_failure.html
dom/indexedDB/test/test_advance.html
dom/indexedDB/test/test_autoIncrement.html
dom/indexedDB/test/test_autoIncrement_indexes.html
dom/indexedDB/test/test_clear.html
dom/indexedDB/test/test_count.html
dom/indexedDB/test/test_create_index.html
dom/indexedDB/test/test_create_index_with_integer_keys.html
dom/indexedDB/test/test_cursor_mutation.html
dom/indexedDB/test/test_cursor_update_updates_indexes.html
dom/indexedDB/test/test_cursors.html
dom/indexedDB/test/test_event_source.html
dom/indexedDB/test/test_getAll.html
dom/indexedDB/test/test_global_data.html
dom/indexedDB/test/test_index_empty_keyPath.html
dom/indexedDB/test/test_index_getAll.html
dom/indexedDB/test/test_index_getAllObjects.html
dom/indexedDB/test/test_index_object_cursors.html
dom/indexedDB/test/test_index_update_delete.html
dom/indexedDB/test/test_indexes.html
dom/indexedDB/test/test_indexes_bad_values.html
dom/indexedDB/test/test_key_requirements.html
dom/indexedDB/test/test_keys.html
dom/indexedDB/test/test_multientry.html
dom/indexedDB/test/test_objectCursors.html
dom/indexedDB/test/test_objectStore_inline_autoincrement_key_added_on_put.html
dom/indexedDB/test/test_objectStore_remove_values.html
dom/indexedDB/test/test_object_identity.html
dom/indexedDB/test/test_odd_result_order.html
dom/indexedDB/test/test_open_empty_db.html
dom/indexedDB/test/test_open_objectStore.html
dom/indexedDB/test/test_optionalArguments.html
dom/indexedDB/test/test_overlapping_transactions.html
dom/indexedDB/test/test_put_get_values.html
dom/indexedDB/test/test_put_get_values_autoIncrement.html
dom/indexedDB/test/test_remove_index.html
dom/indexedDB/test/test_remove_objectStore.html
dom/indexedDB/test/test_request_readyState.html
dom/indexedDB/test/test_setVersion.html
dom/indexedDB/test/test_setVersion_abort.html
dom/indexedDB/test/test_setVersion_events.html
dom/indexedDB/test/test_setVersion_exclusion.html
dom/indexedDB/test/test_success_events_after_abort.html
dom/indexedDB/test/test_traffic_jam.html
dom/indexedDB/test/test_transaction_abort.html
dom/indexedDB/test/test_transaction_lifetimes.html
dom/indexedDB/test/test_transaction_lifetimes_nested.html
dom/indexedDB/test/test_transaction_ordering.html
dom/indexedDB/test/test_writer_starvation.html
dom/indexedDB/test/unit/Makefile.in
dom/indexedDB/test/unit/head_idb.js
dom/indexedDB/test/unit/test_add_put.js
dom/indexedDB/test/unit/test_add_twice_failure.js
dom/indexedDB/test/unit/test_advance.js
dom/indexedDB/test/unit/test_autoIncrement.js
dom/indexedDB/test/unit/test_autoIncrement_indexes.js
dom/indexedDB/test/unit/test_clear.js
dom/indexedDB/test/unit/test_count.js
dom/indexedDB/test/unit/test_create_index.js
dom/indexedDB/test/unit/test_create_index_with_integer_keys.js
dom/indexedDB/test/unit/test_create_objectStore.js
dom/indexedDB/test/unit/test_cursor_mutation.js
dom/indexedDB/test/unit/test_cursor_update_updates_indexes.js
dom/indexedDB/test/unit/test_cursors.js
dom/indexedDB/test/unit/test_event_source.js
dom/indexedDB/test/unit/test_getAll.js
dom/indexedDB/test/unit/test_global_data.js
dom/indexedDB/test/unit/test_index_empty_keyPath.js
dom/indexedDB/test/unit/test_index_getAll.js
dom/indexedDB/test/unit/test_index_getAllObjects.js
dom/indexedDB/test/unit/test_index_object_cursors.js
dom/indexedDB/test/unit/test_index_update_delete.js
dom/indexedDB/test/unit/test_indexes.js
dom/indexedDB/test/unit/test_indexes_bad_values.js
dom/indexedDB/test/unit/test_key_requirements.js
dom/indexedDB/test/unit/test_keys.js
dom/indexedDB/test/unit/test_multientry.js
dom/indexedDB/test/unit/test_objectCursors.js
dom/indexedDB/test/unit/test_objectStore_inline_autoincrement_key_added_on_put.js
dom/indexedDB/test/unit/test_objectStore_remove_values.js
dom/indexedDB/test/unit/test_object_identity.js
dom/indexedDB/test/unit/test_odd_result_order.js
dom/indexedDB/test/unit/test_open_empty_db.js
dom/indexedDB/test/unit/test_open_objectStore.js
dom/indexedDB/test/unit/test_optionalArguments.js
dom/indexedDB/test/unit/test_overlapping_transactions.js
dom/indexedDB/test/unit/test_put_get_values.js
dom/indexedDB/test/unit/test_put_get_values_autoIncrement.js
dom/indexedDB/test/unit/test_remove_index.js
dom/indexedDB/test/unit/test_remove_objectStore.js
dom/indexedDB/test/unit/test_request_readyState.js
dom/indexedDB/test/unit/test_setVersion.js
dom/indexedDB/test/unit/test_setVersion_abort.js
dom/indexedDB/test/unit/test_setVersion_events.js
dom/indexedDB/test/unit/test_setVersion_exclusion.js
dom/indexedDB/test/unit/test_success_events_after_abort.js
dom/indexedDB/test/unit/test_traffic_jam.js
dom/indexedDB/test/unit/test_transaction_abort.js
dom/indexedDB/test/unit/test_transaction_lifetimes.js
dom/indexedDB/test/unit/test_transaction_lifetimes_nested.js
dom/indexedDB/test/unit/test_transaction_ordering.js
dom/indexedDB/test/unit/test_writer_starvation.js
dom/indexedDB/test/unit/xpcshell.ini
testing/xpcshell/xpcshell.ini
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1509,18 +1509,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(WebSocket, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CloseEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(IDBFactory, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(IDBRequest, nsEventTargetSH,
-                           EVENTTARGET_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(IDBRequest, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBDatabase, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBObjectStore, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBTransaction, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
--- a/dom/indexedDB/AsyncConnectionHelper.cpp
+++ b/dom/indexedDB/AsyncConnectionHelper.cpp
@@ -39,17 +39,16 @@
 
 #include "AsyncConnectionHelper.h"
 
 #include "mozilla/storage.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
-#include "nsWrapperCacheInlines.h"
 
 #include "IDBEvents.h"
 #include "IDBTransaction.h"
 #include "IndexedDatabaseManager.h"
 #include "TransactionThreadPool.h"
 
 USING_INDEXEDDB_NAMESPACE
 
@@ -141,28 +140,21 @@ HelperBase::WrapNative(JSContext* aCx,
                        nsISupports* aNative,
                        jsval* aResult)
 {
   NS_ASSERTION(aCx, "Null context!");
   NS_ASSERTION(aNative, "Null pointer!");
   NS_ASSERTION(aResult, "Null pointer!");
   NS_ASSERTION(mRequest, "Null request!");
 
-  JSObject* obj;
-  if (mRequest->ScriptContext()) {
-    obj = mRequest->ScriptContext()->GetNativeGlobal();
-  }
-  else {
-    obj = mRequest->GetWrapper();
-  }
-
-  NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+  JSObject* global = mRequest->ScriptContext()->GetNativeGlobal();
+  NS_ENSURE_TRUE(global, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsresult rv =
-    nsContentUtils::WrapNative(aCx, obj, aNative, aResult);
+    nsContentUtils::WrapNative(aCx, global, aNative, aResult);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   return NS_OK;
 }
 
 void
 HelperBase::ReleaseMainThreadObjects()
 {
--- a/dom/indexedDB/CheckPermissionsHelper.cpp
+++ b/dom/indexedDB/CheckPermissionsHelper.cpp
@@ -72,21 +72,16 @@ GetIndexedDBPermissions(const nsACString
                         nsIDOMWindow* aWindow)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!Preferences::GetBool(PREF_INDEXEDDB_ENABLED)) {
     return nsIPermissionManager::DENY_ACTION;
   }
 
-  // No window here means chrome access
-  if (!aWindow) {
-    return nsIPermissionManager::ALLOW_ACTION;
-  }
-
   nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aWindow));
   NS_ENSURE_TRUE(sop, nsIPermissionManager::DENY_ACTION);
 
   if (nsContentUtils::IsSystemPrincipal(sop->GetPrincipal())) {
     return nsIPermissionManager::ALLOW_ACTION;
   }
 
   if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode()) {
--- a/dom/indexedDB/CheckPermissionsHelper.h
+++ b/dom/indexedDB/CheckPermissionsHelper.h
@@ -71,16 +71,17 @@ public:
     mASCIIOrigin(aASCIIOrigin),
     // If we're trying to delete the database, we should never prompt the user.
     // Anything that would prompt is translated to denied.
     mPromptAllowed(!aForDeletion),
     mHasPrompted(false),
     mPromptResult(0)
   {
     NS_ASSERTION(aHelper, "Null pointer!");
+    NS_ASSERTION(aWindow, "Null pointer!");
     NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty origin!");
   }
 
 private:
   nsRefPtr<OpenDatabaseHelper> mHelper;
   nsCOMPtr<nsIDOMWindow> mWindow;
   nsCString mASCIIOrigin;
   bool mPromptAllowed;
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -710,20 +710,16 @@ IDBDatabase::GetOnversionchange(nsIDOMEv
                                aVersionChangeListener);
 }
 
 nsresult
 IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
 
-  if (!mOwner) {
-    return NS_OK;
-  }
-
   if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) {
     nsString type;
     nsresult rv = aVisitor.mDOMEvent->GetType(type);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (type.EqualsLiteral(ERROR_EVT_STR)) {
       nsRefPtr<nsDOMEvent> duplicateEvent =
         CreateGenericEvent(type, eDoesNotBubble, eNotCancelable);
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -101,30 +101,29 @@ public:
 
   const nsString& FilePath()
   {
     return mFilePath;
   }
 
   nsIScriptContext* ScriptContext()
   {
+    NS_ASSERTION(mScriptContext, "This should never be null!");
     return mScriptContext;
   }
 
   nsPIDOMWindow* Owner()
   {
+    NS_ASSERTION(mOwner, "This should never be null!");
     return mOwner;
   }
 
   already_AddRefed<nsIDocument> GetOwnerDocument()
   {
-    if (!mOwner) {
-      return nsnull;
-    }
-
+    NS_ASSERTION(mOwner, "This should never be null!");
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mOwner->GetExtantDocument());
     return doc.forget();
   }
 
   nsCString& Origin()
   {
     return mASCIIOrigin;
   }
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -96,28 +96,27 @@ IDBFactory::IDBFactory()
   IDBFactory::NoteUsedByProcessType(XRE_GetProcessType());
 }
 
 // static
 already_AddRefed<nsIIDBFactory>
 IDBFactory::Create(nsPIDOMWindow* aWindow)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(aWindow, "Must have a window!");
 
-  if (aWindow && aWindow->IsOuterWindow()) {
+  if (aWindow->IsOuterWindow()) {
     aWindow = aWindow->GetCurrentInnerWindow();
-    NS_ENSURE_TRUE(aWindow, nsnull);
   }
+  NS_ENSURE_TRUE(aWindow, nsnull);
 
   nsRefPtr<IDBFactory> factory = new IDBFactory();
 
-  if (aWindow) {
-    factory->mWindow = do_GetWeakReference(aWindow);
-    NS_ENSURE_TRUE(factory->mWindow, nsnull);
-  }
+  factory->mWindow = do_GetWeakReference(aWindow);
+  NS_ENSURE_TRUE(factory->mWindow, nsnull);
 
   return factory.forget();
 }
 
 // static
 already_AddRefed<mozIStorageConnection>
 IDBFactory::GetConnection(const nsAString& aDatabaseFilePath)
 {
@@ -423,30 +422,24 @@ IDBFactory::OpenCommon(const nsAString& 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     // Force ContentChild to cache the path from the parent, so that
     // we do not end up in a side thread that asks for the path (which
     // would make ContentChild try to send a message in a thread other
     // than the main one).
     ContentChild::GetSingleton()->GetIndexedDBPath();
   }
 
-  nsCOMPtr<nsPIDOMWindow> window;
-  nsCOMPtr<nsIScriptGlobalObject> sgo;
-  nsIScriptContext* context = nsnull;
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_TRUE(window, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
-  if (mWindow) {
-    window = do_QueryReferent(mWindow);
-    NS_ENSURE_TRUE(window, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-    
-    sgo = do_QueryInterface(window);
-    NS_ENSURE_TRUE(sgo, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-    
-    context = sgo->GetContext();
-    NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-  }
+  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(window);
+  NS_ENSURE_TRUE(sgo, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+  nsIScriptContext* context = sgo->GetContext();
+  NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsCString origin;
   nsresult rv =
     IndexedDatabaseManager::GetASCIIOriginFromWindow(window, origin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<IDBOpenDBRequest> request =
     IDBOpenDBRequest::Create(context, window);
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -35,32 +35,31 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IDBRequest.h"
 
-#include "nsIJSContextStack.h"
 #include "nsIScriptContext.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsStringGlue.h"
 #include "nsThreadUtils.h"
-#include "nsWrapperCacheInlines.h"
 
 #include "AsyncConnectionHelper.h"
 #include "IDBEvents.h"
 #include "IDBTransaction.h"
+#include "nsContentUtils.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 IDBRequest::IDBRequest()
 : mResultVal(JSVAL_VOID),
   mErrorCode(0),
   mResultValRooted(false),
   mHaveResultOrErrorCode(false)
@@ -83,16 +82,22 @@ IDBRequest::~IDBRequest()
 // static
 already_AddRefed<IDBRequest>
 IDBRequest::Create(nsISupports* aSource,
                    nsIScriptContext* aScriptContext,
                    nsPIDOMWindow* aOwner,
                    IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  if (!aScriptContext || !aOwner) {
+    NS_ERROR("Null context and owner!");
+    return nsnull;
+  }
+
   nsRefPtr<IDBRequest> request(new IDBRequest());
 
   request->mSource = aSource;
   request->mTransaction = aTransaction;
   request->mScriptContext = aScriptContext;
   request->mOwner = aOwner;
 
   return request.forget();
@@ -130,39 +135,25 @@ IDBRequest::NotifyHelperCompleted(Helper
 
   // If the request failed then set the error code and return.
   if (NS_FAILED(rv)) {
     mErrorCode = NS_ERROR_GET_CODE(rv);
     return NS_OK;
   }
 
   // Otherwise we need to get the result from the helper.
-  JSContext* cx = nsnull;
-  JSObject* obj = nsnull;
-  if (mScriptContext) {   
-    cx = mScriptContext->GetNativeContext();
-    NS_ASSERTION(cx, "Failed to get a context!");
+  JSContext* cx = mScriptContext->GetNativeContext();
+  NS_ASSERTION(cx, "Failed to get a context!");
 
-    obj = mScriptContext->GetNativeGlobal();
-    NS_ASSERTION(obj, "Failed to get global object!");
-  } 
-  else {
-    nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
-    NS_ASSERTION(cxStack, "Failed to get thread context stack!");
-
-    NS_ENSURE_SUCCESS(cxStack->GetSafeJSContext(&cx),
-                      NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-
-    obj = GetWrapper();
-    NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
-  }
+  JSObject* global = mScriptContext->GetNativeGlobal();
+  NS_ASSERTION(global, "Failed to get global object!");
 
   JSAutoRequest ar(cx);
   JSAutoEnterCompartment ac;
-  if (!ac.enter(cx, obj)) {
+  if (!ac.enter(cx, global)) {
     rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
   else {
     RootResultVal();
 
     rv = aHelper->GetSuccessResult(cx, &mResultVal);
     if (NS_SUCCEEDED(rv)) {
       // Unroot if we don't really need to be rooted.
@@ -294,52 +285,51 @@ IDBRequest::GetOnerror(nsIDOMEventListen
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return GetInnerEventListener(mOnErrorListener, aErrorListener);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest,
-                                                  nsDOMEventTargetWrapperCache)
+                                                  nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
                                                        nsPIDOMEventTarget)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest,
-                                                nsDOMEventTargetWrapperCache)
+                                                nsDOMEventTargetHelper)
   if (tmp->mResultValRooted) {
     tmp->mResultVal = JSVAL_VOID;
     tmp->UnrootResultVal();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest,
-                                               nsDOMEventTargetWrapperCache)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBRequest)
   if (JSVAL_IS_GCTHING(tmp->mResultVal)) {
     void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal);
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResultVal")
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
   NS_INTERFACE_MAP_ENTRY(nsIIDBRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
-NS_IMPL_ADDREF_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
-NS_IMPL_RELEASE_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
+NS_IMPL_ADDREF_INHERITED(IDBRequest, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(IDBRequest, nsDOMEventTargetHelper)
 
 DOMCI_DATA(IDBRequest, IDBRequest)
 
 nsresult
 IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
@@ -358,16 +348,22 @@ IDBOpenDBRequest::~IDBOpenDBRequest()
 }
 
 // static
 already_AddRefed<IDBOpenDBRequest>
 IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext,
                          nsPIDOMWindow* aOwner)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  if (!aScriptContext || !aOwner) {
+    NS_ERROR("Null context and owner!");
+    return nsnull;
+  }
+
   nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
 
   request->mScriptContext = aScriptContext;
   request->mOwner = aOwner;
 
   return request.forget();
 }
 
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -52,24 +52,24 @@
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class HelperBase;
 class IDBTransaction;
 
-class IDBRequest : public nsDOMEventTargetWrapperCache,
+class IDBRequest : public nsDOMEventTargetHelper,
                    public nsIIDBRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIIDBREQUEST
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
-                                                         nsDOMEventTargetWrapperCache)
+                                                         nsDOMEventTargetHelper)
 
   static
   already_AddRefed<IDBRequest> Create(nsISupports* aSource,
                                       nsIScriptContext* aScriptContext,
                                       nsPIDOMWindow* aOwner,
                                       IDBTransaction* aTransaction);
 
   // nsIDOMEventTarget
@@ -89,21 +89,23 @@ public:
     NS_ASSERTION(NS_FAILED(rv), "Er, what?");
     NS_ASSERTION(mErrorCode == NS_OK, "Already have an error?");
 
     mErrorCode = rv;
   }
 
   nsIScriptContext* ScriptContext()
   {
+    NS_ASSERTION(mScriptContext, "This should never be null!");
     return mScriptContext;
   }
 
   nsPIDOMWindow* Owner()
   {
+    NS_ASSERTION(mOwner, "This should never be null!");
     return mOwner;
   }
 
   virtual void RootResultVal();
   virtual void UnrootResultVal();
 
 protected:
   IDBRequest();
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -35,17 +35,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IndexedDatabaseManager.h"
 #include "DatabaseInfo.h"
 
-#include "nsIDOMScriptObjectFactory.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISHEntry.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 
@@ -59,17 +58,16 @@
 #include "test_quota.h"
 #include "xpcpublic.h"
 
 #include "AsyncConnectionHelper.h"
 #include "CheckQuotaHelper.h"
 #include "IDBDatabase.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
-#include "IDBKeyRange.h"
 #include "LazyIdleThread.h"
 #include "OpenDatabaseHelper.h"
 #include "TransactionThreadPool.h"
 
 // The amount of time, in milliseconds, that our IO thread will stay alive
 // after the last event it processes.
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 
@@ -82,18 +80,16 @@
 
 // Preference that users can set to override DEFAULT_QUOTA_MB
 #define PREF_INDEXEDDB_QUOTA "dom.indexedDB.warningQuota"
 
 USING_INDEXEDDB_NAMESPACE
 using namespace mozilla::services;
 using mozilla::Preferences;
 
-static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
-
 namespace {
 
 PRInt32 gShutdown = 0;
 PRInt32 gClosed = 0;
 
 // Does not hold a reference.
 IndexedDatabaseManager* gInstance = nsnull;
 
@@ -604,20 +600,20 @@ IndexedDatabaseManager::SetCurrentWindow
   if (aWindow) {
 #ifdef DEBUG
     NS_ASSERTION(!PR_GetThreadPrivate(mCurrentWindowIndex),
                  "Somebody forgot to clear the current window!");
 #endif
     PR_SetThreadPrivate(mCurrentWindowIndex, aWindow);
   }
   else {
-    // We cannot assert PR_GetThreadPrivate(mCurrentWindowIndex) here
-    // because we cannot distinguish between the thread private became
-    // null and that it was set to null on the first place, 
-    // because we didn't have a window.
+#ifdef DEBUG
+    NS_ASSERTION(PR_GetThreadPrivate(mCurrentWindowIndex),
+               "Somebody forgot to clear the current window!");
+#endif
     PR_SetThreadPrivate(mCurrentWindowIndex, nsnull);
   }
 }
 
 // static
 PRUint32
 IndexedDatabaseManager::GetIndexedDBQuotaMB()
 {
@@ -889,23 +885,16 @@ IndexedDatabaseManager::CancelPromptsFor
 // static
 nsresult
 IndexedDatabaseManager::GetASCIIOriginFromWindow(nsPIDOMWindow* aWindow,
                                                  nsCString& aASCIIOrigin)
 {
   NS_ASSERTION(NS_IsMainThread(),
                "We're about to touch a window off the main thread!");
 
-  if (!aWindow) {
-    aASCIIOrigin.AssignLiteral("chrome");
-    NS_ASSERTION(nsContentUtils::IsCallerChrome(), 
-                 "Null window but not chrome!");
-    return NS_OK;
-  }
-
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
   NS_ENSURE_TRUE(sop, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
   NS_ENSURE_TRUE(principal, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   if (nsContentUtils::IsSystemPrincipal(principal)) {
     aASCIIOrigin.AssignLiteral("chrome");
@@ -1594,58 +1583,16 @@ IndexedDatabaseManager::SynchronizedOp::
   PRUint32 count = mDelayedRunnables.Length();
   for (PRUint32 index = 0; index < count; index++) {
     NS_DispatchToCurrentThread(mDelayedRunnables[index]);
   }
 
   mDelayedRunnables.Clear();
 }
 
-NS_IMETHODIMP
-IndexedDatabaseManager::InitWindowless(const jsval& aObj, JSContext* aCx)
-{
-  NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
-  
-  // Instantiating this class will register exception providers so even 
-  // in xpcshell we will get typed (dom) exceptions, instead of general exceptions.
-  nsCOMPtr<nsIDOMScriptObjectFactory> sof(do_GetService(kDOMSOF_CID));
-
-  // Defining IDBKeyrange static functions on the global.
-  if (JSVAL_IS_PRIMITIVE(aObj)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsCOMPtr<nsIIDBFactory> factory = IDBFactory::Create(nsnull);
-  NS_ASSERTION(factory, "IDBFactory should not be null.");
-
-  JSObject* obj = JSVAL_TO_OBJECT(aObj);
-  jsval mozIndexedDBVal;
-  nsresult rv = nsContentUtils::WrapNative(aCx, obj, factory, &mozIndexedDBVal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, 
-      nsnull, nsnull, JSPROP_ENUMERATE)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSObject* keyrangeObj = JS_NewObject(aCx, nsnull, nsnull, nsnull);
-  NS_ENSURE_TRUE(keyrangeObj, NS_ERROR_OUT_OF_MEMORY);
-    
-  if (!IDBKeyRange::DefineConstructors(aCx, keyrangeObj)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (!JS_DefineProperty(aCx, obj, "IDBKeyRange", OBJECT_TO_JSVAL(keyrangeObj),
-                         nsnull, nsnull, JSPROP_ENUMERATE)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
 NS_IMPL_THREADSAFE_ISUPPORTS1(IndexedDatabaseManager::AsyncDeleteFileRunnable,
                               nsIRunnable)
 
 NS_IMETHODIMP
 IndexedDatabaseManager::AsyncDeleteFileRunnable::Run()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
 
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -390,16 +390,17 @@ private:
   mozilla::Mutex mFileMutex;
 };
 
 class AutoEnterWindow
 {
 public:
   AutoEnterWindow(nsPIDOMWindow* aWindow)
   {
+    NS_ASSERTION(aWindow, "This should never be null!");
     IndexedDatabaseManager::SetCurrentWindow(aWindow);
   }
 
   ~AutoEnterWindow()
   {
     IndexedDatabaseManager::SetCurrentWindow(nsnull);
   }
 };
--- a/dom/indexedDB/Makefile.in
+++ b/dom/indexedDB/Makefile.in
@@ -94,17 +94,16 @@ EXPORTS_mozilla/dom/indexedDB = \
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/db/sqlite3/src \
   -I$(topsrcdir)/xpcom/build \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/src/storage \
   -I$(topsrcdir)/content/base/src \
   -I$(topsrcdir)/content/events/src \
-  -I$(topsrcdir)/js/xpconnect/src \
   $(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
 
 # Make sure to quickstub as much as possible here! See
 # js/xpconnect/src/dom_quickstubs.qsconf.
 XPIDLSRCS = \
   nsIIDBCursor.idl \
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1606,17 +1606,20 @@ OpenDatabaseHelper::DoDatabaseWork()
   mState = eFiringEvents; // In case we fail somewhere along the line.
 
   if (IndexedDatabaseManager::IsShuttingDown()) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   NS_ASSERTION(mOpenDBRequest, "This should never be null!");
 
+  // Once we support IDB outside of Windows this assertion will no longer hold.
   nsPIDOMWindow* window = mOpenDBRequest->Owner();
+  NS_ASSERTION(window, "This should never be null");
+
   AutoEnterWindow autoWindow(window);
 
   nsCOMPtr<nsIFile> dbDirectory;
 
   IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
   NS_ASSERTION(mgr, "This should never be null!");
 
   nsresult rv = mgr->EnsureOriginIsInitialized(mASCIIOrigin,
--- a/dom/indexedDB/nsIIndexedDatabaseManager.idl
+++ b/dom/indexedDB/nsIIndexedDatabaseManager.idl
@@ -47,17 +47,17 @@ interface nsIIndexedDatabaseUsageCallbac
   /**
    *
    */
   void onUsageResult(in nsIURI aURI,
                      in unsigned long long aUsage,
                      in unsigned long long aFileUsage);
 };
 
-[scriptable, builtinclass, uuid(02256aa7-70d8-473f-bf3b-8cb35d28fd75)]
+[scriptable, builtinclass, uuid(415f5684-6c84-4a8b-b777-d01f5df778f2)]
 interface nsIIndexedDatabaseManager : nsISupports
 {
   /**
    * Schedules an asynchronous callback that will return the total amount of
    * disk space being used by databases for the given origin.
    *
    * @param aURI
    *        The URI whose usage is being queried.
@@ -83,19 +83,9 @@ interface nsIIndexedDatabaseManager : ns
   /**
    * Removes all databases stored for the given URI. The files may not be
    * deleted immediately depending on prohibitive concurrent operations.
    *
    * @param aURI
    *        The URI whose databases are to be cleared.
    */
   void clearDatabasesForURI(in nsIURI aURI);
-
-  /**
-   * Defines mozIndexedDB and IDBKeyrange with its static functions on 
-   * aObject and initializes DOM exception providers if needed.
-   *
-   * @param aObject
-   *        The object, mozIndexedDB and IDBKeyrange should be defined on.
-   */
-  [implicit_jscontext]
-  void initWindowless(in jsval aObject);
 };
--- a/dom/indexedDB/test/Makefile.in
+++ b/dom/indexedDB/test/Makefile.in
@@ -35,25 +35,20 @@
 #
 # ***** END LICENSE BLOCK *****
 
 DEPTH = ../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 relativesrcdir = dom/indexedDB/test
-DIRS += unit
 
 include $(DEPTH)/config/autoconf.mk
-
-XPCSHELL_TESTS = unit
-
 include $(topsrcdir)/config/rules.mk
 
-
 TEST_FILES = \
   bfcache_iframe1.html \
   bfcache_iframe2.html \
   error_events_abort_transactions_iframe.html \
   event_propagation_iframe.html \
   exceptions_in_success_events_iframe.html \
   file.js \
   helpers.js \
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -1,20 +1,15 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var testGenerator = testSteps();
 
-function executeSoon(aFun)
-{
-  SimpleTest.executeSoon(aFun);
-}
-
 function runTest()
 {
   allowIndexedDB();
   allowUnlimitedQuota();
 
   SimpleTest.waitForExplicitFinish();
   testGenerator.next();
 }
--- a/dom/indexedDB/test/test_add_put.html
+++ b/dom/indexedDB/test/test_add_put.html
@@ -4,15 +4,173 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_add_put.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      let openRequest = mozIndexedDB.open(name, 1);
+      openRequest.onerror = errorHandler;
+      openRequest.onupgradeneeded = grabEventAndContinueHandler;
+      openRequest.onsuccess = unexpectedSuccessHandler;
+      let event = yield;
+      let db = event.target.result;
+      let trans = event.target.transaction;
+
+      for each (let autoincrement in [true, false]) {
+        for each (let keypath in [false, true, "missing", "invalid"]) {
+          for each (let method in ["put", "add"]) {
+            for each (let explicit in [true, false, undefined, "invalid"]) {
+              for each (let existing in [true, false]) {
+                let speccedNoKey = (keypath == false || keypath == "missing") &&
+                                   !explicit;
+
+                // We can't do 'existing' checks if we use autogenerated key
+                if (speccedNoKey && autoincrement && existing) {
+                  continue;
+                }
+
+                // Create store
+                if (db.objectStoreNames.contains("mystore"))
+                  db.deleteObjectStore("mystore");
+                let store = db.createObjectStore("mystore",
+                                                 { autoIncrement: autoincrement,
+                                                   keyPath: (keypath ? "id" : null) });
+
+                test = " for test " + JSON.stringify({ autoincrement: autoincrement,
+                                                       keypath: keypath,
+                                                       method: method,
+                                                       explicit: explicit === undefined ? "undefined" : explicit,
+                                                       existing: existing });
+
+                // Insert "existing" data if needed
+                if (existing) {
+                  if (keypath)
+                    store.add({ existing: "data", id: 5 }).onsuccess = grabEventAndContinueHandler;
+                  else
+                    store.add({ existing: "data" }, 5).onsuccess = grabEventAndContinueHandler;
+
+                  let e = yield;
+                  is(e.type, "success", "success inserting existing" + test);
+                  is(e.target.result, 5, "inserted correct key" + test);
+                }
+
+                // Set up value to be inserted
+                let value = { theObj: true };
+                if (keypath === true) {
+                  value.id = 5;
+                }
+                else if (keypath === "invalid") {
+                  value.id = /x/;
+                }
+
+                // Which arguments are passed to function
+                args = [value];
+                if (explicit === true) {
+                  args.push(5);
+                }
+                else if (explicit === undefined) {
+                  args.push(undefined);
+                }
+                else if (explicit === "invalid") {
+                  args.push(/x/);
+                }
+
+                let expected = expectedResult(method, keypath, explicit, autoincrement, existing);
+
+                let valueJSON = JSON.stringify(value);
+
+                ok(true, "making call" + test);
+
+                // Make function call for throwing functions
+                if (expected === "throw") {
+                  try {
+                    store[method].apply(store, args);
+                    ok(false, "should have thrown" + test);
+                  }
+                  catch (ex) {
+                    ok(true, "did throw" + test);
+                    ok(ex instanceof IDBDatabaseException, "Got a IDBDatabaseException" + test);
+                    is(ex.code, IDBDatabaseException.DATA_ERR, "expect a DATA_ERR" + test);
+                    is(JSON.stringify(value), valueJSON, "call didn't modify value" + test);
+                  }
+                  continue;
+                }
+
+                // Make non-throwing function call
+                let req = store[method].apply(store, args);
+                is(JSON.stringify(value), valueJSON, "call didn't modify value" + test);
+
+                req.onsuccess = req.onerror = grabEventAndContinueHandler;
+                let e = yield;
+
+                // Figure out what key we used
+                let key = 5;
+                if (autoincrement && speccedNoKey) {
+                  key = 1;
+                }
+
+                // Adjust value if expected
+                if (autoincrement && keypath && speccedNoKey) {
+                  value.id = key;
+                }
+
+                // Check result
+                if (expected === "error") {
+                  is(e.type, "error", "write should fail" + test);
+                  e.preventDefault();
+                  e.stopPropagation();
+                  continue;
+                }
+
+                is(e.type, "success", "write should succeed" + test);
+                is(e.target.result, key, "write should return correct key" + test);
+
+                store.get(key).onsuccess = grabEventAndContinueHandler;
+                e = yield;
+                is(e.type, "success", "read back should succeed" + test);
+                is(JSON.stringify(e.target.result),
+                   JSON.stringify(value),
+                   "read back should return correct value" + test);
+              }
+            }
+          }
+        }
+      }
+
+      
+      function expectedResult(method, keypath, explicit, autoincrement, existing) {
+        if (keypath && explicit)
+          return "throw";
+        if (!keypath && !explicit && !autoincrement)
+          return "throw";
+        if (keypath == "invalid")
+          return "throw";
+        if (keypath == "missing" && !autoincrement)
+          return "throw";
+        if (explicit == "invalid")
+          return "throw";
+
+        if (method == "add" && existing)
+          return "error";
+
+        return "success";
+      }
+
+      openRequest.onsuccess = grabEventAndContinueHandler;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_add_twice_failure.html
+++ b/dom/indexedDB/test/test_add_twice_failure.html
@@ -4,16 +4,49 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_add_twice_failure.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = request.result;
+
+      ok(event.target === request, "Good event target");
+
+      let objectStore = db.createObjectStore("foo", { keyPath: null });
+      let key = 10;
+
+      request = objectStore.add({}, key);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(request.result, key, "Correct key");
+
+      request = objectStore.add({}, key);
+      request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      request.onsuccess = unexpectedSuccessHandler;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_advance.html
+++ b/dom/indexedDB/test/test_advance.html
@@ -4,15 +4,201 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_advance.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const dataCount = 30;
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      event.target.onsuccess = continueToNextStep;
+
+      let objectStore = db.createObjectStore("", { keyPath: "key" });
+      objectStore.createIndex("", "index");
+
+      for (let i = 0; i < dataCount; i++) {
+        objectStore.add({ key: i, index: i });
+      }
+      yield;
+
+      function getObjectStore() {
+        return db.transaction("").objectStore("");
+      }
+
+      function getIndex() {
+        return db.transaction("").objectStore("").index("");
+      }
+
+      let count = 0;
+
+      getObjectStore().openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, dataCount, "Saw all data");
+
+      count = 0;
+
+      getObjectStore().openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          if (count) {
+            count++;
+            cursor.continue();
+          }
+          else {
+            count = 10;
+            cursor.advance(10);
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, dataCount, "Saw all data");
+
+      count = 0;
+
+      getIndex().openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          if (count) {
+            count++;
+            cursor.continue();
+          }
+          else {
+            count = 10;
+            cursor.advance(10);
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, dataCount, "Saw all data");
+
+      count = 0;
+
+      getIndex().openKeyCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          if (count) {
+            count++;
+            cursor.continue();
+          }
+          else {
+            count = 10;
+            cursor.advance(10);
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, dataCount, "Saw all data");
+
+      count = 0;
+
+      getObjectStore().openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          if (count == 0) {
+            cursor.advance(dataCount + 1);
+          }
+          else {
+            ok(false, "Should never get here!");
+            cursor.continue();
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, 0, "Saw all data");
+
+      count = dataCount - 1;
+
+      getObjectStore().openCursor(null, IDBCursor.PREV).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          count--;
+          if (count == dataCount - 2) {
+            cursor.advance(10);
+            count -= 9;
+          }
+          else {
+            cursor.continue();
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, -1, "Saw all data");
+
+      count = dataCount - 1;
+
+      getObjectStore().openCursor(null, IDBCursor.PREV).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.primaryKey, count, "Got correct object");
+          if (count == dataCount - 1) {
+            cursor.advance(dataCount + 1);
+          }
+          else {
+            ok(false, "Should never get here!");
+            cursor.continue();
+          }
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(count, dataCount - 1, "Saw all data");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_autoIncrement.html
+++ b/dom/indexedDB/test/test_autoIncrement.html
@@ -4,15 +4,399 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_autoIncrement.js"></script>
+  <script type="text/javascript;version=1.7">
+    function genCheck(key, value, test, options) {
+      return function(event) {
+        is(JSON.stringify(event.target.result), JSON.stringify(key),
+           "correct returned key in " + test);
+        if (options && options.store) {
+          is(event.target.source, options.store, "correct store in " + test);
+        }
+        if (options && options.trans) {
+          is(event.target.transaction, options.trans, "correct transaction in " + test);
+        }
+        
+        event.target.source.get(key).onsuccess = function(event) {
+          is(JSON.stringify(event.target.result), JSON.stringify(value),
+             "correct stored value in " + test);
+          continueToNextStepSync();
+        }
+      }
+    }
+
+    function testSteps()
+    {
+      const dbname = window.location.pathname;
+      const RW = IDBTransaction.READ_WRITE
+      let c1 = 1;
+      let c2 = 1;
+
+      let openRequest = mozIndexedDB.open(dbname, 1);
+      openRequest.onerror = errorHandler;
+      openRequest.onupgradeneeded = grabEventAndContinueHandler;
+      openRequest.onsuccess = unexpectedSuccessHandler;
+      let event = yield;
+      let db = event.target.result;
+      let trans = event.target.transaction;
+
+      // Create test stores
+      let store1 = db.createObjectStore("store1", { autoIncrement: true });
+      let store2 = db.createObjectStore("store2", { autoIncrement: true, keyPath: "id" });
+      let store3 = db.createObjectStore("store3", { autoIncrement: false });
+      is(store1.autoIncrement, true, "store1 .autoIncrement");
+      is(store2.autoIncrement, true, "store2 .autoIncrement");
+      is(store3.autoIncrement, false, "store3 .autoIncrement");
+
+      store1.createIndex("unique1", "unique", { unique: true });
+      store2.createIndex("unique1", "unique", { unique: true });
+
+      // Test simple inserts
+      let test = " for test simple insert"
+      store1.add({ foo: "value1" }).onsuccess =
+        genCheck(c1++, { foo: "value1" }, "first" + test);
+      store1.add({ foo: "value2" }).onsuccess =
+        genCheck(c1++, { foo: "value2" }, "second" + test);
+
+      yield;
+      yield;
+
+      store2.put({ bar: "value1" }).onsuccess =
+        genCheck(c2, { bar: "value1", id: c2 }, "first in store2" + test,
+                 { store: store2 });
+      c2++;
+      store1.put({ foo: "value3" }).onsuccess =
+        genCheck(c1++, { foo: "value3" }, "third" + test,
+                 { store: store1 });
+
+      yield;
+      yield;
+      
+      store2.get(IDBKeyRange.lowerBound(c2)).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+      is(event.target.result, undefined, "no such value" + test);
+
+      // Close version_change transaction
+      openRequest.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+      is(event.target, openRequest, "succeeded to open" + test);
+      is(event.type, "success", "succeeded to open" + test);
+
+      // Test inserting explicit keys
+      test = " for test explicit keys";
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 1 }, 100).onsuccess =
+        genCheck(100, { explicit: 1 }, "first" + test);
+      c1 = 101;
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 2 }).onsuccess =
+        genCheck(c1++, { explicit: 2 }, "second" + test);
+      yield; yield;
+
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 3 }, 200).onsuccess =
+        genCheck(200, { explicit: 3 }, "third" + test);
+      c1 = 201;
+      trans.objectStore("store1").add({ explicit: 4 }).onsuccess =
+        genCheck(c1++, { explicit: 4 }, "fourth" + test);
+      yield; yield;
+
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 5 }, 150).onsuccess =
+        genCheck(150, { explicit: 5 }, "fifth" + test);
+      yield;
+      trans.objectStore("store1").add({ explicit: 6 }).onsuccess =
+        genCheck(c1++, { explicit: 6 }, "sixth" + test);
+      yield;
+
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 7 }, "key").onsuccess =
+        genCheck("key", { explicit: 7 }, "seventh" + test);
+      yield;
+      trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
+        genCheck(c1++, { explicit: 8 }, "eighth" + test);
+      yield;
+
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 7 }, [100000]).onsuccess =
+        genCheck([100000], { explicit: 7 }, "seventh" + test);
+      yield;
+      trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
+        genCheck(c1++, { explicit: 8 }, "eighth" + test);
+      yield;
+
+      trans = db.transaction("store1", RW);
+      trans.objectStore("store1").add({ explicit: 9 }, -100000).onsuccess =
+        genCheck(-100000, { explicit: 9 }, "ninth" + test);
+      yield;
+      trans.objectStore("store1").add({ explicit: 10 }).onsuccess =
+        genCheck(c1++, { explicit: 10 }, "tenth" + test);
+      yield;
+
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit2: 1, id: 300 }).onsuccess =
+        genCheck(300, { explicit2: 1, id: 300 }, "first store2" + test);
+      c2 = 301;
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit2: 2 }).onsuccess =
+        genCheck(c2, { explicit2: 2, id: c2 }, "second store2" + test);
+      c2++;
+      yield; yield;
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit2: 3, id: 400 }).onsuccess =
+        genCheck(400, { explicit2: 3, id: 400 }, "third store2" + test);
+      c2 = 401;
+      trans.objectStore("store2").add({ explicit2: 4 }).onsuccess =
+        genCheck(c2, { explicit2: 4, id: c2 }, "fourth store2" + test);
+      c2++;
+      yield; yield;
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit: 5, id: 150 }).onsuccess =
+        genCheck(150, { explicit: 5, id: 150 }, "fifth store2" + test);
+      yield;
+      trans.objectStore("store2").add({ explicit: 6 }).onsuccess =
+        genCheck(c2, { explicit: 6, id: c2 }, "sixth store2" + test);
+      c2++;
+      yield;
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit: 7, id: "key" }).onsuccess =
+        genCheck("key", { explicit: 7, id: "key" }, "seventh store2" + test);
+      yield;
+      trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
+        genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
+      c2++;
+      yield;
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit: 7, id: [100000] }).onsuccess =
+        genCheck([100000], { explicit: 7, id: [100000] }, "seventh store2" + test);
+      yield;
+      trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
+        genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
+      c2++;
+      yield;
+
+      trans = db.transaction("store2", RW);
+      trans.objectStore("store2").add({ explicit: 9, id: -100000 }).onsuccess =
+        genCheck(-100000, { explicit: 9, id: -100000 }, "ninth store2" + test);
+      yield;
+      trans.objectStore("store2").add({ explicit: 10 }).onsuccess =
+        genCheck(c2, { explicit: 10, id: c2 }, "tenth store2" + test);
+      c2++;
+      yield;
+
+
+      // Test separate transactions doesn't generate overlapping numbers
+      test = " for test non-overlapping counts";
+      trans = db.transaction("store1", RW);
+      trans2 = db.transaction("store1", RW);
+      trans2.objectStore("store1").put({ over: 2 }).onsuccess =
+        genCheck(c1 + 1, { over: 2 }, "first" + test,
+                 { trans: trans2 });
+      trans.objectStore("store1").put({ over: 1 }).onsuccess =
+        genCheck(c1, { over: 1 }, "second" + test,
+                 { trans: trans });
+      c1 += 2;
+      yield; yield;
+
+      trans = db.transaction("store2", RW);
+      trans2 = db.transaction("store2", RW);
+      trans2.objectStore("store2").put({ over: 2 }).onsuccess =
+        genCheck(c2 + 1, { over: 2, id: c2 + 1 }, "third" + test,
+                 { trans: trans2 });
+      trans.objectStore("store2").put({ over: 1 }).onsuccess =
+        genCheck(c2, { over: 1, id: c2 }, "fourth" + test,
+                 { trans: trans });
+      c2 += 2;
+      yield; yield;
+
+      // Test that error inserts doesn't increase generator
+      test = " for test error inserts";
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ unique: 1 }, -1);
+      trans.objectStore("store2").add({ unique: 1, id: "unique" });
+
+      trans.objectStore("store1").add({ error: 1, unique: 1 }).onerror =
+        new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      trans.objectStore("store1").add({ error: 2 }).onsuccess =
+        genCheck(c1++, { error: 2 }, "first" + test);
+      yield; yield;
+
+      trans.objectStore("store2").add({ error: 3, unique: 1 }).onerror =
+        new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      trans.objectStore("store2").add({ error: 4 }).onsuccess =
+        genCheck(c2, { error: 4, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      trans.objectStore("store1").add({ error: 5, unique: 1 }, 100000).onerror =
+        new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      trans.objectStore("store1").add({ error: 6 }).onsuccess =
+        genCheck(c1++, { error: 6 }, "third" + test);
+      yield; yield;
+
+      trans.objectStore("store2").add({ error: 7, unique: 1, id: 100000 }).onerror =
+        new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      trans.objectStore("store2").add({ error: 8 }).onsuccess =
+        genCheck(c2, { error: 8, id: c2 }, "fourth" + test);
+      c2++;
+      yield; yield;
+
+      // Test that aborts doesn't increase generator
+      test = " for test aborted transaction";
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ abort: 1 }).onsuccess =
+        genCheck(c1, { abort: 1 }, "first" + test);
+      trans.objectStore("store2").put({ abort: 2 }).onsuccess =
+        genCheck(c2, { abort: 2, id: c2 }, "second" + test);
+      yield; yield;
+
+      trans.objectStore("store1").add({ abort: 3 }, 500).onsuccess =
+        genCheck(500, { abort: 3 }, "third" + test);
+      trans.objectStore("store2").put({ abort: 4, id: 600 }).onsuccess =
+        genCheck(600, { abort: 4, id: 600 }, "fourth" + test);
+      yield; yield;
+
+      trans.objectStore("store1").add({ abort: 5 }).onsuccess =
+        genCheck(501, { abort: 5 }, "fifth" + test);
+      trans.objectStore("store2").put({ abort: 6 }).onsuccess =
+        genCheck(601, { abort: 6, id: 601 }, "sixth" + test);
+      yield; yield;
+
+      trans.abort();
+      trans.onabort = grabEventAndContinueHandler;
+      event = yield
+      is(event.type, "abort", "transaction aborted");
+      is(event.target, trans, "correct transaction aborted");
+
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ abort: 1 }).onsuccess =
+        genCheck(c1++, { abort: 1 }, "re-first" + test);
+      trans.objectStore("store2").put({ abort: 2 }).onsuccess =
+        genCheck(c2, { abort: 2, id: c2 }, "re-second" + test);
+      c2++;
+      yield; yield;
+
+      // Test that delete doesn't decrease generator
+      test = " for test delete items"
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ delete: 1 }).onsuccess =
+        genCheck(c1++, { delete: 1 }, "first" + test);
+      trans.objectStore("store2").put({ delete: 2 }).onsuccess =
+        genCheck(c2, { delete: 2, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      trans.objectStore("store1").delete(c1 - 1).onsuccess =
+        grabEventAndContinueHandler;
+      trans.objectStore("store2").delete(c2 - 1).onsuccess =
+        grabEventAndContinueHandler;
+      yield; yield;
+
+      trans.objectStore("store1").add({ delete: 3 }).onsuccess =
+        genCheck(c1++, { delete: 3 }, "first" + test);
+      trans.objectStore("store2").put({ delete: 4 }).onsuccess =
+        genCheck(c2, { delete: 4, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      trans.objectStore("store1").delete(c1 - 1).onsuccess =
+        grabEventAndContinueHandler;
+      trans.objectStore("store2").delete(c2 - 1).onsuccess =
+        grabEventAndContinueHandler;
+      yield; yield;
+
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ delete: 5 }).onsuccess =
+        genCheck(c1++, { delete: 5 }, "first" + test);
+      trans.objectStore("store2").put({ delete: 6 }).onsuccess =
+        genCheck(c2, { delete: 6, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      // Test that clears doesn't decrease generator
+      test = " for test clear stores";
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ clear: 1 }).onsuccess =
+        genCheck(c1++, { clear: 1 }, "first" + test);
+      trans.objectStore("store2").put({ clear: 2 }).onsuccess =
+        genCheck(c2, { clear: 2, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      trans.objectStore("store1").clear().onsuccess =
+        grabEventAndContinueHandler;
+      trans.objectStore("store2").clear().onsuccess =
+        grabEventAndContinueHandler;
+      yield; yield;
+
+      trans.objectStore("store1").add({ clear: 3 }).onsuccess =
+        genCheck(c1++, { clear: 3 }, "third" + test);
+      trans.objectStore("store2").put({ clear: 4 }).onsuccess =
+        genCheck(c2, { clear: 4, id: c2 }, "forth" + test);
+      c2++;
+      yield; yield;
+
+      trans.objectStore("store1").clear().onsuccess =
+        grabEventAndContinueHandler;
+      trans.objectStore("store2").clear().onsuccess =
+        grabEventAndContinueHandler;
+      yield; yield;
+
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").add({ clear: 5 }).onsuccess =
+        genCheck(c1++, { clear: 5 }, "fifth" + test);
+      trans.objectStore("store2").put({ clear: 6 }).onsuccess =
+        genCheck(c2, { clear: 6, id: c2 }, "sixth" + test);
+      c2++;
+      yield; yield;
+
+ 
+      // Test that close/reopen doesn't decrease generator
+      test = " for test clear stores";
+      trans = db.transaction(["store1", "store2"], RW);
+      trans.objectStore("store1").clear().onsuccess =
+        grabEventAndContinueHandler;
+      trans.objectStore("store2").clear().onsuccess =
+        grabEventAndContinueHandler;
+      yield; yield;
+      db.close();
+
+      SpecialPowers.gc();
+
+      openRequest = mozIndexedDB.open(dbname, 2);
+      openRequest.onerror = errorHandler;
+      openRequest.onupgradeneeded = grabEventAndContinueHandler;
+      openRequest.onsuccess = unexpectedSuccessHandler;
+      event = yield;
+      db = event.target.result;
+      trans = event.target.transaction;
+
+      trans.objectStore("store1").add({ reopen: 1 }).onsuccess =
+        genCheck(c1++, { reopen: 1 }, "first" + test);
+      trans.objectStore("store2").put({ reopen: 2 }).onsuccess =
+        genCheck(c2, { reopen: 2, id: c2 }, "second" + test);
+      c2++;
+      yield; yield;
+
+      openRequest.onsuccess = grabEventAndContinueHandler;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_autoIncrement_indexes.html
+++ b/dom/indexedDB/test/test_autoIncrement_indexes.html
@@ -4,16 +4,66 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_autoIncrement_indexes.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = request.result;
+      db.onerror = errorHandler;
+
+      let objectStore = db.createObjectStore("foo", { keyPath: "id",
+                                                      autoIncrement: true });
+      objectStore.createIndex("first","first");
+      objectStore.createIndex("second","second");
+      objectStore.createIndex("third","third");
+
+      let data = { first: "foo", second: "foo", third: "foo" };
+
+      objectStore.add(data).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1, "Added entry");
+      request.onsuccess = grabEventAndContinueHandler;
+
+      event = yield;
+
+      let objectStore = db.transaction("foo").objectStore("foo");
+      let first = objectStore.index("first");
+      let second = objectStore.index("second");
+      let third = objectStore.index("third");
+
+      first.get("foo").onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is (event.target.result.id, 1, "Entry in first");
+
+      second.get("foo").onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is (event.target.result.id, 1, "Entry in second");
+
+      third.get("foo").onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is (event.target.result.id, 1, "Entry in third");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_clear.html
+++ b/dom/indexedDB/test/test_clear.html
@@ -4,16 +4,106 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_clear.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const entryCount = 1000;
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = request.result;
+
+      event.target.onsuccess = continueToNextStep;
+
+      let objectStore = db.createObjectStore("foo", { autoIncrement: true });
+
+      let firstKey;
+      for (let i = 0; i < entryCount; i++) {
+        request = objectStore.add({});
+        request.onerror = errorHandler;
+        if (!i) {
+          request.onsuccess = function(event) {
+            firstKey = event.target.result;
+          };
+        }
+      }
+      yield;
+
+      isnot(firstKey, undefined, "got first key");
+
+      let seenEntryCount = 0;
+
+      request = db.transaction("foo").objectStore("foo").openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          seenEntryCount++;
+          cursor.continue();
+        }
+        else {
+          continueToNextStep();
+        }
+      }
+      yield;
+
+      is(seenEntryCount, entryCount, "Correct entry count");
+
+      try {
+        db.transaction("foo").objectStore("foo").clear();
+        ok(false, "clear should throw on READ_ONLY transactions");
+      }
+      catch (e) {
+        ok(true, "clear should throw on READ_ONLY transactions");
+      }
+
+      request = db.transaction("foo", READ_WRITE).objectStore("foo").clear();
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(event.target.result === undefined, "Correct event.target.result");
+      ok(request.result === undefined, "Correct request.result");
+      ok(request === event.target, "Correct event.target");
+
+      request = db.transaction("foo").objectStore("foo").openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        let cursor = request.result;
+        if (cursor) {
+          ok(false, "Shouldn't have any entries");
+        }
+        continueToNextStep();
+      }
+      yield;
+
+      request = db.transaction("foo", READ_WRITE).objectStore("foo").add({});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      isnot(event.target.result, firstKey, "Got a different key");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_count.html
+++ b/dom/indexedDB/test/test_count.html
@@ -1,18 +1,366 @@
-<!--
+<!--
   Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_count.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const objectStoreName = "People";
+
+      const objectStoreData = [
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7738", value: { name: "Mel", height: 66, weight: {} } },
+        { key: "237-23-7739", value: { name: "Tom", height: 62, weight: 130 } }
+      ];
+
+      const indexData = {
+        name: "weight",
+        keyPath: "weight",
+        options: { unique: false }
+      };
+
+      const weightSort = [1, 0, 3, 7, 4, 2];
+
+      let request = mozIndexedDB.open(name, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      is(event.type, "upgradeneeded", "Got correct event type");
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      let objectStore = db.createObjectStore(objectStoreName, { });
+      objectStore.createIndex(indexData.name, indexData.keyPath,
+                              indexData.options);
+
+      for each (let data in objectStoreData) {
+        objectStore.add(data.value, data.key);
+      }
+
+      event = yield;
+
+      is(event.type, "success", "Got correct event type");
+
+      objectStore = db.transaction(db.objectStoreNames)
+                      .objectStore(objectStoreName);
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length,
+         "Correct number of object store entries for all keys");
+
+      objectStore.count(null).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length,
+         "Correct number of object store entries for null key");
+
+      objectStore.count(objectStoreData[2].key).onsuccess =
+        grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of object store entries for single existing key");
+
+      objectStore.count("foo").onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of object store entries for single non-existing key");
+
+      let keyRange = IDBKeyRange.only(objectStoreData[2].key);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of object store entries for existing only keyRange");
+
+      keyRange = IDBKeyRange.only("foo");
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of object store entries for non-existing only keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length - 2,
+         "Correct number of object store entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key, true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length - 3,
+         "Correct number of object store entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound("foo");
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of object store entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, false);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 3,
+         "Correct number of object store entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 2,
+         "Correct number of object store entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound("foo", true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length,
+         "Correct number of object store entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[0].key,
+                                   objectStoreData[objectStoreData.length - 1].key);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length,
+         "Correct number of object store entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[0].key,
+                                   objectStoreData[objectStoreData.length - 1].key,
+                                   true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length - 1,
+         "Correct number of object store entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[0].key,
+                                   objectStoreData[objectStoreData.length - 1].key,
+                                   true, true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length - 2,
+         "Correct number of object store entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound("foo", "foopy", true, true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of object store entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[0].key, "foo", true, true);
+      objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, objectStoreData.length - 1,
+         "Correct number of object store entries for bound keyRange");
+
+      let index = objectStore.index(indexData.name);
+
+      index.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for no key");
+
+      index.count(objectStoreData[7].value.weight).onsuccess =
+        grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 2,
+         "Correct number of index entries for duplicate key");
+
+      index.count(objectStoreData[0].value.weight).onsuccess =
+        grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of index entries for single key");
+
+      keyRange = IDBKeyRange.only(objectStoreData[0].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of index entries for only existing keyRange");
+
+      keyRange = IDBKeyRange.only("foo");
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of index entries for only non-existing keyRange");
+
+      keyRange = IDBKeyRange.only(objectStoreData[7].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 2,
+         "Correct number of index entries for only duplicate keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[1]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 1,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight - 1);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 1,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight + 1,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of index entries for lowerBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 1,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 1,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
+                                        true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 1,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.upperBound("foo");
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for upperBound keyRange");
+
+      keyRange = IDBKeyRange.bound("foo", "foopy");
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0,
+         "Correct number of index entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
+                                   objectStoreData[weightSort[weightSort.length - 1]].value.weight);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length,
+         "Correct number of index entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
+                                   objectStoreData[weightSort[weightSort.length - 1]].value.weight,
+                                   true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 1,
+         "Correct number of index entries for bound keyRange");
+
+      keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
+                                   objectStoreData[weightSort[weightSort.length - 1]].value.weight,
+                                   true, true);
+      index.count(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, weightSort.length - 2,
+         "Correct number of index entries for bound keyRange");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_create_index.html
+++ b/dom/indexedDB/test/test_create_index.html
@@ -4,15 +4,134 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_create_index.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+      const nsIIDBTransaction = Components.interfaces.nsIIDBTransaction;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreInfo = [
+        { name: "a", options: { keyPath: "id", autoIncrement: true } },
+        { name: "b", options: { keyPath: "id", autoIncrement: false } },
+      ];
+      const indexInfo = [
+        { name: "1", keyPath: "unique_value", options: { unique: true } },
+        { name: "2", keyPath: "value", options: { unique: false } },
+        { name: "3", keyPath: "value", options: { unique: false } },
+        { name: "", keyPath: "value", options: { unique: false } },
+        { name: null, keyPath: "value", options: { unique: false } },
+        { name: undefined, keyPath: "value", options: { unique: false } },
+      ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+      let db = event.target.result;
+
+      for (let i = 0; i < objectStoreInfo.length; i++) {
+        let info = objectStoreInfo[i];
+        let objectStore = info.hasOwnProperty("options") ?
+                          db.createObjectStore(info.name, info.options) :
+                          db.createObjectStore(info.name);
+
+        try {
+          request = objectStore.createIndex("Hola");
+          ok(false, "createIndex with no keyPath should throw");
+        }
+        catch(e) {
+          ok(true, "createIndex with no keyPath should throw");
+        }
+
+        try {
+          request = objectStore.createIndex("Hola", ["foo"], { multiEntry: true });
+          ok(false, "createIndex with array keyPath and multiEntry should throw");
+        }
+        catch(e) {
+          ok(true, "createIndex with array keyPath and multiEntry should throw");
+        }
+
+        try {
+          request = objectStore.createIndex("Hola", []);
+          ok(false, "createIndex with empty array keyPath should throw");
+        }
+        catch(e) {
+          ok(true, "createIndex with empty array keyPath should throw");
+        }
+
+        try {
+          request = objectStore.createIndex("foo", "bar", 10);
+          ok(false, "createIndex with bad options should throw");
+        }
+        catch(e) {
+          ok(true, "createIndex with bad options threw");
+        }
+
+        ok(objectStore.createIndex("foo", "bar", { foo: "" }),
+           "createIndex with unknown options should not throw");
+        objectStore.deleteIndex("foo");
+
+        // Test index creation, and that it ends up in indexNames.
+        let objectStoreName = info.name;
+        for (let j = 0; j < indexInfo.length; j++) {
+          let info = indexInfo[j];
+          let count = objectStore.indexNames.length;
+          let index = info.hasOwnProperty("options") ?
+                      objectStore.createIndex(info.name, info.keyPath,
+                                              info.options) :
+                      objectStore.createIndex(info.name, info.keyPath);
+
+          let name = info.name;
+          if (name === null) {
+            name = "null";
+          }
+          else if (name === undefined) {
+            name = "undefined";
+          }
+
+          is(index.name, name, "correct name");
+          is(index.keyPath, info.keyPath, "correct keyPath");
+          is(index.unique, info.options.unique, "correct uniqueness");
+
+          is(objectStore.indexNames.length, count + 1,
+             "indexNames grew in size");
+          let found = false;
+          for (let k = 0; k < objectStore.indexNames.length; k++) {
+            if (objectStore.indexNames.item(k) == name) {
+              found = true;
+              break;
+            }
+          }
+          ok(found, "Name is on objectStore.indexNames");
+
+          ok(event.target.transaction, "event has a transaction");
+          ok(event.target.transaction.db === db,
+             "transaction has the right db");
+          is(event.target.transaction.readyState, nsIIDBTransaction.LOADING,
+             "transaction has the correct readyState");
+          is(event.target.transaction.mode, nsIIDBTransaction.VERSION_CHANGE,
+             "transaction has the correct mode");
+          is(event.target.transaction.objectStoreNames.length, i + 1,
+             "transaction only has one object store");
+          is(event.target.transaction.objectStoreNames.item(0), objectStoreName,
+             "transaction has the correct object store");
+        }
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_create_index_with_integer_keys.html
+++ b/dom/indexedDB/test/test_create_index_with_integer_keys.html
@@ -4,15 +4,75 @@
 -->
 <html>
 <head>
   <title>Indexed Database Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_create_index_with_integer_keys.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const data = { id: new Date().getTime(),
+                     num: parseInt(Math.random() * 1000) };
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      event.target.onsuccess = continueToNextStep;
+
+      // Make object store, add data.
+      let objectStore = db.createObjectStore("foo", { keyPath: "id" });
+      objectStore.add(data);
+      yield;
+      db.close();
+
+      let request = mozIndexedDB.open(window.location.pathname, 2);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db2 = event.target.result;
+      db2.onerror = errorHandler;
+
+      event.target.onsuccess = continueToNextStep;
+
+      // Create index.
+      event.target.transaction.objectStore("foo").createIndex("foo", "num");
+      yield;
+
+      // Make sure our object made it into the index.
+      let seenCount = 0;
+
+
+      db2.transaction("foo").objectStore("foo").index("foo")
+         .openKeyCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, data.num, "Good key");
+          is(cursor.primaryKey, data.id, "Good value");
+          seenCount++;
+          cursor.continue();
+        }
+        else {
+          continueToNextStep();
+        }
+      };
+      yield;
+
+      is(seenCount, 1, "Saw our entry");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_cursor_mutation.html
+++ b/dom/indexedDB/test/test_cursor_mutation.html
@@ -4,16 +4,125 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_cursor_mutation.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const objectStoreData = [
+        // This one will be removed.
+        { ss: "237-23-7732", name: "Bob" },
+
+        // These will always be included.
+        { ss: "237-23-7733", name: "Ann" },
+        { ss: "237-23-7734", name: "Ron" },
+        { ss: "237-23-7735", name: "Sue" },
+        { ss: "237-23-7736", name: "Joe" },
+
+        // This one will be added.
+        { ss: "237-23-7737", name: "Pat" }
+      ];
+
+      // Post-add and post-remove data ordered by name.
+      const objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ];
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      event.target.onsuccess = continueToNextStep;
+
+      let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
+      objectStore.createIndex("name", "name", { unique: true });
+
+      for (let i = 0; i < objectStoreData.length - 1; i++) {
+        objectStore.add(objectStoreData[i]);
+      }
+      yield;
+
+      let count = 0;
+
+      let sawAdded = false;
+      let sawRemoved = false;
+
+      db.transaction("foo").objectStore("foo").openCursor().onsuccess =
+        function(event) {
+          event.target.transaction.oncomplete = continueToNextStep;
+          let cursor = event.target.result;
+          if (cursor) {
+            if (cursor.value.name == objectStoreData[0].name) {
+              sawRemoved = true;
+            }
+            if (cursor.value.name ==
+                objectStoreData[objectStoreData.length - 1].name) {
+              sawAdded = true;
+            }
+            cursor.continue();
+            count++;
+          }
+        };
+      yield;
+
+      is(count, objectStoreData.length - 1, "Good initial count");
+      is(sawAdded, false, "Didn't see item that is about to be added");
+      is(sawRemoved, true, "Saw item that is about to be removed");
+
+      count = 0;
+      sawAdded = false;
+      sawRemoved = false;
+
+      db.transaction("foo", IDBTransaction.READ_WRITE).objectStore("foo")
+        .index("name").openCursor().onsuccess = function(event) {
+          event.target.transaction.oncomplete = continueToNextStep;
+          let cursor = event.target.result;
+          if (cursor) {
+            if (cursor.value.name == objectStoreData[0].name) {
+              sawRemoved = true;
+            }
+            if (cursor.value.name ==
+                objectStoreData[objectStoreData.length - 1].name) {
+              sawAdded = true;
+            }
+
+            is(cursor.value.name,
+               objectStoreData[objectStoreDataNameSort[count++]].name,
+               "Correct name");
+
+            if (count == 1) {
+              let objectStore = event.target.transaction.objectStore("foo");
+              objectStore.delete(objectStoreData[0].ss)
+                         .onsuccess = function(event) {
+                objectStore.add(objectStoreData[objectStoreData.length - 1])
+                           .onsuccess =
+                  function(event) {
+                    cursor.continue();
+                  };
+              };
+            }
+            else {
+              cursor.continue();
+            }
+          }
+        };
+      yield;
+
+      is(count, objectStoreData.length - 1, "Good final count");
+      is(sawAdded, true, "Saw item that was added");
+      is(sawRemoved, false, "Didn't see item that was removed");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_cursor_update_updates_indexes.html
+++ b/dom/indexedDB/test/test_cursor_update_updates_indexes.html
@@ -4,15 +4,106 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_cursor_update_updates_indexes.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+      const nsIIDBTransaction = Components.interfaces.nsIIDBTransaction;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const START_DATA = "hi";
+      const END_DATA = "bye";
+      const objectStoreInfo = [
+        { name: "1", options: { keyPath: null }, key: 1,
+          entry: { data: START_DATA } },
+        { name: "2", options: { keyPath: "foo" },
+          entry: { foo: 1, data: START_DATA } },
+        { name: "3", options: { keyPath: null, autoIncrement: true },
+          entry: { data: START_DATA } },
+        { name: "4", options: { keyPath: "foo", autoIncrement: true },
+          entry: { data: START_DATA } },
+      ];
+
+      for (let i = 0; i < objectStoreInfo.length; i++) {
+        // Create our object stores.
+        let info = objectStoreInfo[i];
+
+        ok(true, "1");
+        request = mozIndexedDB.open(name, i + 1, description);
+        request.onerror = errorHandler;
+        request.onupgradeneeded = grabEventAndContinueHandler;
+        event = yield;
+
+        let db = event.target.result;
+
+        ok(true, "2");
+        let objectStore = info.hasOwnProperty("options") ?
+                          db.createObjectStore(info.name, info.options) :
+                          db.createObjectStore(info.name);
+
+        // Create the indexes on 'data' on the object store.
+        let index = objectStore.createIndex("data_index", "data",
+                                            { unique: false });
+        let uniqueIndex = objectStore.createIndex("unique_data_index", "data",
+                                                  { unique: true });
+        // Populate the object store with one entry of data.
+        request = info.hasOwnProperty("key") ?
+                  objectStore.add(info.entry, info.key) :
+                  objectStore.add(info.entry);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+        ok(true, "3");
+
+        // Use a cursor to update 'data' to END_DATA.
+        request = objectStore.openCursor();
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+        ok(true, "4");
+
+        let cursor = request.result;
+        let obj = cursor.value;
+        obj.data = END_DATA;
+        request = cursor.update(obj);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+        ok(true, "5");
+
+        // Check both indexes to make sure that they were updated.
+        request = index.get(END_DATA);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+        ok(true, "6");
+        SimpleTest.ok(obj.data, event.target.result.data,
+                      "Non-unique index was properly updated.");
+
+        request = uniqueIndex.get(END_DATA);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+
+        ok(true, "7");
+        SimpleTest.ok(obj.data, event.target.result.data,
+                      "Unique index was properly updated.");
+        db.close();
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_cursors.html
+++ b/dom/indexedDB/test/test_cursors.html
@@ -4,16 +4,371 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_cursors.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const keys = [1, -1, 0, 10, 2000, "q", "z", "two", "b", "a"];
+      const sortedKeys = [-1, 0, 1, 10, 2000, "a", "b", "q", "two", "z"];
+
+      is(keys.length, sortedKeys.length, "Good key setup");
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore("autoIncrement",
+                                             { autoIncrement: true });
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        ok(!event.target.result, "No results");
+        testGenerator.next();
+      }
+      yield;
+
+      objectStore = db.createObjectStore("autoIncrementKeyPath",
+                                         { keyPath: "foo",
+                                           autoIncrement: true });
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        ok(!event.target.result, "No results");
+        testGenerator.next();
+      }
+      yield;
+
+      objectStore = db.createObjectStore("keyPath", { keyPath: "foo" });
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        ok(!event.target.result, "No results");
+        testGenerator.next();
+      }
+      yield;
+
+      objectStore = db.createObjectStore("foo");
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        ok(!event.target.result, "No results");
+        testGenerator.next();
+      }
+      yield;
+
+      let keyIndex = 0;
+
+      for (let i in keys) {
+        request = objectStore.add("foo", keys[i]);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++keyIndex == keys.length) {
+            testGenerator.next();
+          }
+        };
+      }
+      yield;
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          cursor.continue();
+
+          try {
+            cursor.continue();
+            ok(false, "continue twice should throw");
+          }
+          catch (e) {
+            ok(e instanceof IDBDatabaseException, "got a database exception");
+            is(e.code, IDBDatabaseException.NOT_ALLOWED_ERR, "correct code");
+          }
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all added items");
+
+      keyIndex = 4;
+
+      let range = IDBKeyRange.bound(2000, "q");
+      request = objectStore.openCursor(range);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          cursor.continue();
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 8, "Saw all the expected keys");
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          if (keyIndex) {
+            cursor.continue();
+          }
+          else {
+            cursor.continue("b");
+          }
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex += keyIndex ? 1: 6;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all the expected keys");
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          if (keyIndex) {
+            cursor.continue();
+          }
+          else {
+            cursor.continue(10);
+          }
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex += keyIndex ? 1: 3;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all the expected keys");
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          if (keyIndex) {
+            cursor.continue();
+          }
+          else {
+            cursor.continue("c");
+          }
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex += keyIndex ? 1 : 7;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all the expected keys");
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          if (keyIndex == 4) {
+            request = cursor.update("bar");
+            request.onerror = errorHandler;
+            request.onsuccess = function(event) {
+              keyIndex++;
+              cursor.continue();
+            };
+          }
+          else {
+            keyIndex++;
+            cursor.continue();
+          }
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all the expected keys");
+
+      request = objectStore.get(sortedKeys[4]);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, "bar", "Update succeeded");
+
+      request = objectStore.put("foo", sortedKeys[4]);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      keyIndex = 0;
+
+      let gotRemoveEvent = false;
+      let retval = false;
+
+      request = objectStore.openCursor(null, IDBCursor.NEXT);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          if (keyIndex == 4) {
+            request = cursor.delete();
+            request.onerror = errorHandler;
+            request.onsuccess = function(event) {
+              ok(event.target.result === undefined, "Should be undefined");
+              is(keyIndex, 5, "Got result of remove before next continue");
+              gotRemoveEvent = true;
+            };
+          }
+
+          keyIndex++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, keys.length, "Saw all the expected keys");
+      is(gotRemoveEvent, true, "Saw the remove event");
+
+      request = objectStore.get(sortedKeys[4]);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, undefined, "Entry was deleted");
+
+      request = objectStore.add("foo", sortedKeys[4]);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      keyIndex = sortedKeys.length - 1;
+
+      request = objectStore.openCursor(null, IDBCursor.PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          cursor.continue();
+
+          is(cursor.key, sortedKeys[keyIndex], "Correct key");
+          is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
+          is(cursor.value, "foo", "Correct value");
+
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all added items");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_event_source.html
+++ b/dom/indexedDB/test/test_event_source.html
@@ -4,15 +4,42 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_event_source.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "Objects";
+
+      var request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      var event = yield;
+
+      is(event.target.source, null, "correct event.target.source");
+
+      var db = event.target.result;
+      var objectStore = db.createObjectStore(objectStoreName,
+                                             { autoIncrement: true });
+      request = objectStore.add({});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(event.target.source === objectStore, "correct event.source");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_getAll.html
+++ b/dom/indexedDB/test/test_getAll.html
@@ -4,16 +4,170 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_getAll.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore("foo", { autoIncrement: true });
+
+      request.onsuccess = grabEventAndContinueHandler;
+      request = objectStore.getAll();
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 0, "No elements");
+
+      let addedCount = 0;
+
+      for (let i in values) {
+        request = objectStore.add(values[i]);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedCount == values.length) {
+            SimpleTest.executeSoon(function() { testGenerator.next(); });
+          }
+        }
+      }
+      yield;
+      yield;
+
+      request = db.transaction("foo").objectStore("foo").getAll();
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, values.length, "Same length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[i], "Same value");
+      }
+
+      request = db.transaction("foo").objectStore("foo").getAll(null, 5);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 5, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[i], "Same value");
+      }
+
+      let keyRange = IDBKeyRange.bound(1, 9);
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, values.length, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[i], "Same value");
+      }
+
+      keyRange = IDBKeyRange.bound(4, 7);
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 4, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[parseInt(i) + 3], "Same value");
+      }
+
+      // Get should take a key range also but it doesn't return an array.
+      request = db.transaction("foo").objectStore("foo").get(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, false, "Not an array object");
+      is(event.target.result, values[3], "Correct value");
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange, 2);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 2, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[parseInt(i) + 3], "Same value");
+      }
+
+      keyRange = IDBKeyRange.bound(4, 7);
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange, 50);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 4, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[parseInt(i) + 3], "Same value");
+      }
+
+      keyRange = IDBKeyRange.bound(4, 7);
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange, 0);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 0, "Correct length");
+
+      keyRange = IDBKeyRange.bound(4, 7, true, true);
+
+      request = db.transaction("foo").objectStore("foo").getAll(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 2, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], values[parseInt(i) + 4], "Same value");
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_global_data.html
+++ b/dom/indexedDB/test/test_global_data.html
@@ -4,15 +4,67 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_global_data.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStore =  { name: "Objects",
+                             options: { keyPath: "id", autoIncrement: true } };
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db1 = event.target.result;
+
+      is(db1.objectStoreNames.length, 0, "No objectStores in db1");
+
+      db1.createObjectStore(objectStore.name, objectStore.options);
+
+      continueToNextStep();
+      yield;
+
+      request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      let db2 = event.target.result;
+
+      ok(db1 !== db2, "Databases are not the same object");
+
+      is(db1.objectStoreNames.length, 1, "1 objectStore in db1");
+      is(db1.objectStoreNames.item(0), objectStore.name, "Correct name");
+
+      is(db2.objectStoreNames.length, 1, "1 objectStore in db2");
+      is(db2.objectStoreNames.item(0), objectStore.name, "Correct name");
+
+      let objectStore1 = db1.transaction(objectStore.name)
+                            .objectStore(objectStore.name);
+      is(objectStore1.name, objectStore.name, "Same name");
+      is(objectStore1.keyPath, objectStore.options.keyPath, "Same keyPath");
+
+      let objectStore2 = db2.transaction(objectStore.name)
+                            .objectStore(objectStore.name);
+
+      ok(objectStore1 !== objectStore2, "Different objectStores");
+      is(objectStore1.name, objectStore2.name, "Same name");
+      is(objectStore1.keyPath, objectStore2.keyPath, "Same keyPath");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_index_empty_keyPath.html
+++ b/dom/indexedDB/test/test_index_empty_keyPath.html
@@ -4,15 +4,92 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_index_empty_keyPath.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+
+      const objectStoreData = [
+        { key: "1", value: "foo" },
+        { key: "2", value: "bar" },
+        { key: "3", value: "baz" }
+      ];
+
+      let request = mozIndexedDB.open(name, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield; // upgradeneeded
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore("data", { keyPath: null });
+
+      // First, add all our data to the object store.
+      let addedData = 0;
+      for (let i in objectStoreData) {
+        request = objectStore.add(objectStoreData[i].value,
+                                  objectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == objectStoreData.length) {
+            testGenerator.send(event);
+          }
+        }
+      }
+      event = yield; // testGenerator.send
+
+      // Now create the index.
+      objectStore.createIndex("set", "", { unique: true });
+      yield; // success
+
+      let trans = db.transaction("data", IDBTransaction.READ_WRITE);
+      objectStore = trans.objectStore("data");
+      index = objectStore.index("set");
+
+      let request = index.get("bar");
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      
+      let event = yield;
+
+      is(event.target.result, "bar", "Got correct result");
+
+      let request = objectStore.add("foopy", 4);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+
+      yield;
+
+      let request = index.get("foopy");
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      
+      let event = yield;
+
+      is(event.target.result, "foopy", "Got correct result");
+
+      let request = objectStore.add("foopy", 5);
+      request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      request.onsuccess = unexpectedSuccessHandler;
+
+      trans.oncomplete = grabEventAndContinueHandler;
+
+      yield;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_index_getAll.html
+++ b/dom/indexedDB/test/test_index_getAll.html
@@ -4,16 +4,160 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_index_getAll.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "People";
+
+      const objectStoreData = [
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } }
+      ];
+
+      const indexData = [
+        { name: "name", keyPath: "name", options: { unique: true } },
+        { name: "height", keyPath: "height", options: { unique: false } },
+        { name: "weight", keyPath: "weight", options: { unique: false } }
+      ];
+
+      const objectStoreDataNameSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
+      ];
+
+      const objectStoreDataWeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      const objectStoreDataHeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName);
+
+      // First, add all our data to the object store.
+      let addedData = 0;
+      for (let i in objectStoreData) {
+        request = objectStore.add(objectStoreData[i].value,
+                                  objectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == objectStoreData.length) {
+            testGenerator.send(event);
+          }
+        }
+      }
+      yield;
+      ok(true, "1");
+
+      // Now create the indexes.
+      for (let i in indexData) {
+        objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
+                                indexData[i].options);
+      }
+
+      is(objectStore.indexNames.length, indexData.length, "Good index count");
+      yield;
+
+      ok(true, "2");
+      objectStore = db.transaction(objectStoreName)
+                      .objectStore(objectStoreName);
+
+      request = objectStore.index("height").getAllKeys(65);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+      ok(true, "3");
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 2, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
+           "Correct key");
+      }
+
+      request = objectStore.index("height").getAllKeys();
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+      ok(true, "4");
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, objectStoreDataHeightSort.length,
+         "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
+      }
+
+      request = objectStore.index("height").getAllKeys(null, 4);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(true, "5");
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 4, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
+      }
+
+      request = objectStore.index("height").getAllKeys(65, 1);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(true, "6");
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 1, "Correct length");
+
+      for (let i in event.target.result) {
+        is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
+           "Correct key");
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_index_getAllObjects.html
+++ b/dom/indexedDB/test/test_index_getAllObjects.html
@@ -4,16 +4,184 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_index_getAllObjects.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "People";
+
+      const objectStoreData = [
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } }
+      ];
+
+      const indexData = [
+        { name: "name", keyPath: "name", options: { unique: true } },
+        { name: "height", keyPath: "height", options: { unique: false } },
+        { name: "weight", keyPath: "weight", options: { unique: false } }
+      ];
+
+      const objectStoreDataNameSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
+      ];
+
+      const objectStoreDataWeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      const objectStoreDataHeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName, {});
+
+      // First, add all our data to the object store.
+      let addedData = 0;
+      for (let i in objectStoreData) {
+        request = objectStore.add(objectStoreData[i].value,
+                                  objectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == objectStoreData.length) {
+            testGenerator.send(event);
+          }
+        }
+      }
+      event = yield;
+
+      // Now create the indexes.
+      for (let i in indexData) {
+        objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
+                                indexData[i].options);
+      }
+
+      is(objectStore.indexNames.length, indexData.length, "Good index count");
+      yield;
+
+      objectStore = db.transaction(objectStoreName)
+                      .objectStore(objectStoreName);
+
+      request = objectStore.index("height").getAll(65);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 2, "Correct length");
+
+      for (let i in event.target.result) {
+        let result = event.target.result[i];
+        let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
+
+        is(result.name, testObj.name, "Correct name");
+        is(result.height, testObj.height, "Correct height");
+
+        if (testObj.hasOwnProperty("weight")) {
+          is(result.weight, testObj.weight, "Correct weight");
+        }
+      }
+
+      request = objectStore.index("height").getAll();
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, objectStoreDataHeightSort.length,
+         "Correct length");
+
+      for (let i in event.target.result) {
+        let result = event.target.result[i];
+        let testObj = objectStoreDataHeightSort[i].value;
+
+        is(result.name, testObj.name, "Correct name");
+        is(result.height, testObj.height, "Correct height");
+
+        if (testObj.hasOwnProperty("weight")) {
+          is(result.weight, testObj.weight, "Correct weight");
+        }
+      }
+
+      request = objectStore.index("height").getAll(null, 4);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 4, "Correct length");
+
+      for (let i in event.target.result) {
+        let result = event.target.result[i];
+        let testObj = objectStoreDataHeightSort[i].value;
+
+        is(result.name, testObj.name, "Correct name");
+        is(result.height, testObj.height, "Correct height");
+
+        if (testObj.hasOwnProperty("weight")) {
+          is(result.weight, testObj.weight, "Correct weight");
+        }
+      }
+
+      request = objectStore.index("height").getAll(65, 1);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array object");
+      is(event.target.result.length, 1, "Correct length");
+
+      for (let i in event.target.result) {
+        let result = event.target.result[i];
+        let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
+
+        is(result.name, testObj.name, "Correct name");
+        is(result.height, testObj.height, "Correct height");
+
+        if (testObj.hasOwnProperty("weight")) {
+          is(result.weight, testObj.weight, "Correct weight");
+        }
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_index_object_cursors.html
+++ b/dom/indexedDB/test/test_index_object_cursors.html
@@ -4,15 +4,154 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_index_object_cursors.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const objectStoreData = [
+        { name: "", options: { keyPath: "id", autoIncrement: true } },
+        { name: null, options: { keyPath: "ss" } },
+        { name: undefined, options: { } },
+        { name: "4", options: { autoIncrement: true } },
+      ];
+
+      const indexData = [
+        { name: "", keyPath: "name", options: { unique: true } },
+        { name: null, keyPath: "height", options: { } }
+      ];
+
+      const data = [
+        { ss: "237-23-7732", name: "Ann", height: 60 },
+        { ss: "237-23-7733", name: "Bob", height: 65 }
+      ];
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      event.target.onsuccess = continueToNextStep;
+
+      for (let objectStoreIndex in objectStoreData) {
+        const objectStoreInfo = objectStoreData[objectStoreIndex];
+        let objectStore = db.createObjectStore(objectStoreInfo.name,
+                                               objectStoreInfo.options);
+        for (let indexIndex in indexData) {
+          const indexInfo = indexData[indexIndex];
+          let index = objectStore.createIndex(indexInfo.name,
+                                              indexInfo.keyPath,
+                                              indexInfo.options);
+        }
+      }
+      yield;
+
+      ok(true, "Initial setup");
+
+      for (let objectStoreIndex in objectStoreData) {
+        const info = objectStoreData[objectStoreIndex];
+
+        for (let indexIndex in indexData) {
+          const objectStoreName = objectStoreData[objectStoreIndex].name;
+          const indexName = indexData[indexIndex].name;
+
+          let objectStore =
+            db.transaction(objectStoreName, IDBTransaction.READ_WRITE)
+              .objectStore(objectStoreName);
+          ok(true, "Got objectStore " + objectStoreName);
+
+          for (let dataIndex in data) {
+            const obj = data[dataIndex];
+            let key;
+            if (!info.options.keyPath && !info.options.autoIncrement) {
+              key = obj.ss;
+            }
+            objectStore.add(obj, key);
+          }
+
+          let index = objectStore.index(indexName);
+          ok(true, "Got index " + indexName);
+
+          let keyIndex = 0;
+
+          index.openCursor().onsuccess = function(event) {
+            let cursor = event.target.result;
+            if (!cursor) {
+              continueToNextStep();
+              return;
+            }
+
+            is(cursor.key, data[keyIndex][indexData[indexIndex].keyPath],
+               "Good key");
+            is(cursor.value.ss, data[keyIndex].ss, "Correct ss");
+            is(cursor.value.name, data[keyIndex].name, "Correct name");
+            is(cursor.value.height, data[keyIndex].height, "Correct height");
+
+            if (!keyIndex) {
+              let obj = cursor.value;
+              obj.updated = true;
+
+              cursor.update(obj).onsuccess = function(event) {
+                ok(true, "Object updated");
+                cursor.continue();
+                keyIndex++
+              }
+              return;
+            }
+
+            cursor.delete().onsuccess = function(event) {
+              ok(true, "Object deleted");
+              cursor.continue();
+              keyIndex++
+            }
+          };
+          yield;
+
+          is(keyIndex, 2, "Saw all the items");
+
+          keyIndex = 0;
+
+          db.transaction(objectStoreName).objectStore(objectStoreName)
+                                         .openCursor()
+                                         .onsuccess = function(event) {
+            let cursor = event.target.result;
+            if (!cursor) {
+              continueToNextStep();
+              return;
+            }
+
+            is(cursor.value.ss, data[keyIndex].ss, "Correct ss");
+            is(cursor.value.name, data[keyIndex].name, "Correct name");
+            is(cursor.value.height, data[keyIndex].height, "Correct height");
+            is(cursor.value.updated, true, "Correct updated flag");
+
+            cursor.continue();
+            keyIndex++;
+          };
+          yield;
+
+          is(keyIndex, 1, "Saw all the items");
+
+          db.transaction(objectStoreName, IDBTransaction.READ_WRITE)
+            .objectStore(objectStoreName).clear()
+            .onsuccess = continueToNextStep();
+          yield;
+        }
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_index_update_delete.html
+++ b/dom/indexedDB/test/test_index_update_delete.html
@@ -4,16 +4,177 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_index_update_delete.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+
+      let event = yield;
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      for each (let autoIncrement in [false, true]) {
+        let objectStore =
+          db.createObjectStore(autoIncrement, { keyPath: "id",
+                                                autoIncrement: autoIncrement });
+
+        for (let i = 0; i < 10; i++) {
+          objectStore.add({ id: i, index: i });
+        }
+
+        for each (let unique in [false, true]) {
+          objectStore.createIndex(unique, "index", { unique: unique });
+        }
+
+        for (let i = 10; i < 20; i++) {
+          objectStore.add({ id: i, index: i });
+        }
+      }
+
+      event = yield;
+      is(event.type, "success", "expect a success event");
+
+      for each (let autoIncrement in [false, true]) {
+        let objectStore = db.transaction(autoIncrement)
+                            .objectStore(autoIncrement);
+
+        objectStore.count().onsuccess = grabEventAndContinueHandler;
+        let event = yield;
+
+        is(event.target.result, 20, "Correct number of entries in objectStore");
+
+        let objectStoreCount = event.target.result;
+        let indexCount = event.target.result;
+
+        for each (let unique in [false, true]) {
+          let index = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
+                        .objectStore(autoIncrement)
+                        .index(unique);
+
+          index.count().onsuccess = grabEventAndContinueHandler;
+          let event = yield;
+
+          is(event.target.result, indexCount,
+             "Correct number of entries in index");
+
+          let modifiedEntry = unique ? 5 : 10;
+          let keyRange = IDBKeyRange.only(modifiedEntry);
+
+          let sawEntry = false;
+          index.openCursor(keyRange).onsuccess = function(event) {
+            let cursor = event.target.result;
+            if (cursor) {
+              sawEntry = true;
+              is(cursor.key, modifiedEntry, "Correct key");
+
+              cursor.value.index = unique ? 30 : 35;
+              cursor.update(cursor.value).onsuccess = function(event) {
+                cursor.continue();
+              }
+            }
+            else {
+              continueToNextStep();
+            }
+          }
+          yield;
+
+          is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
+
+          // Recount index. Shouldn't change.
+          index = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
+                    .objectStore(autoIncrement)
+                    .index(unique);
+
+          index.count().onsuccess = grabEventAndContinueHandler;
+          event = yield;
+
+          is(event.target.result, indexCount,
+             "Correct number of entries in index");
+
+          modifiedEntry = unique ? 30 : 35;
+          keyRange = IDBKeyRange.only(modifiedEntry);
+
+          sawEntry = false;
+          index.openCursor(keyRange).onsuccess = function(event) {
+            let cursor = event.target.result;
+            if (cursor) {
+              sawEntry = true;
+              is(cursor.key, modifiedEntry, "Correct key");
+
+              delete cursor.value.index;
+              cursor.update(cursor.value).onsuccess = function(event) {
+                indexCount--;
+                cursor.continue();
+              }
+            }
+            else {
+              continueToNextStep();
+            }
+          }
+          yield;
+
+          is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
+
+          // Recount objectStore. Should be unchanged.
+          objectStore = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
+                          .objectStore(autoIncrement);
+
+          objectStore.count().onsuccess = grabEventAndContinueHandler;
+          event = yield;
+
+          is(event.target.result, objectStoreCount,
+             "Correct number of entries in objectStore");
+
+          // Recount index. Should be one item less.
+          index = objectStore.index(unique);
+
+          index.count().onsuccess = grabEventAndContinueHandler;
+          event = yield;
+
+          is(event.target.result, indexCount,
+             "Correct number of entries in index");
+
+          modifiedEntry = objectStoreCount - 1;
+
+          objectStore.delete(modifiedEntry).onsuccess =
+            grabEventAndContinueHandler;
+          event = yield;
+
+          objectStoreCount--;
+          indexCount--;
+
+          objectStore.count().onsuccess = grabEventAndContinueHandler;
+          event = yield;
+
+          is(event.target.result, objectStoreCount,
+             "Correct number of entries in objectStore");
+
+          index.count().onsuccess = grabEventAndContinueHandler;
+          event = yield;
+
+          is(event.target.result, indexCount,
+             "Correct number of entries in index");
+        }
+      }
+
+      finishTest();
+      yield;
+    }
+
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_indexes.html
+++ b/dom/indexedDB/test/test_indexes.html
@@ -4,15 +4,1284 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_indexes.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const CONSTRAINT_ERR =
+        Components.interfaces.nsIIDBDatabaseException.CONSTRAINT_ERR;
+      const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
+      const NEXT = Components.interfaces.nsIIDBCursor.NEXT;
+      const PREV = Components.interfaces.nsIIDBCursor.PREV;
+      const NEXT_NO_DUPLICATE =
+        Components.interfaces.nsIIDBCursor.NEXT_NO_DUPLICATE;
+      const PREV_NO_DUPLICATE =
+        Components.interfaces.nsIIDBCursor.PREV_NO_DUPLICATE;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      const objectStoreName = "People";
+
+      const objectStoreData = [
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } }
+      ];
+
+      const indexData = [
+        { name: "name", keyPath: "name", options: { unique: true } },
+        { name: "height", keyPath: "height", options: { } },
+        { name: "weight", keyPath: "weight", options: { unique: false } }
+      ];
+
+      const objectStoreDataNameSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
+      ];
+
+      const objectStoreDataWeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      const objectStoreDataHeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
+
+      // First, add all our data to the object store.
+      let addedData = 0;
+      for (let i in objectStoreData) {
+        request = objectStore.add(objectStoreData[i].value,
+                                  objectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == objectStoreData.length) {
+            testGenerator.send(event);
+          }
+        }
+      }
+      event = yield;
+
+      // Now create the indexes.
+      for (let i in indexData) {
+        objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
+                                indexData[i].options);
+      }
+      is(objectStore.indexNames.length, indexData.length, "Good index count");
+      yield;
+
+      objectStore = db.transaction(objectStoreName)
+                      .objectStore(objectStoreName);
+
+      // Check global properties to make sure they are correct.
+      is(objectStore.indexNames.length, indexData.length, "Good index count");
+      for (let i in indexData) {
+        let found = false;
+        for (let j = 0; j < objectStore.indexNames.length; j++) {
+          if (objectStore.indexNames.item(j) == indexData[i].name) {
+            found = true;
+            break;
+          }
+        }
+        is(found, true, "objectStore has our index");
+        let index = objectStore.index(indexData[i].name);
+        is(index.name, indexData[i].name, "Correct name");
+        is(index.storeName, objectStore.name, "Correct store name");
+        is(index.keyPath, indexData[i].keyPath, "Correct keyPath");
+        is(index.unique, indexData[i].options.unique ? true : false,
+           "Correct unique value");
+      }
+
+      request = objectStore.index("name").getKey("Bob");
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, "237-23-7732", "Correct key returned!");
+
+      request = objectStore.index("name").get("Bob");
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, "Bob", "Correct name returned!");
+      is(event.target.result.height, 60, "Correct height returned!");
+      is(event.target.result.weight, 120, "Correct weight returned!");
+
+      ok(true, "Test group 1");
+
+      let keyIndex = 0;
+
+      request = objectStore.index("name").openKeyCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          ok(!("value" in cursor), "No value");
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+          ok(!("value" in cursor), "No value");
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreData.length, "Saw all the expected keys");
+
+      ok(true, "Test group 2");
+
+      keyIndex = 0;
+
+      request = objectStore.index("weight").openKeyCursor(null, NEXT);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataWeightSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataWeightSort[keyIndex].key,
+             "Correct value");
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreData.length - 1, "Saw all the expected keys");
+
+      // Check that the name index enforces its unique constraint.
+      objectStore = db.transaction(objectStoreName, READ_WRITE)
+                      .objectStore(objectStoreName);
+      request = objectStore.add({ name: "Bob", height: 62, weight: 170 },
+                                "237-23-7738");
+      request.onerror = new ExpectError(CONSTRAINT_ERR);
+      request.onsuccess = unexpectedSuccessHandler;
+      event = yield;
+
+      ok(true, "Test group 3");
+
+      keyIndex = objectStoreDataNameSort.length - 1;
+
+      request = objectStore.index("name").openKeyCursor(null, PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 4");
+
+      keyIndex = 1;
+      let keyRange = IDBKeyRange.bound("Bob", "Ron");
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 5");
+
+      keyIndex = 2;
+      let keyRange = IDBKeyRange.bound("Bob", "Ron", true);
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 6");
+
+      keyIndex = 1;
+      let keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 7");
+
+      keyIndex = 2;
+      keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 8");
+
+      keyIndex = 1;
+      keyRange = IDBKeyRange.lowerBound("Bob");
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
+
+      ok(true, "Test group 9");
+
+      keyIndex = 2;
+      keyRange = IDBKeyRange.lowerBound("Bob", true);
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
+
+      ok(true, "Test group 10");
+
+      keyIndex = 0;
+      keyRange = IDBKeyRange.upperBound("Joe");
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 3, "Saw all the expected keys");
+
+      ok(true, "Test group 11");
+
+      keyIndex = 0;
+      keyRange = IDBKeyRange.upperBound("Joe", true);
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 2, "Saw all the expected keys");
+
+      ok(true, "Test group 12");
+
+      keyIndex = 3;
+      keyRange = IDBKeyRange.only("Pat");
+
+      request = objectStore.index("name").openKeyCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 13");
+
+      keyIndex = 0;
+
+      request = objectStore.index("name").openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
+
+      ok(true, "Test group 14");
+
+      keyIndex = objectStoreDataNameSort.length - 1;
+
+      request = objectStore.index("name").openCursor(null, PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 15");
+
+      keyIndex = 1;
+      keyRange = IDBKeyRange.bound("Bob", "Ron");
+
+      request = objectStore.index("name").openCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 16");
+
+      keyIndex = 2;
+      keyRange = IDBKeyRange.bound("Bob", "Ron", true);
+
+      request = objectStore.index("name").openCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 17");
+
+      keyIndex = 1;
+      keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
+
+      request = objectStore.index("name").openCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 18");
+
+      keyIndex = 2;
+      keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
+
+      request = objectStore.index("name").openCursor(keyRange);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 19");
+
+      keyIndex = 4;
+      keyRange = IDBKeyRange.bound("Bob", "Ron");
+
+      request = objectStore.index("name").openCursor(keyRange, PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 0, "Saw all the expected keys");
+
+      ok(true, "Test group 20");
+
+      // Test NEXT_NO_DUPLICATE
+      keyIndex = 3;
+      keyRange = IDBKeyRange.only(65);
+
+      request = objectStore.index("height").openKeyCursor(keyRange, NEXT);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 21");
+
+      keyIndex = 3;
+      keyRange = IDBKeyRange.only(65);
+
+      request = objectStore.index("height").openKeyCursor(keyRange,
+                                                          NEXT_NO_DUPLICATE);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 21.5");
+
+      keyIndex = 5;
+
+      request = objectStore.index("height").openKeyCursor(null, PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 22");
+
+      keyIndex = 5;
+
+      request = objectStore.index("height").openKeyCursor(null,
+                                                          PREV_NO_DUPLICATE);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct value");
+
+          cursor.continue();
+          if (keyIndex == 5) {
+            keyIndex--;
+          }
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 23");
+
+      keyIndex = 3;
+      keyRange = IDBKeyRange.only(65);
+
+      request = objectStore.index("height").openCursor(keyRange, NEXT);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataHeightSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 5, "Saw all the expected keys");
+
+      ok(true, "Test group 24");
+
+      keyIndex = 3;
+      keyRange = IDBKeyRange.only(65);
+
+      request = objectStore.index("height").openCursor(keyRange,
+                                                       NEXT_NO_DUPLICATE);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataHeightSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+          keyIndex++;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, 4, "Saw all the expected keys");
+
+      ok(true, "Test group 24.5");
+
+      keyIndex = 5;
+
+      request = objectStore.index("height").openCursor(null, PREV);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataHeightSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 25");
+
+      keyIndex = 5;
+
+      request = objectStore.index("height").openCursor(null,
+                                                       PREV_NO_DUPLICATE);
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataHeightSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataHeightSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataHeightSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataHeightSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          cursor.continue();
+          if (keyIndex == 5) {
+            keyIndex--;
+          }
+          keyIndex--;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, -1, "Saw all the expected keys");
+
+      ok(true, "Test group 26");
+
+      keyIndex = 0;
+
+      request = objectStore.index("name").openKeyCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          let nextKey = !keyIndex ? "Pat" : undefined;
+
+          cursor.continue(nextKey);
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          if (!keyIndex) {
+            keyIndex = 3;
+          }
+          else {
+            keyIndex++;
+          }
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreData.length, "Saw all the expected keys");
+
+      ok(true, "Test group 27");
+
+      keyIndex = 0;
+
+      request = objectStore.index("name").openKeyCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          let nextKey = !keyIndex ? "Flo" : undefined;
+
+          cursor.continue(nextKey);
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct value");
+
+          keyIndex += keyIndex ? 1 : 2;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreData.length, "Saw all the expected keys");
+
+      ok(true, "Test group 28");
+
+      keyIndex = 0;
+
+      request = objectStore.index("name").openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          let nextKey = !keyIndex ? "Pat" : undefined;
+
+          cursor.continue(nextKey);
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          if (!keyIndex) {
+            keyIndex = 3;
+          }
+          else {
+            keyIndex++;
+          }
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
+
+      ok(true, "Test group 29");
+
+      keyIndex = 0;
+
+      request = objectStore.index("name").openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          let nextKey = !keyIndex ? "Flo" : undefined;
+
+          cursor.continue(nextKey);
+
+          is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataNameSort[keyIndex].key,
+             "Correct primary key");
+          is(cursor.value.name, objectStoreDataNameSort[keyIndex].value.name,
+             "Correct name");
+          is(cursor.value.height,
+             objectStoreDataNameSort[keyIndex].value.height,
+             "Correct height");
+          if ("weight" in cursor.value) {
+            is(cursor.value.weight,
+               objectStoreDataNameSort[keyIndex].value.weight,
+               "Correct weight");
+          }
+
+          keyIndex += keyIndex ? 1 : 2;
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_indexes_bad_values.html
+++ b/dom/indexedDB/test/test_indexes_bad_values.html
@@ -4,15 +4,144 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_indexes_bad_values.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const CONSTRAINT_ERR =
+        Components.interfaces.nsIIDBDatabaseException.CONSTRAINT_ERR;
+      const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      const objectStoreName = "People";
+
+      const objectStoreData = [
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7737", value: { name: "Pat", height: 65 } },
+        { key: "237-23-7738", value: { name: "Mel", height: 66, weight: {} } }
+      ];
+
+      const badObjectStoreData = [
+        { key: "237-23-7739", value: { name: "Rob", height: 65 } },
+        { key: "237-23-7740", value: { name: "Jen", height: 66, weight: {} } }
+      ];
+
+      const indexData = [
+        { name: "weight", keyPath: "weight", options: { unique: false } }
+      ];
+
+      const objectStoreDataWeightSort = [
+        { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
+        { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
+        { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
+        { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
+        { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
+      ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName, { } );
+
+      let addedData = 0;
+      for (let i in objectStoreData) {
+        request = objectStore.add(objectStoreData[i].value,
+                                  objectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == objectStoreData.length) {
+            testGenerator.send(event);
+          }
+        }
+      }
+      event = yield;
+
+      for (let i in indexData) {
+        objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
+                                indexData[i].options);
+      }
+
+      addedData = 0;
+      for (let i in badObjectStoreData) {
+        request = objectStore.add(badObjectStoreData[i].value,
+                                  badObjectStoreData[i].key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedData == badObjectStoreData.length) {
+            SimpleTest.executeSoon(function() { testGenerator.next() });
+          }
+        }
+      }
+      yield;
+      yield;
+
+      objectStore = db.transaction(objectStoreName)
+                      .objectStore(objectStoreName);
+
+      let keyIndex = 0;
+
+      request = objectStore.index("weight").openKeyCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
+             "Correct key");
+          is(cursor.primaryKey, objectStoreDataWeightSort[keyIndex].key,
+             "Correct value");
+          keyIndex++;
+
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreDataWeightSort.length, "Saw all weights");
+
+      keyIndex = 0;
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function (event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          keyIndex++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(keyIndex, objectStoreData.length + badObjectStoreData.length,
+         "Saw all people");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_key_requirements.html
+++ b/dom/indexedDB/test/test_key_requirements.html
@@ -4,16 +4,292 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_key_requirements.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      db.addEventListener("error", function(event) {
+        event.preventDefault();
+      }, false);
+
+      let objectStore = db.createObjectStore("foo", { autoIncrement: true });
+
+      request = objectStore.add({});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      let key1 = event.target.result;
+
+      request = objectStore.put({}, key1);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key1, "put gave the same key back");
+
+      let key2 = 10;
+
+      request = objectStore.put({}, key2);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key2, "put gave the same key back");
+
+      key2 = 100;
+
+      request = objectStore.add({}, key2);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key2, "put gave the same key back");
+
+      try {
+        objectStore.put({});
+        ok(true, "put with no key should not throw with autoIncrement!");
+      }
+      catch (e) {
+        ok(false, "put with no key threw with autoIncrement");
+      }
+
+      try {
+        objectStore.put({});
+        ok(true, "put with no key should not throw with autoIncrement!");
+      }
+      catch (e) {
+        ok(false, "put with no key threw with autoIncrement");
+      }
+
+      try {
+        objectStore.delete();
+        ok(false, "remove with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "remove with no key threw");
+      }
+
+      objectStore = db.createObjectStore("bar");
+
+      try {
+        objectStore.add({});
+        ok(false, "add with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "add with no key threw");
+      }
+
+      try {
+        objectStore.put({});
+        ok(false, "put with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with no key threw");
+      }
+
+      try {
+        objectStore.put({});
+        ok(false, "put with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with no key threw");
+      }
+
+      try {
+        objectStore.delete();
+        ok(false, "remove with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "remove with no key threw");
+      }
+
+      objectStore = db.createObjectStore("baz", { keyPath: "id" });
+
+      try {
+        objectStore.add({});
+        ok(false, "add with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "add with no key threw");
+      }
+
+      try {
+        objectStore.add({id:5}, 5);
+        ok(false, "add with inline key and passed key should throw!");
+      }
+      catch (e) {
+        ok(true, "add with inline key and passed key threw");
+      }
+
+      try {
+        objectStore.put({});
+        ok(false, "put with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with no key threw");
+      }
+
+      try {
+        objectStore.put({});
+        ok(false, "put with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with no key threw");
+      }
+
+      try {
+        objectStore.delete();
+        ok(false, "remove with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "remove with no key threw");
+      }
+
+      key1 = 10;
+
+      request = objectStore.add({id:key1});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key1, "add gave back the same key");
+
+      request = objectStore.put({id:10});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key1, "put gave back the same key");
+
+      request = objectStore.put({id:10});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key1, "put gave back the same key");
+
+      request = objectStore.add({id:10});
+      request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+      request.onsuccess = unexpectedSuccessHandler;
+      event = yield;
+
+      try {
+        objectStore.add({}, null);
+        ok(false, "add with null key should throw!");
+      }
+      catch (e) {
+        ok(true, "add with null key threw");
+      }
+
+      try {
+        objectStore.put({}, null);
+        ok(false, "put with null key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with null key threw");
+      }
+
+      try {
+        objectStore.put({}, null);
+        ok(false, "put with null key should throw!");
+      }
+      catch (e) {
+        ok(true, "put with null key threw");
+      }
+
+      try {
+        objectStore.delete({}, null);
+        ok(false, "remove with null key should throw!");
+      }
+      catch (e) {
+        ok(true, "remove with null key threw");
+      }
+
+      objectStore = db.createObjectStore("bazing", { keyPath: "id",
+                                                     autoIncrement: true });
+
+      request = objectStore.add({});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      key1 = event.target.result;
+
+      request = objectStore.put({id:key1});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key1, "put gave the same key back");
+
+      key2 = 10;
+
+      request = objectStore.put({id:key2});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, key2, "put gave the same key back");
+
+      try {
+        objectStore.put({});
+        ok(true, "put with no key should not throw with autoIncrement!");
+      }
+      catch (e) {
+        ok(false, "put with no key threw with autoIncrement");
+      }
+
+      try {
+        objectStore.put({});
+        ok(true, "put with no key should not throw with autoIncrement!");
+      }
+      catch (e) {
+        ok(false, "put with no key threw with autoIncrement");
+      }
+
+      try {
+        objectStore.delete();
+        ok(false, "remove with no key should throw!");
+      }
+      catch (e) {
+        ok(true, "remove with no key threw");
+      }
+
+      try {
+        objectStore.add({id:5}, 5);
+        ok(false, "add with inline key and passed key should throw!");
+      }
+      catch (e) {
+        ok(true, "add with inline key and passed key threw");
+      }
+
+      request = objectStore.delete(key2);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_keys.html
+++ b/dom/indexedDB/test/test_keys.html
@@ -4,15 +4,273 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_keys.js"></script>
+  <script type="text/javascript;version=1.7">
+
+    function testSteps()
+    {
+      const dbname = window.location.pathname;
+      const RW = IDBTransaction.READ_WRITE
+      let c1 = 1;
+      let c2 = 1;
+
+      let openRequest = mozIndexedDB.open(dbname, 1);
+      openRequest.onerror = errorHandler;
+      openRequest.onupgradeneeded = grabEventAndContinueHandler;
+      openRequest.onsuccess = unexpectedSuccessHandler;
+      let event = yield;
+      let db = event.target.result;
+      let trans = event.target.transaction;
+
+      // Create test stores
+      let store = db.createObjectStore("store");
+
+        // Test simple inserts
+      var keys = [
+        -1/0,
+        -1.7e308,
+        -10000,
+        -2,
+        -1.5,
+        -1,
+        -1.00001e-200,
+        -1e-200,
+        0,
+        1e-200,
+        1.00001e-200,
+        1,
+        2,
+        10000,
+        1.7e308,
+        1/0,
+        new Date("1750-01-02"),
+        new Date("1800-12-31T12:34:56.001"),
+        new Date(-1000),
+        new Date(-10),
+        new Date(-1),
+        new Date(0),
+        new Date(1),
+        new Date(2),
+        new Date(1000),
+        new Date("1971-01-01"),
+        new Date("1971-01-01T01:01:01"),
+        new Date("1971-01-01T01:01:01.001"),
+        new Date("1971-01-01T01:01:01.01"),
+        new Date("1971-01-01T01:01:01.1"),
+        new Date("1980-02-02"),
+        new Date("3333-03-19T03:33:33.333"),
+        "",
+        "\x00",
+        "\x00\x00",
+        "\x00\x01",
+        "\x01",
+        "\x02",
+        "\x03",
+        "\x04",
+        "\x07",
+        "\x08",
+        "\x0F",
+        "\x10",
+        "\x1F",
+        "\x20",
+        "01234",
+        "\x3F",
+        "\x40",
+        "A",
+        "A\x00",
+        "A1",
+        "ZZZZ",
+        "a",
+        "a\x00",
+        "aa",
+        "azz",
+        "}",
+        "\x7E",
+        "\x7F",
+        "\x80",
+        "\xFF",
+        "\u0100",
+        "\u01FF",
+        "\u0200",
+        "\u03FF",
+        "\u0400",
+        "\u07FF",
+        "\u0800",
+        "\u0FFF",
+        "\u1000",
+        "\u1FFF",
+        "\u2000",
+        "\u3FFF",
+        "\u4000",
+        "\u7FFF",
+        "\u8000",
+        "\uD800",
+        "\uD800a",
+        "\uD800\uDC01",
+        "\uDBFF",
+        "\uDC00",
+        "\uDFFF\uD800",
+        "\uFFFE",
+        "\uFFFF",
+         "\uFFFF\x00",
+        "\uFFFFZZZ",
+        [],
+        [-1/0],
+        [-1],
+        [0],
+        [1],
+        [1, "a"],
+        [1, []],
+        [1, [""]],
+        [2, 3],
+        [2, 3.0000000000001],
+        [12, [[]]],
+        [12, [[[]]]],
+        [12, [[[""]]]],
+        [12, [[["foo"]]]],
+        [12, [[[[[3]]]]]],
+        [12, [[[[[[3]]]]]]],
+        [new Date(-1)],
+        [new Date(1)],
+        [""],
+        ["", [[]]],
+        ["", [[[]]]],
+        ["abc"],
+        ["abc", "def"],
+        ["abc\x00"],
+        ["abc\x00", "\x00\x01"],
+        ["abc\x00", "\x00def"],
+        ["abc\x00\x00def"],
+        ["x", [[]]],
+        ["x", [[[]]]],
+        [[]],
+        [[],"foo"],
+        [[],[]],
+        [[[]]],
+        [[[]], []],
+        [[[]], [[]]],
+        [[[]], [[1]]],
+        [[[]], [[[]]]],
+        [[[1]]],
+        [[[[]], []]],
+        ];
+  
+      for (var i = 0; i < keys.length; ++i) {
+        let keyI = keys[i];
+        is(mozIndexedDB.cmp(keyI, keyI), 0, i + " compared to self");
+ 
+        function doCompare(keyI) {
+          for (var j = i-1; j >= i-10 && j >= 0; --j) {
+            is(mozIndexedDB.cmp(keyI, keys[j]), 1, i + " compared to " + j);
+            is(mozIndexedDB.cmp(keys[j], keyI), -1, j + " compared to " + i);
+          }
+        }
+        
+        doCompare(keyI);
+        store.add(i, keyI).onsuccess = function(e) {
+          is(mozIndexedDB.cmp(e.target.result, keyI), 0,
+             "Returned key should cmp as equal");
+          ok(compareKeys(e.target.result, keyI),
+             "Returned key should actually be equal");
+        };
+        
+        // Test that -0 compares the same as 0
+        if (keyI === 0) {
+          doCompare(-0);
+          let req = store.add(i, -0);
+          req.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+          req.onsuccess = unexpectedSuccessHandler;
+          yield;
+        }
+        else if (Array.isArray(keyI) && keyI.length === 1 && keyI[0] === 0) {
+          doCompare([-0]);
+          let req = store.add(i, [-0]);
+          req.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
+          req.onsuccess = unexpectedSuccessHandler;
+          yield;
+        }
+      }
+
+      store.openCursor().onsuccess = grabEventAndContinueHandler;
+      for (i = 0; i < keys.length; ++i) {
+        event = yield;
+        let cursor = event.target.result;
+        is(mozIndexedDB.cmp(cursor.key, keys[i]), 0,
+           "Read back key should cmp as equal");
+        ok(compareKeys(cursor.key, keys[i]),
+           "Read back key should actually be equal");
+        is(cursor.value, i, "Stored with right value");
+
+        cursor.continue();
+      }
+      event = yield;
+      is(event.target.result, undefined, "no more results expected");
+  
+      var nan = 0/0;
+      var invalidKeys = [
+        nan,
+        undefined,
+        null,
+        /x/,
+        {},
+        [nan],
+        [undefined],
+        [null],
+        [/x/],
+        [{}],
+        [1, nan],
+        [1, undefined],
+        [1, null],
+        [1, /x/],
+        [1, {}],
+        [1, [nan]],
+        [1, [undefined]],
+        [1, [null]],
+        [1, [/x/]],
+        [1, [{}]],
+        ];
+      
+      for (i = 0; i < invalidKeys.length; ++i) {
+        try {
+          mozIndexedDB.cmp(invalidKeys[i], 1);
+          ok(false, "didn't throw");
+        }
+        catch(ex) {
+          ok(ex instanceof IDBDatabaseException, "Threw IDBDatabaseException");
+          is(ex.code, IDBDatabaseException.DATA_ERR, "Threw right IDBDatabaseException");
+        }
+        try {
+          mozIndexedDB.cmp(1, invalidKeys[i]);
+          ok(false, "didn't throw2");
+        }
+        catch(ex) {
+          ok(ex instanceof IDBDatabaseException, "Threw IDBDatabaseException2");
+          is(ex.code, IDBDatabaseException.DATA_ERR, "Threw right IDBDatabaseException2");
+        }
+        try {
+          store.put(1, invalidKeys[i]);
+          ok(false, "didn't throw3");
+        }
+        catch(ex) {
+          ok(ex instanceof IDBDatabaseException, "Threw IDBDatabaseException3");
+          is(ex.code, IDBDatabaseException.DATA_ERR, "Threw right IDBDatabaseException3");
+        }
+      }
+
+      openRequest.onsuccess = grabEventAndContinueHandler;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_multientry.html
+++ b/dom/indexedDB/test/test_multientry.html
@@ -4,15 +4,227 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_multientry.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      // Test object stores
+
+      let openRequest = mozIndexedDB.open(window.location.pathname, 1);
+      openRequest.onerror = errorHandler;
+      openRequest.onupgradeneeded = grabEventAndContinueHandler;
+      openRequest.onsuccess = unexpectedSuccessHandler;
+      let event = yield;
+      let db = event.target.result;
+      db.onerror = errorHandler;
+      let tests =
+        [{ add:     { x: 1, id: 1 },
+           indexes:[{ v: 1, k: 1 }] },
+         { add:     { x: [2, 3], id: 2 },
+           indexes:[{ v: 1, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 }] },
+         { put:     { x: [2, 4], id: 1 },
+           indexes:[{ v: 2, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 },
+                    { v: 4, k: 1 }] },
+         { add:     { x: [5, 6, 5, -2, 3], id: 3 },
+           indexes:[{ v:-2, k: 3 },
+                    { v: 2, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 },
+                    { v: 3, k: 3 },
+                    { v: 4, k: 1 },
+                    { v: 5, k: 3 },
+                    { v: 6, k: 3 }] },
+         { delete:  IDBKeyRange.bound(1, 3),
+           indexes:[] },
+         { put:     { x: ["food", {}, false, undefined, /x/, [73, false]], id: 2 },
+           indexes:[{ v: "food", k: 2 }] },
+         { add:     { x: [{}, /x/, -12, "food", null, [false], undefined], id: 3 },
+           indexes:[{ v: -12, k: 3 },
+                    { v: "food", k: 2 },
+                    { v: "food", k: 3 }] },
+         { put:     { x: [], id: 2 },
+           indexes:[{ v: -12, k: 3 },
+                    { v: "food", k: 3 }] },
+         { put:     { x: { y: 3 }, id: 3 },
+           indexes:[] },
+         { add:     { x: false, id: 7 },
+           indexes:[] },
+         { delete:  IDBKeyRange.lowerBound(0),
+           indexes:[] },
+        ];
+
+      let store = db.createObjectStore("mystore", { keyPath: "id" });
+      let index = store.createIndex("myindex", "x", { multiEntry: true });
+      is(index.multiEntry, true, "index created with multiEntry");
+
+      let i;
+      for (i = 0; i < tests.length; ++i) {
+        let test = tests[i];
+        let testName = " for " + JSON.stringify(test);
+        let req;
+        if (test.add) {
+          req = store.add(test.add);
+        }
+        else if (test.put) {
+          req = store.put(test.put);
+        }
+        else if (test.delete) {
+          req = store.delete(test.delete);
+        }
+        else {
+          ok(false, "borked test");
+        }
+        req.onsuccess = grabEventAndContinueHandler;
+        let e = yield;
+        
+        req = index.openKeyCursor();
+        req.onsuccess = grabEventAndContinueHandler;
+        for (let j = 0; j < test.indexes.length; ++j) {
+          e = yield;
+          is(req.result.key, test.indexes[j].v, "found expected index key at index " + j + testName);
+          is(req.result.primaryKey, test.indexes[j].k, "found expected index primary key at index " + j + testName);
+          req.result.continue();
+        }
+        e = yield;
+        is(req.result, undefined, "exhausted indexes");
+
+        let tempIndex = store.createIndex("temp index", "x", { multiEntry: true });
+        req = tempIndex.openKeyCursor();
+        req.onsuccess = grabEventAndContinueHandler;
+        for (let j = 0; j < test.indexes.length; ++j) {
+          e = yield;
+          is(req.result.key, test.indexes[j].v, "found expected temp index key at index " + j + testName);
+          is(req.result.primaryKey, test.indexes[j].k, "found expected temp index primary key at index " + j + testName);
+          req.result.continue();
+        }
+        e = yield;
+        is(req.result, undefined, "exhausted temp index");
+        store.deleteIndex("temp index");
+      }
+
+      // Unique indexes
+      tests =
+        [{ add:     { x: 1, id: 1 },
+           indexes:[{ v: 1, k: 1 }] },
+         { add:     { x: [2, 3], id: 2 },
+           indexes:[{ v: 1, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 }] },
+         { put:     { x: [2, 4], id: 3 },
+           fail:    true },
+         { put:     { x: [1, 4], id: 1 },
+           indexes:[{ v: 1, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 },
+                    { v: 4, k: 1 }] },
+         { add:     { x: [5, 0, 5, 5, 5], id: 3 },
+           indexes:[{ v: 0, k: 3 },
+                    { v: 1, k: 1 },
+                    { v: 2, k: 2 },
+                    { v: 3, k: 2 },
+                    { v: 4, k: 1 },
+                    { v: 5, k: 3 }] },
+         { delete:  IDBKeyRange.bound(1, 2),
+           indexes:[{ v: 0, k: 3 },
+                    { v: 5, k: 3 }] },
+         { add:     { x: [0, 6], id: 8 },
+           fail:    true },
+         { add:     { x: 5, id: 8 },
+           fail:    true },
+         { put:     { x: 0, id: 8 },
+           fail:    true },
+        ];
+
+      store.deleteIndex("myindex");
+      index = store.createIndex("myindex", "x", { multiEntry: true, unique: true });
+      is(index.multiEntry, true, "index created with multiEntry");
+
+      let i;
+      let indexes;
+      for (i = 0; i < tests.length; ++i) {
+        let test = tests[i];
+        let testName = " for " + JSON.stringify(test);
+        let req;
+        if (test.add) {
+          req = store.add(test.add);
+        }
+        else if (test.put) {
+          req = store.put(test.put);
+        }
+        else if (test.delete) {
+          req = store.delete(test.delete);
+        }
+        else {
+          ok(false, "borked test");
+        }
+        
+        if (!test.fail) {
+          req.onsuccess = grabEventAndContinueHandler;
+          let e = yield;
+          indexes = test.indexes;
+        }
+        else {
+          req.onsuccess = unexpectedSuccessHandler;
+          req.onerror = grabEventAndContinueHandler;
+          ok(true, "waiting for error");
+          let e = yield;
+          ok(true, "got error: " + e.type);
+          e.preventDefault();
+          e.stopPropagation();
+        }
+
+        let e;
+        req = index.openKeyCursor();
+        req.onsuccess = grabEventAndContinueHandler;
+        for (let j = 0; j < indexes.length; ++j) {
+          e = yield;
+          is(req.result.key, indexes[j].v, "found expected index key at index " + j + testName);
+          is(req.result.primaryKey, indexes[j].k, "found expected index primary key at index " + j + testName);
+          req.result.continue();
+        }
+        e = yield;
+        is(req.result, undefined, "exhausted indexes");
+
+        let tempIndex = store.createIndex("temp index", "x", { multiEntry: true, unique: true });
+        req = tempIndex.openKeyCursor();
+        req.onsuccess = grabEventAndContinueHandler;
+        for (let j = 0; j < indexes.length; ++j) {
+          e = yield;
+          is(req.result.key, indexes[j].v, "found expected temp index key at index " + j + testName);
+          is(req.result.primaryKey, indexes[j].k, "found expected temp index primary key at index " + j + testName);
+          req.result.continue();
+        }
+        e = yield;
+        is(req.result, undefined, "exhausted temp index");
+        store.deleteIndex("temp index");
+      }
+
+
+      openRequest.onsuccess = grabEventAndContinueHandler;
+      yield;
+
+      let trans = db.transaction(["mystore"], IDBTransaction.READ_WRITE);
+      store = trans.objectStore("mystore");
+      index = store.index("myindex");
+      is(index.multiEntry, true, "index still is multiEntry");
+      trans.oncomplete = grabEventAndContinueHandler;
+      yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_objectCursors.html
+++ b/dom/indexedDB/test/test_objectCursors.html
@@ -4,16 +4,93 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_objectCursors.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      const objectStores = [
+        { name: "a", autoIncrement: false },
+        { name: "b", autoIncrement: true }
+      ];
+
+      const indexes = [
+        { name: "a", options: { } },
+        { name: "b", options: { unique: true } }
+      ];
+
+      var j = 0;
+      for (let i in objectStores) {
+        let request = mozIndexedDB.open(name, ++j, description);
+        request.onerror = errorHandler;
+        request.onupgradeneeded = grabEventAndContinueHandler;
+        let event = yield;
+
+        let db = event.target.result;
+
+        let objectStore =
+          db.createObjectStore(objectStores[i].name,
+                               { keyPath: "id",
+                                 autoIncrement: objectStores[i].autoIncrement });
+
+        for (let j in indexes) {
+          objectStore.createIndex(indexes[j].name, "name", indexes[j].options);
+        }
+
+        let data = { name: "Ben" };
+        if (!objectStores[i].autoIncrement) {
+          data.id = 1;
+        }
+
+        request = objectStore.add(data);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        event = yield;
+
+        ok(event.target.result == 1 || event.target.result == 2, "Good id");
+        db.close();
+      }
+
+      SimpleTest.executeSoon(function() { testGenerator.next(); });
+      yield;
+
+      let request = mozIndexedDB.open(name, j, description);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      for (let i in objectStores) {
+        for (let j in indexes) {
+          let objectStore = db.transaction(objectStores[i].name)
+                              .objectStore(objectStores[i].name);
+          let index = objectStore.index(indexes[j].name);
+
+          request = index.openCursor();
+          request.onerror = errorHandler;
+          request.onsuccess = function (event) {
+            is(event.target.result.value.name, "Ben", "Good object");
+            SimpleTest.executeSoon(function() { testGenerator.next(); });
+          }
+          yield;
+        }
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_objectStore_inline_autoincrement_key_added_on_put.html
+++ b/dom/indexedDB/test/test_objectStore_inline_autoincrement_key_added_on_put.html
@@ -4,16 +4,65 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_objectStore_inline_autoincrement_key_added_on_put.js"></script>
+  <script type="text/javascript;version=1.7">
+
+function testSteps()
+{
+  const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+  const IDBDatabaseException = Components.interfaces.nsIIDBDatabaseException;
+  const name = window.location.pathname;
+  const description = "My Test Database";
+
+  var request = mozIndexedDB.open(name, 1, description);
+  request.onerror = errorHandler;
+  request.onupgradeneeded = grabEventAndContinueHandler;
+  var event = yield;
+
+  var db = event.target.result;
+
+  var test = {
+    name: "inline key; key generator",
+    autoIncrement: true,
+    storedObject: {name: "Lincoln"},
+    keyName: "id",
+  };
+
+  let objectStore = db.createObjectStore(test.name,
+                                         { keyPath: test.keyName,
+                                           autoIncrement: test.autoIncrement });
+
+  request = objectStore.add(test.storedObject);
+  request.onerror = errorHandler;
+  request.onsuccess = grabEventAndContinueHandler;
+  event = yield;
+
+  let id = event.target.result;
+  request = objectStore.get(id);
+  request.onerror = errorHandler;
+  request.onsuccess = grabEventAndContinueHandler;
+  event = yield;
+
+  // Sanity check!
+  is(event.target.result.name, test.storedObject.name,
+     "The correct object was stored.");
+
+  // Ensure that the id was also stored on the object.
+  is(event.target.result.id, id, "The object had the id stored on it.");
+
+  finishTest();
+  yield;
+}
+
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_objectStore_remove_values.html
+++ b/dom/indexedDB/test/test_objectStore_remove_values.html
@@ -4,16 +4,100 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_objectStore_remove_values.js"></script>
+  <script type="text/javascript;version=1.7">
+
+function testSteps()
+{
+  const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+  const IDBDatabaseException = Components.interfaces.nsIIDBDatabaseException;
+  const name = window.location.pathname;
+  const description = "My Test Database";
+
+  var data = [
+    { name: "inline key; key generator",
+      autoIncrement: true,
+      storedObject: {name: "Lincoln"},
+      keyName: "id",
+      keyValue: undefined,
+    },
+    { name: "inline key; no key generator",
+      autoIncrement: false,
+      storedObject: {id: 1, name: "Lincoln"},
+      keyName: "id",
+      keyValue: undefined,
+    },
+    { name: "out of line key; key generator",
+      autoIncrement: true,
+      storedObject: {name: "Lincoln"},
+      keyName: undefined,
+      keyValue: undefined,
+    },
+    { name: "out of line key; no key generator",
+      autoIncrement: false,
+      storedObject: {name: "Lincoln"},
+      keyName: null,
+      keyValue: 1,
+    }
+  ];
+
+  for (let i = 0; i < data.length; i++) {
+    let test = data[i];
+
+    let request = mozIndexedDB.open(name, i+1, description);
+    request.onerror = errorHandler;
+    request.onupgradeneeded = grabEventAndContinueHandler;
+    let event = yield;
+
+    let db = event.target.result;
+
+    let objectStore = db.createObjectStore(test.name,
+                                           { keyPath: test.keyName,
+                                             autoIncrement: test.autoIncrement });
+
+    request = objectStore.add(test.storedObject, test.keyValue);
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    let id = event.target.result;
+    request = objectStore.get(id);
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    // Sanity check!
+    is(test.storedObject.name, event.target.result.name,
+                  "The correct object was stored.");
+
+    request = objectStore.delete(id);
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    // Make sure it was removed.
+    request = objectStore.get(id);
+    request.onerror = errorHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    ok(event.target.result === undefined, "Object was deleted");
+    db.close();
+  }
+
+  finishTest();
+  yield;
+}
+
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_object_identity.html
+++ b/dom/indexedDB/test/test_object_identity.html
@@ -4,16 +4,57 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_object_identity.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      let transaction = event.target.transaction;
+
+      let objectStore1 = db.createObjectStore("foo");
+      let objectStore2 = transaction.objectStore("foo");
+      ok(objectStore1 === objectStore2, "Got same objectStores");
+
+      let index1 = objectStore1.createIndex("bar", "key");
+      let index2 = objectStore2.index("bar");
+      ok(index1 === index2, "Got same indexes");
+
+      request.onsuccess = continueToNextStep;
+      yield;
+
+      transaction = db.transaction(db.objectStoreNames);
+
+      let objectStore3 = transaction.objectStore("foo");
+      let objectStore4 = transaction.objectStore("foo");
+      ok(objectStore3 === objectStore4, "Got same objectStores");
+
+      ok(objectStore3 !== objectStore1, "Different objectStores");
+      ok(objectStore4 !== objectStore2, "Different objectStores");
+
+      let index3 = objectStore3.index("bar");
+      let index4 = objectStore4.index("bar");
+      ok(index3 === index4, "Got same indexes");
+
+      ok(index3 !== index1, "Different indexes");
+      ok(index4 !== index2, "Different indexes");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_odd_result_order.html
+++ b/dom/indexedDB/test/test_odd_result_order.html
@@ -4,15 +4,85 @@
 -->
 <html>
 <head>
   <title>Indexed Database Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_odd_result_order.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const data = { key: 5, index: 10 };
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      ok(db instanceof IDBDatabase, "Got a real database");
+
+      db.onerror = errorHandler;
+
+      let objectStore = db.createObjectStore("foo", { keyPath: "key",
+                                                      autoIncrement: true });
+      let index = objectStore.createIndex("foo", "index");
+
+      event.target.onsuccess = continueToNextStep;
+      yield;
+
+      objectStore = db.transaction("foo", IDBTransaction.READ_WRITE)
+                      .objectStore("foo");
+      request = objectStore.add(data);
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      let key;
+      setTimeout(function() {
+        key = request.result;
+        continueToNextStep();
+      }, 0);
+      yield;
+
+      is(key, data.key, "Got the right key");
+
+      objectStore = db.transaction("foo").objectStore("foo");
+      objectStore.get(data.key).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      let obj;
+      setTimeout(function() {
+        obj = event.target.result;
+        continueToNextStep();
+      }, 0);
+      yield;
+
+      is(obj.key, data.key, "Got the right key");
+      is(obj.index, data.index, "Got the right property value");
+
+      objectStore = db.transaction("foo", IDBTransaction.READ_WRITE)
+                      .objectStore("foo");
+      request = objectStore.delete(data.key);
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      key = undefined;
+      setTimeout(function() {
+        key = request.result;
+        continueToNextStep();
+      }, 0);
+      yield;
+
+      ok(key === undefined, "Got the right value");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_open_empty_db.html
+++ b/dom/indexedDB/test/test_open_empty_db.html
@@ -4,16 +4,55 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_open_empty_db.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const names = [
+        "",
+        null,
+        undefined,
+        window.location.pathname
+      ];
+
+      const version = 1;
+
+      for each (let name in names) {
+        let request = mozIndexedDB.open(name, version);
+        request.onerror = errorHandler;
+        request.onsuccess = grabEventAndContinueHandler;
+        let event = yield;
+
+        if (name === null) {
+          name = "null";
+        }
+        else if (name === undefined) {
+          name = "undefined";
+        }
+
+        let db = event.target.result;
+        is(db.name, name, "Bad name");
+        is(db.version, version, "Bad version");
+        is(db.objectStoreNames.length, 0, "Bad objectStores list");
+
+        is(db.name, request.result.name, "Bad name");
+        is(db.version, request.result.version, "Bad version");
+        is(db.objectStoreNames.length, request.result.objectStoreNames.length,
+           "Bad objectStores list");
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_open_objectStore.html
+++ b/dom/indexedDB/test/test_open_objectStore.html
@@ -4,16 +4,50 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_open_objectStore.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "Objects";
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      is(db.objectStoreNames.length, 0, "Bad objectStores list");
+
+      let objectStore = db.createObjectStore(objectStoreName,
+                                             { keyPath: "foo" });
+
+      is(db.objectStoreNames.length, 1, "Bad objectStores list");
+      is(db.objectStoreNames.item(0), objectStoreName, "Bad name");
+
+      yield;
+
+      objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
+
+      is(objectStore.name, objectStoreName, "Bad name");
+      is(objectStore.keyPath, "foo", "Bad keyPath");
+      if(objectStore.indexNames.length, 0, "Bad indexNames");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_optionalArguments.html
+++ b/dom/indexedDB/test/test_optionalArguments.html
@@ -1,18 +1,1715 @@
-<!--
+<!--
   Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_optionalArguments.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const osName = "people";
+      const indexName = "weight";
+
+      const data = [
+        { ssn: "237-23-7732", name: "Bob", height: 60, weight: 120 },
+        { ssn: "237-23-7733", name: "Ann", height: 52, weight: 110 },
+        { ssn: "237-23-7734", name: "Ron", height: 73, weight: 180 },
+        { ssn: "237-23-7735", name: "Sue", height: 58, weight: 130 },
+        { ssn: "237-23-7736", name: "Joe", height: 65, weight: 150 },
+        { ssn: "237-23-7737", name: "Pat", height: 65 },
+        { ssn: "237-23-7738", name: "Mel", height: 66, weight: {} },
+        { ssn: "237-23-7739", name: "Tom", height: 62, weight: 130 }
+      ];
+
+      const weightSort = [1, 0, 3, 7, 4, 2];
+
+      let request = mozIndexedDB.open(window.location.pathname, 1);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield;
+
+      is(event.type, "upgradeneeded", "Got upgradeneeded event");
+
+      let db = event.target.result;
+      db.onerror = errorHandler;
+
+      let objectStore = db.createObjectStore(osName, { keyPath: "ssn" });
+      objectStore.createIndex(indexName, "weight", { unique: false });
+
+      for each (let i in data) {
+        objectStore.add(i);
+      }
+
+      event = yield;
+
+      is(event.type, "success", "Got success event");
+
+      try {
+        IDBKeyRange.bound(1, -1);
+        ok(false, "Bound keyRange with backwards args should throw!");
+      }
+      catch (e) {
+        is(e.code, IDBDatabaseException.DATA_ERR, "Threw correct exception");
+      }
+
+      try {
+        IDBKeyRange.bound(1, 1);
+        ok(true, "Bound keyRange with same arg should be ok");
+      }
+      catch (e) {
+        ok(false, "Bound keyRange with same arg should have been ok");
+      }
+
+      try {
+        IDBKeyRange.bound(1, 1, true);
+        ok(false, "Bound keyRange with same arg and open should throw!");
+      }
+      catch (e) {
+        is(e.code, IDBDatabaseException.DATA_ERR, "Threw correct exception");
+      }
+
+      try {
+        IDBKeyRange.bound(1, 1, true, true);
+        ok(false, "Bound keyRange with same arg and open should throw!");
+      }
+      catch (e) {
+        is(e.code, IDBDatabaseException.DATA_ERR, "Threw correct exception");
+      }
+
+      objectStore = db.transaction(osName).objectStore(osName);
+
+      try {
+        objectStore.get();
+        ok(false, "Get with unspecified arg should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with unspecified arg should have thrown");
+      }
+
+      try {
+        objectStore.get(undefined);
+        ok(false, "Get with undefined should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with undefined arg should have thrown");
+      }
+
+      try {
+        objectStore.get(null);
+        ok(false, "Get with null should have thrown");
+      }
+      catch(e) {
+        is(e instanceof IDBDatabaseException, true,
+           "Got right kind of exception");
+        is(e.code, IDBDatabaseException.DATA_ERR, "Correct error code.");
+      }
+
+      objectStore.get(data[2].ssn).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[2].name, "Correct data");
+
+      let keyRange = IDBKeyRange.only(data[2].ssn);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[2].name, "Correct data");
+
+      keyRange = IDBKeyRange.lowerBound(data[2].ssn);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[2].name, "Correct data");
+
+      keyRange = IDBKeyRange.lowerBound(data[2].ssn, true);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[3].name, "Correct data");
+
+      keyRange = IDBKeyRange.upperBound(data[2].ssn);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[0].name, "Correct data");
+
+      keyRange = IDBKeyRange.bound(data[2].ssn, data[4].ssn);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[2].name, "Correct data");
+
+      keyRange = IDBKeyRange.bound(data[2].ssn, data[4].ssn, true);
+
+      objectStore.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.name, data[3].name, "Correct data");
+
+      objectStore = db.transaction(osName, IDBTransaction.READ_WRITE)
+                      .objectStore(osName);
+
+      try {
+        objectStore.delete();
+        ok(false, "Delete with unspecified arg should have thrown");
+      }
+      catch(e) {
+        ok(true, "Delete with unspecified arg should have thrown");
+      }
+
+      try {
+        objectStore.delete(undefined);
+        ok(false, "Delete with undefined should have thrown");
+      }
+      catch(e) {
+        ok(true, "Delete with undefined arg should have thrown");
+      }
+
+      try {
+        objectStore.delete(null);
+        ok(false, "Delete with null should have thrown");
+      }
+      catch(e) {
+        is(e instanceof IDBDatabaseException, true,
+           "Got right kind of exception");
+        is(e.code, IDBDatabaseException.DATA_ERR, "Correct error code.");
+      }
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data.length, "Correct count");
+
+      objectStore.delete(data[2].ssn).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(event.target.result === undefined, "Correct result");
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data.length - 1, "Correct count");
+
+      keyRange = IDBKeyRange.bound(data[3].ssn, data[5].ssn);
+
+      objectStore.delete(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(event.target.result === undefined, "Correct result");
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data.length - 4, "Correct count");
+
+      keyRange = IDBKeyRange.lowerBound(10);
+
+      objectStore.delete(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      ok(event.target.result === undefined, "Correct result");
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, 0, "Correct count");
+
+      event.target.transaction.oncomplete = grabEventAndContinueHandler;
+
+      for each (let i in data) {
+        objectStore.add(i);
+      }
+
+      yield;
+
+      objectStore = db.transaction(osName).objectStore(osName);
+
+      objectStore.count().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data.length, "Correct count");
+
+      let count = 0;
+
+      objectStore.openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, data.length, "Correct count for no arg to openCursor");
+
+      count = 0;
+
+      objectStore.openCursor(null).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, data.length, "Correct count for null arg to openCursor");
+
+      count = 0;
+
+      objectStore.openCursor(undefined).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, data.length, "Correct count for undefined arg to openCursor");
+
+      count = 0;
+
+      objectStore.openCursor(data[2].ssn).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for single key arg to openCursor");
+
+      count = 0;
+
+      objectStore.openCursor("foo").onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent single key arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only(data[2].ssn);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for only keyRange arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[2].ssn);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, data.length - 2,
+         "Correct count for lowerBound arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[2].ssn, true);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, data.length - 3,
+         "Correct count for lowerBound arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound("foo");
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent lowerBound arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[2].ssn, data[3].ssn);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 2, "Correct count for bound arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[2].ssn, data[3].ssn, true);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for bound arg to openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[2].ssn, data[3].ssn, true, true);
+
+      objectStore.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0, "Correct count for bound arg to openCursor");
+
+      let index = objectStore.index(indexName);
+
+      count = 0;
+
+      index.openKeyCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for unspecified arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(null).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for null arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(undefined).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for undefined arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(data[0].weight).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for single key arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor("foo").onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent key arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only("foo");
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only(data[0].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1,
+         "Correct count for only keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for lowerBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight, true);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for lowerBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound("foo");
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for lowerBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight, true);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[weightSort.length - 1]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[weightSort.length - 1]].weight,
+                                        true);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound("foo");
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(0);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for upperBound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight,
+                                   true);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight,
+                                   true, true);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 2,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight - 1,
+                                   data[weightSort[weightSort.length - 1]].weight + 1);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight - 2,
+                                   data[weightSort[0]].weight - 1);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[1]].weight,
+                                   data[weightSort[2]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 3,
+         "Correct count for bound keyRange arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for unspecified arg to index.openCursor");
+
+      count = 0;
+
+      index.openCursor(null).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for null arg to index.openCursor");
+
+      count = 0;
+
+      index.openCursor(undefined).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for undefined arg to index.openCursor");
+
+      count = 0;
+
+      index.openCursor(data[0].weight).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for single key arg to index.openCursor");
+
+      count = 0;
+
+      index.openCursor("foo").onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent key arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only("foo");
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only(data[0].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1,
+         "Correct count for only keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for lowerBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight, true);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for lowerBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.lowerBound("foo");
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for lowerBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight, true);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[weightSort.length - 1]].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(data[weightSort[weightSort.length - 1]].weight,
+                                        true);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound("foo");
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.upperBound(0);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for upperBound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight,
+                                   true);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 1,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[weightSort.length - 1]].weight,
+                                   true, true);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length - 2,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight - 1,
+                                   data[weightSort[weightSort.length - 1]].weight + 1);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight - 2,
+                                   data[weightSort[0]].weight - 1);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.bound(data[weightSort[1]].weight,
+                                   data[weightSort[2]].weight);
+
+      index.openCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 3,
+         "Correct count for bound keyRange arg to index.openCursor");
+
+      try {
+        index.get();
+        ok(false, "Get with unspecified arg should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with unspecified arg should have thrown");
+      }
+
+      try {
+        index.get(undefined);
+        ok(false, "Get with undefined should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with undefined arg should have thrown");
+      }
+
+      try {
+        index.get(null);
+        ok(false, "Get with null should have thrown");
+      }
+      catch(e) {
+        is(e instanceof IDBDatabaseException, true,
+           "Got right kind of exception");
+        is(e.code, IDBDatabaseException.DATA_ERR, "Correct error code.");
+      }
+
+      index.get(data[0].weight).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[0].weight, "Got correct result");
+
+      keyRange = IDBKeyRange.only(data[0].weight);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[0].weight, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[0]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight - 1);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[0]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight + 1);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[1]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight, true);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[1]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[0]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight, true);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[1]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight, true, true);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, undefined, "Got correct result");
+
+      keyRange = IDBKeyRange.upperBound(data[weightSort[5]].weight);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result.weight, data[weightSort[0]].weight,
+         "Got correct result");
+
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight, true);
+
+      index.get(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, undefined, "Got correct result");
+
+      try {
+        index.getKey();
+        ok(false, "Get with unspecified arg should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with unspecified arg should have thrown");
+      }
+
+      try {
+        index.getKey(undefined);
+        ok(false, "Get with undefined should have thrown");
+      }
+      catch(e) {
+        ok(true, "Get with undefined arg should have thrown");
+      }
+
+      try {
+        index.getKey(null);
+        ok(false, "Get with null should have thrown");
+      }
+      catch(e) {
+        is(e instanceof IDBDatabaseException, true,
+           "Got right kind of exception");
+        is(e.code, IDBDatabaseException.DATA_ERR, "Correct error code.");
+      }
+
+      index.getKey(data[0].weight).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[0].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.only(data[0].weight);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[0].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight - 1);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight + 1);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[1]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(data[weightSort[0]].weight, true);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[1]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight, true);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[1]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.bound(data[weightSort[0]].weight,
+                                   data[weightSort[1]].weight, true, true);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, undefined, "Got correct result");
+
+      keyRange = IDBKeyRange.upperBound(data[weightSort[5]].weight);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.upperBound(data[weightSort[0]].weight, true);
+
+      index.getKey(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result, undefined, "Got correct result");
+
+      count = 0;
+
+      index.openKeyCursor().onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for no arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(null).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for null arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(undefined).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, weightSort.length,
+         "Correct count for undefined arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor(data[weightSort[0]].weight).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1, "Correct count for single key arg to index.openKeyCursor");
+
+      count = 0;
+
+      index.openKeyCursor("foo").onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 0,
+         "Correct count for non-existent single key arg to index.openKeyCursor");
+
+      count = 0;
+      keyRange = IDBKeyRange.only(data[weightSort[0]].weight);
+
+      index.openKeyCursor(keyRange).onsuccess = function(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          count++;
+          cursor.continue();
+        }
+        else {
+          testGenerator.next();
+        }
+      }
+      yield;
+
+      is(count, 1,
+         "Correct count for only keyRange arg to index.openKeyCursor");
+
+      objectStore.getAll(data[1].ssn).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, 1, "Got correct length");
+      is(event.target.result[0].ssn, data[1].ssn, "Got correct result");
+
+      objectStore.getAll(null).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, data.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
+      }
+
+      objectStore.getAll(undefined).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, data.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
+      }
+
+      objectStore.getAll().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, data.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
+      }
+
+      keyRange = IDBKeyRange.lowerBound(0);
+
+      objectStore.getAll(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, data.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[i].ssn, "Got correct value");
+      }
+
+      index.getAll().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAll(undefined).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAll(null).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAll(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, 1, "Got correct length");
+      is(event.target.result[0].ssn, data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(0);
+
+      index.getAll(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i].ssn, data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAllKeys().onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i], data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAllKeys(undefined).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i], data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAllKeys(null).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i], data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      index.getAllKeys(data[weightSort[0]].weight).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, 1, "Got correct length");
+      is(event.target.result[0], data[weightSort[0]].ssn, "Got correct result");
+
+      keyRange = IDBKeyRange.lowerBound(0);
+
+      index.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(event.target.result instanceof Array, true, "Got an array");
+      is(event.target.result.length, weightSort.length, "Got correct length");
+      for (let i in event.target.result) {
+        is(event.target.result[i], data[weightSort[i]].ssn,
+           "Got correct value");
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_overlapping_transactions.html
+++ b/dom/indexedDB/test/test_overlapping_transactions.html
@@ -4,16 +4,100 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_overlapping_transactions.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStores = [ "foo", "bar" ];
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
+
+      event.target.onsuccess = grabEventAndContinueHandler;
+      for (let i in objectStores) {
+        db.createObjectStore(objectStores[i], { autoIncrement: true });
+      }
+      let event = yield;
+
+      is(db.objectStoreNames.length, objectStores.length,
+         "Correct objectStoreNames list");
+
+      for (let i = 0; i < 50; i++) {
+        let stepNumber = 0;
+
+        request = db.transaction(["foo"], READ_WRITE)
+                    .objectStore("foo")
+                    .add({});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(stepNumber, 1, "This callback came first");
+          stepNumber++;
+        }
+
+        request = db.transaction(["foo"], READ_WRITE)
+                    .objectStore("foo")
+                    .add({});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(stepNumber, 2, "This callback came second");
+          stepNumber++;
+        }
+
+        request = db.transaction(["foo", "bar"], READ_WRITE)
+                    .objectStore("bar")
+                    .add({});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(stepNumber, 3, "This callback came third");
+          stepNumber++;
+        }
+
+        request = db.transaction(["foo", "bar"], READ_WRITE)
+                    .objectStore("bar")
+                    .add({});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(stepNumber, 4, "This callback came fourth");
+          stepNumber++;
+        }
+
+        request = db.transaction(["bar"], READ_WRITE)
+                    .objectStore("bar")
+                    .add({});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(stepNumber, 5, "This callback came fifth");
+          stepNumber++;
+          event.target.transaction.oncomplete = grabEventAndContinueHandler;
+        }
+
+        stepNumber++;
+        yield;
+
+        is(stepNumber, 6, "All callbacks received");
+      }
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_put_get_values.html
+++ b/dom/indexedDB/test/test_put_get_values.html
@@ -4,16 +4,61 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_put_get_values.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "Objects";
+
+      let testString = { key: 0, value: "testString" };
+      let testInt = { key: 1, value: 1002 };
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName,
+                                             { autoIncrement: 0 });
+
+      request = objectStore.add(testString.value, testString.key);
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        is(event.target.result, testString.key, "Got the right key");
+        request = objectStore.get(testString.key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(event.target.result, testString.value, "Got the right value");
+        };
+      };
+
+      request = objectStore.add(testInt.value, testInt.key);
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        is(event.target.result, testInt.key, "Got the right key");
+        request = objectStore.get(testInt.key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(event.target.result, testInt.value, "Got the right value");
+          finishTest();
+        };
+      }
+
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_put_get_values_autoIncrement.html
+++ b/dom/indexedDB/test/test_put_get_values_autoIncrement.html
@@ -4,16 +4,61 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_put_get_values_autoIncrement.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "Objects";
+
+      let testString = { value: "testString" };
+      let testInt = { value: 1002 };
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore(objectStoreName,
+                                             { autoIncrement: 1 });
+
+      request = objectStore.put(testString.value);
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        testString.key = event.target.result;
+        request = objectStore.get(testString.key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(event.target.result, testString.value, "Got the right value");
+        };
+      };
+
+      request = objectStore.put(testInt.value);
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        testInt.key = event.target.result;
+        request = objectStore.get(testInt.key);
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          is(event.target.result, testInt.value, "Got the right value");
+          finishTest();
+        };
+      }
+
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_remove_index.html
+++ b/dom/indexedDB/test/test_remove_index.html
@@ -4,16 +4,67 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_remove_index.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const indexName = "My Test Index";
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
+
+      let objectStore = db.createObjectStore("test store", { keyPath: "foo" });
+      is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
+      is(db.objectStoreNames.item(0), objectStore.name, "Correct name");
+
+      is(objectStore.indexNames.length, 0, "Correct indexNames list");
+
+      let index = objectStore.createIndex(indexName, "foo");
+
+      is(objectStore.indexNames.length, 1, "Correct indexNames list");
+      is(objectStore.indexNames.item(0), indexName, "Correct name");
+      is(objectStore.index(indexName), index, "Correct instance");
+
+      objectStore.deleteIndex(indexName);
+
+      is(objectStore.indexNames.length, 0, "Correct indexNames list");
+      try {
+        objectStore.index(indexName);
+        ok(false, "should have thrown");
+      }
+      catch(ex) {
+        ok(ex instanceof IDBDatabaseException, "Got a IDBDatabaseException");
+        is(ex.code, IDBDatabaseException.NOT_FOUND_ERR, "expect a NOT_FOUND_ERR");
+      }
+
+      let index2 = objectStore.createIndex(indexName, "foo");
+      isnot(index, index2, "New instance should be created");
+
+      is(objectStore.indexNames.length, 1, "Correct recreacted indexNames list");
+      is(objectStore.indexNames.item(0), indexName, "Correct recreacted name");
+      is(objectStore.index(indexName), index2, "Correct instance");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_remove_objectStore.html
+++ b/dom/indexedDB/test/test_remove_objectStore.html
@@ -4,16 +4,119 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_remove_objectStore.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
+      const UNKNOWN_ERR =
+        Components.interfaces.nsIIDBDatabaseException.UNKNOWN_ERR;
+
+      const name = window.location.pathname;
+      const description = "My Test Database";
+      const objectStoreName = "Objects";
+
+      let request = mozIndexedDB.open(name, 1, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
+
+      let objectStore = db.createObjectStore(objectStoreName,
+                                             { keyPath: "foo" });
+
+      let addedCount = 0;
+
+      for (let i = 0; i < 100; i++) {
+        request = objectStore.add({foo: i});
+        request.onerror = errorHandler;
+        request.onsuccess = function(event) {
+          if (++addedCount == 100) {
+            SimpleTest.executeSoon(function() { testGenerator.next(); });
+          }
+        }
+      }
+      yield;
+
+      is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
+      is(db.objectStoreNames.item(0), objectStoreName, "Correct name");
+
+      db.close();
+
+      let request = mozIndexedDB.open(name, 2, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+      let trans = event.target.transaction;
+
+      let oldObjectStore = trans.objectStore(objectStoreName);
+      isnot(oldObjectStore, null, "Correct object store prior to deleting");
+      db.deleteObjectStore(objectStoreName);
+      is(db.objectStoreNames.length, 0, "Correct objectStores list");
+      try {
+        trans.objectStore(objectStoreName);
+        ok(false, "should have thrown");
+      }
+      catch(ex) {
+        ok(ex instanceof IDBDatabaseException, "Got a IDBDatabaseException");
+        is(ex.code, IDBDatabaseException.NOT_FOUND_ERR, "expect a NOT_FOUND_ERR");
+      }
+
+      objectStore = db.createObjectStore(objectStoreName, { keyPath: "foo" });
+      is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
+      is(db.objectStoreNames.item(0), objectStoreName, "Correct name");
+      is(trans.objectStore(objectStoreName), objectStore, "Correct new objectStore");
+      isnot(oldObjectStore, objectStore, "Old objectStore is not new objectStore");
+
+      request = objectStore.openCursor();
+      request.onerror = errorHandler;
+      request.onsuccess = function(event) {
+        is(event.target.result, undefined, "ObjectStore shouldn't have any items");
+        testGenerator.send(event);
+      }
+      event = yield;
+
+      db.deleteObjectStore(objectStore.name);
+      is(db.objectStoreNames.length, 0, "Correct objectStores list");
+
+      continueToNextStep();
+      yield;
+
+      db.close();
+
+      let request = mozIndexedDB.open(name, 3, description);
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      let db = event.target.result;
+
+      objectStore = db.createObjectStore(objectStoreName, { keyPath: "foo" });
+
+      request = objectStore.add({foo:"bar"});
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+
+      db.deleteObjectStore(objectStoreName);
+
+      event = yield;
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_request_readyState.html
+++ b/dom/indexedDB/test/test_request_readyState.html
@@ -4,16 +4,61 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_request_readyState.js"></script>
+  <script type="text/javascript;version=1.7">
+    function testSteps()
+    {
+      const name = window.location.pathname;
+      const description = "My Test Database";
+
+      const LOADING = Components.interfaces.nsIIDBRequest.LOADING;
+      const DONE = Components.interfaces.nsIIDBRequest.DONE;
+
+      let request = mozIndexedDB.open(name, 1, description);
+      is(request.readyState, LOADING, "Correct readyState");
+
+      request.onerror = errorHandler;
+      request.onupgradeneeded = grabEventAndContinueHandler;
+      let event = yield;
+
+      is(request.readyState, DONE, "Correct readyState");
+
+      let db = event.target.result;
+
+      let objectStore = db.createObjectStore("foo");
+      let key = 10;
+
+      request = objectStore.add({}, key);
+      is(request.readyState, LOADING, "Correct readyState");
+
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      event = yield;
+
+      is(request.readyState, DONE, "Correct readyState");
+      is(event.target.result, key, "Correct key");
+
+      request = objectStore.get(key);
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      is(request.readyState, LOADING, "Correct readyState");
+      event = yield;
+
+      ok(event.target.result, "Got something");
+      is(request.readyState, DONE, "Correct readyState");
+
+      finishTest();
+      yield;
+    }
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_setVersion.html
+++ b/dom/indexedDB/test/test_setVersion.html
@@ -4,16 +4,64 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_setVersion.js"></script>
+  <script type="text/javascript;version=1.7">
+
+function testSteps()
+{
+  const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
+  const VERSION_CHANGE = Components.interfaces.nsIIDBTransaction.VERSION_CHANGE;
+
+  const name = window.location.pathname;
+  const description = "My Test Database";
+
+  let request = mozIndexedDB.open(name, 1, description);
+  request.onerror = errorHandler;
+  request.onsuccess = grabEventAndContinueHandler;
+  let event = yield;
+
+  let db = event.target.result;
+
+  // Check default state.
+  is(db.version, 1, "Correct default version for a new database.");
+
+  const versions = [
+    7,
+    42,
+  ];
+
+  db.close();
+
+  for (let i = 0; i < versions.length; i++) {
+    let version = versions[i];
+
+    let request = mozIndexedDB.open(name, version, description);
+    request.onerror = errorHandler;
+    request.onupgradeneeded = grabEventAndContinueHandler;
+    let event = yield;
+
+    let db = event.target.result;
+
+    is(db.version, version, "Database version number updated correctly");
+    is(event.target.transaction.mode, VERSION_CHANGE, "Correct mode");
+
+    SimpleTest.executeSoon(function() { testGenerator.next(); });
+    yield;
+    db.close();
+  }
+
+  finishTest();
+  yield;
+}
+  </script>
   <script type="text/javascript;version=1.7" src="helpers.js"></script>
 
 </head>
 
 <body onload="runTest();"></body>
 
 </html>
--- a/dom/indexedDB/test/test_setVersion_abort.html
+++ b/dom/indexedDB/test/test_setVersion_abort.html
@@ -4,16 +4,75 @@
 -->
 <html>
 <head>
   <title>Indexed Database Property Test</title>
 
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 
-  <script type="text/javascript;version=1.7" src="unit/test_setVersion_abort.js"></script>
+  <script type="text/javascript;version=1.7">
+
+function testSteps()
+{
+  const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;