 +////////////////////////////////////////////////////////////////////////////////
 +/// @}
 +////////////////////////////////////////////////////////////////////////////////
-+
-+// -----------------------------------------------------------------------------
+ 
+ // -----------------------------------------------------------------------------
  // --SECTION--                                                  HELPER FUNCTIONS
- // -----------------------------------------------------------------------------
- 
-@@ -513,7 +579,9 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
+@@ -476,14 +535,19 @@ static v8::Handle<v8::Value> EnsurePathIndex (string const& cmd,
+ 
+ ////////////////////////////////////////////////////////////////////////////////
+ /// @brief looks up a document
++///
++/// it is the caller's responsibility to acquire and release the required locks
++/// the collection must also have the correct status already. don't use this
++/// function if you're unsure about it!
+ ////////////////////////////////////////////////////////////////////////////////
+ 
+ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
+                                                  TRI_vocbase_col_t const* collection,
+-                                                 v8::Arguments const& argv) {
++                                                 v8::Arguments const& argv,
++                                                 const bool lock) {
+   v8::HandleScope scope;
+ 
+-  // first and only argument schould be a document idenfifier
++  // first and only argument should be a document idenfifier
+   if (argv.Length() != 1) {
+     return scope.Close(v8::ThrowException(
+                          TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
+@@ -492,10 +556,10 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
+ 
+   TRI_voc_did_t did;
+   TRI_voc_rid_t rid;
+-  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, argv[0]);
++  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, lock, argv[0]);
+ 
+   if (! err.IsEmpty()) {
+-    if (collection != 0) {
++    if (collection != 0 && lock) {
+       TRI_ReleaseCollection(collection);
+     }
+ 
+@@ -513,7 +577,9 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
    // inside a read transaction
    // .............................................................................
  
-+  LOG_TRACE("before beginRead");
-   collection->_collection->beginRead(collection->_collection);
-+  LOG_TRACE("after beginRead");
+-  collection->_collection->beginRead(collection->_collection);
++  if (lock) {
++    collection->_collection->beginRead(collection->_collection);
++  }
  
    document = collection->_collection->read(collection->_collection, did);
  
-@@ -524,7 +592,9 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
+@@ -524,13 +590,17 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (TRI_vocbase_t* vocbase,
      result = TRI_WrapShapedJson(collection, &document, barrier);
    }
  
-+  LOG_TRACE("before endRead");
-   collection->_collection->endRead(collection->_collection);
-+  LOG_TRACE("after beginRead");
+-  collection->_collection->endRead(collection->_collection);
++  if (lock) {
++    collection->_collection->endRead(collection->_collection);
++  }
  
    // .............................................................................
    // outside a write transaction
-@@ -610,7 +680,9 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (TRI_vocbase_t* vocbase,
-   // inside a write transaction
    // .............................................................................
  
-+  LOG_TRACE("before beginWrite");
-   collection->_collection->beginWrite(collection->_collection);
-+  LOG_TRACE("after beginWrite");
- 
-   TRI_voc_rid_t oldRid = 0;
-   TRI_doc_mptr_t mptr = doc->update(doc, shaped, did, rid, &oldRid, policy, true);
-@@ -1006,6 +1078,7 @@ static v8::Handle<v8::Value> ExecuteQueryNativeAhuacatl (TRI_aql_context_t* cons
-                                                          const TRI_json_t* const parameters) {
-   v8::HandleScope scope;
- 
-+  LOGGER_DEBUG << "executing native query";
-   // parse & validate
-   // bind values
-   // optimise
-@@ -1014,21 +1087,28 @@ static v8::Handle<v8::Value> ExecuteQueryNativeAhuacatl (TRI_aql_context_t* cons
-       !TRI_BindQueryContextAql(context, parameters) ||
-       !TRI_LockQueryContextAql(context) ||
-       !TRI_OptimiseQueryContextAql(context)) {
-+    LOGGER_DEBUG << "executing native query failed";
-     v8::Handle<v8::Object> errorObject = CreateErrorObjectAhuacatl(&context->_error);
- 
-     return scope.Close(v8::ThrowException(errorObject));
-   }
- 
-+  LOGGER_DEBUG << "generating code for native query";
-   // generate code
-   char* code = TRI_GenerateCodeAql(context);
-+  LOGGER_DEBUG << "generating code finished";
-   if (!code) {
-+    LOGGER_DEBUG << "generating code failed";
-     v8::Handle<v8::Object> errorObject = CreateErrorObjectAhuacatl(&context->_error);
- 
-     return scope.Close(v8::ThrowException(errorObject));
-   }
-+  LOGGER_DEBUG << "generating code succeeded";
- 
-   // execute code
-+  LOGGER_DEBUG << "executing generated Javascript code";
-   v8::Handle<v8::Value> result = TRI_ExecuteJavaScriptString(v8::Context::GetCurrent(), v8::String::New(code), v8::String::New("query"), false);
-+  LOGGER_DEBUG << "finished executing generated Javascript code";
-   TRI_Free(TRI_UNKNOWN_MEM_ZONE, code);
- 
-   // return the result as a javascript array
-@@ -1048,14 +1128,18 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
-   v8::HandleScope scope;
-   v8::TryCatch tryCatch;
- 
-+  LOGGER_DEBUG << "executing query cursor";
-   v8::Handle<v8::Value> result = ExecuteQueryNativeAhuacatl(context, parameters);
-+  LOGGER_DEBUG << "finished executing query cursor";
- 
-   if (tryCatch.HasCaught()) {
-+    LOGGER_DEBUG << "executing query cursor failed";
-     return scope.Close(v8::ThrowException(tryCatch.Exception()));
-   }
- 
-   if (allowDirectReturn || !result->IsArray()) {
-     // return the value we got as it is. this is a performance optimisation
-+    LOGGER_DEBUG << "executing query cursor returned directly";
-     return scope.Close(result);
-   }
- 
-@@ -1063,6 +1147,7 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
-   TRI_json_t* json = TRI_JsonObject(result);
- 
-   if (!json) {
-+    LOGGER_DEBUG << "executing query cursor failed with out-of-memory";
-     v8::Handle<v8::Object> errorObject = TRI_CreateErrorObject(TRI_ERROR_OUT_OF_MEMORY, "out of memory");
- 
-     return scope.Close(v8::ThrowException(errorObject));
-@@ -1073,6 +1158,7 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
-   if (!cursorResult) {
-     TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
- 
-+    LOGGER_DEBUG << "executing query cursor failed with out-of-memory at cursor result";
-     v8::Handle<v8::Object> errorObject = TRI_CreateErrorObject(TRI_ERROR_OUT_OF_MEMORY, "out of memory");
- 
-     return scope.Close(v8::ThrowException(errorObject));
-@@ -1083,6 +1169,7 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
-     TRI_Free(TRI_UNKNOWN_MEM_ZONE, cursorResult);
-     TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
- 
-+    LOGGER_DEBUG << "creating general cursor failed";
-     v8::Handle<v8::Object> errorObject = TRI_CreateErrorObject(TRI_ERROR_OUT_OF_MEMORY, "out of memory");
- 
-     return scope.Close(v8::ThrowException(errorObject));
-@@ -1091,6 +1178,7 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
-   assert(cursor);
-   TRI_StoreShadowData(vocbase->_cursors, (const void* const) cursor);
- 
-+  LOGGER_DEBUG << "returning general cursor";
-   return scope.Close(WrapGeneralCursor(cursor));
- }
- 
-@@ -1299,12 +1387,10 @@ static v8::Handle<v8::Value> JS_DisposeGeneralCursor (v8::Arguments const& argv)
-   bool found = TRI_DeleteDataShadowData(vocbase->_cursors, UnwrapGeneralCursor(argv.Holder()));
- 
-   if (found) {
--    return scope.Close(v8::True());
--  }
--
+-  TRI_ReleaseCollection(collection);
++  if (lock) {
++    TRI_ReleaseCollection(collection);
++  }
+ 
+   if (document._did == 0) {
+     return scope.Close(v8::ThrowException(
+@@ -571,7 +641,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (TRI_vocbase_t* vocbase,
+   TRI_voc_did_t did;
+   TRI_voc_rid_t rid;
+ 
+-  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, argv[0]);
++  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, true, argv[0]);
+ 
+   if (! err.IsEmpty()) {
+     if (collection != 0) {
+@@ -658,7 +728,7 @@ static v8::Handle<v8::Value> DeleteVocbaseCol (TRI_vocbase_t* vocbase,
+   TRI_voc_did_t did;
+   TRI_voc_rid_t rid;
+ 
+-  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, argv[0]);
++  v8::Handle<v8::Value> err = TRI_ParseDocumentOrDocumentHandle(vocbase, collection, did, rid, true, argv[0]);
+ 
+   if (! err.IsEmpty()) {
+     if (collection != 0) {
+@@ -1302,9 +1372,7 @@ static v8::Handle<v8::Value> JS_DisposeGeneralCursor (v8::Arguments const& argv)
+     return scope.Close(v8::True());
+   }
+ 
 -  return scope.Close(v8::ThrowException(
 -                       TRI_CreateErrorObject(TRI_ERROR_CURSOR_NOT_FOUND,
 -                                             "disposed or unknown cursor")));
-+     return scope.Close(v8::True());
-+   }
++  return scope.Close(v8::False());
+ }
+ 
+ ////////////////////////////////////////////////////////////////////////////////
+@@ -1664,6 +1732,32 @@ static v8::Handle<v8::Value> JS_HasNextGeneralCursor (v8::Arguments const& argv)
+                        TRI_CreateErrorObject(TRI_ERROR_CURSOR_NOT_FOUND,
+                                              "disposed or unknown cursor")));
+ }
 + 
-+  return scope.Close(v8::False()); 
- }
- 
- ////////////////////////////////////////////////////////////////////////////////
-@@ -1365,7 +1451,7 @@ static v8::Handle<v8::Value> JS_CountGeneralCursor (v8::Arguments const& argv) {
-   cursor = (TRI_general_cursor_t*) TRI_BeginUsageDataShadowData(vocbase->_cursors, UnwrapGeneralCursor(argv.Holder()));
- 
-   if (cursor) {
--    size_t  length = (size_t) cursor->_length;
-+    size_t length = (size_t) cursor->_length;
-     TRI_EndUsageDataShadowData(vocbase->_cursors, cursor);
-     return scope.Close(v8::Number::New(length));
-   }
-@@ -1666,6 +1752,32 @@ static v8::Handle<v8::Value> JS_HasNextGeneralCursor (v8::Arguments const& argv)
- }
- 
- ////////////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////////////
 +/// @brief unuse a general cursor
 +////////////////////////////////////////////////////////////////////////////////
 +

   // return the collection names
-  result->Set(v8::String::New("collections"), TRI_ArrayAssociativePointer(&context->_collectionNames));
+  result->Set(v8::String::New("collections"), TRI_ArrayAssociativePointer(&(context.ptr())->_collectionNames));
 
-  TRI_FreeContextAql(context);
   if (tryCatch.HasCaught()) {
     if (tryCatch.Exception()->IsObject() && v8::Handle<v8::Array>::Cast(tryCatch.Exception())->HasOwnProperty(v8::String::New("errorNum"))) {
       // we already have an ArangoError object
@@ -2987,9 +3098,13 @@ static v8::Handle<v8::Value> JS_FiguresVocbaseCol (v8::Arguments const& argv) {
 
   TRI_doc_collection_t* doc = collection->_collection;
 
+  LOG_TRACE("before beginRead");
   doc->beginRead(doc);
+  LOG_TRACE("after beginRead");
   TRI_doc_collection_info_t* info = doc->figures(doc);
+  LOG_TRACE("before endRead");
   doc->endRead(doc);
+  LOG_TRACE("after endRead");
 
   if (info == NULL) {
     TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
@@ -3464,7 +3579,9 @@ static v8::Handle<v8::Value> JS_SaveVocbaseCol (v8::Arguments const& argv) {
   // inside a write transaction
   // .............................................................................
 
+  LOG_TRACE("before beginWrite");
   collection->_collection->beginWrite(collection->_collection);
+  LOG_TRACE("after beginWrite");
 
   // the lock is freed in create
   TRI_doc_mptr_t mptr = doc->create(doc, TRI_DOC_MARKER_DOCUMENT, shaped, 0, did, rid, true);
@@ -3705,7 +3822,9 @@ static v8::Handle<v8::Value> JS_SaveEdgesCol (v8::Arguments const& argv) {
   // inside a write transaction
   // .............................................................................
 
+  LOG_TRACE("before beginWrite");
   collection->_collection->beginWrite(collection->_collection);
+  LOG_TRACE("after beginWrite");
 
   TRI_doc_mptr_t mptr = doc->create(doc, TRI_DOC_MARKER_EDGE, shaped, &edge, did, rid, true);
 
@@ -4907,6 +5026,7 @@ TRI_v8_global_t* TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocba
   v8::Handle<v8::String> StatusFuncName = v8::Persistent<v8::String>::New(v8::String::New("status"));
   v8::Handle<v8::String> TruncateDatafileFuncName = v8::Persistent<v8::String>::New(v8::String::New("truncateDatafile"));
   v8::Handle<v8::String> UnloadFuncName = v8::Persistent<v8::String>::New(v8::String::New("unload"));

           TRI_RemoveKeyAssociativePointer(&store->_ids, &shadow->_id);
           TRI_RemoveKeyAssociativePointer(&store->_pointers, shadow->_data);
diff --git a/arangod/VocBase/simple-collection.c b/arangod/VocBase/simple-collection.c
index 3e28a19..fa13261 100644
--- a/arangod/VocBase/simple-collection.c
+++ b/arangod/VocBase/simple-collection.c
@@ -2868,7 +2868,8 @@ static int ComparePidName (void const* left, void const* right) {
 /// @brief returns a description of all indexes
 ////////////////////////////////////////////////////////////////////////////////
 
-TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim) {
+TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim,
+                                                const bool lock) {
   TRI_vector_pointer_t* vector;
   size_t n;
   size_t i;
@@ -2884,7 +2885,9 @@ TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim) {
   // inside read-lock
   // .............................................................................
 
-  TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
+  if (lock) {
+    TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
+  }
 
   n = sim->_indexes._length;
 
@@ -2901,7 +2904,9 @@ TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t* sim) {
     }
   }
 
-  TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
+  if (lock) {
+    TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
+  }
 
   // .............................................................................
   // outside read-lock
diff --git a/arangod/VocBase/simple-collection.h b/arangod/VocBase/simple-collection.h
index 1a8c2e7..c5cce0a 100644
--- a/arangod/VocBase/simple-collection.h
+++ b/arangod/VocBase/simple-collection.h
@@ -349,7 +349,8 @@ int TRI_CloseSimCollection (TRI_sim_collection_t* collection);
 /// @brief returns a description of all indexes
 ////////////////////////////////////////////////////////////////////////////////
 
-TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t*);
+TRI_vector_pointer_t* TRI_IndexesSimCollection (TRI_sim_collection_t*, 
+                                                const bool);
 
 ////////////////////////////////////////////////////////////////////////////////
 /// @brief drops an index
diff --git a/js/actions/system/api-cursor.js b/js/actions/system/api-cursor.js
index c2d1107..6b1ec42 100644
--- a/js/actions/system/api-cursor.js
