     ///
     @objc public func saveObjects(objects: [[String: AnyObject]], completionHandler: CompletionHandler? = nil) -> NSOperation {
         let operation = NSBlockOperation() {
-            var content: [String: AnyObject]?
-            var error: NSError?
-            do {
-                let jsonFilePath = try self.writeTempJSONFile(objects)
-                let statusCode = Int(self.localIndex.buildFromSettingsFile(nil, objectFiles: [jsonFilePath], clearIndex: false, deletedObjectIDs: nil))
-                if statusCode == StatusCode.OK.rawValue {
-                    content = [:]
-                } else {
-                    error = NSError(domain: ErrorDomain, code: statusCode, userInfo: nil)
-                }
-                try NSFileManager.defaultManager().removeItemAtPath(jsonFilePath)
-            } catch let e as NSError {
-                error = e
-            }
+            let (content, error) = self.saveObjectsSync(objects)
             self.callCompletionHandler(completionHandler, content: content, error: error)
         }
         client.buildQueue.addOperation(operation)
         return operation
     }
     
+    /// Update several objects (synchronous version).
+    ///
+    /// + Warning: It is the caller's responsibility to ensure proper serialization of index write operations.
+    ///
+    /// - parameter objects: New versions of the objects to update. Each one must contain an `objectID` attribute.
+    /// - returns: A mutually exclusive (content, error) pair.
+    ///
+    private func saveObjectsSync(objects: [[String: AnyObject]]) -> APIResponse {
+        var content: [String: AnyObject]?
+        var error: NSError?
+        do {
+            let jsonFilePath = try self.writeTempJSONFile(objects)
+            let statusCode = Int(self.localIndex.buildFromSettingsFile(nil, objectFiles: [jsonFilePath], clearIndex: false, deletedObjectIDs: nil))
+            if statusCode == StatusCode.OK.rawValue {
+                content = [:]
+            } else {
+                error = NSError(domain: ErrorDomain, code: statusCode, userInfo: nil)
+            }
+            try NSFileManager.defaultManager().removeItemAtPath(jsonFilePath)
+        } catch let e as NSError {
+            error = e
+        }
+        return (content, error)
+    }
+    
     /// Search this index.
     ///
     /// - parameter query: Search parameters.

    ///
    @objc public func getObjects(objectIDs: [String], completionHandler: CompletionHandler) -> NSOperation {
        let operation = NSBlockOperation() {
            var content: [String: AnyObject]?
            var error: NSError?
            let searchResults = self.localIndex.getObjects(objectIDs, parameters: nil)
            (content, error) = OfflineClient.parseSearchResults(searchResults)
            self.callCompletionHandler(completionHandler, content: content, error: error)
        }
        client.searchQueue.addOperation(operation)
        return operation
    }
    
    /// Update an object.

    /// Run multiple queries on this index.
    ///
    /// - parameter queries: The queries to run.
    /// - parameter strategy: The strategy to use.
    /// - parameter completionHandler: Completion handler to be notified of the request's outcome.
    /// - returns: A cancellable operation.
    ///
    @objc public func multipleQueries(queries: [Query], strategy: String?, completionHandler: CompletionHandler) -> NSOperation {
        let operation = NSBlockOperation() {
            let (content, error) = self.multipleQueriesSync(queries, strategy: strategy)
            self.callCompletionHandler(completionHandler, content: content, error: error)
        }
        client.searchQueue.addOperation(operation)
        return operation
    }

    /// Run multiple queries on this index (synchronous version).
    ///
    /// - parameter queries: The queries to run.
    /// - parameter strategy: The strategy to use.
    /// - returns: A mutually exclusive (content, error) pair.
    ///
    private func multipleQueriesSync(queries: [Query], strategy: String?) -> APIResponse {
        let emulator = MultipleQueryEmulator(indexName: self.name, querier: { (query: Query) in
            return self.searchSync(query)
        })
        return emulator.multipleQueries(queries, strategy: strategy)
    }

    /// Run multiple queries on this index.
    ///
    /// - parameter queries: The queries to run.
    /// - parameter strategy: The strategy to use.
    /// - parameter completionHandler: Completion handler to be notified of the request's outcome.
    /// - returns: A cancellable operation.
    ///
    public func multipleQueries(queries: [Query], strategy: Client.MultipleQueriesStrategy? = nil, completionHandler: CompletionHandler) -> NSOperation {
        return self.multipleQueries(queries, strategy: strategy?.rawValue, completionHandler: completionHandler)
    }

    /// Run multiple queries on this index (synchronous version).
    ///
    /// - parameter queries: The queries to run.
    /// - parameter strategy: The strategy to use.
    /// - returns: A mutually exclusive (content, error) pair.
    ///
    private func multipleQueriesSync(queries: [Query], strategy: Client.MultipleQueriesStrategy? = nil) -> APIResponse {
        return self.multipleQueriesSync(queries, strategy: strategy?.rawValue)
    }

    // MARK: - Utils
    
    /// Call a completion handler on the main queue.
