From f663a08007095e58f60fcf9a815a8b3d31b87c83 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 8 Sep 2020 00:11:49 +0200
Subject: Rewritten some code managing comments.

---
 plugins/arm/v7/fetch.c                             |  25 +-
 plugins/dalvik/link.c                              |   2 +-
 plugins/fmtp/parser.c                              |  34 +-
 plugins/lnxsyscalls/writer.c                       |  48 +-
 plugins/pychrysalide/analysis/db/items/Makefile.am |   1 +
 plugins/pychrysalide/analysis/db/items/comment.c   | 550 ++++++++++++--
 plugins/pychrysalide/analysis/db/items/comment.h   |  20 +
 plugins/pychrysalide/analysis/db/items/constants.c | 129 ++++
 plugins/pychrysalide/analysis/db/items/constants.h |  42 ++
 plugins/pychrysalide/analysis/db/items/module.c    |   1 +
 src/analysis/db/items/comment.c                    | 793 ++++++++-------------
 src/analysis/db/items/comment.h                    |  60 +-
 src/core/collections.c                             |   2 +-
 src/format/preload.c                               |  77 +-
 src/format/preload.h                               |   6 +
 15 files changed, 1191 insertions(+), 599 deletions(-)
 create mode 100644 plugins/pychrysalide/analysis/db/items/constants.c
 create mode 100644 plugins/pychrysalide/analysis/db/items/constants.h

diff --git a/plugins/arm/v7/fetch.c b/plugins/arm/v7/fetch.c
index 876ad51..2d38cbf 100644
--- a/plugins/arm/v7/fetch.c
+++ b/plugins/arm/v7/fetch.c
@@ -33,6 +33,7 @@
 #include <arch/instructions/raw.h>
 #include <arch/operands/immediate.h>
 #include <arch/operands/register.h>
+#include <common/extstr.h>
 #include <format/known.h>
 #include <format/format.h>
 #include <format/preload.h>
@@ -389,6 +390,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     GArchInstruction *loaded;               /* Instruction de valeur       */
     bool inserted;                          /* Bilan d'une insertion       */
     char *desc;                             /* Description d'accompagnement*/
+    size_t index;                           /* Indice d'un existant ?      */
     GDbComment *comment;                    /* Définition de commentaire   */
     GArchOperand *new;                      /* Instruction de ciblage      */
 
@@ -494,30 +496,35 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
         g_preload_info_lock_comments(info);
 
-        comment = _g_preload_info_find_comment_at(info, &loaded_addr);
+        comment = g_preload_info_find_comment_at(info, &loaded_addr, &index);
 
-        if (comment != NULL)
+        if (comment == NULL)
         {
-            g_db_comment_add_static_text(comment, "\n");
-            g_db_comment_add_dynamic_text(comment, desc);
+            comment = g_db_comment_new(&loaded_addr, CET_INLINED, BLF_HAS_CODE, desc);
+            g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
 
-            g_object_unref(G_OBJECT(comment));
+            _g_preload_info_add_comment(info, comment);
 
         }
 
         else
         {
-            comment = g_db_comment_new_inlined(&loaded_addr, BLF_HAS_CODE, false);
-            g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+            desc = strprep(desc, "\n");
+            desc = strprep(desc, g_db_comment_get_text(comment));
 
-            g_db_comment_add_dynamic_text(comment, desc);
+            g_object_unref(G_OBJECT(comment));
 
-            _g_preload_info_add_comment(info, comment);
+            comment = g_db_comment_new(&loaded_addr, CET_INLINED, BLF_HAS_CODE, desc);
+            g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+            g_preload_info_replace_comment_at(info, index, comment);
 
         }
 
         g_preload_info_unlock_comments(info);
 
+        free(desc);
+
     }
 
     /* Mise à jour de l'affichage et conclusion */
diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c
index d412511..9fb1992 100644
--- a/plugins/dalvik/link.c
+++ b/plugins/dalvik/link.c
@@ -358,7 +358,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
 
                 }
 
-                item = g_db_comment_new_area(&comment->handler, BLF_NONE, msg, true);
+                item = g_db_comment_new(&comment->handler, CET_BEFORE, BLF_NONE, msg);
 
                 g_db_item_add_flag(G_DB_ITEM(item), DIF_VOLATILE);
                 g_proc_context_add_db_item(context, G_DB_ITEM(item));
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index 4a8749d..84bb86f 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -25,10 +25,12 @@
 
 
 #include <assert.h>
+#include <string.h>
 
 
 #include <i18n.h>
 #include <arch/instructions/raw.h>
+#include <common/extstr.h>
 #include <format/known.h>
 
 
@@ -63,6 +65,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
     GArchInstruction *instr;                /* Instruction décodée         */
     GImmOperand *imm;                       /* Opérande à transformer      */
     size_t i;                               /* Boucle de parcours          */
+    char *text;                             /* Texte du commentaire complet*/
     const vmpa2t *addr;                     /* Emplacement d'instruction   */
     GDbComment *comment;                    /* Définition de commentaire   */
     uint64_t raw;                           /* Valeur brute à étudier      */
@@ -125,15 +128,12 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 
     /* Commentaire */
 
-    addr = get_mrange_addr(g_arch_instruction_get_range(instr));
-
-    comment = g_db_comment_new_inlined(addr, BLF_HAS_CODE, false);
-    g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+    text = NULL;
 
     switch (def->ctype)
     {
         case FCT_PLAIN:
-            g_db_comment_add_static_text(comment, _(def->comment.plain));
+            text = strdup(_(def->comment.plain));
             break;
 
         case FCT_SWITCH:
@@ -155,13 +155,16 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
                 else if (raw != def->comment.choices[i].fixed)
                     continue;
 
-                g_db_comment_add_static_text(comment, _(def->comment.choices[i].desc));
+                text = strnadd(text, _(def->comment.choices[i].desc), strlen(_(def->comment.choices[i].desc)));
                 break;
 
             }
 
-            if (i == def->comment.ccount)
-                g_db_comment_add_static_text(comment, _(def->comment.def_choice));
+            if (text == NULL)
+            {
+                assert(i == def->comment.ccount);
+                text = strdup(_(def->comment.def_choice));
+            }
 
             break;
 
@@ -174,16 +177,16 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
                 if (part->is_static)
                 {
                     if (part->avoid_i18n)
-                        g_db_comment_add_static_text(comment, part->static_text);
+                        text = strnadd(text, part->static_text, strlen(part->static_text));
                     else
-                        g_db_comment_add_static_text(comment, _(part->static_text));
+                        text = strnadd(text, _(part->static_text), strlen(_(part->static_text)));
                 }
                 else
                 {
                     if (part->avoid_i18n)
-                        g_db_comment_add_dynamic_text(comment, part->dynamic_text);
+                        text = strnadd(text, part->dynamic_text, strlen(part->dynamic_text));
                     else
-                        g_db_comment_add_dynamic_text(comment, _(part->dynamic_text));
+                        text = strnadd(text, _(part->dynamic_text), strlen(_(part->dynamic_text)));
                 }
 
             }
@@ -192,6 +195,13 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 
     }
 
+    addr = get_mrange_addr(g_arch_instruction_get_range(instr));
+
+    comment = g_db_comment_new(addr, CET_INLINED, BLF_HAS_CODE, text);
+    g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+    free(text);
+
     /* Insertions */
 
     inserted = g_preload_info_add_instruction(info, instr);
diff --git a/plugins/lnxsyscalls/writer.c b/plugins/lnxsyscalls/writer.c
index 743e5c6..0b90d68 100644
--- a/plugins/lnxsyscalls/writer.c
+++ b/plugins/lnxsyscalls/writer.c
@@ -29,6 +29,7 @@
 
 
 #include <analysis/db/items/comment.h>
+#include <common/extstr.h>
 
 
 
