public void writeSlimeEncoder(Writer w, CNode node, String parent, boolean root) throws IOException
    {
        String indent = "    ";
        if (root) {
            w.write("void\n"
                    + parent + "serialize(::config::ConfigDataBuffer & __buffer) const\n"
                    + "{\n");
            w.write(indent + "vespalib::Slime & __slime(__buffer.slimeObject());\n");
            w.write(indent + "vespalib::slime::Cursor & __croot = __slime.setObject();\n");
            w.write(indent + "__croot.setDouble(\"version\", CONFIG_DEF_SERIALIZE_VERSION);\n");
            w.write(indent + "vespalib::slime::Cursor & __key = __croot.setObject(\"configKey\");\n");
            w.write(indent + "__key.setString(\"defName\", vespalib::Memory(CONFIG_DEF_NAME));\n");
            w.write(indent + "__key.setString(\"defNamespace\", vespalib::Memory(CONFIG_DEF_NAMESPACE));\n");
            w.write(indent + "__key.setString(\"defMd5\", vespalib::Memory(CONFIG_DEF_MD5));\n");
            w.write(indent + "vespalib::slime::Cursor & __keySchema =__key.setArray(\"defSchema\");\n");
            w.write(indent + "for (size_t i = 0; i < CONFIG_DEF_SCHEMA.size(); i++) {\n");
            w.write(indent + "    __keySchema.addString(vespalib::Memory(CONFIG_DEF_SCHEMA[i]));\n");
            w.write(indent + "}\n");
            w.write(indent + "vespalib::slime::Cursor & __cursor = __croot.setObject(\"configPayload\");\n");
        } else {
            w.write("void\n"
                    + parent + "serialize(vespalib::slime::Cursor & __cursor) const\n"
                    + "{\n");
        }
        for (CNode child : node.getChildren()) {
            String childName = getIdentifier(child.getName());
            String childType = getTypeName(child, false);
            w.write(indent + "{\n");
            indent = "        ";
            w.write(indent + "vespalib::slime::Cursor & __c = __cursor.setObject(\"" + child.getName() + "\");\n");
            if (child.isArray) {
                w.write(indent + "__c.setString(\"type\", \"array\");\n");
                w.write(indent + "vespalib::slime::Cursor & __c2 = __c.setArray(\"value\");\n");
                w.write(indent + "for (const auto & child : " + childName +") {\n");
                w.write(indent + "    vespalib::slime::Cursor & __c3 = __c2.addObject();\n");
                if (child instanceof LeafCNode.EnumLeaf) {
                    String repType = slimeTypeMap.get("enum");
                    w.write(indent + "    __c3.setString(\"type\", \"enum\");\n");
                    w.write(indent + "    __c3.set" + repType);
                    w.write("(\"value\", vespalib::Memory(get" + childType + "Name(child)));\n");
                } else if (child instanceof LeafCNode) {
                    String type = ((LeafCNode) child).getType();
                    String repType = slimeTypeMap.get(type);
                    w.write(indent + "    __c3.setString(\"type\", \"" + type + "\");\n");
                    w.write(indent + "    __c3.set" + repType);
                    if ("String".equals(repType)) {
                        w.write("(\"value\", vespalib::Memory(child));\n");
                    } else {
                        w.write("(\"value\", child);\n");
                    }
                } else {
                    w.write(indent + "    __c3.setString(\"type\", \"struct\");\n");
                    w.write(indent + "    Cursor & __c4 = __c3.setObject(\"value\");\n");
                    w.write(indent + "    child.serialize(__c4);\n");
                }
                w.write(indent + "}\n");
            } else if (child.isMap) {
                w.write(indent + "__c.setString(\"type\", \"map\");\n");
                w.write(indent + "vespalib::slime::Cursor & __c2 = __c.setArray(\"value\");\n");
                w.write(indent + "for (const auto & entry : " + childName + ") {\n");
                w.write(indent + "    vespalib::slime::Cursor & __c3 = __c2.addObject();\n");
                w.write(indent + "    __c3.setString(\"key\", vespalib::Memory(entry.first));\n");
                if (child instanceof LeafCNode.EnumLeaf) {
                    String repType = slimeTypeMap.get("enum");
                    w.write(indent + "    __c3.setString(\"type\", \"enum\");\n");
                    w.write(indent + "    __c3.set" + repType);
                    w.write("(\"value\", vespalib::Memory(get" + childType + "Name(entry.second)));\n");
                } else if (child instanceof LeafCNode) {
                    String type = ((LeafCNode) child).getType();
                    String repType = slimeTypeMap.get(type);
                    w.write(indent + "    __c3.setString(\"type\", \"" + type + "\");\n");
                    w.write(indent + "    __c3.set" + repType);
                    if ("String".equals(repType)) {
                        w.write("(\"value\", vespalib::Memory(entry.second));\n");
                    } else {
                        w.write("(\"value\", entry.second);\n");
                    }
                } else {
                    w.write(indent + "    __c3.setString(\"type\", \"struct\");\n");
                    w.write(indent + "    Cursor & __c4 = __c3.setObject(\"value\");\n");
                    w.write(indent + "    entry.second.serialize(__c4);\n");
                }
                w.write(indent + "}\n");
            } else {
                if (child instanceof LeafCNode.EnumLeaf) {
                    String repType = slimeTypeMap.get("enum");
                    w.write(indent + "__c.setString(\"type\", \"enum\");\n");
                    w.write(indent + "__c.set" + repType);
                    w.write("(\"value\", vespalib::Memory(get" + childType + "Name(" + childName + ")));\n");
                } else if (child instanceof LeafCNode) {
                    String type = ((LeafCNode) child).getType();
                    String repType = slimeTypeMap.get(type);
                    w.write(indent + "__c.setString(\"type\", \"" + type + "\");\n");
                    w.write(indent + "__c.set" + repType);
                    if ("String".equals(repType)) {
                        w.write("(\"value\", vespalib::Memory(" + childName + "));\n");
                    } else {
                        w.write("(\"value\", " + childName + ");\n");
                    }
                } else {
                    w.write(indent + "__c.setString(\"type\", \"struct\");\n");
                    w.write(indent + "Cursor & __c2 = __c.setObject(\"value\");\n");
                    w.write(indent + childName + ".serialize(__c2);\n");
                }
            }
            indent = "    ";
            w.write(indent + "}\n");

        }
        w.write("}\n\n");
    }
\n");
        do {
            String current;
            // Extract first line to write
            int newLine = comment.indexOf('\n');
            if (newLine == -1) {
                current = comment;
                comment = "";
            } else {
                current = comment.substring(0, newLine);
                comment = comment.substring(newLine + 1);
            }
            // If line too long, cut it in two
            if (current.length() > maxLineLen) {
                int spaceIndex = current.lastIndexOf(' ', maxLineLen);
                if (spaceIndex >= maxLineLen - 15) {
                    comment = current.substring(spaceIndex + 1)
                              + "\n" + comment;
                    current = current.substring(0, spaceIndex);
                } else {
                    comment = current.substring(maxLineLen) + "\n" + comment;
                    current = current.substring(0, maxLineLen) + "-";
                }
            }
            w.write(indent + (javadoc ? " * " : "// ") + current + "\n");
        } while (comment.length() > 0);
        if (javadoc) w.write(indent + "
configgen/src/main/java/com/yahoo/config/codegen/CppClassBuilder.java