From 6ed1e4110eb19b78f76154aa095a74414531f04c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 26 Sep 2019 00:20:25 +0200
Subject: Prepared history for database items.

---
 plugins/pychrysalide/analysis/binary.c        |  50 +++
 plugins/pychrysalide/analysis/db/client.c     |  60 ++-
 plugins/pychrysalide/analysis/db/collection.c |  26 +-
 plugins/pychrysalide/analysis/db/constants.c  |   1 +
 plugins/pychrysalide/analysis/db/item.c       |  40 ++
 src/analysis/binary.c                         |  59 +--
 src/analysis/binary.h                         |   6 +-
 src/analysis/db/cdb.c                         |  12 +-
 src/analysis/db/client.c                      |   3 +-
 src/analysis/db/collection-int.h              |  10 +-
 src/analysis/db/collection.c                  | 625 +++++++++++++-------------
 src/analysis/db/collection.h                  |  31 +-
 src/analysis/db/item-int.h                    |   4 +-
 src/analysis/db/item.c                        | 171 ++++---
 src/analysis/db/item.h                        |  22 +-
 src/analysis/db/items/bookmark.c              |  39 +-
 src/analysis/db/items/comment.c               |  78 +---
 src/analysis/db/items/move.c                  |  40 +-
 src/analysis/db/items/switcher.c              |  53 +--
 src/analysis/db/misc/timestamp.h              |   4 +-
 src/analysis/db/protocol.h                    |   9 +-
 src/core/collections.c                        |   6 +-
 src/gui/menus/edition.c                       |   5 +-
 src/gui/panels/bookmarks.c                    |  10 +-
 src/gui/panels/history.c                      |  14 +-
 25 files changed, 701 insertions(+), 677 deletions(-)

diff --git a/plugins/pychrysalide/analysis/binary.c b/plugins/pychrysalide/analysis/binary.c
index 01160a5..e97bea6 100644
--- a/plugins/pychrysalide/analysis/binary.c
+++ b/plugins/pychrysalide/analysis/binary.c
@@ -55,6 +55,9 @@ static PyObject *py_loaded_binary_find_collection(PyObject *, PyObject *);
 /* Demande l'intégration d'une modification dans une collection. */
 static PyObject *py_loaded_binary_add_to_collection(PyObject *, PyObject *);
 
+/* Active les éléments en amont d'un horodatage donné. */
+static PyObject *py_loaded_binary_set_last_active(PyObject *, PyObject *);
+
 /* Fournit le nom associé à l'élément binaire. */
 static PyObject *py_loaded_binary_get_name(PyObject *, void *);
 
@@ -268,6 +271,52 @@ static PyObject *py_loaded_binary_add_to_collection(PyObject *self, PyObject *ar
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self = binaire chargé à manipuler.                           *
+*                args = arguments d'appel à consulter.                        *
+*                                                                             *
+*  Description : Active les éléments en amont d'un horodatage donné.          *
+*                                                                             *
+*  Retour      : True si la commande a bien été envoyée, False sinon.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_loaded_binary_set_last_active(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    unsigned long long timestamp;           /* Horodatage de limite        */
+    int ret;                                /* Bilan de lecture des args.  */
+    GLoadedBinary *binary;                  /* Binaire en cours d'analyse  */
+    bool status;                            /* Bilan de l'opération        */
+
+#define LOADED_BINARY_SET_LAST_ACTIVE_METHOD PYTHON_METHOD_DEF          \
+(                                                                       \
+    set_last_active, "$self, timestamp, /",                             \
+    METH_VARARGS, py_loaded_binary,                                     \
+    "Define the timestamp of the last active item in the collection"    \
+    " and returns the status of the request transmission."              \
+)
+
+    ret = PyArg_ParseTuple(args, "K", &timestamp);
+    if (!ret) return NULL;
+
+    binary = G_LOADED_BINARY(pygobject_get(self));
+
+    status = g_loaded_binary_set_last_active(binary, timestamp);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
@@ -468,6 +517,7 @@ PyTypeObject *get_python_loaded_binary_type(void)
         LOADED_BINARY_GET_CLIENT_METHOD,
         LOADED_BINARY_FIND_COLLECTION_METHOD,
         LOADED_BINARY_ADD_TO_COLLECTION_METHOD,
+        LOADED_BINARY_SET_LAST_ACTIVE_METHOD,
         { NULL }
     };
 
diff --git a/plugins/pychrysalide/analysis/db/client.c b/plugins/pychrysalide/analysis/db/client.c
index 13966f5..e5b67da 100644
--- a/plugins/pychrysalide/analysis/db/client.c
+++ b/plugins/pychrysalide/analysis/db/client.c
@@ -51,6 +51,9 @@ static PyObject *py_hub_client_stop(PyObject *, PyObject *);
 /* Effectue une demande de sauvegarde de l'état courant. */
 static PyObject *py_hub_client_save(PyObject *, PyObject *);
 
+/* Active les éléments en amont d'un horodatage donné. */
+static PyObject *py_hub_client_set_last_active(PyObject *, PyObject *);
+
 
 
 /******************************************************************************
@@ -146,7 +149,7 @@ static PyObject *py_hub_client_new(PyTypeObject *type, PyObject *args, PyObject
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = serveur à manipuler.                                  *
+*  Paramètres  : self = client à manipuler.                                   *
 *                args = paramètres à transmettre à l'appel natif.             *
 *                                                                             *
 *  Description : Démarre la connexion à la base de données.                   *
@@ -201,7 +204,7 @@ static PyObject *py_hub_client_start(PyObject *self, PyObject *args)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = serveur à manipuler.                                  *
+*  Paramètres  : self = client à manipuler.                                   *
 *                args = arguments d'appel non utilisés ici.                   *
 *                                                                             *
 *  Description : Arrête la connexion à la base de données.                    *
@@ -238,7 +241,7 @@ static PyObject *py_hub_client_stop(PyObject *self, PyObject *args)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = serveur à manipuler.                                  *
+*  Paramètres  : self = client à manipuler.                                   *
 *                args = arguments d'appel non utilisés ici.                   *
 *                                                                             *
 *  Description : Effectue une demande de sauvegarde de l'état courant.        *
@@ -279,6 +282,56 @@ static PyObject *py_hub_client_save(PyObject *self, PyObject *args)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self = client à manipuler.                                   *
+*                args = arguments d'appel à consulter.                        *
+*                                                                             *
+*  Description : Active les éléments en amont d'un horodatage donné.          *
+*                                                                             *
+*  Retour      : True si la commande a bien été envoyée, False sinon.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_hub_client_set_last_active(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    unsigned long long timestamp;           /* Horodatage de limite        */
+    int ret;                                /* Bilan de lecture des args.  */
+    GHubClient *client;                     /* Version native du serveur   */
+    bool status;                            /* Bilan de l'opération        */
+
+#define HUB_CLIENT_SET_LAST_ACTIVE_METHOD PYTHON_METHOD_DEF             \
+(                                                                       \
+    set_last_active, "$self, timestamp, /",                             \
+    METH_VARARGS, py_hub_client,                                        \
+    "Define the timestamp of the last active item in the collection"    \
+    " and returns the status of the request transmission."              \
+    "\n"                                                                \
+    "This method should not be used directly. Prefer calling"           \
+    " pychrysalide.analysis.LoadedBinary.set_last_active() instead,"    \
+    " as some items may be volatile and thus not handled by clients."   \
+)
+
+    ret = PyArg_ParseTuple(args, "K", &timestamp);
+    if (!ret) return NULL;
+
+    client = G_HUB_CLIENT(pygobject_get(self));
+
+    status = g_hub_client_set_last_active(client, timestamp);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Fournit un accès à une définition de type à diffuser.        *
@@ -295,6 +348,7 @@ PyTypeObject *get_python_hub_client_type(void)
         HUB_CLIENT_START_METHOD,
         HUB_CLIENT_STOP_METHOD,
         HUB_CLIENT_SAVE_METHOD,
+        HUB_CLIENT_SET_LAST_ACTIVE_METHOD,
         { NULL }
     };
 
diff --git a/plugins/pychrysalide/analysis/db/collection.c b/plugins/pychrysalide/analysis/db/collection.c
index e62c17e..53cdccc 100644
--- a/plugins/pychrysalide/analysis/db/collection.c
+++ b/plugins/pychrysalide/analysis/db/collection.c
@@ -59,10 +59,9 @@ static PyObject *py_db_collection_get_items(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Trouvailles à retourner     */
     GDbCollection *collec;                  /* Version native              */
-    size_t counter;                         /* Décompte des éléments       */
-    GList *items;                           /* Eléments déjà en place      */
-    GList *iter;                            /* Boucle de parcours          */
-    int ret;                                /* Bilan d'une extension       */
+    size_t count;                           /* Décompte des éléments       */
+    GDbItem **items;                        /* Eléments déjà en place      */
+    size_t i;                               /* Boucle de parcours          */
 
 #define DB_COLLECTION_ITEMS_ATTRIB PYTHON_GET_DEF_FULL      \
 (                                                           \
@@ -74,22 +73,21 @@ static PyObject *py_db_collection_get_items(PyObject *self, void *closure)
 
     collec = G_DB_COLLECTION(pygobject_get(self));
 
-    counter = 0;
-    result = PyTuple_New(counter);
-
     g_db_collection_rlock(collec);
 
-    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
-
-    for (iter = g_list_first(items); iter != NULL; iter = g_list_next(iter))
-    {
-        ret = _PyTuple_Resize(&result, ++counter);
-        if (ret == -1) break;
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec), &count);
 
-        PyTuple_SetItem(result, counter - 1, pygobject_new(G_OBJECT(iter->data)));
+    result = PyTuple_New(count);
 
+    for (i = 0; i < count; i++)
+    {
+        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(items[i])));
+        g_object_unref(G_OBJECT(items[i]));
     }
 
+    if (items != NULL)
+        free(items);
+
     g_db_collection_runlock(collec);
 
     return result;
diff --git a/plugins/pychrysalide/analysis/db/constants.c b/plugins/pychrysalide/analysis/db/constants.c
index 46d0876..07c7a06 100644
--- a/plugins/pychrysalide/analysis/db/constants.c
+++ b/plugins/pychrysalide/analysis/db/constants.c
@@ -96,6 +96,7 @@ bool define_db_item_constants(PyTypeObject *type)
     if (result) result = add_const_to_group(values, "UPDATED", DIF_UPDATED);
     if (result) result = add_const_to_group(values, "VOLATILE", DIF_VOLATILE);
     if (result) result = add_const_to_group(values, "BROKEN", DIF_BROKEN);