@@ -196,43 +197,60 @@ void write_all_comments(comment_writer *writer, GPreloadInfo *preload)
 {
     size_t i;                               /* Boucle de parcours #1       */
     comment_data *target;                   /* Commentaire à éditer        */
-    GDbComment *comment;                    /* Commentaire final à intégrer*/
-    bool new;                               /* Nature du commentaire       */
+    char *text;                             /* Texte du commentaire complet*/
     size_t k;                               /* Boucle de parcours #2       */
+    size_t index;                           /* Indice d'un existant ?      */
+    GDbComment *comment;                    /* Commentaire final à intégrer*/
 
     for (i = 0; i < writer->count; i++)
     {
         target = &writer->comments[i];
 
-        g_preload_info_lock_comments(preload);
+        /* Construction de la nouveauté */
 
-        comment = _g_preload_info_find_comment_at(preload, &target->addr);
+        text = NULL;
+
+        for (k = 0; k < target->count; k++)
+        {
+            if (k > 0)
+                text = stradd(text, " / ");
 
-        new = (comment == NULL);
+            text = stradd(text, target->text[k]);
+
+        }
+
+        /* Inclusion de l'existant */
+
+        g_preload_info_lock_comments(preload);
+
+        comment = g_preload_info_find_comment_at(preload, &target->addr, &index);
 
         if (comment == NULL)
         {
-            comment = g_db_comment_new_inlined(&target->addr, BLF_HAS_CODE, false);
+            comment = g_db_comment_new(&target->addr, CET_INLINED, BLF_HAS_CODE, text);
             g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
 
-            g_object_ref(G_OBJECT(comment));
-
             _g_preload_info_add_comment(preload, comment);
 
         }
 
-        g_preload_info_unlock_comments(preload);
-
-        for (k = 0; k < target->count; k++)
+        else
         {
-            if (k > 0 || !new)
-                g_db_comment_add_static_text(comment, " / ");
+            text = strprep(text, " / ");
+            text = strprep(text, g_db_comment_get_text(comment));
 
-            g_db_comment_add_dynamic_text(comment, strdup(target->text[k]));
+            g_object_unref(G_OBJECT(comment));
+
+            comment = g_db_comment_new(&target->addr, CET_INLINED, BLF_HAS_CODE, text);
+            g_db_item_add_flag(G_DB_ITEM(comment), DIF_VOLATILE);
+
+            g_preload_info_replace_comment_at(preload, index, comment);
 
         }
 
-        g_object_unref(G_OBJECT(comment));
+        g_preload_info_unlock_comments(preload);
+
+        free(text);
 
     }
 
diff --git a/plugins/pychrysalide/analysis/db/items/Makefile.am b/plugins/pychrysalide/analysis/db/items/Makefile.am
index 07593f8..35f4ee6 100644
--- a/plugins/pychrysalide/analysis/db/items/Makefile.am
+++ b/plugins/pychrysalide/analysis/db/items/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libpychrysaanalysisdbitems.la
 libpychrysaanalysisdbitems_la_SOURCES =	\
 	bookmark.h bookmark.c				\
 	comment.h comment.c					\
+	constants.h constants.c				\
 	module.h module.c					\
 	switcher.h switcher.c
 
diff --git a/plugins/pychrysalide/analysis/db/items/comment.c b/plugins/pychrysalide/analysis/db/items/comment.c
index 845a118..78d4902 100644
--- a/plugins/pychrysalide/analysis/db/items/comment.c
+++ b/plugins/pychrysalide/analysis/db/items/comment.c
@@ -29,28 +29,57 @@
 #include <pygobject.h>
 
 
-#include <i18n.h>
 #include <analysis/db/items/comment.h>
+#include <plugins/dt.h>
 
 
+#include "constants.h"
+#include "../collection.h"
 #include "../item.h"
 #include "../../../access.h"
 #include "../../../helpers.h"
 #include "../../../arch/vmpa.h"
+#include "../../../glibext/constants.h"
+#include "../../../glibext/bufferline.h"
 
 
 
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
 /* Crée un nouvel objet Python de type 'DbComment'. */
 static PyObject *py_db_comment_new(PyTypeObject *, PyObject *, PyObject *);
 
-/* Associe un contenu statique supplémentaire à un commentaire. */
-static PyObject *py_db_comment_add_text(PyObject *, PyObject *);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_db_comment_init(PyObject *, PyObject *, PyObject *);
+
+/* Fournit l'adresse associée à un commentaire. */
+static PyObject *py_db_comment_get_address(PyObject *, void *);
+
+/* Indique le type d'incrustation prévue pour un commentaire. */
+static PyObject *py_db_comment_get_embedding_type(PyObject *, void *);
+
+/* Fournit les particularités d'accroche liées à un commentaire. */
+static PyObject *py_db_comment_get_flags(PyObject *, void *);
 
 /* Fournit le commentaire associé à un commentaire. */
 static PyObject *py_db_comment_get_text(PyObject *, void *);
 
 
 
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Crée un nouvel objet Python de type 'CommentCollection'. */
+static PyObject *py_comment_collection_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       ELABORATION D'UN ELEMENT DE COLLECTION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : type = type de l'objet à instancier.                         *
@@ -67,58 +96,170 @@ static PyObject *py_db_comment_get_text(PyObject *, void *);
 
 static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-    PyObject *result;                       /* Instance à retourner        */
-    int repeatable;                         /* Note une répétition demandée*/
-    const char *text;                       /* Eventuel premier commentaire*/
-    int before;                             /* Indication sur l'emplacement*/
+    PyObject *result;                       /* Objet à retourner           */
+    PyTypeObject *base;                     /* Type de base à dériver      */
+    bool first_time;                        /* Evite les multiples passages*/
+    GType gtype;                            /* Nouveau type de processeur  */
+    bool status;                            /* Bilan d'un enregistrement   */
+
+    /* Validations diverses */
+
+    base = get_python_db_comment_type();
+
+    if (type == base)
+        goto simple_way;
+
+    /* Mise en place d'un type dédié */
+
+    first_time = (g_type_from_name(type->tp_name) == 0);
+
+    gtype = build_dynamic_type(G_TYPE_DB_COMMENT, type->tp_name, NULL, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+        if (!status)
+        {
+            result = NULL;
+            goto exit;
+        }
+
+    }
+
+    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+    result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0 en cas de succès, -1 sinon.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_db_comment_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int result;                             /* Bilan à renvoyer            */
     vmpa2t *addr;                           /* Emplacement ciblé           */
-    unsigned long flags;                    /* Identifiants de ligne visée */
+    CommentEmbeddingType type;              /* Type d'incrustation         */
+    BufferLineFlags flags;                  /* Particularités de l'accroche*/
+    const char *text;                       /* Eventuel contenu textuel    */
     int ret;                                /* Bilan de lecture des args.  */
-    GDbComment *comment;                    /* Version GLib du commentaire */
-
-    static char *kwlist[] = { "addr", "flags", "repeatable", "text", "before", NULL };
+    GDbComment *comment;                    /* Version GLib du signet      */
+    bool status;                            /* Bilan de l'initialisation   */
+
+#define DB_COMMENT_DOC                                                          \
+    "DbComment provides support for comments to embed into the disassembled"    \
+    " code.\n"                                                                  \
+    "\n"                                                                        \
+    "Instances can be created using the following constructor:\n"               \
+    "\n"                                                                        \
+    "    DbComment(addr, addr, type, flags, text=None)\n"                       \
+    "\n"                                                                        \
+    "Where *addr* is a location of type pychrysalide.arch.vmpa, *type* defines" \
+    " the kind of embedding as a"                                               \
+    " pychrysalide.analysis.db.items.DbComment.CommentEmbeddingType value,"     \
+    " *flags* states for the pychrysalide.glibext.BufferLine.BufferLineFlags"   \
+    " property of the line to attach and *text* is an optional string for the"  \
+    " comment.\n"                                                               \
+    "\n"                                                                        \
+    "An empty comment is not enough to delete a comment for a given address;"   \
+    " the *ERASER* flag from the pychrysalide.analysis.db.DbItem.DbItemFlags"   \
+    " enumeration must be explicitly add to the item by a call to the"          \
+    " pychrysalide.analysis.db.DbItem.add_flag() function."
+
+    result = -1;
 
     /* Récupération des paramètres */
 
-    repeatable = -1;
     text = NULL;
-    before = -1;
 
-    ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&k|$psp", kwlist,
-                                      convert_any_to_vmpa, &addr, &flags, &repeatable, &text, &before);
-    if (!ret) return NULL;
+    ret = PyArg_ParseTuple(args, "O&O&O&|s",
+                           convert_any_to_vmpa, &addr,
+                           convert_to_comment_embedding_type, &type,
+                           convert_to_buffer_line_flags, &flags,
+                           &text);
+    if (!ret) goto exit;
 
-    /* Vérifications diverses */
+    /* Initialisation d'un objet GLib */
 
-    if (flags > BLF_ALL)
+    ret = forward_pygobjet_init(self);
+    if (ret == -1)
     {
         clean_vmpa_arg(addr);
+        goto exit;
+    }
 
-        PyErr_SetString(PyExc_ValueError, _("Invalid flag combination"));
-        return NULL;
+    /* Eléments de base */
 
-    }
+    comment = G_DB_COMMENT(pygobject_get(self));
 
-    if ((repeatable == -1 && before == -1) || (repeatable != -1 && before != -1))
+    status = g_db_comment_fill(comment, addr, type, flags, text);
+    if (!status)
     {
         clean_vmpa_arg(addr);
+        goto exit;
+    }
 
-        PyErr_SetString(PyExc_ValueError, _("repeatable or before has to be defined"));
-        return NULL;
+    clean_vmpa_arg(addr);
 
-    }
+    result = 0;
 
-    /* Construction */
+ exit:
 
-    if (repeatable)
-        comment = g_db_comment_new_inlined(addr, flags, repeatable);
-    else
-        comment = g_db_comment_new_area(addr, flags, text, before);
+    return result;
 
-    result = pygobject_new(G_OBJECT(comment));
-    g_object_unref(comment);
+}
 
