From 4b54747c0ee3736591b3fb38b156837b0958b1cc Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 4 Jan 2020 14:54:17 +0100
Subject: Stuck to the Yaml specifications a little bit more.

---
 plugins/yaml/Makefile.am        |   1 +
 plugins/yaml/node-int.h         |   2 +
 plugins/yaml/node.c             |  29 +++
 plugins/yaml/node.h             |   2 +-
 plugins/yaml/pair.c             | 394 ++++++++++++++++++++++++++++++++++++++++
 plugins/yaml/pair.h             |  72 ++++++++
 plugins/yaml/python/Makefile.am |   1 +
 plugins/yaml/python/module.c    |   2 +
 plugins/yaml/python/node.c      |  49 +++++
 plugins/yaml/python/pair.c      | 393 +++++++++++++++++++++++++++++++++++++++
 plugins/yaml/python/pair.h      |  45 +++++
 plugins/yaml/python/scalar.c    |  49 -----
 plugins/yaml/python/tree.c      |   4 +-
 plugins/yaml/tree.c             |  23 +--
 tests/plugins/yamlrdr.py        |  42 +++--
 15 files changed, 1026 insertions(+), 82 deletions(-)
 create mode 100644 plugins/yaml/pair.c
 create mode 100644 plugins/yaml/pair.h
 create mode 100644 plugins/yaml/python/pair.c
 create mode 100644 plugins/yaml/python/pair.h

diff --git a/plugins/yaml/Makefile.am b/plugins/yaml/Makefile.am
index 9ba479c..5432c9d 100644
--- a/plugins/yaml/Makefile.am
+++ b/plugins/yaml/Makefile.am
@@ -32,6 +32,7 @@ libyaml_la_SOURCES =						\
 	line.h line.c							\
 	node-int.h								\
 	node.h node.c							\
+	pair.h pair.c							\
 	reader.h reader.c						\
 	scalar.h scalar.c						\
 	tree.h tree.c
diff --git a/plugins/yaml/node-int.h b/plugins/yaml/node-int.h
index 9100c92..8fec2a2 100644
--- a/plugins/yaml/node-int.h
+++ b/plugins/yaml/node-int.h
@@ -38,6 +38,8 @@ struct _GYamlNode
 {
     GObject parent;                         /* A laisser en premier        */
 
+    GYamlLine *line;                        /* Line Yaml d'origine         */
+
 };
 
 /* Noeud d'une arborescence au format Yaml (classe) */
diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c
index d35de9c..5f596c1 100644
--- a/plugins/yaml/node.c
+++ b/plugins/yaml/node.c
@@ -87,6 +87,7 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass)
 
 static void g_yaml_node_init(GYamlNode *node)
 {
+    node->line = NULL;
 
 }
 
@@ -105,6 +106,8 @@ static void g_yaml_node_init(GYamlNode *node)
 
 static void g_yaml_node_dispose(GYamlNode *node)
 {
+    g_clear_object(&node->line);
+
     G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node));
 
 }
@@ -131,6 +134,32 @@ static void g_yaml_node_finalize(GYamlNode *node)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                *
+*                                                                             *
+*  Description : Fournit la ligne d'origine associée à un noeud.              *
+*                                                                             *
+*  Retour      : Ligne Yaml à l'origine du noeud.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node)
+{
+    GYamlLine *result;                      /* Ligne d'origine à renvoyer  */
+
+    result = node->line;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : node    = noeud d'arborescence Yaml à consulter.             *
 *                path    = chemin d'accès à parcourir.                        *
 *                prepare = indication sur une préparation d'un prochain appel.*
diff --git a/plugins/yaml/node.h b/plugins/yaml/node.h
index 4c290f7..1bb7670 100644
--- a/plugins/yaml/node.h
+++ b/plugins/yaml/node.h
@@ -54,7 +54,7 @@ typedef struct _GYamlNodeClass GYamlNodeClass;
 /* Indique le type défini pour un noeud d'arborescence Yaml. */
 GType g_yaml_node_get_type(void);
 
-/* Fournit la ligne principale associée à un noeud. */
+/* Fournit la ligne d'origine associée à un noeud. */
 GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *);
 
 /* Recherche les noeuds correspondant à un chemin. */