+    if (result) result = add_const_to_group(values, "DISABLED", DIF_DISABLED);
 
     if (!result)
     {
diff --git a/plugins/pychrysalide/analysis/db/item.c b/plugins/pychrysalide/analysis/db/item.c
index 0923268..7ef30af 100644
--- a/plugins/pychrysalide/analysis/db/item.c
+++ b/plugins/pychrysalide/analysis/db/item.c
@@ -48,6 +48,9 @@ static PyObject *py_db_item_remove_flag(PyObject *, PyObject *);
 /* Décrit l'élément de collection en place. */
 static PyObject *py_db_item_get_label(PyObject *, void *);
 
+/* Fournit l'horodatage associé à l'élément de collection. */
+static PyObject *py_db_item_get_timestamp(PyObject *, void *);
+
 /* Indique les propriétés particulières appliquées à l'élément. */
 static PyObject *py_db_item_get_flags(PyObject *, void *);
 
@@ -178,6 +181,42 @@ static PyObject *py_db_item_get_label(PyObject *self, void *closure)
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
+*  Description : Fournit l'horodatage associé à l'élément de collection.      *
+*                                                                             *
+*  Retour      : Date de création de l'élément.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_get_timestamp(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GDbItem *item;                          /* Elément à consulter         */
+    timestamp_t timestamp;                  /* Horodatage de l'élément     */
+
+#define DB_ITEM_TIMESTAMP_ATTRIB PYTHON_GET_DEF_FULL    \
+(                                                       \
+    timestamp, py_db_item,                              \
+    "Timestamp of the item creation."                   \
+)
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    timestamp = g_db_item_get_timestamp(item);
+
+    result = PyLong_FromUnsignedLongLong(timestamp);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
 *  Description : Indique les propriétés particulières appliquées à l'élément. *
 *                                                                             *
 *  Retour      : Propriétés actives de l'élément.                             *
@@ -232,6 +271,7 @@ PyTypeObject *get_python_db_item_type(void)
 
     static PyGetSetDef py_db_item_getseters[] = {
         DB_ITEM_LABEL_ATTRIB,
+        DB_ITEM_TIMESTAMP_ATTRIB,
         DB_ITEM_FLAGS_ATTRIB,
         { NULL }
     };
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 822510c..05e42c7 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -1127,87 +1127,56 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bo
 
         }
 
+        g_object_unref(G_OBJECT(item));
+
     }
 
     g_object_unref(G_OBJECT(collec));
-    g_object_unref(G_OBJECT(item));
 
     return result;
 
 }
 
 
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary  = élément binaire à consulter.                       *
-*                feature = fonctionnalité visée par la requête.               *
-*                item    = élémnent à retirer d'un serveur de collection.     *
-*                lock    = indique si le verrou d'écriture doit être posé.    *
+*  Paramètres  : binary    = élément binaire à consulter.                     *
+*                timestamp = date du dernier élément à garder comme actif.    *
 *                                                                             *
-*  Description : Demande la suppression de modification dans une collection.  *
+*  Description : Active les éléments en amont d'un horodatage donné.      XXXXXXXXXXXXXXXXX    *
 *                                                                             *
-*  Retour      : Bilan partiel de l'opération demandée.                       *
+*  Retour      : true si la commande a bien été envoyée, false sinon.         *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool _g_loaded_binary_remove_from_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item, bool lock)
+bool g_loaded_binary_set_last_active(GLoadedBinary *binary, timestamp_t timestamp)
 {
-    bool result;                            /* Bilan à faire remonter      */
-    GDbCollection *collec;                  /* Collection visée au final   */
-    DBStorage storage;                      /* Forme d'enregistrement      */
-    GHubClient *client;                     /* Liaison à utiliser          */
-    packed_buffer out_pbuf;                 /* Tampon d'émission           */
-    SSL *tls_fd;                            /* Canal de communication SSL  */
+    bool result;                            /* Bilan à retourner           */
 
-    collec = g_loaded_binary_find_collection(binary, feature);
-    if (collec == NULL) return false;
 
-    /* S'il n'y a pas besoin de sauvegarde... */
-    if (g_db_item_get_flags(item) & DIF_VOLATILE)
-        result = _g_db_collection_remove_item(collec, item, lock, true);
+    result = false;
 
-    /* Sinon on envoie par le réseau ! */
-    else
-    {
-        storage = g_loaded_binary_get_storage(binary, feature);
 
-        if (storage == DBS_ALL_REMOTE)
-            client = binary->remote;
-        else
-            client = NULL;
 
-        if (client == NULL)
-            client = binary->local;
 
-        init_packed_buffer(&out_pbuf);
+    return result;
+
+}
 
-        tls_fd = g_hub_client_get_ssl_fd(client);
 
-        if (tls_fd == NULL)
-            result = false;
 
-        else
-        {
-            result = g_db_collection_pack(collec, &out_pbuf, DBA_REM_ITEM, item);
 
-            if (result)
-                result = ssl_send_packed_buffer(&out_pbuf, tls_fd);
 
-            g_hub_client_put_ssl_fd(client, tls_fd);
 
-        }
 
-        exit_packed_buffer(&out_pbuf);
 
-    }
 
-    g_object_unref(G_OBJECT(collec));
 
-    return result;
 
-}
 
 
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index dd3dfc6..b4c8652 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -131,12 +131,10 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *, GDbItem *, bool);
 #define g_loaded_binary_add_to_collection(b, i) \
     _g_loaded_binary_add_to_collection(b, i, true)
 
-/* Demande la suppression de modification dans une collection. */
-bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool);
 
-#define g_loaded_binary_remove_from_collection(b, f, i) \
-    _g_loaded_binary_remove_from_collection(b, f, i, true)
 
+/* Active les éléments en amont d'un horodatage donné. */
+bool g_loaded_binary_set_last_active(GLoadedBinary *, timestamp_t);
 
 
 
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index a787a19..ca39a58 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -967,8 +967,16 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
 
                     case DBC_SET_LAST_ACTIVE:
 
-                        status = update_activity_in_collections(archive->collections, &in_pbuf, archive->db);
-                        if (!status) goto gcap_bad_exchange;
+                        init_packed_buffer(&out_pbuf);
+
+                        status = update_activity_in_collections(archive->collections, \
+                                                                &in_pbuf, &out_pbuf, archive->db);
+                        if (!status) goto gcap_bad_reply;
+
+                        status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].ssl_fd);
+                        if (!status) goto gcap_bad_reply;
+
+                        exit_packed_buffer(&out_pbuf);
 
                         break;
 
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 744fa57..beb30c1 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -789,7 +789,7 @@ static void *g_hub_client_update(GHubClient *client)
                     status = extract_packed_buffer(&in_pbuf, &tmp8, sizeof(uint8_t), true);
                     if (!status) goto gdcu_bad_exchange;
 
-                    client->can_get_updates = (tmp8 == 0x0);
+                    client->can_get_updates = (tmp8 == 0x1);
                     break;
 
             }
@@ -797,6 +797,7 @@ static void *g_hub_client_update(GHubClient *client)
             if (has_more_data_in_packed_buffer(&in_pbuf))
                 goto next_command;
 
+            client->can_get_updates = true;
             continue;
 
  gdcu_bad_exchange:
diff --git a/src/analysis/db/collection-int.h b/src/analysis/db/collection-int.h
index b3b83bb..c9d37bf 100644
--- a/src/analysis/db/collection-int.h
+++ b/src/analysis/db/collection-int.h
@@ -35,9 +35,6 @@
 /* Crée la table associée à une collection d'éléments. */
 typedef bool (* collec_create_db_table_fc) (const GDbCollection *, sqlite3 *);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-typedef bool (* collec_setup_load_fc) (GDbCollection *, bound_value **, size_t *);
-
 /* Charge les valeurs utiles pour une localisation. */
 typedef bool (* collec_load_item) (GDbCollection *, const bound_value *, size_t);
 
@@ -58,8 +55,8 @@ struct _GDbCollection
     /* Référence circulaire */
     GLoadedBinary *binary;                  /* Binaire rattaché éventuel   */
 
-    GList *items;                           /* Eléments rassemblés         */
-    GList *sorted;                          /* Eléments triés              */
+    GDbItem **items;                        /* Eléments rassemblés         */
+    size_t count;                           /* Quantité de ces éléments    */
     GHashTable *last_items;                 /* Statuts courants d'éléments */
     GRWLock params_access;                  /* Verrou de protection        */
 
@@ -71,7 +68,6 @@ struct _GDbCollectionClass
     GObjectClass parent;                    /* A laisser en premier        */
 
     collec_create_db_table_fc create_table; /* Création de la table en SQL */
-    collec_setup_load_fc setup_load;        /* Prépare le chargement       */
     collec_load_item load_item;             /* Charge un élément           */
     collec_has_key_fc has_key;              /* Recherche de présence       */
 
@@ -79,6 +75,8 @@ struct _GDbCollectionClass
 
     void (* content_extended) (GDbCollection *, GDbItem *);
 
+    void (* state_changed) (GDbCollection *, GDbItem *);
+
 };
 
 
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index f728718..edb55d8 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -58,14 +58,23 @@ static void g_db_collection_finalize(GDbCollection *);
 
 
 
-/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
+#define g_db_collection_find_by_timestamped(c, i) c->count
+
+#define g_db_collection_find_by_timestamp(c, i) c->count
+
+
+
 
+/* Ajoute un élément dans la liste des éléments actifs. */
+static void g_db_collection_set_last_item(GDbCollection *, GDbItem *, bool);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool _g_db_collection_setup_load(GDbCollection *, bound_value **, size_t *);
+/* Retire un élément de la liste des éléments courants. */
+static void g_db_collection_unset_last_item(GDbCollection *, GDbItem *, size_t);
+
+
+
+/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool g_db_collection_setup_load(GDbCollection *, bound_value **, size_t *);
 
 /* Charge et intère un élément dans une collection. */
 static bool g_db_collection_load_new_item(const bound_value *, size_t, GDbCollection *);
@@ -104,8 +113,6 @@ static void g_db_collection_class_init(GDbCollectionClass *klass)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_db_collection_dispose;
     object->finalize = (GObjectFinalizeFunc)g_db_collection_finalize;
 
-    klass->setup_load = (collec_setup_load_fc)_g_db_collection_setup_load;
-
     g_signal_new("content-extended",
                  G_TYPE_DB_COLLECTION,
                  G_SIGNAL_RUN_LAST,
@@ -114,6 +121,14 @@ static void g_db_collection_class_init(GDbCollectionClass *klass)
                  g_cclosure_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1, G_TYPE_OBJECT);
 
+    g_signal_new("state-changed",
+                 G_TYPE_DB_COLLECTION,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GDbCollectionClass, state_changed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
 }
 
 