-    clean_vmpa_arg(addr);
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit l'adresse associée à un commentaire.                 *
+*                                                                             *
+*  Retour      : Adresse mémoire.                                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_comment_get_address(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GDbComment *comment;                    /* Commentaire à consulter     */
+    const vmpa2t *addr;                     /* Localisation du commentaire */
+
+#define DB_COMMENT_ADDRESS_ATTRIB PYTHON_GET_DEF_FULL   \
+(                                                       \
+    address, py_db_comment,                             \
+    "Location of the comment, provided as a"            \
+    " pychrysalide.arch.vmpa instance."                 \
+)
+
+    comment = G_DB_COMMENT(pygobject_get(self));
+
+    addr = g_db_comment_get_address(comment);
+
+    result = build_from_internal_vmpa(addr);
 
     return result;
 
@@ -127,31 +268,74 @@ static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = classe représentant un commentaire.                   *
-*                args = arguments fournis à l'appel.                          *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
 *                                                                             *
-*  Description : Associe un contenu statique supplémentaire à un commentaire. *
+*  Description : Indique le type d'incrustation prévue pour un commentaire.   *
 *                                                                             *
-*  Retour      : None.                                                        *
+*  Retour      : Incrustation associée au commentaire.                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_db_comment_add_text(PyObject *self, PyObject *args)
+static PyObject *py_db_comment_get_embedding_type(PyObject *self, void *closure)
 {
-    const char *text;                       /* Commentaire complémentaire  */
-    int ret;                                /* Bilan de lecture des args.  */
+    PyObject *result;                       /* Résultat à retourner        */
     GDbComment *comment;                    /* Commentaire à consulter     */
+    CommentEmbeddingType type;              /* Type d'incrustation         */
 
-    ret = PyArg_ParseTuple(args, "s", &text);
-    if (!ret) return NULL;
+#define DB_COMMENT_EMBEDDING_TYPE_ATTRIB PYTHON_GET_DEF_FULL                \
+(                                                                           \
+    embedding_type, py_db_comment,                                          \
+    "Type of embedding required for the comment, as a"                      \
+    " pychrysalide.analysis.db.items.DbComment.CommentEmbeddingType value." \
+)
 
     comment = G_DB_COMMENT(pygobject_get(self));
 
-    g_db_comment_add_static_text(comment, text);
+    type = g_db_comment_get_embedding_type(comment);
+
+    result = cast_with_constants_group_from_type(get_python_db_comment_type(), "CommentEmbeddingType", type);
 
-    Py_RETURN_NONE;
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit les particularités d'accroche liées à un commentaire.*
+*                                                                             *
+*  Retour      : Particularités éventuelles pour l'accroche.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_comment_get_flags(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GDbComment *comment;                    /* Commentaire à consulter     */
+    BufferLineFlags flags;                  /* Fanions à rechercher        */
+
+#define DB_COMMENT_FLAGS_ATTRIB PYTHON_GET_DEF_FULL             \
+(                                                               \
+    flags, py_db_comment,                                       \
+    "Flags of the line where to attach the comment, as a"       \
+    " pychrysalide.glibext.BufferLine.BufferLineFlags value."   \
+)
+
+    comment = G_DB_COMMENT(pygobject_get(self));
+
+    flags = g_db_comment_get_flags(comment);
+
+    result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
+
+    return result;
 
 }
 
@@ -175,6 +359,13 @@ static PyObject *py_db_comment_get_text(PyObject *self, void *closure)
     GDbComment *comment;                    /* Commentaire à consulter     */
     char *text;                             /* Contenu textuel associé     */
 
+#define DB_COMMENT_TEXT_ATTRIB PYTHON_GET_DEF_FULL                          \
+(                                                                           \
+    text, py_db_comment,                                                    \
+    "Content of the comment, as a string which may contain several lines,"  \
+    " or None of no text is linked to the comment."                         \
+)
+
     comment = G_DB_COMMENT(pygobject_get(self));
     text = g_db_comment_get_text(comment);
 
@@ -209,19 +400,14 @@ static PyObject *py_db_comment_get_text(PyObject *self, void *closure)
 PyTypeObject *get_python_db_comment_type(void)
 {
     static PyMethodDef py_db_comment_methods[] = {
-        {
-            "add_text", py_db_comment_add_text,
-            METH_VARARGS,
-            "add_text($self, text, /)\n--\n\nAppend extra text to a given comment."
-        },
         { NULL }
     };
 
     static PyGetSetDef py_db_comment_getseters[] = {
-        {
-            "text", py_db_comment_get_text, NULL,
-            "Give access to the content of a given comment.", NULL
-        },
+        DB_COMMENT_ADDRESS_ATTRIB,
+        DB_COMMENT_EMBEDDING_TYPE_ATTRIB,
+        DB_COMMENT_FLAGS_ATTRIB,
+        DB_COMMENT_TEXT_ATTRIB,
         { NULL }
     };
 
@@ -234,11 +420,13 @@ PyTypeObject *get_python_db_comment_type(void)
 
         .tp_flags       = Py_TPFLAGS_DEFAULT,
 
-        .tp_doc         = "PyChrysalide comment for edited binary",
+        .tp_doc         = DB_COMMENT_DOC,
 
         .tp_methods     = py_db_comment_methods,
         .tp_getset      = py_db_comment_getseters,
-        .tp_new         = py_db_comment_new
+
+        .tp_init        = py_db_comment_init,
+        .tp_new         = py_db_comment_new,
 
     };
 
@@ -279,8 +467,260 @@ bool ensure_python_db_comment_is_registered(void)
         if (!register_class_for_pygobject(dict, G_TYPE_DB_COMMENT, type, get_python_db_item_type()))
             return false;
 
+        if (!define_db_comment_constants(type))
+            return false;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en commentaire de base.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_db_comment(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_db_comment_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to database comment");
+            break;
+
+        case 1:
+            *((GDbComment **)dst) = G_DB_COMMENT(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        DEFINITION DE LA COLLECTION ASSOCIEE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'CommentCollection'.    *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_comment_collection_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Objet à retourner           */
+    PyTypeObject *base;                     /* Type de base à dériver      */
+    bool first_time;                        /* Evite les multiples passages*/
+    GType gtype;                            /* Nouveau type de processeur  */
+    bool status;                            /* Bilan d'un enregistrement   */
+
+#define COMMENT_COLLECTION_DOC                                          \
+    "CommentCollection remembers all comment definitions.\n"            \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    CommentCollection()\n"                                         \
+    "\n"                                                                \
+    "There should be no need for creating such instances manually."
+
+    /* Validations diverses */
+
+    base = get_python_db_comment_type();
+
+    if (type == base)
+        goto simple_way;
+
+    /* Mise en place d'un type dédié */
+
+    first_time = (g_type_from_name(type->tp_name) == 0);
+
+    gtype = build_dynamic_type(G_TYPE_DB_COMMENT, type->tp_name, NULL, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+        if (!status)
+        {
+            result = NULL;
+            goto exit;
+        }
+
+    }
+
+    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+    result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_comment_collection_type(void)
+{
+    static PyMethodDef py_comment_collection_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_comment_collection_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_comment_collection_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.db.items.CommentCollection",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = COMMENT_COLLECTION_DOC,
+
+        .tp_methods     = py_comment_collection_methods,
+        .tp_getset      = py_comment_collection_getseters,
+
+        .tp_new         = py_comment_collection_new,
+
+    };
+
+    return &py_comment_collection_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....CommentCollection'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_comment_collection_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'DbComment'    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_comment_collection_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.db.items");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_db_collection_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_COMMENT_COLLECTION, type, get_python_db_collection_type()))
+            return false;
+
     }
 
     return true;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en collection de commentaires.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_comment_collection(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_comment_collection_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to comment collection");
+            break;
+
+        case 1:
+            *((GCommentCollection **)dst) = G_COMMENT_COLLECTION(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/db/items/comment.h b/plugins/pychrysalide/analysis/db/items/comment.h
index df02cc6..4e5af64 100644
--- a/plugins/pychrysalide/analysis/db/items/comment.h
+++ b/plugins/pychrysalide/analysis/db/items/comment.h
@@ -31,12 +31,32 @@
 
 
 
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
 /* Fournit un accès à une définition de type à diffuser. */
 PyTypeObject *get_python_db_comment_type(void);
 
 /* Prend en charge l'objet 'pychrysalide.analysis.db.items.DbComment'. */
 bool ensure_python_db_comment_is_registered(void);
 
+/* Tente de convertir en commentaire de base. */
+int convert_to_db_comment(PyObject *, void *);
+
+
+
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_comment_collection_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.items.CommentCollection'. */
+bool ensure_python_comment_collection_is_registered(void);
+
+/* Tente de convertir en collection de commentaires. */
+int convert_to_comment_collection(PyObject *, void *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_COMMENT_H */
diff --git a/plugins/pychrysalide/analysis/db/items/constants.c b/plugins/pychrysalide/analysis/db/items/constants.c
new file mode 100644
index 0000000..e3ef99e
--- /dev/null
+++ b/plugins/pychrysalide/analysis/db/items/constants.c
@@ -0,0 +1,129 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes liées aux éléments de base
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "constants.h"
+
+
+#include <i18n.h>
+#include <analysis/db/items/comment.h>
+
+
+#include "../../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
+*  Description : Définit les constantes relatives aux commentaires de base.   *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_db_comment_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "INLINED", CET_INLINED);
+    if (result) result = add_const_to_group(values, "REPEATED", CET_REPEATED);
+    if (result) result = add_const_to_group(values, "BEFORE", CET_BEFORE);
+    if (result) result = add_const_to_group(values, "AFTER", CET_AFTER);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, false, "CommentEmbeddingType", values,
+                                            "Kinds of insertion for comments.");
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en constante CommentEmbeddingType.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_comment_embedding_type(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+    unsigned long value;                    /* Valeur récupérée            */
+
+    result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type);
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to CommentEmbeddingType");
+            break;
+
+        case 1:
+            value = PyLong_AsUnsignedLong(arg);
+
+            if (value >= CET_COUNT)
+            {
+                PyErr_SetString(PyExc_TypeError, "invalid value to convert to CommentEmbeddingType");
+                result = 0;
+            }
+
+            else
+                *((CommentEmbeddingType *)dst) = value;
+
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/db/items/constants.h b/plugins/pychrysalide/analysis/db/items/constants.h
new file mode 100644
index 0000000..80210d9
--- /dev/null
+++ b/plugins/pychrysalide/analysis/db/items/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes liées aux éléments de base
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux commentaires de base. */
+bool define_db_comment_constants(PyTypeObject *);
+
+/* Tente de convertir en constante CommentEmbeddingType. */
+int convert_to_comment_embedding_type(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/db/items/module.c b/plugins/pychrysalide/analysis/db/items/module.c
index c963354..cbc367d 100644
--- a/plugins/pychrysalide/analysis/db/items/module.c
+++ b/plugins/pychrysalide/analysis/db/items/module.c
@@ -91,6 +91,7 @@ bool populate_analysis_db_items_module(void)
     result = true;
 
     if (result) result = ensure_python_bookmark_collection_is_registered();
+    if (result) result = ensure_python_comment_collection_is_registered();
     if (result) result = ensure_python_switcher_collection_is_registered();
     if (result) result = ensure_python_db_bookmark_is_registered();
     if (result) result = ensure_python_db_comment_is_registered();
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 4b22502..136b62b 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -27,6 +27,7 @@
 #include <assert.h>
 #include <malloc.h>
 #include <stdio.h>
+#include <string.h>
 #include <sys/socket.h>
 
 
@@ -53,23 +54,10 @@ struct _GDbComment
     GDbItem parent;                         /* A laisser en premier        */
 
     vmpa2t addr;                            /* Adresse du commentaire      */
+    CommentEmbeddingType type;              /* Type d'incrustation         */
     BufferLineFlags flags;                  /* Identification de l'accroche*/
 
     flat_array_t *text;                     /* Contenu du commentaire      */
-    size_t count;                           /* Quantité de lignes affichées*/
-
-    bool inlined;                           /* Intégration dans une ligne ?*/
-
-    union
-    {
-        bool repeatable;                    /* Répétition aux lignes liées */
-        bool before;                        /* Zone dédiée au dessus ?     */
-    };
-
-    GLineGenerator *previous;               /* Commentaire remplacé        */
-
-    GLineGenerator **old_inlined;           /* Commentaires d'origine ?    */
-    size_t old_count;                       /* Nombre de places à restaurer*/
 
 };
 
@@ -93,6 +81,15 @@ static void g_db_comment_dispose(GDbComment *);
 /* Procède à la libération totale de la mémoire. */
 static void g_db_comment_finalize(GDbComment *);
 
+/* Constitue un ensemble de lignes pour un commentaire. */
+static void g_db_comment_define_text_lines(GDbComment *, const char *);
+
+/* Calcule le condensat associé à l'élément vu comme clef. */
+static guint g_db_comment_hash_key(const GDbComment *);
+
+/* Compare deux éléments en tant que clefs. */
+static gboolean g_db_comment_cmp_key(const GDbComment *, const GDbComment *);
+
 /* Effectue la comparaison entre deux commentaires enregistrés. */
 static gint g_db_comment_cmp(const GDbComment *, const GDbComment *);
 
@@ -120,19 +117,13 @@ static bool g_db_comment_load(GDbComment *, const bound_value *, size_t);
 /* Constitue les champs destinés à une insertion / modification. */
 static bool g_db_comment_store(GDbComment *, bound_value **, size_t *);
 
-/* Associe un contenu formaté supplémentaire à un commentaire. */
-static void g_db_comment_add_rle_string(GDbComment *, const rle_string *);
-
 
 
 /* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
 
 
-/* Calcule le nombre de lignes suite à un changement de contenu. */
-static void g_db_comment_update_count_lines(GDbComment *);
-
 /* Indique le nombre de ligne prêtes à être générées. */
-static size_t g_db_comment_count_lines(const GDbComment *);
+static size_t g_db_comment_count_lines(GDbComment *);
 
 /* Retrouve l'emplacement correspondant à une position donnée. */
 static void g_db_comment_compute_cursor(const GDbComment *, gint, size_t, size_t, GLineCursor **);
@@ -141,7 +132,7 @@ static void g_db_comment_compute_cursor(const GDbComment *, gint, size_t, size_t
 static int g_db_comment_contain_cursor(const GDbComment *, size_t, size_t, const GLineCursor *);
 
 /* Renseigne sur les propriétés liées à un générateur. */
-static BufferLineFlags g_db_comment_get_flags(const GDbComment *, size_t, size_t);
+static BufferLineFlags g_db_comment_get_generator_flags(const GDbComment *, size_t, size_t);
 
 /* Imprime dans une ligne de rendu le contenu représenté. */
 static void g_db_comment_print(GDbComment *, GBufferLine *, size_t, size_t, const GBinContent *);
@@ -222,6 +213,8 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
 
     item->feature = DBF_COMMENTS;
 
+    item->hash_key = (hash_db_item_key_fc)g_db_comment_hash_key;
+    item->cmp_key = (cmp_db_item_key_fc)g_db_comment_cmp_key;
     item->cmp = (cmp_db_item_fc)g_db_comment_cmp;
 
     item->unpack = (unpack_db_item_fc)g_db_comment_unpack;
@@ -251,8 +244,12 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
 
 static void g_db_comment_init(GDbComment *comment)
 {
+    init_vmpa(&comment->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+    comment->type = CET_COUNT;
+    comment->flags = BLF_NONE;
+
     comment->text = NULL;
-    comment->count = 0;
 
 }
 
@@ -274,7 +271,7 @@ static void g_db_comment_interface_init(GLineGeneratorInterface *iface)
     iface->count = (linegen_count_lines_fc)g_db_comment_count_lines;
     iface->compute = (linegen_compute_fc)g_db_comment_compute_cursor;
     iface->contain = (linegen_contain_fc)g_db_comment_contain_cursor;
-    iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags;
+    iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_generator_flags;
     iface->print = (linegen_print_fc)g_db_comment_print;
 
 }
@@ -294,13 +291,6 @@ static void g_db_comment_interface_init(GLineGeneratorInterface *iface)
 
 static void g_db_comment_dispose(GDbComment *comment)
 {
-    size_t i;                               /* Boucle de parcours          */
-
-    g_clear_object(&comment->previous);
-
-    for (i = 0; i < comment->old_count; i++)
-        g_clear_object(&comment->old_inlined[i]);
-
     G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
 
 }
@@ -340,9 +330,6 @@ static void g_db_comment_finalize(GDbComment *comment)
 
     unlock_flat_array(&comment->text);
 
-    if (comment->old_inlined != NULL)
-        free(comment->old_inlined);
-
     G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment));
 
 }
@@ -350,11 +337,12 @@ static void g_db_comment_finalize(GDbComment *comment)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : addr       = adresse inamovible localisant une position.     *
-*                flags      = indentifiants supplémentaires de ligne visée.   *
-*                repeatable = repétition aux instructions liées ?             *
+*  Paramètres  : addr  = adresse inamovible localisant une position.          *
+*                type  = type d'incrustation à respecter pour l'insertion.    *
+*                flags = indentifiants supplémentaires de ligne visée.        *
+*                text  = contenu textuel associé au commentaire ou NULL.      *
 *                                                                             *
-*  Description : Crée une définition de commentaire dans une zone de texte.   *
+*  Description : Crée une définition de commentaire textuel.                  *
 *                                                                             *
 *  Retour      : Commentaire mis en place ou NULL en cas d'erreur.            *
 *                                                                             *
@@ -362,19 +350,59 @@ static void g_db_comment_finalize(GDbComment *comment)
 *                                                                             *
 ******************************************************************************/
 
-GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, bool repeatable)
+GDbComment *g_db_comment_new(const vmpa2t *addr, CommentEmbeddingType type, BufferLineFlags flags, const char *text)
 {
-    GDbComment *result;                    /* Instance à retourner        */
+    GDbComment *result;                     /* Instance à retourner        */
+    bool status;                            /* Bilan de l'initialisation   */
 
     result = g_object_new(G_TYPE_DB_COMMENT, NULL);
 
-    copy_vmpa(&result->addr, addr);
+    status = g_db_comment_fill(result, addr, type, flags, text);
+    if (!status) goto error;
+
+    return result;
+
+ error:
+
+    g_object_unref(G_OBJECT(result));
+
+    return NULL;
+
+}
+
 
