     private var settingsFilePath: String?
     private var objectsFilePaths: [String]?
     
+    private var mirrorSettingsFilePath: String {
+        get { return "\(self.indexDataDir)/mirror.plist" }
+    }
+    
+    private var indexDataDir: String {
+        get { return "\(self.client.rootDataDir!)/\(self.client.appID)/\(self.indexName)" }
+    }
+    
     // TODO: Move to top-level/other file?
     public class MirrorSettings {
-        /// Data selection queries.
-        var queries : [NSString] = []
+        var lastSyncDate: NSDate = NSDate(timeIntervalSince1970: 0)
+        var queries : [String] = [] ///< Data selection queries.
+        var queriesModificationDate: NSDate = NSDate(timeIntervalSince1970: 0)
+        
+        func save(filePath: String) {
+            let settings = [
+                "lastSyncDate": lastSyncDate,
+                "queries": queries,
+                "queriesModificationDate": queriesModificationDate
+            ]
+            (settings as NSDictionary).writeToFile(filePath, atomically: true)
+        }
+        
+        func load(filePath: String) {
+            if let settings = NSDictionary(contentsOfFile: filePath) {
+                if let lastSyncDate = settings["lastSyncDate"] as? NSDate {
+                    self.lastSyncDate = lastSyncDate
+                }
+                if let queries = settings["queries"] as? [String] {
+                    self.queries = queries
+                }
+                if let queriesModificationDate = settings["queriesModificationDate"] as? NSDate {
+                    self.queriesModificationDate = queriesModificationDate
+                }
+            }
+        }
     }
     
     /// Add a data selection query to the local mirror.
     /// The query is not run immediately. It will be run during the subsequent refreshes.
+    /// @pre The index must have been marked as mirrored.
     public func addDataSelectionQuery(query: Query) {
+        assert(mirrored);
         mirrorSettings.queries.append(query.buildURL())
-    }
-    
-    public func syncNow() {
-        assert(NSThread.isMainThread(), "Index.syncNow() should only be called from the main thread")
+        mirrorSettings.queriesModificationDate = NSDate()
+        mirrorSettings.save(self.mirrorSettingsFilePath)
+    }
+
+    /// Add any number of data selection queries to the local mirror.
+    /// The query is not run immediately. It will be run during the subsequent refreshes.
+    /// @pre The index must have been marked as mirrored.
+    public func addDataSelectionQueries(queries: [Query]) {
+        assert(mirrored);
+        for query in queries {
+            mirrorSettings.queries.append(query.buildURL())
+        }
+        mirrorSettings.queriesModificationDate = NSDate()
+        mirrorSettings.save(self.mirrorSettingsFilePath)
+    }
+
+    public func sync() {
+        assert(NSThread.isMainThread(), "Should only be called from the main thread")
         if syncing {
             return
-        } else {
-            syncing = true
-            dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
-                self.sync()
-            }
+        }
+        syncing = true
+        dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
+            self._sync()
+        }
+    }
+    
+    public func syncIfNeeded() {
+        assert(NSThread.isMainThread(), "Should only be called from the main thread")
+        let currentDate = NSDate()
+        if currentDate.timeIntervalSinceDate(mirrorSettings.lastSyncDate) > self.delayBetweenSyncs
+            || mirrorSettings.queriesModificationDate.compare(mirrorSettings.lastSyncDate) == .OrderedDescending {
+            sync()
         }
     }
     
     /// Refresh the local mirror.
-    private func sync() {
+    private func _sync() {
         assert(!NSThread.isMainThread()) // make sure it's run in the background
         assert(client.rootDataDir != nil, "Please enable offline mode in client first")
     

    /// The mirrored index settings.
    public let mirrorSettings = MirrorSettings()
    
    // Sync status:

    /// Syncing indicator.

                let status = self.localIndex!.buildFromSettingsFile(self.settingsFilePath!, objectFiles: self.objectsFilePaths!)
                if status != 200 {
                    NSLog("Error %d building index %@", status, self.indexName)
                } else {
                    // Remember the sync's date
                    self.mirrorSettings.lastSyncDate = NSDate()
                    self.mirrorSettings.save(self.mirrorSettingsFilePath)
                }
            }
            
