diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index 26353cd..a9572c9 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -52,13 +52,24 @@ public errordomain Folks.IndividualAggregatorError
 public class Folks.IndividualAggregator : Object
 {
   private BackendStore backend_store;
-  private HashMap<string, PersonaStore> stores;
   private unowned PersonaStore writeable_store;
   private HashSet<Backend> backends;
   private HashTable<string, Individual> link_map;
   private bool linking_enabled = true;
 
   /**
+   * A table mapping {@link PersonaStore.id}s to their {@link PersonaStore}.
+   *
+   * This is the canonical set of available, prepared {@link PersonaStore}s
+   * provided by this IndividualAggregator.
+   *
+   * If a {@link PersonaStore} may be validly (indirectly) targetted by
+   * {@link IndividualAggregator.add_persona_from_details}, it will be in this
+   * table.
+   */
+  public HashTable<string, PersonaStore> stores { get; private set; }
+
+  /**
    * A table mapping {@link Individual.id}s to their {@link Individual}s.
    *
    * This is the canonical set of {@link Individual}s provided by this
@@ -89,6 +100,21 @@ public class Folks.IndividualAggregator : Object
       Persona? actor,
       Groups.ChangeReason reason);
 
+  /**
+   * Emitted when a {@link PersonaStore} becomes available and prepared or
+   * becomes unavailable.
+   *
+   * This will not be emitted until after {@link IndividualAggregator.prepare}
+   * has been called.
+   *
+   * @param store a {@link PersonaStore} which has been added or removed
+   * @param is_member whether the store is now a member
+   *
+   * @since 0.1.17
+   */
+  public signal void store_changed (PersonaStore store,
+      bool is_member);
+
   /* FIXME: make this a singleton? */
   /**
    * Create a new IndividualAggregator.
@@ -107,7 +133,7 @@ public class Folks.IndividualAggregator : Object
    */
   public IndividualAggregator ()
     {
-      this.stores = new HashMap<string, PersonaStore> ();
+      this.stores = new HashTable<string, PersonaStore> (str_hash, str_equal);
       this.individuals = new HashTable<string, Individual> (str_hash,
           str_equal);
       this.link_map = new HashTable<string, Individual> (str_hash, str_equal);
@@ -176,7 +202,7 @@ public class Folks.IndividualAggregator : Object
           this.writeable_store = store;
         }
 
-      this.stores.set (store_id, store);
+      this.stores.insert (store_id, store);
       store.personas_changed.connect (this.personas_changed_cb);
       store.notify["is-writeable"].connect (this.is_writeable_changed_cb);
       store.notify["trust-level"].connect (this.trust_level_changed_cb);
@@ -186,6 +212,7 @@ public class Folks.IndividualAggregator : Object
           try
             {
               store.prepare.end (result);
+              this.store_changed (store, true);
             }
           catch (GLib.Error e)
             {
@@ -208,7 +235,9 @@ public class Folks.IndividualAggregator : Object
 
       if (this.writeable_store == store)
         this.writeable_store = null;
-      this.stores.unset (this.get_store_full_id (store.type_id, store.id));
+
+      this.stores.remove (this.get_store_full_id (store.type_id, store.id));
+      this.store_changed (store, false);
     }
 
   private string get_store_full_id (string type_id, string id)
@@ -579,7 +608,7 @@ public class Folks.IndividualAggregator : Object
     {
       var full_id = this.get_store_full_id (persona_store_type,
           persona_store_id);
-      var store = this.stores[full_id];
+      var store = this.stores.lookup (full_id);
 
       if (store == null)
         {