-    result->flags = flags;
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : addr  = adresse inamovible localisant une position.          *
+*                type  = type d'incrustation à respecter pour l'insertion.    *
+*                flags = indentifiants supplémentaires de ligne visée.        *
+*                text  = contenu textuel associé au commentaire ou NULL.      *
+*                                                                             *
+*  Description : Initialise la définition d'un commentaire à incruster.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    result->inlined = true;
+bool g_db_comment_fill(GDbComment *comment, const vmpa2t *addr, CommentEmbeddingType type, BufferLineFlags flags, const char *text)
+{
+    bool result;                            /* Bilan à retourner           */
 
-    result->repeatable = repeatable;
+    /**
+     * Cette fonction est principalement destinée aux initialisations
+     * depuis l'extension Python.
+     */
+
+    result = true;
+
+    copy_vmpa(&comment->addr, addr);
+
+    comment->type = type;
+    comment->flags = flags;
+
+    g_db_comment_define_text_lines(comment, text);
 
     return result;
 
@@ -383,34 +411,98 @@ GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags,
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : addr   = adresse inamovible localisant une position.         *
-*                flags  = indentifiants supplémentaires de ligne visée.       *
-*                text   = commentaire construit ou NULL.                      *
-*                before = précision quant à la position de la zone à définir. *
+*  Paramètres  : comment = commentaire dont les lignes sont à constituer.     *
+*                text  = contenu textuel associé au commentaire ou NULL.      *
 *                                                                             *
-*  Description : Crée une définition de commentaire dans une zone de texte.   *
+*  Description : Constitue un ensemble de lignes pour un commentaire.         *
 *                                                                             *
-*  Retour      : Commentaire mis en place ou NULL en cas d'erreur.            *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool before)
+static void g_db_comment_define_text_lines(GDbComment *comment, const char *text)
 {
-    GDbComment *result;                    /* Instance à retourner        */
+    char *tmp;                              /* Zone de travail modifiable  */
+    char **lines;                           /* Lignes du texte découpé     */
+    size_t count;                           /* Quantité de ces lignes      */
+    size_t i;                               /* Boucle de parcours          */
+    rle_string string;                      /* Fragment de texte à ajouter */
 
-    result = g_object_new(G_TYPE_DB_COMMENT, NULL);
+    if (text != NULL)
+    {
+        tmp = strdup(text);
+
+        tmp = strrpl(tmp, "\r", "");
+
+        lines = strtoka(tmp, "\n", &count);
+
+        lock_flat_array(&comment->text);
+
+        for (i = 0; i < count; i++)
+        {
+            init_dynamic_rle_string(&string, lines[i]);
+
+            add_item_to_flat_array(&comment->text, &string, sizeof(rle_string));
+
+        }
+
+        unlock_flat_array(&comment->text);
+
+        free(lines);
+
+        free(tmp);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = élément de collection à consulter.                 *
+*                                                                             *
+*  Description : Calcule le condensat associé à l'élément vu comme clef.      *
+*                                                                             *
+*  Retour      : Condensat associé à l'élément.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    copy_vmpa(&result->addr, addr);
+static guint g_db_comment_hash_key(const GDbComment *comment)
+{
+    guint result;                           /* Valeur "unique" à renvoyer  */
 
-    result->flags = flags;
+    result = hash_vmpa(&comment->addr);
 
-    g_db_comment_add_dynamic_text(result, strdup(text));
+    return result;
 
-    result->inlined = false;
+}
 
-    result->before = before;
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément de collection à consulter.               *
+*                b = second élément de collection à consulter.                *
+*                                                                             *
+*  Description : Compare deux éléments en tant que clefs.                     *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean g_db_comment_cmp_key(const GDbComment *a, const GDbComment *b)
+{
+    gboolean result;                        /* Bilan à retourner           */
+    int ret;                                /* Bilan intermédiaire         */
+
+    ret = cmp_vmpa(&a->addr, &b->addr);
+
+    result = (ret == 0);
 
     return result;
 
@@ -440,8 +532,8 @@ static gint g_db_comment_cmp(const GDbComment *a, const GDbComment *b)
 
     if (result == 0)
     {
-        string_a = g_db_comment_get_text(a);
-        string_b = g_db_comment_get_text(b);
+        string_a = g_db_comment_get_text((GDbComment *)a);
+        string_b = g_db_comment_get_text((GDbComment *)b);
 
         if (string_a == NULL && string_b == NULL)
             result = 0;
@@ -481,9 +573,9 @@ static gint g_db_comment_cmp(const GDbComment *a, const GDbComment *b)
 static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
 {
     bool result;                            /* Bilan à retourner           */
-    uint32_t tmp32;                         /* Valeur sur 32 bits          */
-    rle_string string;                      /* Texte brut récupéré         */
     uint8_t tmp8;                           /* Valeur sur 8 bits           */
+    uint32_t tmp32;                         /* Valeur sur 32 bits          */
+    rle_string text;                        /* Texte brut récupéré         */
 
     result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->unpack(G_DB_ITEM(comment), pbuf);
 
@@ -492,29 +584,25 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf)
 
     if (result)
     {
-        result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true);
-        comment->flags = tmp32;
+        result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
+        comment->type = tmp8;
     }
 
     if (result)
     {
-        result = unpack_rle_string(&string, pbuf);
-
-        if (!is_rle_string_empty(&string) > 0)
-            g_db_comment_add_rle_string(comment, &string);
-
+        result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true);
+        comment->flags = tmp32;
     }
 
     if (result)
     {
-        result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
-        comment->inlined = tmp8;
-    }
+        setup_empty_rle_string(&text);
+        result = unpack_rle_string(&text, pbuf);
+
+        g_db_comment_define_text_lines(comment, get_rle_string(&text));
+
+        exit_rle_string(&text);
 
-    if (result)
-    {
-        result = extract_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true);
-        comment->repeatable = tmp8;
     }
 
     return result;
@@ -546,6 +634,9 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
         result = pack_vmpa(&comment->addr, pbuf);
 
     if (result)
+        result = extend_packed_buffer(pbuf, (uint8_t []) { comment->type }, sizeof(uint8_t), true);
+
+    if (result)
         result = extend_packed_buffer(pbuf, (uint32_t []) { comment->flags }, sizeof(uint32_t), true);
 
     if (result)
@@ -555,12 +646,6 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
         exit_rle_string(&text);
     }
 
-    if (result)
-        result = extend_packed_buffer(pbuf, (uint8_t []) { comment->inlined }, sizeof(uint8_t), true);
-
-    if (result)
-        result = extend_packed_buffer(pbuf, (uint8_t []) { comment->repeatable }, sizeof(uint8_t), true);
-
     return result;
 
 }
