public InnerCNode getTree() throws CodegenRuntimeException {
        try {
            if (root == null) parse();
        } catch (DefParserException | IOException e) {
            throw new CodegenRuntimeException("Error parsing or reading config definition." + e.getMessage(), e);
        }
        return root;
    }
@Test
    void testTraverseTree() throws IOException {
        File defFile = new File(DEF_NAME);
        CNode root = new DefParser("test", new FileReader(defFile)).getTree();
        assertNotNull(root);
        CNode[] children = root.getChildren();
        assertEquals(38, children.length);

        int numGrandChildren = 0;
        int numGreatGrandChildren = 0;
        for (CNode child : children) {
            CNode[] childsChildren = child.getChildren();
            numGrandChildren += childsChildren.length;
            for (CNode grandChild : childsChildren) {
                numGreatGrandChildren += grandChild.getChildren().length;
            }
        }
        assertEquals(14, numGrandChildren);
        assertEquals(6, numGreatGrandChildren);

        // Verify that each array creates a sub-tree, and that defaults for leafs are handled correctly.
        CNode myArray = root.getChild("myArray");
        assertEquals(5, myArray.getChildren().length);
        // int within array
        LeafCNode myArrayInt = (LeafCNode) myArray.getChild("intVal");
        assertEquals("14", myArrayInt.getDefaultValue().getValue());
        // enum within array
        LeafCNode myArrayEnum = (LeafCNode) myArray.getChild("enumVal");
        assertEquals("TYPE", myArrayEnum.getDefaultValue().getValue());

        // Verify array within array and a default value for a leaf in the inner array.
        CNode anotherArray = myArray.getChild("anotherArray");
        assertEquals(1, anotherArray.getChildren().length);
        LeafCNode foo = (LeafCNode) anotherArray.getChild("foo");
        assertEquals("-4", foo.getDefaultValue().getValue());
    }