@@ -133,6 +148,9 @@ static void g_db_collection_init(GDbCollection *collec)
 {
     collec->binary = NULL;
 
+    collec->items = NULL;
+    collec->count = 0;
+
     collec->last_items = g_hash_table_new_full((GHashFunc)g_db_item_hash_key,
                                                (GEqualFunc)g_db_item_cmp_key,
                                                (GDestroyNotify)g_object_unref,
@@ -157,17 +175,10 @@ static void g_db_collection_init(GDbCollection *collec)
 
 static void g_db_collection_dispose(GDbCollection *collec)
 {
-    if (collec->items != NULL)
-    {
-        g_list_free_full(collec->items, g_object_unref);
-        collec->items = NULL;
-    }
+    size_t i;                               /* Boucle de parcours          */
 
-    if (collec->sorted != NULL)
-    {
-        g_list_free_full(collec->sorted, g_object_unref);
-        collec->sorted = NULL;
-    }
+    for (i = 0; i < collec->count; i++)
+        g_clear_object(&collec->items[i]);
 
     G_OBJECT_CLASS(g_db_collection_parent_class)->dispose(G_OBJECT(collec));
 
@@ -188,6 +199,9 @@ static void g_db_collection_dispose(GDbCollection *collec)
 
 static void g_db_collection_finalize(GDbCollection *collec)
 {
+    if (collec->items != NULL)
+        free(collec->items);
+
     g_rw_lock_clear(&collec->params_access);
 
     G_OBJECT_CLASS(g_db_collection_parent_class)->finalize(G_OBJECT(collec));
@@ -361,8 +375,6 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
     bool result;                            /* Bilan à faire remonter      */
     DBAction action;                        /* Commande de la requête      */
     GDbItem *item;                          /* Définition d'élément visé   */
-    GList *found;                           /* Test de présence existante  */
-    timestamp_t inactive;                   /* Horodatage de désactivation */
 
     result = _g_db_collection_unpack(collec, pbuf, &action, &item);
     if (!result) return false;
@@ -379,7 +391,7 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
 
             if (result)
             {
-                if (collec->binary != NULL && g_db_item_is_active(item))
+                if (collec->binary != NULL && !g_db_item_has_flag(item, DIF_DISABLED))
                     g_db_item_apply(item, collec->binary);
 
                 if (db != NULL)
@@ -389,50 +401,29 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
 
             break;
 
-        case DBA_REM_ITEM:
-
-            g_db_collection_wlock(collec);
-
-            found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp);
-
-            result = (found != NULL);
+        case DBA_CHANGE_STATE:
 
-            if (result)
+            if (collec->binary != NULL)
             {
-                /* Côté client */
-                if (db == NULL)
-                    result = _g_db_collection_remove_item(collec, item, false, true);
+                result = g_db_collection_update_item_state(collec, item);
 
-                /* Côté serveur */
-                else
+                if (result)
                 {
-                    if (g_db_item_is_active(G_DB_ITEM(found->data)))
-                    {
-                        inactive = _g_db_collection_compute_inactivity_timestamp(collec, false);
-                        result = _g_db_collection_update_item_activity(collec, item, &inactive, false);
-                    }
+                    if (g_db_item_has_flag(item, DIF_DISABLED))
+                        g_db_item_cancel(item, collec->binary);
+                    else
+                        g_db_item_apply(item, collec->binary);
                 }
 
             }
 
-            g_db_collection_wunlock(collec);
-
-            break;
-
-        case DBA_CHANGE_STATE:
-
-            if (db == NULL)
-            {
-                if (g_db_item_is_active(item))
-                    result = g_db_collection_update_item_activity(collec, item, NULL);
-                else
-                {
-                    inactive = g_db_item_get_timestamp(item) + 1;
-                    result = g_db_collection_update_item_activity(collec, item, &inactive);
-                }
-            }
             else
+            {
+                assert(db != NULL);
                 result = false;
+            }
+
+            g_object_unref(G_OBJECT(item));
 
             break;
 
@@ -442,8 +433,6 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
 
     }
 
-    g_object_unref(G_OBJECT(item));
-
     return result;
 
 }
@@ -500,7 +489,7 @@ bool g_db_collection_pack(GDbCollection *collec, packed_buffer *pbuf, DBAction a
 bool g_db_collection_pack_all_updates(GDbCollection *collec, packed_buffer *pbuf)
 {
     bool result;                            /* Bilan à renvoyer            */
-    GList *iter;                            /* Boucle de parcours          */
+    size_t i;                               /* Boucle de parcours          */
 
     result = true;
 
@@ -509,13 +498,8 @@ bool g_db_collection_pack_all_updates(GDbCollection *collec, packed_buffer *pbuf
      * g_cdb_archive_add_client().
     */
 
-    for (iter = g_list_first(collec->items);
-         iter != NULL && result;
-         iter = g_list_next(iter))
-    {
-        result = g_db_collection_pack(collec, pbuf, DBA_ADD_ITEM, G_DB_ITEM(iter->data));
-
-    }
+    for (i = 0; i < collec->count && result; i++)
+        result = g_db_collection_pack(collec, pbuf, DBA_ADD_ITEM, G_DB_ITEM(collec->items[i]));
 
     return result;
 
@@ -560,6 +544,7 @@ void g_db_collection_lock_unlock(GDbCollection *collec, bool write, bool lock)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
+*                count  = taille de la liste constituée. [OUT]                *
 *                                                                             *
 *  Description : Renvoie la liste des éléments rassemblés.                    *
 *                                                                             *
@@ -569,14 +554,34 @@ void g_db_collection_lock_unlock(GDbCollection *collec, bool write, bool lock)
 *                                                                             *
 ******************************************************************************/
 
-GList *g_db_collection_get_items(const GDbCollection *collec)
+GDbItem **g_db_collection_get_items(const GDbCollection *collec, size_t *count)
 {
+    GDbItem **result;                       /* Liste à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
     /**
      * Un verrou doit être posé !
      * Il n'y a pas d'assert() possible pour le vérifier...
      */
 
-    return collec->items;
+    *count = collec->count;
+
+    if (*count == 0)
+        result = NULL;
+
+    else
+    {
+        result = malloc(*count * sizeof(GDbItem *));
+
+        for (i = 0; i < *count; i++)
+        {
+            result[i] = collec->items[i];
+            g_object_ref(G_OBJECT(result[i]));
+        }
+
+    }
+
+    return result;
 
 }
 
@@ -626,16 +631,16 @@ GDbItem *g_db_collection_has_key(GDbCollection *collec, ...)
 bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item)
 {
     bool result;                            /* Bilan à retourner           */
-    GList *found;                           /* Test de présence existante  */
+    size_t index;                           /* Indice de l'élément trouvé  */ 
 
     /**
      * Un verrou doit être posé !
      * Il n'y a pas d'assert() possible pour le vérifier...
      */
 
-    found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp);
+    index = g_db_collection_find_by_timestamped(collec, item);
 
-    result = (found != NULL);
+    result = (index < collec->count);
 
     return result;
 
@@ -646,36 +651,46 @@ bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item)
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à considérer.                   *
 *                item   = élément de collection à manipuler.                  *
-*                lock   = indique si le verrou d'écriture doit être posé.     *
+*                new    = précise la nature de l'élément à insérer.           *
 *                                                                             *
-*  Description : Procède à l'ajout d'un nouvel élément dans la collection.    *
+*  Description : Ajoute un élément dans la liste des éléments actifs.         *
 *                                                                             *
-*  Retour      : Bilan de l'exécution de l'opération.                         *
+*  Retour      : -                                                            *
 *                                                                             *
-*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      *
+*  Remarques   :                                                              *
 *                                                                             *
 ******************************************************************************/
 
-bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
+static void g_db_collection_set_last_item(GDbCollection *collec, GDbItem *item, bool new)
 {
-    bool result;                            /* Bilan à faire remonter      */
     GDbItem *prev;                          /* Elément similaire précédent */
+    timestamp_t its;                        /* Horodatage #0               */
+    timestamp_t pts;                        /* Horodatage #1               */
 
-    result = true;
-
-    if (lock)
-        g_db_collection_wlock(collec);
-
-    g_object_ref(G_OBJECT(item));
-    collec->items = g_list_append(collec->items, item);
-
-    g_object_ref(G_OBJECT(item));
-    collec->sorted = g_list_insert_sorted(collec->sorted, item, (GCompareFunc)g_db_item_compare_with_timestamp);
+    assert(!g_db_item_has_flag(item, DIF_DISABLED));
 
     prev = g_hash_table_lookup(collec->last_items, item);
 
     if (prev != NULL)
     {
+        /**
+         * Dans le cas où le changement intervient sans contexte particulier,
+         * on s'assure de le pas remplacer un élément plus récent déjà en place
+         * par un élément nouvellement actif mais dépassé.
+         *
+         * Le code de g_db_collection_disable_at(), aux conséquences portant
+         * dans le serveur et le client, procède de manière à éviter cette
+         * situation par un ordre de parcours choisi.
+         *
+         * On insère néanmoins une petite sécurité.
+         */
+
+        its = g_db_item_get_timestamp(item);
+        pts = g_db_item_get_timestamp(prev);
+
+        if (timestamp_is_younger(its, pts))
+            goto already_up_to_date;
+
         g_object_ref(G_OBJECT(prev));
 
         if (g_db_item_get_flags(item) & DIF_ERASER)
@@ -683,7 +698,8 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
 
         else
         {
-            g_db_item_add_flag(item, DIF_UPDATED);
+            if (new)
+                g_db_item_add_flag(item, DIF_UPDATED);
 
             g_object_ref(G_OBJECT(item));
             g_object_ref(G_OBJECT(item));
@@ -698,19 +714,20 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
 
     else
     {
-        g_object_ref(G_OBJECT(item));
-        g_object_ref(G_OBJECT(item));
+        if (g_db_item_get_flags(item) & DIF_ERASER)
+        {
+            g_object_ref(G_OBJECT(item));
+            g_object_ref(G_OBJECT(item));
 
-        g_hash_table_add(collec->last_items, item);
+            g_hash_table_add(collec->last_items, item);
+
+        }
 
     }
 
-    g_signal_emit_by_name(collec, "content-extended", item);
+ already_up_to_date:
 
-    if (lock)
-        g_db_collection_wunlock(collec);
-
-    return result;
+    ;
 
 }
 
@@ -720,49 +737,30 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
 *  Paramètres  : collec = ensemble d'éléments à considérer.                   *
 *                item   = élément de collection à manipuler.                  *
 *                lock   = indique si le verrou d'écriture doit être posé.     *
-*                signal = émet un événement pour signaler le retrait.         *
 *                                                                             *
-*  Description : Procède au retrait d'un nouvel élément dans la collection.   *
+*  Description : Procède à l'ajout d'un nouvel élément dans la collection.    *
 *                                                                             *
 *  Retour      : Bilan de l'exécution de l'opération.                         *
 *                                                                             *
-*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      *
+*  Remarques   : L'appelant perd la propriété de l'object transféré.          *
 *                                                                             *
 ******************************************************************************/
 
-bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool lock, bool signal)
+bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)
 {
     bool result;                            /* Bilan à faire remonter      */
-    GList *found;                           /* Test de présence existante  */
-    GDbItem *internal;                      /* Elément interne à modifier  */
 
     result = true;
 
     if (lock)
         g_db_collection_wlock(collec);
 
-    found = g_list_find_custom(collec->sorted, item, (GCompareFunc)g_db_item_compare_with_timestamp);
-
-    result = (found != NULL);
+    collec->items = realloc(collec->items, ++collec->count * sizeof(GDbItem *));
+    collec->items[collec->count - 1] = item;
 
-    if (result)
-    {
-        internal = G_DB_ITEM(found->data);
+    g_db_collection_set_last_item(collec, item, true);
 
-        collec->sorted = g_list_delete_link(collec->sorted, found);
-
-        found = g_list_find(collec->items, item);
-        assert(found != NULL);
-
-        collec->items = g_list_delete_link(collec->items, found);
-
-        if (signal)
-            ;//g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal);
-
-        g_object_unref(G_OBJECT(internal));
-        g_object_unref(G_OBJECT(internal));
-
-    }
+    g_signal_emit_by_name(collec, "content-extended", item);
 
     if (lock)
         g_db_collection_wunlock(collec);
@@ -775,47 +773,54 @@ bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool loc
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à considérer.                   *
-*                lock   = indique si le verrou d'écriture doit être posé.     *
+*                pbuf   = paquet de données où venir inscrire les infos.      *
 *                                                                             *
-*  Description : Détermine l'horodatage le plus jeune pour une désactivation. *
+*  Description : Procède au retrait des éléments désactivés de la collection. *
 *                                                                             *
-*  Retour      : Horodatage à utiliser pour une phase de désactivation.       *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
 *                                                                             *
-*  Remarques   : -                                                            *
+*  Remarques   :                                                              *
 *                                                                             *
 ******************************************************************************/
 
-timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *collec, bool lock)
+bool g_db_collection_drop_disabled_items(GDbCollection *collec, packed_buffer *pbuf)
 {
-    timestamp_t result;                     /* Horodatage à retourner      */
-    GList *iter;                            /* Boucle de parcours          */
-    GDbItem *item;                          /* Elément interne à consulter */
-    timestamp_t stamp;                      /* Horodatage de l'élément     */
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    GDbItem *item;                          /* Elément désactivé           */
+#ifndef NDEBUG
+    GDbItem *enabled;                       /* Eventuel similarité active  */
+#endif
 
-    result = TIMESTAMP_ALL_ACTIVE;
+    /**
+     * Voie de suppression d'un élément côté serveur.
+     */
 
-    if (lock)
-        g_db_collection_wlock(collec);
+    result = true;
 
-    for (iter = g_list_first(collec->items);
-         iter != NULL;
-         iter = g_list_next(iter))
+    g_db_collection_wlock(collec);
+
+    for (i = collec->count; i > 0 && result; i--)
     {
-        item = G_DB_ITEM(iter->data);
+        item = collec->items[i - 1];
 
-        if (!g_db_item_is_active(item))
-        {
-            stamp = g_db_item_get_timestamp(item);
+        if (!g_db_item_has_flag(item, DIF_DISABLED))
+            break;
 
-            if (timestamp_is_younger(stamp, result))
-                result = stamp;
+#ifndef NDEBUG
+        enabled = g_hash_table_lookup(collec->last_items, item);
+        assert(enabled != item);
+#endif
 
-        }
+        collec->items = realloc(collec->items, --collec->count * sizeof(GDbItem *));
+
+        result = g_db_collection_pack(collec, pbuf, DBA_REM_ITEM, item);
+
+        g_object_unref(G_OBJECT(item));
 
     }
 
-    if (lock)
-        g_db_collection_wunlock(collec);
+    g_db_collection_wunlock(collec);
 
     return result;
 
@@ -826,9 +831,8 @@ timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *collec,
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à considérer.                   *
 *                item   = élément de collection à manipuler.                  *
-*                lock   = indique si le verrou d'écriture doit être posé.     *
 *                                                                             *
-*  Description : Met à jour le statut d'activité d'un élément de collection.  *
+*  Description : Procède au retrait d'un élément dans la collection.          *
 *                                                                             *
 *  Retour      : Bilan de l'exécution de l'opération.                         *
 *                                                                             *
@@ -836,31 +840,47 @@ timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *collec,
 *                                                                             *
 ******************************************************************************/
 
-bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, timestamp_t *timestamp, bool lock)
+bool g_db_collection_remove_item(GDbCollection *collec, const GDbItem *item)
 {
     bool result;                            /* Bilan à faire remonter      */
-    GList *found;                           /* Test de présence existante  */
-    GDbItem *internal;                      /* Elément interne à modifier  */
+    size_t found;                           /* Indice de l'élément concerné*/
+    GDbItem *disabled;                      /* Elément désactivé           */
+#ifndef NDEBUG
+    GDbItem *enabled;                       /* Eventuel similarité active  */
+#endif
 
-    if (lock)
-        g_db_collection_wlock(collec);
+    /**
+     * Voie de suppression d'un élément côté serveur.
+     */
 
-    found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_without_timestamp);
+    g_db_collection_wlock(collec);
 
-    result = (found != NULL);
+    found = g_db_collection_find_by_timestamped(collec, item);
+
+    result = (found < collec->count);
+    assert(result);
 
     if (result)
     {
-        internal = G_DB_ITEM(found->data);
+        disabled = collec->items[found];
+
+        assert(g_db_item_has_flag(disabled, DIF_DISABLED));
+
+#ifndef NDEBUG
+        enabled = g_hash_table_lookup(collec->last_items, disabled);
+        assert(enabled != disabled);
+#endif
+
+        memmove(collec->items + found, collec->items + found + 1,
+                (collec->count - found - 1) * sizeof(GDbItem *));
 
-        result = g_db_item_set_activity(internal, collec->binary, timestamp);
+        collec->items = realloc(collec->items, --collec->count * sizeof(GDbItem *));
 
-        //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, internal);
+        g_object_unref(G_OBJECT(disabled));
 
     }
 
-    if (lock)
-        g_db_collection_wunlock(collec);
+    g_db_collection_wunlock(collec);
 
     return result;
 
@@ -869,157 +889,202 @@ bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item,
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : collec    = ensemble d'éléments à considérer.                *
-*                timestamp = date du dernier élément à garder comme actif.    *
-*                inactive  = date du premier élément inactif rencontré. [OUT] *
-*                db        = base de données à mettre à jour.                 *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                item   = élément de collection à manipuler.                  *
+*                count  = décompte des éléments actifs.                       *
 *                                                                             *
-*  Description : Active les éléments en amont d'un horodatage donné.          *
+*  Description : Retire un élément de la liste des éléments courants.         *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
-*  Remarques   : -                                                            *
+*  Remarques   :                                                              *
 *                                                                             *
 ******************************************************************************/
 
-GList *g_db_collection_set_last_active(GDbCollection *collec, timestamp_t timestamp, timestamp_t *inactive, sqlite3 *db)
+static void g_db_collection_unset_last_item(GDbCollection *collec, GDbItem *item, size_t count)
 {
-    GList *result;                          /* Liste d'inactifs à renvoyer */
-    GList *i;                               /* Parcours des éléments       */
-    GDbItem *item;                          /* Elément à traiter           */
-    timestamp_t stamp;                      /* Horodatage de l'élément     */
+    GDbItem *prev;                          /* Elément similaire précédent */
+    GDbItem *old;                           /* Ancien élément similaire    */
+    size_t i;                               /* Boucle de parcours          */
 
-    result = NULL;
+    assert(g_db_item_has_flag(item, DIF_DISABLED));
+
+    prev = g_hash_table_lookup(collec->last_items, item);
 
-    for (i = g_list_first(collec->items); i != NULL; i = g_list_next(i))
+    if (prev == item)
     {
-        item = G_DB_ITEM(i->data);
-        stamp = g_db_item_get_timestamp(item);
+        old = NULL;
 
-        if (timestamp_is_younger(stamp, timestamp))
-        {
-            if (!g_db_item_is_active(item))
-            {
-                /* ... */g_db_item_set_activity(item, collec->binary, NULL);
-                /* ... */g_db_collection_store_updated_item(collec, item, db);
-                //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item);
-            }
+        for (i = count; i > 0; i++)
+            if (g_db_item_cmp_key(collec->items[i - 1], item))
+                break;
+            else
+                old = collec->items[i - 1];
 
-        }
+        if (old == NULL || g_db_item_get_flags(old) & DIF_ERASER)
+            g_hash_table_remove(collec->last_items, item);
 
         else
         {
-            if (!g_db_item_is_active(item))
-            {
-                if (timestamp_is_younger(stamp, *inactive))
-                    *inactive = stamp;
-            }
+            g_object_ref(G_OBJECT(old));
+            g_object_ref(G_OBJECT(old));
 
-            else
-                result = g_list_append(result, item);
+            g_hash_table_replace(collec->last_items, old, old);
 
         }
 
     }
 
-    return result;
-
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : collec    = ensemble d'éléments à considérer.                *
-*                item      = élément à désactiver.                            *
-*                timestamp = date du premier élément inactif rencontré. [OUT] *
+*  Paramètres  : binary    = élément binaire à consulter.                     *
+*                timestamp = date du dernier élément à garder comme actif.    *
+*                db        = base de données à mettre à jour.                 *
+*                pbuf      = paquet de données où venir inscrire les infos.   *
 *                                                                             *
 *  Description : Désactive les éléments en aval d'un horodatage donné.        *
 *                                                                             *
-*  Retour      : true si l'élément a été traité, false sinon.                 *
+*  Retour      : true si la commande a bien été envoyée, false sinon.         *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool g_db_collection_set_inactive(GDbCollection *collec, GDbItem *item, timestamp_t *timestamp)
+bool g_db_collection_disable_at(GDbCollection *collec, timestamp_t timestamp, sqlite3 *db, packed_buffer *pbuf)
 {
     bool result;                            /* Bilan à retourner           */
+    size_t start;                           /* Début de la zone à changer  */
+    size_t back;                            /* Début de restauration       */
+    size_t i;                               /* Boucle de parcours          */
+    GDbItem *item;                          /* Elément à traiter           */
 
-    /* Si cette collection n'est pas concernée, on ne bouge pas ! */
-    if (G_OBJECT_TYPE(G_OBJECT(item)) != collec->type) return false;
+    result = true;
 
-    result = g_db_item_set_activity(item, collec->binary, timestamp);
+    g_db_collection_wlock(collec);
 
-    //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item);
+    start = g_db_collection_find_by_timestamp(collec, timestamp);
 
-    return result;
+    /* Réactivation d'éléments ? */
 
-}
+    if (start > 0)
+    {
+        back = start;
 
+        for (i = start; i > 0; i--)
+            if (!g_db_item_has_flag(collec->items[i - 1], DIF_DISABLED))
+                break;
+            else
+                back--;
 
+        for (i = back; i < start && result; i++)
+        {
+            item = collec->items[i];
 
-/* ---------------------------------------------------------------------------------- */
-/*                       MANIPULATIONS AVEC UNE BASE DE DONNEES                       */
-/* ---------------------------------------------------------------------------------- */
+            g_db_item_remove_flag(item, DIF_DISABLED);
 
+            g_db_collection_store_updated_item(collec, item, db);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : collec = ensemble d'éléments spectateur des opérations.      *
-*                db     = accès à la base de données.                         *
-*                                                                             *
-*  Description : Crée la table d'élément dans une base de données.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+            g_db_collection_set_last_item(collec, item, false);
 
-bool g_db_collection_create_db_table(const GDbCollection *collec, sqlite3 *db)
-{
-    return G_DB_COLLECTION_GET_CLASS(collec)->create_table(collec, db);
+            result = g_db_collection_pack(collec, pbuf, DBA_CHANGE_STATE, item);
+
+        }
+
+    }
+
+    /* Désactivation des éléments en queue */
+
+    for (i = start; i < collec->count && result; i++)
+    {
+        item = collec->items[i];
+
+        if (g_db_item_has_flag(item, DIF_DISABLED))
+            break;
+
+        g_db_item_add_flag(item, DIF_DISABLED);
+
+        g_db_collection_store_updated_item(collec, item, db);
+
+        g_db_collection_unset_last_item(collec, item, start);
+
+        result = g_db_collection_pack(collec, pbuf, DBA_CHANGE_STATE, item);
+
+    }
+
+    g_db_collection_wunlock(collec);
+
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                item   = élément de collection à manipuler.                  *
 *                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
+*  Description : Prend acte d'un changement d'état d'un élément de collection.*
 *                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
 *                                                                             *
-*  Remarques   : -                                                            *
+*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      *
 *                                                                             *
 ******************************************************************************/
 
-static bool _g_db_collection_setup_load(GDbCollection *collec, bound_value **values, size_t *count)
+bool g_db_collection_update_item_state(GDbCollection *collec, const GDbItem *item)
 {
-    if (!store_timestamp(NULL, "created", values, count))
-        return false;
+    bool result;                            /* Bilan à faire remonter      */
+    size_t index;                           /* Indice de l'élément visé    */
+    GDbItem *changed;                       /* Elément à basculer          */
+    DbItemFlags new;                        /* Nouvelles propriétés        */
+
+    result = false;
+
+    g_db_collection_wlock(collec);
+
+    index = g_db_collection_find_by_timestamped(collec, item);
 
-    if (!store_timestamp(NULL, "timestamp", values, count))
-        return false;
+    result = (index < collec->count);
 
-    if (!store_rle_string(NULL, "author", values, count))
-        return false;
+    if (result)
+    {
+        changed = collec->items[index];
+
+        new = g_db_item_get_flags(item);
+
+        g_db_item_set_flags(changed, new);
+
+        if (new & DIF_DISABLED)
+            g_db_collection_unset_last_item(collec, changed, index);
+        else
+            g_db_collection_set_last_item(collec, changed, false);
+
+        g_signal_emit_by_name(collec, "state-changed", changed);
+
+    }
 
-    return true;
+    g_db_collection_wunlock(collec);
+
+    return result;
 
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                       MANIPULATIONS AVEC UNE BASE DE DONNEES                       */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
+*  Paramètres  : collec = ensemble d'éléments spectateur des opérations.      *
+*                db     = accès à la base de données.                         *
 *                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
+*  Description : Crée la table d'élément dans une base de données.            *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -1027,12 +1092,9 @@ static bool _g_db_collection_setup_load(GDbCollection *collec, bound_value **val
 *                                                                             *
 ******************************************************************************/
 
-static bool g_db_collection_setup_load(GDbCollection *collec, bound_value **values, size_t *count)
+bool g_db_collection_create_db_table(const GDbCollection *collec, sqlite3 *db)
 {
-    *values = NULL;
-    *count = 0;
-    
-    return G_DB_COLLECTION_GET_CLASS(collec)->setup_load(collec, values, count);
+    return G_DB_COLLECTION_GET_CLASS(collec)->create_table(collec, db);
 
 }
 
@@ -1061,13 +1123,10 @@ static bool g_db_collection_load_new_item(const bound_value *values, size_t coun
     result = g_db_item_load(new, values, count);
 
     if (result)
-    {
         result = g_db_collection_add_item(G_DB_COLLECTION(collec), new);
-
+    else
         g_object_unref(G_OBJECT(new));
 
-    }
-
     return result;
 
 }
@@ -1089,10 +1148,15 @@ static bool g_db_collection_load_new_item(const bound_value *values, size_t coun
 bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
 {
     bool result;                            /* Conclusion à faire remonter */
+    GDbItem *dummy;                         /* Interface vide              */
     bound_value *values;                    /* Champs de table à inclure   */
     size_t count;                           /* Nombre de ces champs        */
 
-    result = g_db_collection_setup_load(collec, &values, &count);
+    dummy = g_object_new(collec->type, NULL);
+
+    result = g_db_item_setup_load(dummy, &values, &count);
+
+    g_object_unref(G_OBJECT(dummy));
 
     if (result)
         result = load_db_values(db, collec->name, values, count, (db_load_cb)g_db_collection_load_new_item, collec);
@@ -1447,9 +1511,10 @@ bool pack_all_collection_updates(GList *list, packed_buffer *pbuf)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : list = ensemble de collectons à traiter.                     *
-*                pbuf = paquet de données où venir puiser les infos.          *
-*                db   = base de données à mettre à jour.                      *
+*  Paramètres  : list   = ensemble de collectons à traiter.                   *
+*                inbuf  = paquet de données où venir puiser les infos.        *
+*                outbuf = paquet de données où inscrire les mises à jour.     *
+*                db     = base de données à mettre à jour.                    *
 *                                                                             *
 *  Description : Met à jour les statuts d'activité des éléments.              *
 *                                                                             *
@@ -1459,18 +1524,14 @@ bool pack_all_collection_updates(GList *list, packed_buffer *pbuf)
 *                                                                             *
 ******************************************************************************/
 
-bool update_activity_in_collections(GList *list, packed_buffer *pbuf, sqlite3 *db)
+bool update_activity_in_collections(GList *list, packed_buffer *inbuf, packed_buffer *outbuf, sqlite3 *db)
 {
     bool result;                            /* Résultat global à renvoyer  */
     bool status;                            /* Bilan de lecture initiale   */
     timestamp_t timestamp;                  /* Horodatage de limite        */
-    timestamp_t inactive;                   /* Date du premier inactif     */
-    GList *remaining;                       /* Eléments restants à traiter */
-    GList *c;                               /* Boucle de parcours #1       */
-    GDbCollection *collec;                  /* Collection à manipuler      */
-    GList *got;                             /* Eléments restants à traiter */
-    GList *i;                               /* Boucle de parcours #2       */
-    GDbItem *item;                          /* Elément collecté à manipuler*/
+    GList *iter;                            /* Boucle de parcours          */
+
+    result = true;
 
     /**
      * Cette procédure n'est appelée que depuis g_cdb_archive_process(),
@@ -1479,55 +1540,19 @@ bool update_activity_in_collections(GList *list, packed_buffer *pbuf, sqlite3 *d
      * On a donc l'assurance d'un traitement global homgène des horodatages.
      */
 
-    status = unpack_timestamp(&timestamp, pbuf);
+    status = unpack_timestamp(&timestamp, inbuf);
     if (!status) return false;
 
-    inactive = TIMESTAMP_ALL_ACTIVE;
-
-    remaining = NULL;
-
-    wlock_collections(list);
-
-    for (c = g_list_first(list); c != NULL; c = g_list_next(c))
-    {
-        collec = G_DB_COLLECTION(c->data);
-
-        got = g_db_collection_set_last_active(collec, timestamp, &inactive, db);
-        remaining = g_list_concat(remaining, got);
-
-    }
-
-    gint sort_with_timestamp(GDbItem *a, GDbItem *b)
-    {
-        return g_db_item_cmp(a, b, false);
-    }
 
-    remaining = g_list_sort(remaining, (GCompareFunc)sort_with_timestamp);
 
-    result = true;
-
-    for (i = g_list_last(remaining); i != NULL && result; i = g_list_previous(i))
+    for (iter = g_list_first(list);
+         iter != NULL && result;
+         iter = g_list_next(iter))
     {
-        item = G_DB_ITEM(i->data);
-
-        for (c = g_list_first(list); c != NULL && result; c = g_list_next(c))
-        {
-            collec = G_DB_COLLECTION(c->data);
-
-            if (g_db_collection_set_inactive(collec, item, &inactive))
-            {
-                result = g_db_collection_store_updated_item(collec, item, db);
-                break;
-            }
-
-        }
+        result = g_db_collection_disable_at(G_DB_COLLECTION(iter->data), timestamp, db, outbuf);
 
     }
 
-    wunlock_collections(list);
-
-    g_list_free(remaining);
-
     return result;
 
 }
diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h
index 60e5c26..9539229 100644
--- a/src/analysis/db/collection.h
+++ b/src/analysis/db/collection.h
@@ -93,7 +93,7 @@ void g_db_collection_lock_unlock(GDbCollection *, bool, bool);
 #define g_db_collection_runlock(col) g_db_collection_lock_unlock(col, false, false);
 
 /* Renvoie la liste des éléments rassemblés. */
-GList *g_db_collection_get_items(const GDbCollection *);
+GDbItem **g_db_collection_get_items(const GDbCollection *, size_t *);
 
 /* Détermine si un élément est déjà présent ou non. */
 GDbItem *g_db_collection_has_key(GDbCollection *, ...);
@@ -104,25 +104,24 @@ bool g_db_collection_has_item(GDbCollection *, GDbItem *);
 /* Procède à l'ajout d'un nouvel élément dans la collection. */
 bool _g_db_collection_add_item(GDbCollection *, GDbItem *, bool);
 
-/* Procède au retrait d'un nouvel élément dans la collection. */
-bool _g_db_collection_remove_item(GDbCollection *, GDbItem *, bool, bool);
+/* Procède au retrait des éléments désactivés de la collection. */
+bool g_db_collection_drop_disabled_items(GDbCollection *, packed_buffer *);
 
-/* Détermine l'horodatage le plus jeune pour une désactivation. */
-timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *, bool);
+/* Procède au retrait d'un élément dans la collection. */
+bool g_db_collection_remove_item(GDbCollection *, const GDbItem *);
 
-/* Met à jour le statut d'activité d'un élément de collection. */
-bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, timestamp_t *, bool);
+/* Désactive les éléments en aval d'un horodatage donné. */
+bool g_db_collection_disable_at(GDbCollection *, timestamp_t, sqlite3 *, packed_buffer *);
 
-#define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true)
-#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true, true)
-#define g_db_collection_compute_inactivity_timestamp(c) _g_db_collection_compute_inactivity_timestamp(c, true)
-#define g_db_collection_update_item_activity(c, i, t) _g_db_collection_update_item_activity(c, i, t, true)
+/* Prend acte d'un changement d'état d'un élément de collection. */
+bool g_db_collection_update_item_state(GDbCollection *, const GDbItem *);
 
-/* Active les éléments en amont d'un horodatage donné. */
-GList *g_db_collection_set_last_active(GDbCollection *, timestamp_t, timestamp_t *, sqlite3 *);
 
-/* Désactive les éléments en aval d'un horodatage donné. */
-bool g_db_collection_set_inactive(GDbCollection *, GDbItem *, timestamp_t *);
+
+
+
+#define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true)
+//#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true, true)
 
 
 
@@ -159,7 +158,7 @@ void lock_unlock_collections(GList *, bool, bool);
 bool pack_all_collection_updates(GList *, packed_buffer *);
 
 /* Met à jour les statuts d'activité des éléments. */
-bool update_activity_in_collections(GList *, packed_buffer *, sqlite3 *);
+bool update_activity_in_collections(GList *, packed_buffer *, packed_buffer *, sqlite3 *);
 
 
 
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 8bba8a3..8c13cd9 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -111,8 +111,8 @@ struct _GDbItemClass
 /* Définition du tronc commun pour les créations SQLite */
 #define SQLITE_DB_ITEM_CREATE                   \
     SQLITE_TIMESTAMP_CREATE("created") ", "     \
-    SQLITE_TIMESTAMP_CREATE("timestamp") ", "   \
-    SQLITE_RLESTR_CREATE("author")
+    SQLITE_RLESTR_CREATE("author") ", "         \
+    "flags INTEGER"
 
 
 
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index efa2cdf..f9c4201 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -462,7 +462,7 @@ bool g_db_item_apply(GDbItem *item, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
 
-    assert(g_db_item_is_active(item));
+    assert(!g_db_item_has_flag(item, DIF_DISABLED));
 
     result = G_DB_ITEM_GET_CLASS(item)->apply(item, binary);
 
@@ -491,7 +491,7 @@ bool g_db_item_cancel(GDbItem *item, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
 
-    assert(!g_db_item_is_active(item));
+    assert(g_db_item_has_flag(item, DIF_DISABLED));
 
     result = G_DB_ITEM_GET_CLASS(item)->cancel(item, binary);
 
@@ -533,7 +533,7 @@ char *g_db_item_get_label(GDbItem *item)
 *                                                                             *
 *  Description : Fournit l'horodatage associé à l'élément de collection.      *
 *                                                                             *
-*  Retour      : Date d'activité de l'élément.                                *
+*  Retour      : Date de création de l'élément.                               *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -541,56 +541,9 @@ char *g_db_item_get_label(GDbItem *item)
 
 timestamp_t g_db_item_get_timestamp(const GDbItem *item)
 {
-    return item->timestamp;
+    timestamp_t result;                     /* Horodatage à retourner      */
 
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item   = élément de collection à mettre à jour.              *
-*                binary = binaire chargé en mémoire à modifier.               *
-*                first  = horodatage du premier élément désactivé ou NULL.    *
-*                                                                             *
-*  Description : Active ou désactive un élément de collection en place.       *
-*                                                                             *
-*  Retour      : Bilan de la mise à jour de l'élément.                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_db_item_set_activity(GDbItem *item, GLoadedBinary *binary, timestamp_t *first)
-{
-    bool result;                            /* Bilan à faire remonter      */
-    bool active;                            /* Etat avant changement       */
-
-    active = g_db_item_is_active(item);
-
-    /* Archivage de l'état */
-
-    if (first == NULL)
-    {
-        assert(!active);
-        item->timestamp = item->created;
-    }
-    else
-    {
-        assert(active);
-        item->timestamp = --(*first);
-    }
-
-    /* Application de l'état */
-
-    if (binary != NULL)
-    {
-        if (active)
-            result = g_db_item_cancel(item, binary);
-        else
-            result = g_db_item_apply(item, binary);
-    }
-    else
-        result = true;
+    result = item->created;
 
     return result;
 
@@ -599,19 +552,20 @@ bool g_db_item_set_activity(GDbItem *item, GLoadedBinary *binary, timestamp_t *f
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item = élément de collection à consulter.                    *
+*  Paramètres  : item = base d'éléments à mettre à jour.                      *
+*                flag = type de propriété à traiter.                          *
 *                                                                             *
-*  Description : Indique si l'élément est activé ou désactivé.                *
+*  Description : Applique un ensemble de propriétés à un élément.             *
 *                                                                             *
-*  Retour      : Etat de l'activité de l'élément.                             *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool g_db_item_is_active(const GDbItem *item)
+void g_db_item_set_flags(GDbItem *item, DbItemFlags flag)
 {
-    return (cmp_timestamp(&item->created, &item->timestamp) == 0);
+    g_atomic_int_set(&item->atomic_flags, flag);
 
 }
 
@@ -684,6 +638,50 @@ DbItemFlags g_db_item_get_flags(const GDbItem *item)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément de collection à mettre à jour.              *
+*                binary = binaire chargé en mémoire à modifier.               *
+*                                                                             *
+*  Description : Active ou désactive un élément de collection en place.       *
+*                                                                             *
+*  Retour      : Bilan de la mise à jour de l'élément.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_item_switch_state(GDbItem *item, GLoadedBinary *binary)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    bool enabled;                           /* Etat avant changement       */
+
+    enabled = !g_db_item_has_flag(item, DIF_DISABLED);
+
+    /* Archivage de l'état */
+
+    if (enabled)
+        g_db_item_add_flag(item, DIF_DISABLED);
+    else
+        g_db_item_remove_flag(item, DIF_DISABLED);
+
+    /* Application de l'état */
+
+    if (binary != NULL)
+    {
+        if (enabled)
+            result = g_db_item_cancel(item, binary);
+        else
+            result = g_db_item_apply(item, binary);
+    }
+    else
+        result = true;
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                       MANIPULATIONS AVEC UNE BASE DE DONNEES                       */
@@ -692,6 +690,30 @@ DbItemFlags g_db_item_get_flags(const GDbItem *item)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : item   = base d'éléments à consulter.                        *
+*                values = tableau d'éléments à compléter. [OUT]               *
+*                count  = nombre de descriptions renseignées. [OUT]           *
+*                                                                             *
+*  Description : Décrit les colonnes utiles à un chargement de données.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_item_setup_load(const GDbItem *item, bound_value **values, size_t *count)
+{
+    *values = NULL;
+    *count = 0;
+
+    return G_DB_ITEM_GET_CLASS(item)->store(NULL, values, count);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : item   = base d'éléments à charger depuis les réponses.      *
 *                values = tableau d'éléments à consulter.                     *
 *                count  = nombre de descriptions renseignées.                 *
@@ -707,14 +729,23 @@ DbItemFlags g_db_item_get_flags(const GDbItem *item)
 static bool _g_db_item_load(GDbItem *item, const bound_value *values, size_t count)
 {
     bool result;                            /* Bilan global à retourner    */
+    const bound_value *value;               /* Valeur à intégrer           */
 
     result = load_timestamp(&item->created, "created", values, count);
 
     if (result)
-        result = load_timestamp(&item->timestamp, "timestamp", values, count);
+        result = load_rle_string(&item->author, "author", values, count);
 
     if (result)
-        result = load_rle_string(&item->author, "author", values, count);
+    {
+        value = find_bound_value(values, count, "flags");
+
+        result = (value != NULL && value->type == SQLITE_INTEGER);
+
+        if (result)
+            item->flags = value->integer;
+
+    }
 
     return result;
 
@@ -763,6 +794,7 @@ bool g_db_item_load(GDbItem *item, const bound_value *values, size_t count)
 static bool _g_db_item_store(const GDbItem *item, bound_value **values, size_t *count)
 {
     bool result;                            /* Bilan à retourner           */
+    bound_value *value;                     /* Valeur à éditer / définir   */
 
     if (item == NULL)
         result = store_timestamp(NULL, "created", values, count);
@@ -772,17 +804,26 @@ static bool _g_db_item_store(const GDbItem *item, bound_value **values, size_t *
     if (result)
     {
         if (item == NULL)
-            result = store_timestamp(NULL, "timestamp", values, count);
+            result = store_rle_string(NULL, "author", values, count);
         else
-            result = store_timestamp(&item->timestamp, "timestamp", values, count);
+            result = store_rle_string(&item->author, "author", values, count);
     }
 
     if (result)
     {
-        if (item == NULL)
-            result = store_rle_string(NULL, "author", values, count);
-        else
-            result = store_rle_string(&item->author, "author", values, count);
+        *values = realloc(*values, ++(*count) * sizeof(bound_value));
+
+        value = &(*values)[*count - 1];
+
+        value->cname = "flags";
+        value->built_name = false;
+        value->type = SQLITE_INTEGER;
+
+        value->has_value = (item != NULL);
+
+        if (value->has_value)
+            value->integer = g_db_item_get_flags(item);
+
     }
 
     return result;
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
index 395a56f..b735fb8 100644
--- a/src/analysis/db/item.h
+++ b/src/analysis/db/item.h
@@ -48,6 +48,7 @@ typedef enum _DbItemFlags
     DIF_UPDATED  = (1 << 1),                /* Mise à jour de l'élément    */
     DIF_VOLATILE = (1 << 2),                /* Abscence de sauvegarde      */
     DIF_BROKEN   = (1 << 3),                /* Application impossible      */
+    DIF_DISABLED = (1 << 4),                /* Désactivation forcée        */
 
 } DbItemFlags;
 
@@ -109,11 +110,8 @@ char *g_db_item_get_label(GDbItem *);
 /* Fournit l'horodatage associé à l'élément de collection. */
 timestamp_t g_db_item_get_timestamp(const GDbItem *);
 
-/*  Active ou désactive un élément de collection en place. */
-bool g_db_item_set_activity(GDbItem *, GLoadedBinary *, timestamp_t *);
-
-/* Indique si l'élément est activé ou désactivé. */
-bool g_db_item_is_active(const GDbItem *);
+/* Applique un ensemble de propriétés à un élément. */
+void g_db_item_set_flags(GDbItem *, DbItemFlags);
 
 /* Ajoute une propriété à un élément de base de données. */
 void g_db_item_add_flag(GDbItem *, DbItemFlags);
@@ -124,11 +122,25 @@ void g_db_item_remove_flag(GDbItem *, DbItemFlags);
 /* Indique les propriétés particulières appliquées à l'élément. */
 DbItemFlags g_db_item_get_flags(const GDbItem *);
 
+#define g_db_item_has_flag(i, f) \
+    (g_db_item_get_flags(i) & f)
+
+
+//////////
+#define g_db_item_is_enabled(i) ((g_db_item_get_flags(i) & DIF_DISABLED) == 0)
+
+
+/* Active ou désactive un élément de collection en place. */
+bool g_db_item_switch_state(GDbItem *, GLoadedBinary *);
+
 
 
 /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
 
 
+/* Décrit les colonnes utiles à un chargement de données. */
+bool g_db_item_setup_load(const GDbItem *, bound_value **, size_t *);
+
 /* Charge les valeurs utiles pour un élément de collection. */
 bool g_db_item_load(GDbItem *, const bound_value *, size_t);
 
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 3d66f6b..c1b0fec 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -141,9 +141,6 @@ static void g_bookmark_collection_finalize(GBookmarkCollection *);
 /* Crée la table des signets dans une base de données. */
 static bool g_bookmark_collection_create_db_table(const GBookmarkCollection *, sqlite3 *);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool g_bookmark_collection_setup_load(GBookmarkCollection *, bound_value **, size_t *);
-
 /* Détermine si un élément est déjà présent ou non. */
 static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *, va_list);
 
@@ -796,7 +793,6 @@ static void g_bookmark_collection_class_init(GBookmarkCollectionClass *klass)
     collec = G_DB_COLLECTION_CLASS(klass);
 
     collec->create_table = (collec_create_db_table_fc)g_bookmark_collection_create_db_table;
-    collec->setup_load = (collec_setup_load_fc)g_bookmark_collection_setup_load;
     collec->has_key = (collec_has_key_fc)g_bookmark_collection_has_key;
 
 }
@@ -934,39 +930,6 @@ static bool g_bookmark_collection_create_db_table(const GBookmarkCollection *col
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
-*                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_bookmark_collection_setup_load(GBookmarkCollection *collec, bound_value **values, size_t *count)
-{
-    bool status;                            /* Bilan d'une préparation     */
-
-    status = G_DB_COLLECTION_CLASS(g_bookmark_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
-                                                                                   values, count);
-    if (!status) return false;
-
-    if (!store_vmpa(NULL, NULL, values, count))
-        return false;
-
-    if (!store_rle_string(NULL, "comment", values, count))
-        return false;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
 *                ap     = clef identifiant de manière unique un élément.      *
 *                                                                             *
 *  Description : Détermine si un élément est déjà présent ou non.             *
@@ -989,6 +952,7 @@ static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *collec, va_li
 
     ref = va_arg(ap, vmpa2t *);
 
+#if 0
     items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
@@ -1005,6 +969,7 @@ static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *collec, va_li
             result = G_DB_ITEM(bm);
 
     }
+#endif
 
     return result;
 
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index a987464..a231749 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -183,9 +183,6 @@ static void g_comment_collection_finalize(GCommentCollection *);
 /* Crée la table des commentaires dans une base de données. */
 static bool g_comment_collection_create_db_table(const GCommentCollection *, sqlite3 *);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool g_comment_collection_setup_load(GCommentCollection *, bound_value **, size_t *);
-
 /* Détermine si un élément est déjà présent ou non. */
 static GDbItem *g_comment_collection_has_key(GCommentCollection *, va_list);
 
@@ -995,7 +992,7 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
 
     if (result)
     {
-        value = find_bound_value(values, count, "flags");
+        value = find_bound_value(values, count, "lflags");
         result = (value != NULL && value->type == SQLITE_INTEGER);
 
         if (result)
@@ -1072,16 +1069,20 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
 
     value = &(*values)[*count - 1];
 
-    value->cname = "flags";
+    value->cname = "lflags";
     value->built_name = false;
     value->type = SQLITE_INTEGER;
-    value->integer = comment->flags;
-    value->delete = NULL;
 
     value->has_value = (comment != NULL);
 
     if (value->has_value)
     {
+        value->integer = comment->flags;
+        value->delete = NULL;
+    }
+
+    if (value->has_value)
+    {
         init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
         status = store_rle_string(&text, "text", values, count);
         exit_rle_string(&text);
@@ -1514,7 +1515,6 @@ static void g_comment_collection_class_init(GCommentCollectionClass *klass)
     collec = G_DB_COLLECTION_CLASS(klass);
 
     collec->create_table = (collec_create_db_table_fc)g_comment_collection_create_db_table;
-    collec->setup_load = (collec_setup_load_fc)g_comment_collection_setup_load;
     collec->has_key = (collec_has_key_fc)g_comment_collection_has_key;
 
 }
@@ -1626,7 +1626,7 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
     sql = "CREATE TABLE Comments ("             \
              SQLITE_DB_ITEM_CREATE ", "         \
              "%s, "                             \
-             "flags INTEGER, "                  \
+             "lflags INTEGER, "                 \
              SQLITE_RLESTR_CREATE("text") ", "  \
              "inlined INTEGER, "                \
              "repeatable INTEGER"               \
@@ -1655,64 +1655,6 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
-*                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_value **values, size_t *count)
-{
-    bool status;                            /* Bilan d'une préparation     */
-    bound_value *value;                     /* Valeur à éditer / définir   */
-
-    status = G_DB_COLLECTION_CLASS(g_comment_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
-                                                                                  values, count);
-    if (!status) return false;
-
-    if (!store_vmpa(NULL, NULL, values, count))
-        return false;
-
-    *count += 1;
-    *values = realloc(*values, *count * sizeof(bound_value));
-
-    value = &(*values)[*count - 1];
-
-    value->cname = "flags";
-    value->built_name = false;
-    value->type = SQLITE_INTEGER;
-
-    if (!store_rle_string(NULL, "text", values, count))
-        return false;
-
-    *count += 2;
-    *values = realloc(*values, *count * sizeof(bound_value));
-
-    value = &(*values)[*count - 2];
-
-    value->cname = "inlined";
-    value->built_name = false;
-    value->type = SQLITE_BOOLEAN;
-
-    value = &(*values)[*count - 1];
-
-    value->cname = "repeatable";
-    value->built_name = false;
-    value->type = SQLITE_BOOLEAN;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
 *                ap     = clef identifiant de manière unique un élément.      *
 *                                                                             *
 *  Description : Détermine si un élément est déjà présent ou non.             *
@@ -1735,6 +1677,7 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *collec, va_list
 
     ref = va_arg(ap, vmpa2t *);
 
+#if 0
     items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
@@ -1751,6 +1694,7 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *collec, va_list
             result = G_DB_ITEM(bm);
 
     }
+#endif
 
     return result;
 
diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c
index a5d2773..afc3331 100644
--- a/src/analysis/db/items/move.c
+++ b/src/analysis/db/items/move.c
@@ -136,9 +136,6 @@ static void g_move_collection_finalize(GMoveCollection *);
 /* Crée la table des basculements dans une base de données. */
 static bool g_move_collection_create_db_table(const GMoveCollection *, sqlite3 *);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool g_move_collection_setup_load(GMoveCollection *, bound_value **, size_t *);
-
 /* Détermine si un élément est déjà présent ou non. */
 static GDbItem *g_move_collection_has_key(GMoveCollection *, va_list);
 
@@ -638,7 +635,6 @@ static void g_move_collection_class_init(GMoveCollectionClass *klass)
     collec = G_DB_COLLECTION_CLASS(klass);
 
     collec->create_table = (collec_create_db_table_fc)g_move_collection_create_db_table;
-    collec->setup_load = (collec_setup_load_fc)g_move_collection_setup_load;
     collec->has_key = (collec_has_key_fc)g_move_collection_has_key;
 
 }
@@ -779,40 +775,6 @@ static bool g_move_collection_create_db_table(const GMoveCollection *collec, sql
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
-*                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_move_collection_setup_load(GMoveCollection *collec, bound_value **values, size_t *count)
-{
-    bool status;                            /* Bilan d'une préparation     */
-
-    status = G_DB_COLLECTION_CLASS(g_move_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
-                                                                                   values, count);
-    if (!status) return false;
-
-    if (!g_binary_cursor_store(NULL, "src", values, count))
-        return false;
-
-    if (!g_binary_cursor_store(NULL, "dest", values, count))
-        return false;
-
-    return true;
-
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
 *                ap     = clef identifiant de manière unique un élément.      *
 *                                                                             *
 *  Description : Détermine si un élément est déjà présent ou non.             *
@@ -835,6 +797,7 @@ static GDbItem *g_move_collection_has_key(GMoveCollection *collec, va_list ap)
 
     ref = va_arg(ap, const GLineCursor *);
 
+#if 0
     items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
@@ -851,6 +814,7 @@ static GDbItem *g_move_collection_has_key(GMoveCollection *collec, va_list ap)
             result = G_DB_ITEM(bm);
 
     }
+#endif
 
     return result;
 
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 043effd..94d4940 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -136,9 +136,6 @@ static void g_switcher_collection_finalize(GSwitcherCollection *);
 /* Crée la table des basculements dans une base de données. */
 static bool g_switcher_collection_create_db_table(const GSwitcherCollection *, sqlite3 *);
 
-/* Décrit les colonnes utiles à un chargement de données. */
-static bool g_switcher_collection_setup_load(GSwitcherCollection *, bound_value **, size_t *);
-
 /* Détermine si un élément est déjà présent ou non. */
 static GDbItem *g_switcher_collection_has_key(GSwitcherCollection *, va_list);
 
@@ -790,7 +787,6 @@ static void g_switcher_collection_class_init(GSwitcherCollectionClass *klass)
     collec = G_DB_COLLECTION_CLASS(klass);
 
     collec->create_table = (collec_create_db_table_fc)g_switcher_collection_create_db_table;
-    collec->setup_load = (collec_setup_load_fc)g_switcher_collection_setup_load;
     collec->has_key = (collec_has_key_fc)g_switcher_collection_has_key;
 
 }
@@ -929,53 +925,6 @@ static bool g_switcher_collection_create_db_table(const GSwitcherCollection *col
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
-*                values = tableau d'éléments à compléter. [OUT]               *
-*                count  = nombre de descriptions renseignées. [OUT]           *
-*                                                                             *
-*  Description : Décrit les colonnes utiles à un chargement de données.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_value **values, size_t *count)
-{
-    bool status;                            /* Bilan d'une préparation     */
-    bound_value *value;                     /* Valeur à éditer / définir   */
-
-    status = G_DB_COLLECTION_CLASS(g_switcher_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
-                                                                                   values, count);
-    if (!status) return false;
-
-    if (!store_vmpa(NULL, NULL, values, count))
-        return false;
-
-    *count += 2;
-    *values = realloc(*values, *count * sizeof(bound_value));
-
-    value = &(*values)[*count - 2];
-
-    value->cname = "op_index";
-    value->built_name = false;
-    value->type = SQLITE_INTEGER;
-
-    value = &(*values)[*count - 1];
-
-    value->cname = "type";
-    value->built_name = false;
-    value->type = SQLITE_INTEGER;
-
-    return true;
-
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
 *                ap     = clef identifiant de manière unique un élément.      *
 *                                                                             *
 *  Description : Détermine si un élément est déjà présent ou non.             *
@@ -998,6 +947,7 @@ static GDbItem *g_switcher_collection_has_key(GSwitcherCollection *collec, va_li
 
     ref = va_arg(ap, vmpa2t *);
 
+#if 0
     items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
@@ -1014,6 +964,7 @@ static GDbItem *g_switcher_collection_has_key(GSwitcherCollection *collec, va_li
             result = G_DB_ITEM(bm);
 
     }
+#endif
 
     return result;
 
diff --git a/src/analysis/db/misc/timestamp.h b/src/analysis/db/misc/timestamp.h
index eba0fa7..4ff714e 100644
--- a/src/analysis/db/misc/timestamp.h
+++ b/src/analysis/db/misc/timestamp.h
@@ -39,8 +39,8 @@ typedef uint64_t timestamp_t;
 
 
 /* Valeurs particulières */
-#define TIMESTAMP_ALL_ACTIVE 0
-#define TIMESTAMP_ALL_INACTIVE 1
+#define TIMESTAMP_ALL_ACTIVE 0      // REMME
+#define TIMESTAMP_ALL_INACTIVE 1    // REMME
 
 
 /* Obtient un horodatage initialisé au moment même. */
diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h
index 5c3eed6..d429530 100644
--- a/src/analysis/db/protocol.h
+++ b/src/analysis/db/protocol.h
@@ -95,7 +95,6 @@ typedef enum _DBAction
 {
     DBA_ADD_ITEM,                           /* Ajout d'un élément          */
     DBA_REM_ITEM,                           /* Suppression d'un élément    */
-
     DBA_CHANGE_STATE,                       /* Changement d'activité       */
 
     DBA_COUNT
@@ -186,16 +185,16 @@ typedef enum _DBCommand
      * avec une série de paquets de la forme :
      *
      *    [ Traitement de collection : DBC_COLLECTION   ]
-     *    [ Action : DBC_SET_LAST_ACTIVE                ]
+     *    [ Action : DBA_CHANGE_STATE                   ]
      *    [ <élément dont le statut a évolué>           ]
      *
      * Les traitements se réalisent dans :
-     *  - g_db_collection_set_last_active() pour la partie serveur.
-     *  - g_db_client_set_last_active() pour la partie client.
+     *  - g_db_collection_disable_at() pour la partie serveur.
+     *  - g_db_collection_update_item_state() pour la partie client.
      *
      */
 
-    DBC_SET_LAST_ACTIVE,                    /* Définition du dernier actif */
+    DBC_SET_LAST_ACTIVE,                    /* Définition du dernier actif */   // REMME
 
     DBC_COUNT
 
diff --git a/src/core/collections.c b/src/core/collections.c
index a047a15..34b7bc1 100644
--- a/src/core/collections.c
+++ b/src/core/collections.c
@@ -114,11 +114,11 @@ bool load_hard_coded_collection_definitions(void)
 
     REGISTER_COLLECTION(G_TYPE_BM_COLLECTION, DBF_BOOKMARKS);
 
-    REGISTER_COLLECTION(G_TYPE_COMMENT_COLLECTION, DBF_COMMENTS);
+    //REGISTER_COLLECTION(G_TYPE_COMMENT_COLLECTION, DBF_COMMENTS);
 
-    REGISTER_COLLECTION(G_TYPE_MOVE_COLLECTION, DBF_MOVES);
+    //REGISTER_COLLECTION(G_TYPE_MOVE_COLLECTION, DBF_MOVES);
 
-    REGISTER_COLLECTION(G_TYPE_SWITCHER_COLLECTION, DBF_DISPLAY_SWITCHERS);
+    //REGISTER_COLLECTION(G_TYPE_SWITCHER_COLLECTION, DBF_DISPLAY_SWITCHERS);
 
     return true;
 
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index f4b0712..01f24e8 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -722,7 +722,7 @@ static void mcb_edition_bookmarks_toggle(GtkMenuItem *menuitem, GMenuBar *bar)
     exist = NULL;//g_db_collection_has_key(collec, &addr);
 
     if (exist != NULL)
-        g_loaded_binary_remove_from_collection(binary, DBF_BOOKMARKS, exist);
+        ;//g_loaded_binary_remove_from_collection(binary, DBF_BOOKMARKS, exist);
 
     else
     {
@@ -746,7 +746,10 @@ static void mcb_edition_bookmarks_toggle(GtkMenuItem *menuitem, GMenuBar *bar)
                                           "Do you want to replace it ?"));
 
                 if (ret != GTK_RESPONSE_YES)
+                {
+                    g_object_unref(G_OBJECT(bookmark));
                     goto mcb_ebt_add_finish;
+                }
 
             }
 
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index f32f9f5..ebe1f62 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -473,12 +473,13 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary
 
     g_db_collection_rlock(collec);
 
+    /*
     items = g_db_collection_get_items(collec);
 
     for (b = g_list_first(items); b != NULL; b = g_list_next(b))
     {
         bookmark = G_DB_BOOKMARK(b->data);
-        if (!g_db_item_is_active(G_DB_ITEM(bookmark))) continue;
+        if (!g_db_item_is_enabled(G_DB_ITEM(bookmark))) continue;
 
         addr = g_db_bookmark_get_address(bookmark);
 
@@ -500,6 +501,7 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary
                            -1);
 
     }
+    */
 
     g_db_collection_runlock(collec);
 
@@ -543,7 +545,7 @@ static void on_collection_content_changed(GDbCollection *collec, DBAction action
 
     store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
 
-    if (action == DBA_ADD_ITEM || (action == DBA_CHANGE_STATE && g_db_item_is_active(G_DB_ITEM(bookmark))))
+    if (action == DBA_ADD_ITEM || (action == DBA_CHANGE_STATE && g_db_item_is_enabled(G_DB_ITEM(bookmark))))
     {
         proc = g_loaded_binary_get_processor(panel->binary);
         msize = g_arch_processor_get_memory_size(proc);
@@ -568,7 +570,7 @@ static void on_collection_content_changed(GDbCollection *collec, DBAction action
 
     }
 
-    else /*if (action == DBA_CHANGE_STATE && g_db_item_is_active(G_DB_ITEM(bookmark)))*/
+    else /*if (action == DBA_CHANGE_STATE && g_db_item_is_enabled(G_DB_ITEM(bookmark)))*/
     {
         model = GTK_TREE_MODEL(store);
 
@@ -1183,7 +1185,7 @@ static void mcb_bookmarks_panel_delete(GtkMenuItem *menuitem, GBookmarksPanel *p
     mark = get_selected_panel_bookmark(treeview, NULL);
     if (mark == NULL) return;
 
-    g_loaded_binary_remove_from_collection(panel->binary, DBF_BOOKMARKS, G_DB_ITEM(mark));
+    //g_loaded_binary_remove_from_collection(panel->binary, DBF_BOOKMARKS, G_DB_ITEM(mark));
 
     g_object_unref(G_OBJECT(mark));
 
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index 57e6a14..df3fde1 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -330,6 +330,7 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
     {
         g_db_collection_rlock(collections[k]);
 
+        /*
         items = g_db_collection_get_items(collections[k]);
 
         for (i = g_list_first(items); i != NULL; i = g_list_next(i))
@@ -342,13 +343,14 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
             gtk_list_store_set(store, &iter,
                                HTC_ITEM, item,
                                //HTC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
-                               HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
+                               HTC_FOREGROUND, g_db_item_is_enabled(item) ? NULL : "grey",
                                HTC_LABEL, label,
                                -1);
 
             free(label);
 
         }
+        */
 
         //g_signal_connect_to_main(collections[k], "content-changed", G_CALLBACK(on_history_changed), panel,
         //                         g_cclosure_user_marshal_VOID__ENUM_OBJECT);
@@ -440,7 +442,7 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
             gtk_list_store_set(store, &iter,
                                HTC_ITEM, item,
                                //HTC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
-                               HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
+                               HTC_FOREGROUND, g_db_item_is_enabled(item) ? NULL : "grey",
                                HTC_LABEL, label,
                                -1);
 
@@ -459,7 +461,7 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
 
             if (find_changed_item(model, item, &iter))
                 gtk_list_store_set(store, &iter,
-                                   HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
+                                   HTC_FOREGROUND, g_db_item_is_enabled(item) ? NULL : "grey",
                                    -1);
             break;
 
@@ -480,7 +482,7 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
 
             gtk_tree_model_get(_model, _iter, HTC_ITEM, &item, -1);
 
-            active = g_db_item_is_active(item);
+            active = g_db_item_is_enabled(item);
 
             g_object_unref(G_OBJECT(item));
 
@@ -566,10 +568,10 @@ static void on_history_selection_change(GtkTreeSelection *selection, GHistoryPan
         gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1);
 
         button = GTK_WIDGET(gtk_builder_get_object(builder, "undo"));
-        gtk_widget_set_sensitive(button, g_db_item_is_active(item));
+        gtk_widget_set_sensitive(button, g_db_item_is_enabled(item));
 
         button = GTK_WIDGET(gtk_builder_get_object(builder, "redo"));
-        gtk_widget_set_sensitive(button, !g_db_item_is_active(item));
+        gtk_widget_set_sensitive(button, !g_db_item_is_enabled(item));
 
         g_object_unref(G_OBJECT(item));
 
-- 
cgit v0.11.2-87-g4458