@@ -580,28 +665,40 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
 
 static char *g_db_comment_build_label(GDbComment *comment)
 {
-#if 0
-    VMPA_BUFFER(loc);                       /* Indication de position      */
-    size_t count;                           /* Nombre d'éléments textuels  */
+    char *result;                           /* Description à retourner     */
+    DbItemFlags flags;                      /* Propriétés de l'élément     */
+    const char *text;                       /* Commentaire associé         */
+    const char *prefix;                     /* Préfixe à ajouter           */
 
-    vmpa2_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL);
+    flags = g_db_item_get_flags(G_DB_ITEM(comment));
 
-    lock_flat_array(&comment->text);
-    count = count_flat_array_items(comment->text);
-    unlock_flat_array(&comment->text);
+    if (flags & DIF_ERASER)
+        asprintf(&result, _("Removed comment"));
+
+    else if (flags & DIF_UPDATED)
+    {
+        text = "...";//get_rle_string(&comment->text);
 
-    if (count == 0)
-        asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc);
+        if (text != NULL)
+            asprintf(&result, _("Updated comment: \"%s\""), text);
+        else
+            asprintf(&result, _("Reset comment"));
+    }
 
     else
     {
-        if (comment->inlined)
-            asprintf(&G_DB_ITEM(comment)->label, _("Enter inlined comment at %s"), loc);
+        prefix = _("Created");
+
+        text = "...";//get_rle_string(&comment->text);
+
+        if (text != NULL)
+            asprintf(&result, _("%s comment \"%s\""), prefix, text);
         else
-            asprintf(&G_DB_ITEM(comment)->label, _("Enter comment area at %s"), loc);
+            asprintf(&result, _("%s empty comment"), prefix);
+
     }
-#endif
-    return NULL;
+
+    return result;
 
 }
 
@@ -638,46 +735,30 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
 
     cache = g_loaded_binary_get_disassembly_cache(binary);
 
-    cursor = g_binary_cursor_new();
-    g_binary_cursor_update(G_BINARY_CURSOR(cursor), &comment->addr);
+    g_buffer_cache_lock(cache);
 
-    index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
+    switch (comment->type)
+    {
+        case CET_INLINED:
 
-    g_object_unref(G_OBJECT(cursor));
+            cursor = g_binary_cursor_new();
+            g_binary_cursor_update(G_BINARY_CURSOR(cursor), &comment->addr);
 
-    index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+            index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
 
-    if (comment->inlined)
-    {
+            g_object_unref(G_OBJECT(cursor));
 
-#define RUN_INLINED_COMMENT(idx, new, old)                                                          \
-        if (apply)                                                                                  \
-        {                                                                                           \
-            old = g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false);       \
-                                                                                                    \
-            g_buffer_cache_insert_at(cache, idx, G_LINE_GENERATOR(new), BLF_NONE, false, false);    \
-                                                                                                    \
-        }                                                                                           \
-        else                                                                                        \
-        {                                                                                           \
-            g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false);             \
-                                                                                                    \
-            if (old != NULL)                                                                        \
-            {                                                                                       \
-                g_buffer_cache_insert_at(cache, idx, old, BLF_NONE, false, false);                  \
-                g_object_unref(G_OBJECT(old));                                                      \
-            }                                                                                       \
-                                                                                                    \
-        }
+            index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
 
-        /* Commentaire principal */
+            g_buffer_cache_delete_type_at(cache, index, G_TYPE_DB_COMMENT, false, false);
 
-        RUN_INLINED_COMMENT(index, comment, comment->previous);
+            if (apply)
+                g_buffer_cache_insert_at(cache, index, G_LINE_GENERATOR(comment), BLF_NONE, false, false);
 
-        /* Renvois répétés */
+            break;
+
+        case CET_REPEATED:
 