diff --git a/plugins/yaml/pair.c b/plugins/yaml/pair.c
new file mode 100644
index 0000000..299d587
--- /dev/null
+++ b/plugins/yaml/pair.c
@@ -0,0 +1,394 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pair.c - noeud Yaml de paire clef/valeur
+ *
+ * Copyright (C) 2019 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "pair.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "node-int.h"
+
+
+
+/* Noeud d'une arborescence au format Yaml (instance) */
+struct _GYamlPair
+{
+    GYamlNode parent;                       /* A laisser en premier        */
+
+    char *key;                              /* Clef présente dans le noeud */
+    char *value;                            /* Valeur associée             */
+
+    GYamlCollection *collection;            /* Collection de noeuds        */
+
+};
+
+/* Noeud d'une arborescence au format Yaml (classe) */
+struct _GYamlPairClass
+{
+    GYamlNodeClass parent;                  /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des noeuds d'arborescence Yaml. */
+static void g_yaml_pair_class_init(GYamlPairClass *);
+
+/* Initialise une instance de noeud d'arborescence Yaml. */
+static void g_yaml_pair_init(GYamlPair *);
+
+/* Supprime toutes les références externes. */
+static void g_yaml_pair_dispose(GYamlPair *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_yaml_pair_finalize(GYamlPair *);
+
+/* Recherche les noeuds correspondant à un chemin. */
+static void g_yaml_pair_find_by_path(const GYamlPair *, const char *, bool, GYamlNode ***, size_t *);
+
+
+
+/* Indique le type défini pour un noeud d'arborescence Yaml. */
+G_DEFINE_TYPE(GYamlPair, g_yaml_pair, G_TYPE_YAML_NODE);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des noeuds d'arborescence Yaml.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_pair_class_init(GYamlPairClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GYamlNodeClass *node;                   /* Version parente de classe   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_pair_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_yaml_pair_finalize;
+
+    node = G_YAML_NODE_CLASS(klass);
+
+    node->find = (find_yaml_node_fc)g_yaml_pair_find_by_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de noeud d'arborescence Yaml.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_pair_init(GYamlPair *node)
+{
+    node->key = NULL;
+    node->value = NULL;
+
+    node->collection = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_pair_dispose(GYamlPair *node)
+{
+    g_clear_object(&node->collection);
+
+    G_OBJECT_CLASS(g_yaml_pair_parent_class)->dispose(G_OBJECT(node));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_pair_finalize(GYamlPair *node)
+{
+    if (node->key != NULL)
+        free(node->key);
+
+    if (node->value != NULL)
+        free(node->value);
+
+    G_OBJECT_CLASS(g_yaml_pair_parent_class)->finalize(G_OBJECT(node));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne Yaml à l'origine du futur noeud.                *
+*                                                                             *
+*  Description : Construit un noeud d'arborescence Yaml.                      *
+*                                                                             *
+*  Retour      : Instance mise en place ou NULL en cas d'échec.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlPair *g_yaml_pair_new(GYamlLine *line)
+{
+    GYamlPair *result;                      /* Structure à retourner       */
+    const char *key;                        /* Clef associée au noeud      */
+    const char *value;                      /* Eventuelle valeur associée  */
+
+    key = g_yaml_line_get_key(line);
+    value = g_yaml_line_get_value(line);
+
+    if (key == NULL)
+        result = NULL;
+
+    else
+    {
+        result = g_object_new(G_TYPE_YAML_PAIR, NULL);
+
+        G_YAML_NODE(result)->line = line;
+        g_object_ref(G_OBJECT(line));
+
+        result->key = strdup(key);
+
+        if (value == NULL)
+            result->value = NULL;
+        else
+            result->value = strdup(value);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node    = noeud d'arborescence Yaml à consulter.             *
+*                path    = chemin d'accès à parcourir.                        *
+*                prepare = indication sur une préparation d'un prochain appel.*
+*                nodes   = liste de noeuds avec correspondance établie. [OUT] *
+*                count   = quantité de ces noeuds. [OUT]                      *
+*                                                                             *
+*  Description : Recherche les noeuds correspondant à un chemin.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_pair_find_by_path(const GYamlPair *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count)
+{
+    char *next;                             /* Prochaine partie du chemin  */
+    size_t cmplen;                          /* Etendue de la comparaison   */
+    int ret;                                /* Bilan d'une comparaison     */
+
+    if (path[0] == '\0')
+        goto exit;
+
+    /* Correspondance au niveau du noeud ? */
+
+    if (path[0] == '/')
+    {
+        path++;
+
+        if (path[0] == '\0')
+            goto matched;
+
+    }
+
+    next = strchr(path, '/');
+
+    if (next == NULL)
+        ret = strcmp(path, node->key);
+
+    else
+    {
+        cmplen = next - path;
+
+        if (cmplen == 0)
+            goto cont;
+
+        ret = strncmp(path, node->key, cmplen);
+
+    }
+
+    if (ret != 0)
+        goto done;
+
+    else if (next != NULL)
+    {
+        path += cmplen;
+        goto cont;
+    }
+
+ matched:
+
+    *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **));
+
+    g_object_ref(G_OBJECT(node));
+    (*nodes)[*count - 1] = G_YAML_NODE(node);
+
+    goto done;
+
+ cont:
+
+    if (node->collection != NULL)
+        _g_yaml_node_find_by_path(G_YAML_NODE(node->collection), path, prepare, nodes, count);
+
+ done:
+
+ exit:
+
+    ;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                *
+*                                                                             *
+*  Description : Fournit la clef représentée dans une paire en Yaml.          *
+*                                                                             *
+*  Retour      : Clef sous forme de chaîne de caractères.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_yaml_pair_get_key(const GYamlPair *node)
+{
+    char *result;                           /* Valeur à retourner          */
+
+    result = node->key;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                *
+*                                                                             *
+*  Description : Fournit l'éventuelle valeur d'une paire en Yaml.             *
+*                                                                             *
+*  Retour      : Valeur sous forme de chaîne de caractères ou NULL.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_yaml_pair_get_value(const GYamlPair *node)
+{
+    char *result;                           /* Valeur à retourner          */
+
+    result = node->value;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node   = noeud d'arborescence Yaml à compléter.              *
+*                collec = collection de noeuds Yaml.                          *
+*                                                                             *
+*  Description : Attache une collection de noeuds Yaml à un noeud.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_yaml_pair_set_collection(GYamlPair *node, GYamlCollection *collec)
+{
+    g_clear_object(&node->collection);
+
+    g_object_ref_sink(G_OBJECT(collec));
+    node->collection = collec;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                *
+*                                                                             *
+*  Description : Fournit une éventuelle collection rattachée à un noeud.      *
+*                                                                             *
+*  Retour      : Collection de noeuds Yaml ou NULL.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *node)
+{
+    GYamlCollection *result;                /* Collection à renvoyer       */
+
+    result = node->collection;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
diff --git a/plugins/yaml/pair.h b/plugins/yaml/pair.h
new file mode 100644
index 0000000..7ca97ba
--- /dev/null
+++ b/plugins/yaml/pair.h
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pair.h - prototypes pour un noeud Yaml de paire clef/valeur
+ *
+ * Copyright (C) 2019 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef PLUGINS_YAML_PAIR_H
+#define PLUGINS_YAML_PAIR_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "collection.h"
+#include "line.h"
+#include "node.h"
+
+
+#define G_TYPE_YAML_PAIR            g_yaml_pair_get_type()
+#define G_YAML_PAIR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_PAIR, GYamlPair))
+#define G_IS_YAML_PAIR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_PAIR))
+#define G_YAML_PAIR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_PAIR, GYamlPairClass))
+#define G_IS_YAML_PAIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_PAIR))
+#define G_YAML_PAIR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_PAIR, GYamlPairClass))
+
+
+/* Noeud d'une arborescence au format Yaml (instance) */
+typedef struct _GYamlPair GYamlPair;
+
+/* Noeud d'une arborescence au format Yaml (classe) */
+typedef struct _GYamlPairClass GYamlPairClass;
+
+
+/* Indique le type défini pour un noeud d'arborescence Yaml. */
+GType g_yaml_pair_get_type(void);
+
+/* Construit un noeud d'arborescence Yaml. */
+GYamlPair *g_yaml_pair_new(GYamlLine *);
+
+/* Fournit la clef représentée dans une paire en Yaml. */
+const char *g_yaml_pair_get_key(const GYamlPair *);
+
+/* Fournit l'éventuelle valeur d'une paire en Yaml. */
+const char *g_yaml_pair_get_value(const GYamlPair *);
+
+/* Attache une collection de noeuds Yaml à un noeud. */
+void g_yaml_pair_set_collection(GYamlPair *, GYamlCollection *);
+
+/* Fournit une éventuelle collection rattachée à un noeud. */
+GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *);
+
+
+
+#endif  /* PLUGINS_YAML_PAIR_H */
diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am
index 8d6ddaa..2e66970 100644
--- a/plugins/yaml/python/Makefile.am
+++ b/plugins/yaml/python/Makefile.am
@@ -6,6 +6,7 @@ libyamlpython_la_SOURCES =					\
 	line.h line.c							\
 	module.h module.c						\
 	node.h node.c							\
+	pair.h pair.c							\
 	reader.h reader.c						\
 	scalar.h scalar.c						\
 	tree.h tree.c
diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c
index 0726dc4..cc39c13 100644
--- a/plugins/yaml/python/module.c
+++ b/plugins/yaml/python/module.c
@@ -36,6 +36,7 @@
 #include "collection.h"
 #include "line.h"
 #include "node.h"
+#include "pair.h"
 #include "reader.h"
 #include "scalar.h"
 #include "tree.h"
@@ -113,6 +114,7 @@ bool populate_yaml_module(void)
     if (result) result = register_python_yaml_node(module);
     if (result) result = register_python_yaml_collection(module);
     if (result) result = register_python_yaml_line(module);
+    if (result) result = register_python_yaml_pair(module);
     if (result) result = register_python_yaml_reader(module);
     if (result) result = register_python_yaml_scalar(module);
     if (result) result = register_python_yaml_tree(module);
diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c
index 31daa04..2951f0f 100644
--- a/plugins/yaml/python/node.c
+++ b/plugins/yaml/python/node.c
@@ -52,6 +52,9 @@ static PyObject *py_yaml_node_find_by_path(PyObject *, PyObject *);
 /* Recherche l'unique noeud correspondant à un chemin. */
 static PyObject *py_yaml_node_find_one_by_path(PyObject *, PyObject *);
 
+/* Fournit la ligne d'origine associée à un noeud. */
+static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *);
+
 
 
 /******************************************************************************
@@ -189,6 +192,51 @@ static PyObject *py_yaml_node_find_one_by_path(PyObject *self, PyObject *args)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la ligne principale associée à un noeud.             *
+*                                                                             *
+*  Retour      : Ligne Yaml à l'origine du noeud.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_node_get_yaml_line(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GYamlNode *node;                        /* Version GLib du noeud       */
+    GYamlLine *line;                        /* Line Yaml associée          */
+
+#define YAML_NODE_YAML_LINE_ATTRIB PYTHON_GET_DEF_FULL      \
+(                                                           \
+    yaml_line, py_yaml_node,                                \
+    "Orginal Yaml line linked to the node."                 \
+)
+
+    node = G_YAML_NODE(pygobject_get(self));
+
+    line = g_yaml_node_get_yaml_line(node);
+
+    if (line == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    else
+    {
+        result = pygobject_new(G_OBJECT(line));
+        g_object_unref(G_OBJECT(line));
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Fournit un accès à une définition de type à diffuser.        *
@@ -208,6 +256,7 @@ PyTypeObject *get_python_yaml_node_type(void)
     };
 
     static PyGetSetDef py_yaml_node_getseters[] = {
+        YAML_NODE_YAML_LINE_ATTRIB,
         { NULL }
     };
 
diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c
new file mode 100644
index 0000000..da58904
--- /dev/null
+++ b/plugins/yaml/python/pair.c
@@ -0,0 +1,393 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pair.c - équivalent Python du fichier "plugins/yaml/pair.c"
+ *
+ * Copyright (C) 2019 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 "pair.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "collection.h"
+#include "line.h"
+#include "node.h"
+#include "../pair.h"
+
+
+
+/* Crée un nouvel objet Python de type 'YamlPair'. */
+static PyObject *py_yaml_pair_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Fournit la clef représentée dans une paire en Yaml. */
+static PyObject *py_yaml_pair_get_key(PyObject *, void *);
+
+/* Fournit l'éventuelle valeur d'une paire en Yaml. */
+static PyObject *py_yaml_pair_get_value(PyObject *, void *);
+
+/* Attache une collection de noeuds Yaml à un noeud. */
+static int py_yaml_pair_set_collection(PyObject *, PyObject *, void *);
+
+/* Fournit une éventuelle collection rattachée à un noeud. */
+static PyObject *py_yaml_pair_get_collection(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  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 'YamlPair'.              *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GYamlLine *key;                         /* Ligne principale du noeud   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GYamlPair *node;                      /* Création GLib à transmettre */
+
+#define YAML_PAIR_DOC                                                   \
+    "YamlPair handles a key/value pair node in a Yaml tree.\n"          \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    YamlPair(line)\n"                                              \
+    "\n"                                                                \
+    "Where key is the original Yaml line for the pair."
+
+    ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key);
+    if (!ret) return NULL;
+
+    node = g_yaml_pair_new(key);
+
+    g_object_ref_sink(G_OBJECT(node));
+    result = pygobject_new(G_OBJECT(node));
+    g_object_unref(node);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la clef représentée dans une paire en Yaml.          *
+*                                                                             *
+*  Retour      : Clef sous forme de chaîne de caractères.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GYamlPair *node;                        /* Version GLib du noeud       */
+    const char *key;                        /* Chaîne à transmettre        */
+
+#define YAML_PAIR_KEY_ATTRIB PYTHON_GET_DEF_FULL    \
+(                                                   \
+    key, py_yaml_pair,                              \
+    "Key linked to the Yaml key/value pair node."   \
+)
+
+    node = G_YAML_PAIR(pygobject_get(self));
+
+    key = g_yaml_pair_get_key(node);
+    assert(key != NULL);
+
+    result = PyUnicode_FromString(key);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit l'éventuelle valeur d'une paire en Yaml.             *
+*                                                                             *
+*  Retour      : Valeur sous forme de chaîne de caractères ou None.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GYamlPair *node;                        /* Version GLib du type        */
+    const char *value;                      /* Chaîne à transmettre        */
+
+#define YAML_PAIR_VALUE_ATTRIB PYTHON_GET_DEF_FULL          \
+(                                                           \
+    value, py_yaml_pair,                                    \
+    "Value linked to the Yaml key/value pair node or None." \
+)
+
+    node = G_YAML_PAIR(pygobject_get(self));
+
+    value = g_yaml_pair_get_value(node);
+
+    if (value == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    else
+        result = PyUnicode_FromString(value);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = contenu binaire à manipuler.                       *
+*                value   = collection de noeuds Yaml.                         *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Attache une collection de noeuds Yaml à un noeud.            *
+*                                                                             *
+*  Retour      : Jeu d'attributs liés au contenu courant.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_yaml_pair_set_collection(PyObject *self, PyObject *value, void *closure)
+{
+    int result;                             /* Bilan à renvoyer            */
+    GYamlPair *node;                        /* Version GLib du noeud       */
+    GYamlCollection *collec;                /* Version GLib de la valeur   */
+
+    node = G_YAML_PAIR(pygobject_get(self));
+
+    if (value == Py_None)
+    {
+        g_yaml_pair_set_collection(node, NULL);
+        result = 0;
+    }
+
+    else
+    {
+        if (!convert_to_yaml_collection(value, &collec))
+            result = -1;
+
+        else
+        {
+            g_yaml_pair_set_collection(node, collec);
+            result = 0;
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = contenu binaire à manipuler.                       *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Fournit une éventuelle collection rattachée à un noeud.      *
+*                                                                             *
+*  Retour      : Collection de noeuds Yaml ou None.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GYamlPair *node;                        /* Version GLib du noeud       */
+    GYamlCollection *collec;                /* Collection à transmettre    */
+
+#define YAML_PAIR_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL                      \
+(                                                                               \
+    collection, py_yaml_pair,                                                   \
+    "Provide or define the collection of nodes attached to another Yaml node."  \
+)
+
+    node = G_YAML_PAIR(pygobject_get(self));
+
+    collec = g_yaml_pair_get_collection(node);
+
+    if (collec == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    else
+    {
+        result = pygobject_new(G_OBJECT(collec));
+        g_object_unref(collec);
+    }
+
+    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_yaml_pair_type(void)
+{
+    static PyMethodDef py_yaml_pair_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_yaml_pair_getseters[] = {
+        YAML_PAIR_KEY_ATTRIB,
+        YAML_PAIR_VALUE_ATTRIB,
+        YAML_PAIR_COLLECTION_ATTRIB,
+        { NULL }
+    };
+
+    static PyTypeObject py_yaml_pair_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.plugins.yaml.YamlPair",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = YAML_PAIR_DOC,
+
+        .tp_methods     = py_yaml_pair_methods,
+        .tp_getset      = py_yaml_pair_getseters,
+        .tp_new         = py_yaml_pair_new
+
+    };
+
+    return &py_yaml_pair_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlPair.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_yaml_pair(PyObject *module)
+{
+    PyTypeObject *type;                     /* Type Python 'YamlPair'      */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_yaml_pair_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type, get_python_yaml_node_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 noeud d'arborescence de format Yaml.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_yaml_pair(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_pair_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 Yaml key/value pair");
+            break;
+
+        case 1:
+            *((GYamlPair **)dst) = G_YAML_PAIR(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/yaml/python/pair.h b/plugins/yaml/python/pair.h
new file mode 100644
index 0000000..da93f4f
--- /dev/null
+++ b/plugins/yaml/python/pair.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pair.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/pair.h"
+ *
+ * Copyright (C) 2019 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_YAML_PYTHON_PAIR_H
+#define _PLUGINS_YAML_PYTHON_PAIR_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_yaml_pair_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlPair'. */
+bool register_python_yaml_pair(PyObject *);
+
+/* Tente de convertir en noeud d'arborescence de format Yaml. */
+int convert_to_yaml_pair(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_YAML_PYTHON_PAIR_H */
diff --git a/plugins/yaml/python/scalar.c b/plugins/yaml/python/scalar.c
index ee38edf..bd14f50 100644
--- a/plugins/yaml/python/scalar.c
+++ b/plugins/yaml/python/scalar.c
@@ -41,9 +41,6 @@
 /* Crée un nouvel objet Python de type 'YamlScalar'. */
 static PyObject *py_yaml_scalar_new(PyTypeObject *, PyObject *, PyObject *);
 
-/* Fournit la ligne principale associée à un noeud. */
-static PyObject *py_yaml_scalar_get_yaml_line(PyObject *, void *);
-
 /* Attache une collection de noeuds Yaml à un noeud. */
 static int py_yaml_scalar_set_collection(PyObject *, PyObject *, void *);
 
@@ -98,51 +95,6 @@ static PyObject *py_yaml_scalar_new(PyTypeObject *type, PyObject *args, PyObject
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self    = objet Python concerné par l'appel.                 *
-*                closure = non utilisé ici.                                   *
-*                                                                             *
-*  Description : Fournit la ligne principale associée à un noeud.             *
-*                                                                             *
-*  Retour      : Ligne Yaml à l'origine du noeud.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_yaml_scalar_get_yaml_line(PyObject *self, void *closure)
-{
-    PyObject *result;                       /* Résultat à retourner        */
-    GYamlScalar *node;                      /* Version GLib du noeud       */
-    GYamlLine *line;                        /* Line Yaml associée          */
-
-#define YAML_SCALAR_YAML_LINE_ATTRIB PYTHON_GET_DEF_FULL      \
-(                                                           \
-    yaml_line, py_yaml_scalar,                                \
-    "Orginal Yaml line linked to the scalar."                 \
-)
-
-    node = G_YAML_SCALAR(pygobject_get(self));
-
-    line = g_yaml_scalar_get_yaml_line(node);
-
-    if (line == NULL)
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-    else
-    {
-        result = pygobject_new(G_OBJECT(line));
-        g_object_unref(G_OBJECT(line));
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self    = contenu binaire à manipuler.                       *
 *                value   = collection de noeuds Yaml.                         *
 *                closure = adresse non utilisée ici.                          *
@@ -252,7 +204,6 @@ PyTypeObject *get_python_yaml_scalar_type(void)
     };
 
     static PyGetSetDef py_yaml_scalar_getseters[] = {
-        YAML_SCALAR_YAML_LINE_ATTRIB,
         YAML_SCALAR_COLLECTION_ATTRIB,
         { NULL }
     };
diff --git a/plugins/yaml/python/tree.c b/plugins/yaml/python/tree.c
index c23406a..c39c296 100644
--- a/plugins/yaml/python/tree.c
+++ b/plugins/yaml/python/tree.c
@@ -69,10 +69,10 @@ static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *
     int ret;                                /* Bilan de lecture des args.  */
     size_t count;                           /* Nombre d'éléments présents  */
     GYamlLine **lines;                      /* Lignes au format Yaml       */
+    GYamlTree *tree;                        /* Création GLib à transmettre */
     size_t i;                               /* Boucle de parcours #1       */
     PyObject *item;                         /* Elément de la liste fournie */
     size_t k;                               /* Boucle de parcours #2       */
-    GYamlTree *tree;                        /* Création GLib à transmettre */
 
 #define YAML_TREE_DOC                                                       \
     "YamlTree offers a hierarchical access to Yaml lines as a tree.\n"      \
@@ -90,6 +90,8 @@ static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *
 
     lines = (GYamlLine **)malloc(count * sizeof(GYamlLine *));
 
+    tree = NULL;
+
     for (i = 0; i < count; i++)
     {
         item = PyTuple_GetItem(tuple, i);
diff --git a/plugins/yaml/tree.c b/plugins/yaml/tree.c
index fd2cd8f..5db82ec 100644
--- a/plugins/yaml/tree.c
+++ b/plugins/yaml/tree.c
@@ -33,7 +33,7 @@
 #include <core/logs.h>
 
 
-#include "scalar.h"
+#include "pair.h"
 #include "collection.h"
 
 
@@ -184,10 +184,9 @@ GYamlTree *g_yaml_tree_new(GYamlLine **lines, size_t count)
 
     if (count > 0)
     {
-        result->root = G_YAML_NODE(g_yaml_scalar_new(NULL));
-
         collec = g_yaml_collection_new(g_yaml_line_is_list_item(lines[0]));
-        g_yaml_scalar_set_collection(G_YAML_SCALAR(result->root), collec);
+
+        result->root = G_YAML_NODE(collec);
 
         indent = g_yaml_line_count_indent(lines[0]);
         processed = 0;
@@ -234,7 +233,6 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
     size_t indent;                          /* Indentation de ligne        */
     bool is_item;                           /* Elément d'une liste ?       */
     GYamlCollection *sub;                   /* Nouvelle sous-collection    */
-    GYamlNode *glue;                        /* Noeud vide intermédiaire    */
 
     result = true;
 
@@ -254,7 +252,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
          *
          * L'objectif est de créer une simple association de 'clefs: valeurs'.
          *
-         * Si la collection n'est pas adapté, alors le parcours n'est pas encore
+         * Si la collection n'est pas adaptée, alors le parcours n'est pas encore
          * arrivé à ce stade de construction.
          */
         if (first && is_item && !g_yaml_collection_is_sequence(collec))
@@ -275,7 +273,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
             assert(last != NULL);
 
             sub = g_yaml_collection_new(is_item);
-            g_yaml_scalar_set_collection(G_YAML_SCALAR(last), sub);
+            g_yaml_pair_set_collection(G_YAML_PAIR(last), sub);
 
             result = g_yaml_tree_build_node(sub, lines, count, indent, cur);
             if (!result) goto done;
@@ -290,7 +288,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
                 /* Vérification de cohérence */
                 if (!g_yaml_collection_is_sequence(collec))
                 {
-                    log_variadic_message(LMT_BAD_BINARY, _("A mapping item was expected at line %zu"),
+                    log_variadic_message(LMT_BAD_BINARY, _("A list item was expected at line %zu"),
                                          g_yaml_line_get_number(line));
 
                     result = false;
@@ -298,11 +296,8 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
 
                 }
 
-                glue = G_YAML_NODE(g_yaml_scalar_new(NULL));
-                g_yaml_collection_add_node(collec, glue);
-
                 sub = g_yaml_collection_new(false);
-                g_yaml_scalar_set_collection(G_YAML_SCALAR(glue), sub);
+                g_yaml_collection_add_node(collec, G_YAML_NODE(sub));
 
                 result = g_yaml_tree_build_node(sub, lines, count, expected + 2 /* 2 == strlen("- ") */, cur);
                 if (!result) goto done;
@@ -314,7 +309,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
                 /* Vérification de cohérence */
                 if (g_yaml_collection_is_sequence(collec))
                 {
-                    log_variadic_message(LMT_BAD_BINARY, _("A list item was expected at line %zu"),
+                    log_variadic_message(LMT_BAD_BINARY, _("A mapping item was expected at line %zu"),
                                          g_yaml_line_get_number(line));
 
 
@@ -323,7 +318,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s
 
                 }
 
-                last = G_YAML_NODE(g_yaml_scalar_new(line));
+                last = G_YAML_NODE(g_yaml_pair_new(line));
                 g_yaml_collection_add_node(collec, last);
 
                 (*cur)++;
diff --git a/tests/plugins/yamlrdr.py b/tests/plugins/yamlrdr.py
index e09bb21..47f02ba 100644
--- a/tests/plugins/yamlrdr.py
+++ b/tests/plugins/yamlrdr.py
@@ -99,27 +99,35 @@ root:
             f.close()
 
 
-    def XXXtestSimpleYamlContent(self):
+    def testSimpleYamlContent(self):
         """Validate Yaml content readers."""
 
         def _build_node_desc(node, left, extra = ''):
 
-            line = node.yaml_line
+            if hasattr(node, 'key'):
+
+                line = node.yaml_line
 
-            if line:
                 prefix = '- ' if line.is_list_item else extra
                 desc = left + prefix + line.key + ':' + (' ' + line.value if line.value else '') + '\n'
                 indent = '  '
+
+                collec = node.collection
+
             else:
+
                 desc = ''
                 indent = ''
 
-            if node.collection:
+                if hasattr(node, 'nodes'):
+                    collec = node
+
+            if collec:
 
-                if node.collection.is_sequence:
+                if collec.is_sequence:
                     extra = '  '
 
-                for child in node.collection.nodes:
+                for child in collec.nodes:
                     desc += _build_node_desc(child, left + indent, extra)
 
             return desc
@@ -158,7 +166,7 @@ root:
         self.assertEqual('\n' + fulldesc + '\n', self._mixed_data.decode('ascii'))
 
 
-    def XXXtestSimpleYamlContentFinder(self):
+    def testSimpleYamlContentFinder(self):
         """Validate Yaml nested content search."""
 
         reader = YamlReader.new_from_path(self._nested.name)
@@ -169,7 +177,7 @@ root:
         self.assertEqual(len(found), 1)
 
         if len(found) == 1:
-            self.assertEqual(found[0].yaml_line.key, 'sub')
+            self.assertEqual(found[0].key, 'sub')
 
         found = reader.tree.find_by_path('/root/sub/')
 
@@ -184,7 +192,7 @@ root:
         self.assertEqual(len(found), 1)
 
         if len(found) == 1:
-            self.assertEqual(found[0].yaml_line.key, 'i')
+            self.assertEqual(found[0].key, 'i')
             self.assertEqual(found[0].yaml_line.is_list_item, True)
 
         found = reader.tree.find_by_path('/root/sub/cc')
@@ -201,7 +209,7 @@ root:
 
             if len(found) == 1:
 
-                self.assertEqual(found[0].yaml_line.key, 'i')
+                self.assertEqual(found[0].key, 'i')
                 self.assertEqual(found[0].yaml_line.is_list_item, True)
 
             found = root.find_by_path('/cc/i')
@@ -210,7 +218,7 @@ root:
 
             if len(found) == 1:
 
-                self.assertEqual(found[0].yaml_line.key, 'i')
+                self.assertEqual(found[0].key, 'i')
                 self.assertEqual(found[0].yaml_line.is_list_item, True)
 
             found = root.find_by_path('//i')
@@ -219,7 +227,7 @@ root:
 
             if len(found) == 1:
 
-                self.assertEqual(found[0].yaml_line.key, 'i')
+                self.assertEqual(found[0].key, 'i')
                 self.assertEqual(found[0].yaml_line.is_list_item, True)
 
 
@@ -234,7 +242,7 @@ root:
         self.assertEqual(len(found), 1)
 
         if len(found) == 1:
-            self.assertEqual(found[0].yaml_line.key, 'root')
+            self.assertEqual(found[0].key, 'root')
 
         found = reader.tree.find_by_path('/root/', True)
 
@@ -248,11 +256,11 @@ root:
 
             sub = found.find_one_by_path('/a')
             self.assertIsNotNone(sub)
-            self.assertEqual(sub.yaml_line.key, 'a')
+            self.assertEqual(sub.key, 'a')
 
             sub = found.find_one_by_path('/aa')
             self.assertIsNotNone(sub)
-            self.assertEqual(sub.yaml_line.key, 'aa')
+            self.assertEqual(sub.key, 'aa')
 
         found = reader.tree.find_by_path('/root/')
 
@@ -262,8 +270,8 @@ root:
 
             sub = found[0].find_one_by_path('/a')
             self.assertIsNotNone(sub)
-            self.assertEqual(sub.yaml_line.key, 'a')
+            self.assertEqual(sub.key, 'a')
 
             sub = found[0].find_one_by_path('/aa')
             self.assertIsNotNone(sub)
-            self.assertEqual(sub.yaml_line.key, 'aa')
+            self.assertEqual(sub.key, 'aa')
-- 
cgit v0.11.2-87-g4458