-        if (comment->repeatable)
-        {
             proc = g_loaded_binary_get_processor(binary);
 
             instr = g_arch_processor_find_instr_by_address(proc, &comment->addr);
@@ -685,12 +766,6 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
 
             scount = g_arch_instruction_count_sources(instr);
 
-            if (apply)
-            {
-                comment->old_count = scount;
-                comment->old_inlined = realloc(comment->old_inlined, comment->old_count * sizeof(GLineGenerator *));
-            }
-
             for (i = 0; i < scount && result; i++)
             {
                 source = g_arch_instruction_get_source(instr, i);
@@ -713,202 +788,37 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
 
                 linked = g_buffer_cache_look_for_flag(cache, linked, BLF_HAS_CODE | BLF_IS_LABEL);
 
-                RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]);
-
-                unref_instr_link(source);
-
-            }
+                g_buffer_cache_delete_type_at(cache, linked, G_TYPE_DB_COMMENT, false, false);
 
-            if (!apply)
-            {
-                free(comment->old_inlined);
+                if (apply)
+                    g_buffer_cache_insert_at(cache, linked, G_LINE_GENERATOR(comment), BLF_NONE, false, false);
 
-                comment->old_inlined = NULL;
-                comment->old_count = 0;
+                unref_instr_link(source);
 
             }
 
             g_object_unref(G_OBJECT(proc));
+            break;
 
-        }
-
-
-
-    }
-
-    else
-    {
-
-
-
-
-
-
+        case CET_BEFORE:
+            break;
 
+        case CET_AFTER:
+            break;
 
+        case CET_COUNT:
+            assert(false);
+            result = false;
+            break;
 
     }
 
-
-    //void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
-
-    //GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
-
-
-
+    g_buffer_cache_unlock(cache);
 
     g_object_unref(G_OBJECT(cache));
 
     return result;
 
-
-
-
-#if 0
-
-    bool result;                            /* Bilan à faire remonter      */
-    GCodeBuffer *buffer;                    /* Tampon de lignes à traiter  */
-    GBufferLine *line;                      /* Ligne de tampon à marquer   */
-    GArchProcessor *proc;                   /* Propriétaire d'instructions */
-    GArchInstruction *instr;                /* Instruction à traiter       */
-    instr_link_t *sources;                  /* Instructions diverses liées */
-    size_t scount;                          /* Nbre de sources affichées   */
-    size_t i;                               /* Boucle de parcours          */
-    const mrange_t *range;                  /* Emplacement d'instruction   */
-    GBufferLine *linked;                    /* Ligne liée à traiter        */
-    GDbComment *old;                        /* Ancien élément à restaurer  */
-
-    result = true;
-
-    /* Recherche de la ligne visée */
-
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
-
-    line = g_code_buffer_find_line_by_addr(buffer, &comment->addr, comment->flags, NULL);
-    if (line == NULL)
-    {
-        result = false;
-        goto exit_gui;
-    }
-
-    /* Détermination de l'imprimeur précédent */
-
-    if (apply)
-    {
-        assert(comment->old_count == 0);
-
-        comment->old_count = 1;
-        comment->oldies = calloc(comment->old_count, sizeof(GDbComment *));
-
-    }
-
-    /* Applications globales finales */
-
-#define g_code_buffer_update_inlined_comment_dummy(b, l, c, d, o)   \
-    g_code_buffer_update_inlined_comment(b, l, c, o)
-
-    /**
-     * Note : on part du principe qu'un commentaire intégré ne peut remplacer qu'un
-     * commentaire intégré. Et pareil pour les commentaires en blocs.
-     */
-
-#define RUN_COMMENT_ON(ln, idx, func)                                                               \
-    if (apply)                                                                                      \
-    {                                                                                               \
-        comment->oldies[idx] = (GDbComment *)g_code_buffer_get_comment_creator(buffer, ln);         \
-        assert(comment->oldies[idx] == NULL || G_IS_DB_COMMENT(comment->oldies[idx]));              \
-        assert(comment->oldies[idx] == NULL || comment->oldies[idx]->inlined == comment->inlined);  \
-                                                                                                    \
-        if (is_rle_string_empty(&comment->text))                                                    \
-            result = g_code_buffer_delete_lines_comment(buffer, ln);                                \
-        else                                                                                        \
-            result = func(buffer, ln, get_rle_string(&comment->text),                               \
-                          comment->before, G_OBJECT(comment));                                      \
-    }                                                                                               \
-    else                                                                                            \
-    {                                                                                               \
-        old = comment->oldies[idx];                                                                 \
-                                                                                                    \
-        if (old == NULL)                                                                            \
-        {                                                                                           \
-            if (!is_rle_string_empty(&comment->text))                                               \
-                result = g_code_buffer_delete_lines_comment(buffer, ln);                            \
-            else                                                                                    \
-                result = true;                                                                      \
-        }                                                                                           \
-        else                                                                                        \
-        {                                                                                           \
-            if (is_rle_string_empty(&old->text))                                                    \
-                result = g_code_buffer_delete_lines_comment(buffer, ln);                            \
-            else                                                                                    \
-                result = func(buffer, ln, get_rle_string(&old->text),                               \
-                              old->before, G_OBJECT(old));                                          \
-        }                                                                                           \
-                                                                                                    \
-    }
-
-    if (comment->inlined)
-    {
-        /* Traitement d'un commentaire inscrusté */
-
-        RUN_COMMENT_ON(line, 0, g_code_buffer_update_inlined_comment_dummy);
-
-        /* Traitement des répétitions ? */
-
-        if (comment->repeatable/* && result*/)
-        {
-            proc = g_loaded_binary_get_processor(binary);
-
-            range = g_buffer_line_get_range(line);
-
-            instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
-            assert(instr != NULL);
-
-            scount = g_arch_instruction_get_sources(instr, &sources);
-
-            if (apply)
-            {
-                comment->old_count += scount;
-                comment->oldies = realloc(comment->oldies, comment->old_count * sizeof(GDbComment *));
-            }
-
-            for (i = 0; i < scount && result; i++)
-            {
-                range = g_arch_instruction_get_range(sources[i].linked);
-
-                /**
-                 * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL.
-                 * Comme on ne peut pas traiter les deux cas, on prend la première qui vient
-                 * avec BLF_NONE.
-                 */
-                linked = g_code_buffer_find_line_by_addr(buffer, get_mrange_addr(range), BLF_NONE, NULL);
-                assert(linked != NULL);
-
-                RUN_COMMENT_ON(linked, 1 + i, g_code_buffer_update_inlined_comment_dummy);
-
-            }
-
-            g_object_unref(G_OBJECT(instr));
-
-            g_object_unref(G_OBJECT(proc));
-
-        }
-
-    }
-
-    else
-    {
-        RUN_COMMENT_ON(line, 0, g_code_buffer_update_comment_area);
-    }
-
-    g_object_unref(G_OBJECT(line));
-
- exit_gui:
-
-    /* TODO g_object_unref(G_OBJECT(buffer));*/
-
-    return result;
-#endif
 }
 
 
@@ -982,40 +892,38 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
 
     result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count);
 
-    result &= load_vmpa(&comment->addr, NULL, values, count);
+    if (result)
+        result = load_vmpa(&comment->addr, NULL, values, count);
 
     if (result)
     {
-        value = find_bound_value(values, count, "lflags");
+        value = find_bound_value(values, count, "type");
         result = (value != NULL && value->type == SQLITE_INTEGER);
 
         if (result)
-            comment->flags = value->integer;
+            comment->type = value->integer;
 
     }
 
-    result &= load_rle_string(&string, "text", values, count);
-
-    if (result)
-        g_db_comment_add_rle_string(comment, &string);
-
     if (result)
     {
-        value = find_bound_value(values, count, "inlined");
-        result = (value != NULL && value->type == SQLITE_BOOLEAN);
+        value = find_bound_value(values, count, "line_flags");
+        result = (value != NULL && value->type == SQLITE_INTEGER);
 
         if (result)
-            comment->inlined = value->boolean;
+            comment->flags = value->integer;
 
     }
 
     if (result)
     {
-        value = find_bound_value(values, count, "repeatable");
-        result = (value != NULL && value->type == SQLITE_BOOLEAN);
+        result = load_rle_string(&string, "text", values, count);
 
         if (result)
-            comment->repeatable = value->boolean;
+        {
+            g_db_comment_define_text_lines(comment, get_rle_string(&string));
+            exit_rle_string(&string);
+        }
 
     }
 
@@ -1063,7 +971,7 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
 
     value = &(*values)[*count - 1];
 
-    value->cname = "lflags";
+    value->cname = "type";
     value->built_name = false;
     value->type = SQLITE_INTEGER;
 
@@ -1071,50 +979,39 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
 
     if (value->has_value)
     {
-        value->integer = comment->flags;
+        value->integer = comment->type;
         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);
-    }
-
-    if (!status) return false;
-
-    *count += 2;
+    *count += 1;
     *values = realloc(*values, *count * sizeof(bound_value));
 
-    value = &(*values)[*count - 2];
+    value = &(*values)[*count - 1];
 
-    value->cname = "inlined";
+    value->cname = "line_flags";
     value->built_name = false;
-    value->type = SQLITE_BOOLEAN;
+    value->type = SQLITE_INTEGER;
 
     value->has_value = (comment != NULL);
 
     if (value->has_value)
     {
-        value->boolean = comment->inlined;
+        value->integer = comment->flags;
         value->delete = NULL;
     }
 
-    value = &(*values)[*count - 1];
-
-    value->cname = "repeatable";
-    value->built_name = false;
-    value->type = SQLITE_BOOLEAN;
-
-    value->has_value = (comment != NULL);
+    if (comment == NULL)
+        status = store_rle_string(NULL, "text", values, count);
 
-    if (value->has_value)
+    else
     {
-        value->boolean = comment->repeatable;
-        value->delete = NULL;
+        init_dynamic_rle_string(&text, g_db_comment_get_text(comment));
+        status = store_rle_string(&text, "text", values, count);
+        exit_rle_string(&text);
     }
 
+    if (!status) return false;
+
     return true;
 
 }
@@ -1122,19 +1019,27 @@ static bool g_db_comment_store(GDbComment *comment, bound_value **values, size_t
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : comment = informations à consulter.                          *
+*  Paramètres  : key     = clef de comparaison sous forme de localisation.    *
+*                comment = informations de commentaire à consulter.           *
 *                                                                             *
-*  Description : Fournit l'adresse associée à un commentaire.                 *
+*  Description : Etablit la comparaison d'une adresse avec un commentaire.    *
 *                                                                             *
-*  Retour      : Adresse mémoire.                                             *
+*  Retour      : Bilan de la comparaison.                                     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
+int compare_comment_by_addr(const vmpa2t *key, const GDbComment * const *comment)
 {
-    return &comment->addr;
+    int result;                         /* Bilan à retourner           */
+    const vmpa2t *addr;                 /* Position du commentaire     */
+
+    addr = g_db_comment_get_address(*comment);
+
+    result = cmp_vmpa(key, addr);
+
+    return result;
 
 }
 
@@ -1143,38 +1048,19 @@ const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
 *                                                                             *
 *  Paramètres  : comment = informations à consulter.                          *
 *                                                                             *
-*  Description : Fournit le commentaire associé à un commentaire.             *
+*  Description : Fournit l'adresse associée à un commentaire.                 *
 *                                                                             *
-*  Retour      : Commentaire existant à libérer après usage ou NULL.          *
+*  Retour      : Adresse mémoire.                                             *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-char *g_db_comment_get_text(GDbComment *comment)
+const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
 {
-    char *result;                           /* Chaîne constituée à renvoyer*/
-    size_t count;                           /* Nombre d'éléments textuels  */
-    size_t i;                               /* Boucle de parcours          */
-    rle_string *string;                     /* Chaîne à consulter          */
+    const vmpa2t *result;                   /* Localisation à retourner    */
 
-    result = NULL;
-
-    lock_flat_array(&comment->text);
-
-    count = count_flat_array_items(comment->text);
-
-    for (i = 0; i < count; i++)
-    {
-        string = get_flat_array_item(comment->text, i, sizeof(rle_string));
-
-        assert(!is_rle_string_empty(string));
-
-        result = stradd(result, get_rle_string(string));
-
-    }
-
-    unlock_flat_array(&comment->text);
+    result = &comment->addr;
 
     return result;
 
@@ -1184,30 +1070,22 @@ char *g_db_comment_get_text(GDbComment *comment)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : comment = informations à consulter.                          *
-*                text    = commentaire construit ou NULL.                     *
 *                                                                             *
-*  Description : Associe un contenu supplémentaire à un commentaire.          *
+*  Description : Indique le type d'incrustation prévue pour un commentaire.   *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Incrustation associée au commentaire.                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_db_comment_add_dynamic_text(GDbComment *comment, char *text)
+CommentEmbeddingType g_db_comment_get_embedding_type(const GDbComment *comment)
 {
-    rle_string string;                      /* Fragment de texte à ajouter */
-
-    if (text != NULL)
-    {
-        init_dynamic_rle_string(&string, text);
+    CommentEmbeddingType result;            /* Type à renvoyer             */
 
-        g_db_comment_add_rle_string(comment, &string);
+    result = comment->type;
 
-    }
-
-    else
-        g_db_comment_update_count_lines(comment);
+    return result;
 
 }
 
@@ -1215,30 +1093,22 @@ void g_db_comment_add_dynamic_text(GDbComment *comment, char *text)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : comment = informations à consulter.                          *
-*                text    = commentaire construit ou NULL.                     *
 *                                                                             *
-*  Description : Associe un contenu statique supplémentaire à un commentaire. *
+*  Description : Fournit les particularités d'accroche liées à un commentaire.*
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Particularités éventuelles pour l'accroche.                  *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_db_comment_add_static_text(GDbComment *comment, const char *text)
+BufferLineFlags g_db_comment_get_flags(const GDbComment *comment)
 {
-    rle_string string;                      /* Fragment de texte à ajouter */
+    BufferLineFlags result;                 /* Type à renvoyer             */
 
-    if (text != NULL)
-    {
-        init_static_rle_string(&string, text);
+    result = comment->flags;
 
-        g_db_comment_add_rle_string(comment, &string);
-
-    }
-
-    else
-        g_db_comment_update_count_lines(comment);
+    return result;
 
 }
 
@@ -1246,29 +1116,41 @@ void g_db_comment_add_static_text(GDbComment *comment, const char *text)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : comment = informations à consulter.                          *
-*                string  = commentaire établi à inétgrer.                     *
 *                                                                             *
-*  Description : Associe un contenu formaté supplémentaire à un commentaire.  *
+*  Description : Fournit le commentaire associé à un commentaire.             *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Commentaire existant à libérer après usage ou NULL.          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *string)
+char *g_db_comment_get_text(GDbComment *comment)
 {
-    /* Extension du contenu */
+    char *result;                           /* Chaîne constituée à renvoyer*/
+    size_t count;                           /* Nombre d'éléments textuels  */
+    size_t i;                               /* Boucle de parcours          */
+    rle_string *string;                     /* Chaîne à consulter          */
+
+    result = NULL;
 
     lock_flat_array(&comment->text);
 
-    add_item_to_flat_array(&comment->text, string, sizeof(rle_string));
+    count = count_flat_array_items(comment->text);
 
-    unlock_flat_array(&comment->text);
+    for (i = 0; i < count; i++)
+    {
+        string = get_flat_array_item(comment->text, i, sizeof(rle_string));
 
-    /* Mise à jour de la taille de rendu */
+        assert(!is_rle_string_empty(string));
 
-    g_db_comment_update_count_lines(comment);
+        result = stradd(result, get_rle_string(string));
+
+    }
+
+    unlock_flat_array(&comment->text);
+
+    return result;
 
 }
 
@@ -1281,64 +1163,27 @@ static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *s
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : comment = informations à réactualiser.                       *
+*  Paramètres  : comment = générateur à consulter.                            *
 *                                                                             *
-*  Description : Calcule le nombre de lignes suite à un changement de contenu.*
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_comment_update_count_lines(GDbComment *comment)
+static size_t g_db_comment_count_lines(GDbComment *comment)
 {
-    char *full;                             /* Contenu textuel complet     */
-    char **lines;                           /* Lignes brutes à représenter */
-    GCodingLanguage *lang;                  /* Langage de sortie préféré   */
-    size_t i;                               /* Boucle de parcours          */
+    size_t result;                          /* Quantité à retourner        */
 
-    full = g_db_comment_get_text(comment);
-
-    if (full == NULL)
-        comment->count = 0;
-
-    else
-    {
-        lines = strtoka(full, "\n", &comment->count);
-
-        lang = g_asm_language_new();
-        g_coding_language_encapsulate_comments(lang, &lines, &comment->count);
-        g_object_unref(G_OBJECT(lang));
-
-        for (i = 0; i < comment->count; i++)
-            free(lines[i]);
-
-        if (lines != NULL)
-            free(lines);
-
-        free(full);
-
-    }
-
-}
+    lock_flat_array(&comment->text);
 
+    result = count_flat_array_items(comment->text);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : comment = générateur à consulter.                            *
-*                                                                             *
-*  Description : Indique le nombre de ligne prêtes à être générées.           *
-*                                                                             *
-*  Retour      : Nombre de lignes devant apparaître au final.                 *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+    unlock_flat_array(&comment->text);
 
-static size_t g_db_comment_count_lines(const GDbComment *comment)
-{
-    return comment->count;
+    return result;
 
 }
 
@@ -1413,7 +1258,7 @@ static int g_db_comment_contain_cursor(const GDbComment *comment, size_t index,
 *                                                                             *
 ******************************************************************************/
 
-static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t index, size_t repeat)
+static BufferLineFlags g_db_comment_get_generator_flags(const GDbComment *comment, size_t index, size_t repeat)
 {
     return BLF_NONE;
 
@@ -1454,11 +1299,6 @@ static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t in
         g_coding_language_encapsulate_comments(lang, &lines, &count);
         g_object_unref(G_OBJECT(lang));
 
-        if (count != comment->count)
-            printf("full=%s\n", full);
-
-        assert(count == comment->count);
-
         g_buffer_line_append_text(line, DLC_COMMENTS, SL(lines[repeat]), RTT_COMMENT, NULL);
 
         for (i = 0; i < count; i++)
@@ -1616,13 +1456,12 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
     char *msg;                              /* Message d'erreur            */
     int ret;                                /* Bilan de la création        */
 
-    sql = "CREATE TABLE Comments ("             \
-             SQLITE_DB_ITEM_CREATE ", "         \
-             "%s, "                             \
-             "lflags INTEGER, "                 \
-             SQLITE_RLESTR_CREATE("text") ", "  \
-             "inlined INTEGER, "                \
-             "repeatable INTEGER"               \
+    sql = "CREATE TABLE Comments ("         \
+             SQLITE_DB_ITEM_CREATE ", "     \
+             "%s, "                         \
+             "type INTEGER, "               \
+             "line_flags INTEGER, "         \
+             SQLITE_RLESTR_CREATE("text")   \
           ");";
 
     addr_fields = create_vmpa_db_table(NULL);
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index 7049b28..fa1644f 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -37,12 +37,25 @@
 /* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
 
 
-#define G_TYPE_DB_COMMENT               g_db_comment_get_type()
-#define G_DB_COMMENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_comment_get_type(), GDbComment))
-#define G_IS_DB_COMMENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_comment_get_type()))
-#define G_DB_COMMENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COMMENT, GDbCommentClass))
-#define G_IS_DB_COMMENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COMMENT))
-#define G_DB_COMMENT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COMMENT, GDbCommentClass))
+/* Incrustations possibles pour un commentaire */
+typedef enum _CommentEmbeddingType
+{
+    CET_INLINED,                            /* En bout de ligne            */
+    CET_REPEATED,                           /* Reproduit à chaque référence*/
+    CET_BEFORE,                             /* Placé sur une ligne avant   */
+    CET_AFTER,                              /* Placé sur une ligne après   */
+
+    CET_COUNT
+
+} CommentEmbeddingType;
+
+
+#define G_TYPE_DB_COMMENT            g_db_comment_get_type()
+#define G_DB_COMMENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DB_COMMENT, GDbComment))
+#define G_IS_DB_COMMENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DB_COMMENT))
+#define G_DB_COMMENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COMMENT, GDbCommentClass))
+#define G_IS_DB_COMMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COMMENT))
+#define G_DB_COMMENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COMMENT, GDbCommentClass))
 
 
 /* Commentaire à placer dans du texte quelconque (instance) */
@@ -55,35 +68,38 @@ typedef struct _GDbCommentClass GDbCommentClass;
 /* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
 GType g_db_comment_get_type(void);
 
-/* Crée une définition de commentaire dans une zone de texte. */
-GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, bool);
+/* Crée une définition de commentaire textuel. */
+GDbComment *g_db_comment_new(const vmpa2t *, CommentEmbeddingType, BufferLineFlags, const char *);
+
+/* Initialise la définition d'un commentaire à incruster. */
+bool g_db_comment_fill(GDbComment *, const vmpa2t *, CommentEmbeddingType, BufferLineFlags, const char *);
 
-/* Crée une définition de commentaire dans une zone de texte. */
-GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool);
+/* Etablit la comparaison d'une adresse avec un commentaire. */
+int compare_comment_by_addr(const vmpa2t *, const GDbComment * const *);
 
 /* Fournit l'adresse associée à un commentaire. */
 const vmpa2t *g_db_comment_get_address(const GDbComment *);
 
-/* Fournit le commentaire associé à un commentaire. */
-char *g_db_comment_get_text(GDbComment *);
+/* Indique le type d'incrustation prévue pour un commentaire. */
+CommentEmbeddingType g_db_comment_get_embedding_type(const GDbComment *);
 
-/* Associe un contenu supplémentaire à un commentaire. */
-void g_db_comment_add_dynamic_text(GDbComment *, char *);
+/* Fournit les particularités d'accroche liées à un commentaire. */
+BufferLineFlags g_db_comment_get_flags(const GDbComment *);
 
-/*  Associe un contenu statique supplémentaire à un commentaire. */
-void g_db_comment_add_static_text(GDbComment *, const char *);
+/* Fournit le commentaire associé à un commentaire. */
+char *g_db_comment_get_text(GDbComment *);
 
 
 
 /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
 
 
-#define G_TYPE_COMMENT_COLLECTION               g_comment_collection_get_type()
-#define G_COMMENT_COLLECTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_comment_collection_get_type(), GCommentCollection))
-#define G_IS_COMMENT_COLLECTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_comment_collection_get_type()))
-#define G_COMMENT_COLLECTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
-#define G_IS_COMMENT_COLLECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMMENT_COLLECTION))
-#define G_COMMENT_COLLECTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
+#define G_TYPE_COMMENT_COLLECTION            g_comment_collection_get_type()
+#define G_COMMENT_COLLECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollection))
+#define G_IS_COMMENT_COLLECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_COMMENT_COLLECTION))
+#define G_COMMENT_COLLECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
+#define G_IS_COMMENT_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMMENT_COLLECTION))
+#define G_COMMENT_COLLECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMMENT_COLLECTION, GCommentCollectionClass))
 
 
 /* Collection dédiée aux commentaires textuels (instance) */
diff --git a/src/core/collections.c b/src/core/collections.c
index f5bccd7..660c981 100644
--- a/src/core/collections.c
+++ b/src/core/collections.c
@@ -114,7 +114,7 @@ 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);
 
diff --git a/src/format/preload.c b/src/format/preload.c
index dc254b2..c36db93 100644
--- a/src/format/preload.c
+++ b/src/format/preload.c
@@ -24,6 +24,9 @@
 #include "preload.h"
 
 
+#include <assert.h>
+
+
 #include "preload-int.h"
 
 
@@ -629,7 +632,7 @@ void _g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
 *                                                                             *
 *  Description : Recherche un commentaire dans des préchargements.            *
 *                                                                             *
-*  Retour      : Eventuel commenaire retrouvé ou NULL.                        *
+*  Retour      : Eventuel commentaire retrouvé ou NULL.                       *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -640,23 +643,52 @@ GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *ad
     GDbComment *result;                     /* Trouvaille à retourner      */
     GDbComment **ptr;                       /* Adresse dans le tableau     */
 
-    int cmp_comment_by_addr(const vmpa2t *key, const GDbComment * const *comment)
+    ptr = find_item_in_flat_array(info->comments, sizeof(GDbComment *),
+                                     (__compar_fn_t)compare_comment_by_addr, addr);
+
+    if (ptr != NULL)
     {
-        const vmpa2t *caddr;                /* Position du commentaire     */
+        result = *ptr;
+        g_object_ref(G_OBJECT(result));
+    }
+    else
+        result = NULL;
 
-        caddr = g_db_comment_get_address(*comment);
+    return result;
 
-        return cmp_vmpa(key, caddr);
+}
 
-    }
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info  = instance à mettre à consulter.                       *
+*                addr  = localisation du commentaire recherché.               *
+*                index = indice du commentaire retrouvé ou NULL. [OUT]        *
+*                                                                             *
+*  Description : Recherche un commentaire dans des préchargements.            *
+*                                                                             *
+*  Retour      : Eventuel commentaire retrouvé ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDbComment *g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *addr, size_t *index)
+{
+    GDbComment *result;                     /* Trouvaille à retourner      */
+    GDbComment **ptr;                       /* Adresse dans le tableau     */
 
     ptr = find_item_in_flat_array(info->comments, sizeof(GDbComment *),
-                                     (__compar_fn_t)cmp_comment_by_addr, addr);
+                                     (__compar_fn_t)compare_comment_by_addr, addr);
 
     if (ptr != NULL)
     {
         result = *ptr;
         g_object_ref(G_OBJECT(result));
+
+        if (index != NULL)
+            *index = ((void **)ptr - info->comments);
+
     }
     else
         result = NULL;
@@ -668,6 +700,37 @@ GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *ad
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : info    = instance à mettre à jour.                          *
+*                index   = indice du commentaire à remplacer.                 *
+*                comment = commentaire à venir associer.                      *
+*                                                                             *
+*  Description : Remplace un commentaire par un autre à un emplacement donné. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_preload_info_replace_comment_at(GPreloadInfo *info, size_t index, GDbComment *comment)
+{
+#ifndef NDEBUG
+    GDbComment **current;                   /* Commentaire à remplacer     */
+#endif
+
+#ifndef NDEBUG
+    current = get_flat_array_item(info->comments, index, sizeof(GDbComment *));
+
+    assert(cmp_vmpa(g_db_comment_get_address(*current), g_db_comment_get_address(comment)));
+#endif
+
+    rpl_item_in_flat_array(info->comments, index, &comment, sizeof(GDbComment *));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : info = instance à consulter.                                 *
 *                                                                             *
 *  Description : Indique la quantité de commentaires préchargés disponibles.  *
diff --git a/src/format/preload.h b/src/format/preload.h
index 5557253..587c35d 100644
--- a/src/format/preload.h
+++ b/src/format/preload.h
@@ -102,6 +102,12 @@ void _g_preload_info_add_comment(GPreloadInfo *, GDbComment *);
 /* Recherche un commentaire dans des préchargements. */
 GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *, const vmpa2t *);
 
+/* Recherche un commentaire dans des préchargements. */
+GDbComment *g_preload_info_find_comment_at(GPreloadInfo *, const vmpa2t *, size_t *);
+
+/* Remplace un commentaire par un autre à un emplacement donné. */
+void g_preload_info_replace_comment_at(GPreloadInfo *, size_t, GDbComment *);
+
 /* Indique la quantité de commentaires préchargés disponibles. */
 size_t _g_preload_info_count_comments(const GPreloadInfo *);
 
-- 
cgit v0.11.2-87-g4458