[valadoc] Api: Refactor the API tree



commit 799c28e2ba8461a89f3a2771eddea1a828e99829
Author: Didier 'Ptitjes <ptitjes free fr>
Date:   Wed Oct 14 12:50:38 2009 +0200

    Api: Refactor the API tree

 src/doclets/htmlhelpers/deps/style.css             |    6 +-
 src/doclets/htmlhelpers/deps/wikistyle.css         |    2 +-
 src/doclets/htmlhelpers/doclet/langlet.vala        |    2 +-
 src/libvaladoc/Makefile.am                         |    5 +
 src/libvaladoc/apitree/apiitem.vala                |   48 ++++
 src/libvaladoc/apitree/apimembernode.vala          |   41 ++++
 src/libvaladoc/apitree/apinode.vala                |  154 +++++++++++++
 src/libvaladoc/apitree/apisymbolnode.vala          |  109 +++++++++
 src/libvaladoc/apitree/apitree.vala                |  119 +++-------
 src/libvaladoc/apitree/apitypesymbolnode.vala      |   41 ++++
 src/libvaladoc/apitree/array.vala                  |    6 +-
 src/libvaladoc/apitree/basic.vala                  |   21 +--
 src/libvaladoc/apitree/class.vala                  |  212 +-----------------
 src/libvaladoc/apitree/classhandler.vala           |   59 +-----
 src/libvaladoc/apitree/constant.vala               |   26 +--
 src/libvaladoc/apitree/constanthandler.vala        |   64 +-----
 .../apitree/constructionmethodhandler.vala         |   69 +------
 src/libvaladoc/apitree/delegate.vala               |   41 +---
 src/libvaladoc/apitree/delegatehandler.vala        |   64 +-----
 src/libvaladoc/apitree/documentedelement.vala      |   40 +---
 src/libvaladoc/apitree/enum.vala                   |  123 +---------
 src/libvaladoc/apitree/enumhandler.vala            |   58 +-----
 src/libvaladoc/apitree/enumvalue.vala              |   31 ++-
 src/libvaladoc/apitree/errorcode.vala              |   22 +-
 src/libvaladoc/apitree/errordomain.vala            |  123 ++---------
 src/libvaladoc/apitree/errordomainhandler.vala     |   70 +------
 src/libvaladoc/apitree/exceptionlisthandler.vala   |   30 +--
 src/libvaladoc/apitree/field.vala                  |   30 +--
 src/libvaladoc/apitree/fieldhandler.vala           |   70 +------
 src/libvaladoc/apitree/formalparameter.vala        |   28 +--
 src/libvaladoc/apitree/interface.vala              |  199 +----------------
 src/libvaladoc/apitree/interfacehandler.vala       |   56 +-----
 src/libvaladoc/apitree/method.vala                 |   69 ++----
 src/libvaladoc/apitree/methodhandler.vala          |   68 +------
 src/libvaladoc/apitree/namespace.vala              |  234 ++------------------
 src/libvaladoc/apitree/namespacehandler.vala       |   36 +---
 src/libvaladoc/apitree/package.vala                |   47 +---
 src/libvaladoc/apitree/parameterlisthandler.vala   |   29 +--
 src/libvaladoc/apitree/pointer.vala                |    8 +-
 src/libvaladoc/apitree/property.vala               |   31 +--
 src/libvaladoc/apitree/propertyaccessor.vala       |   53 +----
 src/libvaladoc/apitree/propertyhandler.vala        |   68 +------
 src/libvaladoc/apitree/returntypehandler.vala      |    7 +-
 src/libvaladoc/apitree/signal.vala                 |   31 +--
 src/libvaladoc/apitree/signalhandler.vala          |   67 +------
 src/libvaladoc/apitree/struct.vala                 |  130 +----------
 src/libvaladoc/apitree/structhandler.vala          |   57 +-----
 src/libvaladoc/apitree/symbolaccessibility.vala    |   32 +---
 .../apitree/templateparameterlisthandler.vala      |   38 +---
 src/libvaladoc/apitree/typeparameter.vala          |   28 +--
 src/libvaladoc/apitree/typereference.vala          |   22 +--
 src/libvaladoc/apitree/visitable.vala              |   34 +---
 .../documentation/documentationparser.vala         |   15 +-
 53 files changed, 780 insertions(+), 2293 deletions(-)
---
diff --git a/src/doclets/htmlhelpers/deps/style.css b/src/doclets/htmlhelpers/deps/style.css
index 660fe25..4bac34b 100644
--- a/src/doclets/htmlhelpers/deps/style.css
+++ b/src/doclets/htmlhelpers/deps/style.css
@@ -1,3 +1,7 @@
+* {
+	font-size: 12px;
+}
+
 ul.external_link {
 }
 
@@ -109,7 +113,7 @@ div.site_navigation {
 
 
 .site_content {
-	font-size: 10px;
+	font-size: 12px;
 	margin-left: 250px;
 	margin-right: 5px;
 	text-align: left;
diff --git a/src/doclets/htmlhelpers/deps/wikistyle.css b/src/doclets/htmlhelpers/deps/wikistyle.css
index fb01851..5990d11 100644
--- a/src/doclets/htmlhelpers/deps/wikistyle.css
+++ b/src/doclets/htmlhelpers/deps/wikistyle.css
@@ -105,7 +105,7 @@ div.site_navigation {
 
 
 .site_content {
-	font-size: 10px;
+	font-size: 12px;
 	margin-left: 5px;
 	margin-right: 5px;
 	text-align: left;
diff --git a/src/doclets/htmlhelpers/doclet/langlet.vala b/src/doclets/htmlhelpers/doclet/langlet.vala
index b73cb97..ae15252 100755
--- a/src/doclets/htmlhelpers/doclet/langlet.vala
+++ b/src/doclets/htmlhelpers/doclet/langlet.vala
@@ -190,7 +190,7 @@ public class Valadoc.Html.BasicLanglet : Valadoc.Langlet {
 		weak GLib.FileStream file = (GLib.FileStream)ptr;
 		bool open_bracket = false;
 
-		Gee.ArrayList<FormalParameter> params = thandler.param_list;
+		Gee.List<FormalParameter> params = thandler.param_list;
 		int size = params.size;
 		int i = 0;
 
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index 59b2aed..151fe5a 100644
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -33,7 +33,12 @@ libvaladoc_la_VALASOURCES = \
 	documentation/documentationparser.vala \
 	documentation/wiki.vala \
 	documentation/wikiscanner.vala \
+	apitree/apiitem.vala \
+	apitree/apimembernode.vala \
+	apitree/apinode.vala \
+	apitree/apisymbolnode.vala \
 	apitree/apitree.vala \
+	apitree/apitypesymbolnode.vala \
 	apitree/array.vala \
 	apitree/basic.vala \
 	apitree/class.vala \
diff --git a/src/libvaladoc/apitree/apiitem.vala b/src/libvaladoc/apitree/apiitem.vala
new file mode 100644
index 0000000..3121019
--- /dev/null
+++ b/src/libvaladoc/apitree/apiitem.vala
@@ -0,0 +1,48 @@
+/* apiitem.vala
+ *
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008 Florian Brosch
+ * 
+ * This program 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 2
+ * of the License.
+ * 
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+using Vala;
+using GLib;
+using Gee;
+using Valadoc.Content;
+
+public abstract class Valadoc.Api.Item : Object {
+	public Valadoc.Settings settings {
+		protected get;
+		set;
+	}
+
+	public Basic parent {
+		protected set;
+		get;
+	}
+
+	// TODO rename root
+	public Tree head {
+		protected set;
+		get;
+	}
+
+	protected virtual void resolve_type_references () {
+	}
+
+	protected virtual void parse_comments (DocumentationParser parser) {
+	}
+}
diff --git a/src/libvaladoc/apitree/apimembernode.vala b/src/libvaladoc/apitree/apimembernode.vala
new file mode 100644
index 0000000..4b8aa64
--- /dev/null
+++ b/src/libvaladoc/apitree/apimembernode.vala
@@ -0,0 +1,41 @@
+/* apitypesymbolnode.vala
+ * 
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * 
+ * This program 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 2
+ * of the License.
+ * 
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Author:
+ * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
+ */
+
+using Vala;
+using Gee;
+
+public abstract class Valadoc.Api.MemberNode : Api.SymbolNode {
+
+	public MemberNode (Settings settings, Vala.Member symbol, Api.Node parent, Tree root) {
+		base (settings, symbol, parent, root);
+	}
+
+	protected override void parse_comments (DocumentationParser parser) {
+		var source_comment = ((Vala.Member) symbol).comment;
+		if (source_comment != null) {
+			documentation = parser.parse (this, source_comment);
+		}
+
+		base.parse_comments (parser);
+	}
+}
diff --git a/src/libvaladoc/apitree/apinode.vala b/src/libvaladoc/apitree/apinode.vala
new file mode 100644
index 0000000..825d43a
--- /dev/null
+++ b/src/libvaladoc/apitree/apinode.vala
@@ -0,0 +1,154 @@
+/* apinode.vala
+ * 
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * 
+ * This program 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 2
+ * of the License.
+ * 
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Author:
+ * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
+ */
+
+using Vala;
+using Gee;
+
+public enum Valadoc.Api.NodeType {
+	CLASS,
+	CONSTANT,
+	CREATION_METHOD,
+	DELEGATE,
+	ENUM,
+	ENUM_VALUE,
+	ERROR_CODE,
+	ERROR_DOMAIN,
+	FIELD,
+	FORMAL_PARAMETER,
+	INTERFACE,
+	METHOD,
+	NAMESPACE,
+	PACKAGE,
+	PROPERTY,
+	PROPERTY_ACCESSOR,
+	SIGNAL,
+	STRUCT,
+	TYPE_PARAMETER
+}
+
+// TODO Drop DocumentedElement
+public abstract class Valadoc.Api.Node : /*Api.Item*/DocumentedElement, Visitable {
+
+	// TODO Drop DocumentElement
+	/* public abstract string? name { owned get; } */
+
+	public abstract NodeType node_type { get; }
+
+	private Map<string,Node> per_name_children;
+	private Map<Symbol,Node> per_symbol_children;
+	private Map<NodeType?,Gee.List<Node>> per_type_children;
+
+	public Node (Settings settings, Api.Node? parent, Tree root) {
+		this.settings = settings;
+		this.parent = parent;
+		this.head = root;
+
+		per_name_children = new HashMap<string,Node> ();
+		per_symbol_children = new HashMap<Symbol,Node> ();
+		per_type_children = new HashMap<NodeType?,Gee.List<Node>> (int_hash, int_equal);
+	}
+
+	public abstract void accept (Doclet doclet);
+
+	protected abstract bool is_type_visitor_accessible (Valadoc.Basic element);
+
+	public abstract bool is_visitor_accessible ();
+
+	public override string? get_filename () {
+		return null;
+	}
+
+	protected void add_child (SymbolNode child) {
+		if (child.name != null) {
+			per_name_children.set (child.name, child);
+		} else {
+			// Special case for the root namespace
+			per_name_children.set ("", child);
+		}
+
+		per_symbol_children.set (child.symbol, child);
+
+		Gee.List<Node> children = per_type_children.get (child.node_type);
+		if (children == null) {
+			per_type_children.set (child.node_type, new ArrayList<Node> ());
+		}
+
+		children = per_type_children.get (child.node_type);
+		children.add (child);
+	}
+
+	protected override void resolve_type_references () {
+		foreach (Node node in per_name_children.values) {
+			node.resolve_type_references ();
+		}
+	}
+
+	protected override void parse_comments (DocumentationParser parser) {
+		// TODO check is visitable to avoid unuseful processing
+
+		foreach (Node node in per_name_children.values) {
+			node.parse_comments (parser);
+		}
+	}
+
+	public Gee.List<Node> get_children_by_type (NodeType type) {
+		var children = new ArrayList<Node> ();
+
+		Gee.List<Node> all_children = per_type_children.get (type);
+		if (all_children != null) {
+			foreach (Node child in all_children) {
+				if (!child.is_type_visitor_accessible (this))
+					continue ;
+
+				children.add (child);
+			}
+		}
+
+		return children.read_only_view;
+	}
+
+	public void accept_children_by_type (NodeType type, Doclet doclet) {
+		Gee.List<Node> all_children = per_type_children.get (type);
+		if (all_children != null) {
+			foreach (Node node in all_children) {
+				node.accept (doclet);
+			}
+		}
+	}
+
+	public void accept_children (NodeType[] types, Doclet doclet) {
+		foreach (NodeType type in types) {
+			accept_children_by_type (type, doclet);
+		}
+	}
+
+	public Node? find_by_name (string name) {
+		return per_name_children.get (name);
+	}
+
+	public Node? find_by_symbol (Symbol symbol) {
+		return per_symbol_children.get (symbol);
+	}
+
+	
+}
diff --git a/src/libvaladoc/apitree/apisymbolnode.vala b/src/libvaladoc/apitree/apisymbolnode.vala
new file mode 100644
index 0000000..f6d7061
--- /dev/null
+++ b/src/libvaladoc/apitree/apisymbolnode.vala
@@ -0,0 +1,109 @@
+/* apisymbolnode.vala
+ * 
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * 
+ * This program 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 2
+ * of the License.
+ * 
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Author:
+ * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
+ */
+
+using Vala;
+using Gee;
+
+public abstract class Valadoc.Api.SymbolNode : Api.Node, SymbolAccessibility {
+
+	protected Vala.Symbol symbol { private set; get; }
+	// TODO Drop DocumentedElement
+	/* protected Vala.Comment vcomment { private set; get; } */
+
+	public override string? name {
+		owned get {
+			return symbol.name;
+		}
+	}
+
+	public SymbolNode (Settings settings, Vala.Symbol symbol, Api.Node parent, Tree root) {
+		base (settings, parent, root);
+		this.symbol = symbol;
+	}
+
+	public override string? get_filename () {
+		SourceReference? sref = symbol.source_reference;
+		if ( sref == null )
+			return null;
+
+		Vala.SourceFile? file = sref.file;
+		if ( file == null )
+			return null;
+
+		string path = sref.file.filename;
+		return GLib.Path.get_basename ( path );
+	}
+
+	protected override bool is_type_visitor_accessible (Valadoc.Basic element) {
+		if (!this.settings._private && is_private)
+			return false;
+
+		if (!this.settings._internal && is_internal)
+			return false;
+
+		if (!this.settings._protected && is_protected)
+			return false;
+
+		if (this.parent != element && !this.settings.add_inherited)
+				return false;
+
+		return true;
+	}
+
+	public override bool is_visitor_accessible () {
+		if (!this.settings._private && this.is_private)
+			return false;
+
+		if (!this.settings._internal && this.is_internal)
+			return false;
+
+		if (!this.settings._protected && this.is_protected)
+			return false;
+
+		return true;
+	}
+
+	public bool is_public {
+		get {
+			return symbol.access == Vala.SymbolAccessibility.PUBLIC;
+		}
+	}
+
+	public bool is_protected {
+		get {
+			return symbol.access == Vala.SymbolAccessibility.PROTECTED;
+		}
+	}
+
+	public bool is_internal {
+		get {
+			return symbol.access == Vala.SymbolAccessibility.INTERNAL;
+		}
+	}
+
+	public bool is_private {
+		get {
+			return symbol.access == Vala.SymbolAccessibility.PRIVATE;
+		}
+	}
+}
diff --git a/src/libvaladoc/apitree/apitree.vala b/src/libvaladoc/apitree/apitree.vala
index ec7c7f1..c48d9d2 100644
--- a/src/libvaladoc/apitree/apitree.vala
+++ b/src/libvaladoc/apitree/apitree.vala
@@ -60,101 +60,41 @@ public class Valadoc.Tree : Vala.CodeVisitor {
 		doclet.initialisation ( this.settings, this );
 	}
 
-	private DocumentedElement? search_symbol_in_type ( DocumentedElement element, string[] params, int params_offset = 0 ) {
-		string[] nparams = null;
-		if ( params[0] != "this" ) {
-			nparams = new string[ params.length+1 ];
-			nparams[0] = "this";
-			for ( int i = 0; params.length > i ; i++ ) {
-				nparams [i+1] = params[i];
+	private Api.Node? search_relative_to (Api.Node element, string[] path) {
+		Api.Node? node = element;
+		foreach (string name in path) {
+			node = node.find_by_name (name);
+			if (node == null) {
+				break;
 			}
-		} else {
-			nparams = params;
 		}
 
-		return this.search_symbol_in_symbol (element, nparams, 0);
-	}
-
-	private DocumentedElement? search_symbol_in_symbol ( DocumentedElement element, string[] params, int params_offset = 0 ) {
-		if ( element is Class || element is Interface || element is Struct ) {
-			return element.search_element ( params, params_offset );
-		}
-		else if ( element is Enum ) {
-			return element.search_element ( params, params_offset );
+		if (node == null && element.parent != null) {
+			node = search_relative_to ((Api.Node) element.parent, path);
 		}
-		else if ( element is ErrorDomain ) {
-			return element.search_element ( params, params_offset );
-		}
-		return null;
-	}
-
-	private DocumentedElement? search_symbol_in_global_namespaces ( DocumentedElement? element, string[] params ) {
-		int param_size = 0;
-		for ( param_size = 0; params[param_size] != null; param_size++ );
 
-		string[] global_params = new string[param_size +1];
-
-		global_params[0] = null;
-		for ( int i = 0; params[i-1] != null ; i++ ) {
-			global_params[i+1] = params[i];
-		}
-
-		foreach ( Package pkg in this.packages ) {
-			DocumentedElement? element2 = pkg.search_element ( global_params, 0 );
-			if ( element2 != null )
-				return element2;
-		}
-		return null;
+		return node;
 	}
 
-	private DocumentedElement? search_symbol_in_namespaces ( DocumentedElement? element, string[] params ) {
-		foreach ( Package pkg in this.packages ) {
-			DocumentedElement? element2 = pkg.search_element ( params, 0 );
-			if ( element2 != null )
-				return element2;
-		}
-		return null;
-	}
-
-	private DocumentedElement? search_element ( DocumentedElement? element, string[] params ) {
-		if (element is Field || element is Method || element is Delegate
-		    || element is Signal || element is Property || element is Constant) {
-		    element = (DocumentedElement) element.parent;
-		}
+	public DocumentedElement? search_symbol_str (DocumentedElement? element, string symname) {
+		string[] path = split_name (symname);
 
-		if ( element != null ) {
-			if ( params[0] == "this" ) {
-				return search_symbol_in_type ( element, params, 1 );
+		if (element == null) {
+			Api.Node? node = null;
+			foreach (Package packgage in packages) {
+				node = search_relative_to (packgage, path);
+				if (node != null) {
+					return (DocumentedElement) node;
+				}
 			}
-
-			var tmp = search_symbol_in_type ( element, params );
-			if ( tmp != null )
-				return tmp;
+			return null;
 		}
 
-		var tmp = search_symbol_in_global_namespaces ( element, params );
-		if ( tmp != null )
-			return tmp;
-
-		tmp = this.search_symbol_in_namespaces ( element, params );
-		if ( tmp != null )
-			return tmp;
-
-		return null;
+		return (DocumentedElement) search_relative_to ((Api.Node) element, path);
 	}
 
-	public DocumentedElement? search_symbol_str ( DocumentedElement? element, string symname ) {
-		var result = this.search_element (element, split_name (symname));
-		while (result == null && element.parent != null) {
-			var parent_name = element.name;
-			result = this.search_element ( element, split_name (parent_name + "." + symname) );
-			element = (DocumentedElement) element.parent;
-		}
-		return result;
-	}
-
-	private string[] split_name (string symname) {
-		string[] params = symname.split( ".", -1 );
+	private string[] split_name (string full_name) {
+		string[] params = full_name.split( ".", -1 );
 		int i = 0; while ( params[i] != null ) i++;
 		params.length = i;
 		return params;
@@ -452,7 +392,7 @@ public class Valadoc.Tree : Vala.CodeVisitor {
 		}
 
 		this.context.accept(this);
-		this.set_type_references ();
+		this.resolve_type_references ();
 		this.add_dependencies_to_source_package ();
 		return true;
 	}
@@ -465,9 +405,9 @@ public class Valadoc.Tree : Vala.CodeVisitor {
 		return null;
 	}
 
-	private void set_type_references ( ) {
+	private void resolve_type_references () {
 		foreach (Package pkg in this.packages) {
-			pkg.set_type_references( );
+			pkg.resolve_type_references();
 		}
 	}
 
@@ -504,7 +444,14 @@ public class Valadoc.Tree : Vala.CodeVisitor {
 		Vala.SourceFile vfile = vnode.source_reference.file;
 		Package file = this.find_file(vfile);
 
-		return file.search_element_vala (params, 0);
+		Api.Node? node = file;
+		foreach (Symbol symbol in params) {
+			node = node.find_by_symbol (symbol);
+			if (node == null) {
+				return null;
+			}
+		}
+		return node;
 	}
 
 	private Package? get_external_package_by_name (string name) {
diff --git a/src/libvaladoc/apitree/apitypesymbolnode.vala b/src/libvaladoc/apitree/apitypesymbolnode.vala
new file mode 100644
index 0000000..149f173
--- /dev/null
+++ b/src/libvaladoc/apitree/apitypesymbolnode.vala
@@ -0,0 +1,41 @@
+/* apitypesymbolnode.vala
+ * 
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * 
+ * This program 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 2
+ * of the License.
+ * 
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Author:
+ * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
+ */
+
+using Vala;
+using Gee;
+
+public abstract class Valadoc.Api.TypeSymbolNode : Api.SymbolNode {
+
+	public TypeSymbolNode (Settings settings, Vala.TypeSymbol symbol, Api.Node parent, Tree root) {
+		base (settings, symbol, parent, root);
+	}
+
+	protected override void parse_comments (DocumentationParser parser) {
+		var source_comment = ((Vala.TypeSymbol) symbol).comment;
+		if (source_comment != null) {
+			documentation = parser.parse (this, source_comment);
+		}
+
+		base.parse_comments (parser);
+	}
+}
diff --git a/src/libvaladoc/apitree/array.vala b/src/libvaladoc/apitree/array.vala
index 55c1fde..fdc1c60 100644
--- a/src/libvaladoc/apitree/array.vala
+++ b/src/libvaladoc/apitree/array.vala
@@ -52,11 +52,11 @@ public class Valadoc.Array : Basic {
 		if ( this.data_type == null )
 			/*TODO:possible?*/;
 		else if ( this.data_type is Array )
-			((Array)this.data_type).set_type_references ();
+			((Array)this.data_type).resolve_type_references ();
 		else if ( this.data_type is Pointer )
-			((Pointer)this.data_type).set_type_references ();
+			((Pointer)this.data_type).resolve_type_references ();
 		else
-			((TypeReference)this.data_type).set_type_references ();
+			((TypeReference)this.data_type).resolve_type_references ();
 	}
 }
 
diff --git a/src/libvaladoc/apitree/basic.vala b/src/libvaladoc/apitree/basic.vala
index c350dc5..8abd511 100644
--- a/src/libvaladoc/apitree/basic.vala
+++ b/src/libvaladoc/apitree/basic.vala
@@ -22,25 +22,6 @@ using GLib;
 using Gee;
 
 
-public abstract class Valadoc.Basic : Object {
-	public Valadoc.Settings settings {
-		protected get;
-		set;
-	}
-
-	public Basic parent {
-		set;
-		get;
-	}
-
-	public Tree head {
-		set;
-		get;
-	}
-
-	protected Vala.Symbol vsymbol {
-		protected get;
-		set;
-	}
+public abstract class Valadoc.Basic : Api.Item {
 }
 
diff --git a/src/libvaladoc/apitree/class.vala b/src/libvaladoc/apitree/class.vala
index 858ceca..3ca2f57 100644
--- a/src/libvaladoc/apitree/class.vala
+++ b/src/libvaladoc/apitree/class.vala
@@ -23,22 +23,15 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable, ClassHandler, StructHandler, SignalHandler, MethodHandler, EnumHandler, PropertyHandler, ConstructionMethodHandler, FieldHandler, DelegateHandler, ConstantHandler, TemplateParameterListHandler {
+public class Valadoc.Class : Api.TypeSymbolNode, ClassHandler, StructHandler, SignalHandler, MethodHandler, EnumHandler, PropertyHandler, ConstructionMethodHandler, FieldHandler, DelegateHandler, ConstantHandler, TemplateParameterListHandler {
 	private Gee.ArrayList<Interface> interfaces;
-	private bool inherited = false;
 	private Vala.Class vclass;
 
-	public Class ( Valadoc.Settings settings, Vala.Class vclass, ClassHandler parent, Tree head ) {
-		this.template_param_lst = new Gee.ArrayList<TypeParameter> ();
+	public Class (Valadoc.Settings settings, Vala.Class symbol, ClassHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 		this.interfaces = new Gee.ArrayList<Interface>();
-		this.methods = new Gee.ArrayList<Method> ();
 
-		this.vcomment = vclass.comment;
-		this.settings = settings;
-		this.vsymbol = vclass;
-		this.vclass = vclass;
-		this.parent = parent;
-		this.head = head;
+		this.vclass = symbol;
 
 		if ( glib_error == null ) {
 			if ( this.full_name () == "GLib.Error" ) {
@@ -50,39 +43,30 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		this.set_template_parameter_list ( vtparams );
 
 		Gee.Collection<Vala.Enum> venums = this.vclass.get_enums ();
-		this.enums = new Gee.ArrayList<Enum> ();
 		this.add_enums ( venums );
 
 		Gee.Collection<Vala.Delegate> vdelegates = this.vclass.get_delegates ();
-		this.delegates = new Gee.ArrayList<Delegate> ();
 		this.add_delegates ( vdelegates );
 
 		Gee.Collection<Vala.Class> vclasses = this.vclass.get_classes();
-		this.classes = new Gee.ArrayList<Class> ();
 		this.add_classes ( vclasses );
 
 		Gee.Collection<Vala.Struct> vstructs = this.vclass.get_structs();
-		this.structs = new Gee.ArrayList<Struct> ();
 		this.add_structs ( vstructs );
 
 		Gee.Collection<Vala.Field> vfields = this.vclass.get_fields();
-		this.fields = new Gee.ArrayList<Field> ();
 		this.add_fields ( vfields );
 
 		Gee.Collection<Vala.Method> vmethods = this.vclass.get_methods ();
-		this.construction_methods = new Gee.ArrayList<Method>();
 		this.add_methods_and_construction_methods ( vmethods );
 
 		Gee.Collection<Vala.Signal> vsignals = this.vclass.get_signals();
-		this.signals = new Gee.ArrayList<Signal>();
 		this.add_signals ( vsignals );
 
 		Gee.Collection<Vala.Property> vproperties = this.vclass.get_properties();
-		this.properties = new Gee.ArrayList<Property>();
 		this.add_properties ( vproperties );
 
 		Gee.Collection<Vala.Constant> vconstants = this.vclass.get_constants();
-		this.constants = new Gee.ArrayList<Constant>();
 		this.add_constants ( vconstants );
 	}
 
@@ -91,61 +75,6 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		get;
 	}
 
-	protected Gee.ArrayList<TypeParameter> template_param_lst {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> methods {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Delegate> delegates {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Enum> enums {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Field> fields {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> construction_methods {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Property> properties {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Class> classes {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Struct> structs {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Signal> signals {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Constant> constants {
-		get;
-		set;
-	}
-
 	public string? get_cname () {
 		return this.vclass.get_cname();
 	}
@@ -154,105 +83,6 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		return this.interfaces;
 	}
 
-	internal override DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos];
-
-		if ( velement is Vala.Class == false )
-			return null;
-
-		if ( !this.is_vclass( (Vala.Class)velement ) )
-			return null;
-
-		if ( params.size == pos+1 )
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if ( velement is Vala.Field ) {
-			element = this.search_field_vala ( params, pos );
-		}
-		else if ( velement is Vala.Method ) {
-			element = this.search_method_vala ( params, pos );
-		}
-		else if ( velement is Vala.Delegate ) {
-			element = this.search_delegate_vala ( params, pos );
-		}
-		else if ( velement is Vala.CreationMethod ) {
-			element = this.search_construction_method_vala ( params, pos );
-		}
-		else if ( velement is Vala.Signal ) {
-			element = this.search_signal_vala ( params, pos );
-		}
-		else if ( velement is Vala.Property ) {
-			element = this.search_property_vala ( params, pos );
-		}
-		else if ( velement is Vala.Struct ) {
-			element = this.search_struct_vala ( params, pos );
-		}
-		else if ( velement is Vala.Class ) {
-			element = this.search_class_vala ( params, pos );
-		}
-		else if ( velement is Vala.Enum ) {
-			element = this.search_enum_vala ( params, pos );
-		}
-		else if ( velement is Vala.Constant ) {
-			element = this.search_constant_vala ( params, pos );
-		}
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( !(this.name == params[pos] || params[0] == "this") )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-		DocumentedElement? element = this.search_field ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_delegate ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_construction_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_signal ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_property ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_struct ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_class ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_enum ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_constant ( params, pos );
-		if ( element != null )
-			return element;
-
-		return null;
-	}
-
 	internal bool is_vclass ( Vala.Class vcl ) {
 		return this.vclass == vcl;
 	}
@@ -274,24 +104,10 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		doclet.visit_class ( this );
 	}
 
-	internal void parse_comments ( DocumentationParser docparser ) {
-		if ( this.documentation != null )
-			return ;
-
-		if ( this.vcomment != null ) {
-			this.parse_comment_helper ( docparser );
-		}
+	public override Api.NodeType node_type { get { return Api.NodeType.CLASS; } }
 
-		this.parse_construction_method_comments ( docparser );
-		this.parse_delegate_comments ( docparser );
-		this.parse_constant_comments ( docparser );
-		this.parse_property_comments ( docparser );
-		this.parse_method_comments ( docparser );
-		this.parse_struct_comments ( docparser );
-		this.parse_signal_comments ( docparser );
-		this.parse_class_comments ( docparser );
-		this.parse_field_comments ( docparser );
-		this.parse_enum_comments ( docparser );
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
 	private void set_parent_type_references ( Gee.Collection<Vala.DataType> lst ) {
@@ -309,21 +125,11 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		}
 	}
 
-	internal void set_type_references ( ) {
+	protected override void resolve_type_references () {
 		var lst = this.vclass.get_base_types ();
 		this.set_parent_type_references ( lst );
 
-		this.set_template_parameter_list_references ( );
-		this.set_construction_method_references ( );
-		this.set_constant_type_references ( );
-		this.set_delegate_type_references ( );
-		this.set_property_type_references ( );
-		this.set_method_type_references ( );
-		this.set_signal_type_references ( );
-		this.set_field_type_references ( );
-		this.set_enum_type_references ( );
-		this.set_struct_type_references ( );
-		this.set_class_type_references ( );
+		base.resolve_type_references ( );
 	}
 }
 
diff --git a/src/libvaladoc/apitree/classhandler.vala b/src/libvaladoc/apitree/classhandler.vala
index a93ad26..fef2f9d 100644
--- a/src/libvaladoc/apitree/classhandler.vala
+++ b/src/libvaladoc/apitree/classhandler.vala
@@ -17,38 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.ClassHandler : Basic {
-	protected abstract Gee.ArrayList<Class> classes {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_class_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		foreach ( Class cl in this.classes ) {
-			DocumentedElement? element = cl.search_element_vala ( params, pos+1 );
-			if ( element != null )
-				return element;			
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_class ( string[] params, int pos ) {
-		foreach ( Class cl in this.classes ) {
-			DocumentedElement? element = cl.search_element ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
+public interface Valadoc.ClassHandler : Api.Node {
 	protected Class? find_vclass ( Vala.Class vcl ) {
-		foreach ( Class cl in this.classes ) {
+		foreach ( Class cl in get_class_list () ) {
 			if ( cl.is_vclass ( vcl ) )
 				return cl;
 
@@ -60,20 +35,12 @@ public interface Valadoc.ClassHandler : Basic {
 	}
 
 	public Gee.Collection<Class> get_class_list ( ) {
-		var lst = new Gee.ArrayList<Class> ();
-		foreach ( Class cl in this.classes ) {
-			if ( !cl.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( cl );
-		}
-
-		return lst.read_only_view;
+		return get_children_by_type (Api.NodeType.CLASS);
 	}
 
 	internal void add_class ( Vala.Class vcl ) {
 		Class cl = new Class ( this.settings, vcl, this, this.head );
-		this.classes.add ( cl );
+		add_child ( cl );
 	}
 
 	public void add_classes ( Gee.Collection<Vala.Class> vclasses ) {
@@ -82,23 +49,7 @@ public interface Valadoc.ClassHandler : Basic {
 		}
 	}
 
-
 	public void visit_classes ( Doclet doclet ) {
-		foreach ( Class cl in this.get_class_list() ) {
-			cl.visit ( doclet );
-		}
-	}
-
-	protected void set_class_type_references ( ) {
-		foreach ( Class cl in this.classes ) {
-			cl.set_type_references ();
-		}
-	}
-
-	protected void parse_class_comments ( DocumentationParser docparser ) {
-		foreach ( Class cl in this.classes ) {
-			cl.parse_comments ( docparser );
-		}
+		accept_children_by_type (Api.NodeType.CLASS, doclet);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/constant.vala b/src/libvaladoc/apitree/constant.vala
index 1f74294..eb667f1 100644
--- a/src/libvaladoc/apitree/constant.vala
+++ b/src/libvaladoc/apitree/constant.vala
@@ -23,7 +23,7 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Constant : DocumentedElement, SymbolAccessibility, Visitable, ReturnTypeHandler {
+public class Valadoc.Constant : Api.MemberNode, ReturnTypeHandler {
 	private Vala.Constant vconst;
 
 	public TypeReference? type_reference {
@@ -35,13 +35,9 @@ public class Valadoc.Constant : DocumentedElement, SymbolAccessibility, Visitabl
 		return ( this.vconst == vconst );
 	}
 
-	public Constant ( Valadoc.Settings settings, Vala.Constant vconst, ConstantHandler parent, Tree head ) {
-		this.vcomment = vconst.comment;
-		this.settings = settings;
-		this.vsymbol = vconst;
-		this.vconst = vconst;
-		this.parent = parent;
-		this.head = head;
+	public Constant (Valadoc.Settings settings, Vala.Constant symbol, ConstantHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vconst = symbol;
 
 		var vret = this.vconst.type_reference;
 		this.set_ret_type ( vret );
@@ -51,12 +47,8 @@ public class Valadoc.Constant : DocumentedElement, SymbolAccessibility, Visitabl
 		return this.vconst.get_cname ();
 	}
 
-	internal void set_type_references ( ) {
-		((ReturnTypeHandler)this).set_return_type_references ( );
-	}
-
-	internal void parse_comment ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
+	protected override void resolve_type_references () {
+		this.set_return_type_references ( );
 	}
 
 	public void visit ( Doclet doclet, ConstantHandler? parent ) {
@@ -66,6 +58,12 @@ public class Valadoc.Constant : DocumentedElement, SymbolAccessibility, Visitabl
 		doclet.visit_constant ( this, parent );
 	}
 
+	public override Api.NodeType node_type { get { return Api.NodeType.CONSTANT; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet, (ConstantHandler) parent);
+	}
+
 	public void write ( Langlet langlet, void* ptr, ConstantHandler parent ) {
 		langlet.write_constant ( this, parent, ptr );
 	}
diff --git a/src/libvaladoc/apitree/constanthandler.vala b/src/libvaladoc/apitree/constanthandler.vala
index 6caa948..fc11201 100644
--- a/src/libvaladoc/apitree/constanthandler.vala
+++ b/src/libvaladoc/apitree/constanthandler.vala
@@ -23,51 +23,9 @@ using GLib;
 using Gee;
 
 
-public interface Valadoc.ConstantHandler : Basic {
-	protected abstract Gee.ArrayList<Constant> constants {
-		protected set;
-		get;
-	}
-
-	protected DocumentedElement? search_constant_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Constant == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Constant c in this.constants ) {
-			if ( c.is_vconstant ( (Vala.Constant)velement ) ) {
-				return c;
-			}
-		}
-		return null;
-	}
-
-	internal DocumentedElement? search_constant ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Constant c in this.constants ) {
-			if ( c.name == params[pos] )
-				return c;
-		}
-		return null;
-	}
-
+public interface Valadoc.ConstantHandler : Api.Node {
 	public Gee.Collection<Constant> get_constant_list ( ) {
-		var lstd = new Gee.ArrayList<Constant> ();
-		foreach (Constant c in this.constants) {
-			if (!c.is_type_visitor_accessible (this) )
-				continue ;
-
-			lstd.add (c);
-		}
-
-		return lstd.read_only_view;
+		return get_children_by_type (Api.NodeType.CONSTANT);
 	}
 
 	internal void add_constants (Gee.Collection<Vala.Constant> vconstants) {
@@ -78,25 +36,11 @@ public interface Valadoc.ConstantHandler : Basic {
 
 	internal void add_constant (Vala.Constant vc) {
 		var tmp = new Constant (this.settings, vc, this, this.head);
-		this.constants.add ( tmp );
-	}
-
-	internal void set_constant_type_references ( ) {
-		foreach ( Constant c in this.constants ) {
-			c.set_type_references ( );
-		}
-	}
-
-	internal void parse_constant_comments ( DocumentationParser docparser ) {
-		foreach ( Constant c in this.constants ) {
-			c.parse_comment ( docparser );
-		}
+		add_child ( tmp );
 	}
 
 	public void visit_constants ( Doclet doclet ) {
-		foreach ( Constant c in this.get_constant_list() ) {
-			c.visit ( doclet, this );
-		}
+		accept_children_by_type (Api.NodeType.CONSTANT, doclet);
 	}
 }
 
diff --git a/src/libvaladoc/apitree/constructionmethodhandler.vala b/src/libvaladoc/apitree/constructionmethodhandler.vala
index efe336e..b1d5c10 100644
--- a/src/libvaladoc/apitree/constructionmethodhandler.vala
+++ b/src/libvaladoc/apitree/constructionmethodhandler.vala
@@ -24,78 +24,17 @@ using Gee;
 
 
 public interface Valadoc.ConstructionMethodHandler : Basic, MethodHandler {
-	protected abstract Gee.ArrayList<Method> construction_methods {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_construction_method_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Method == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Method m in this.methods ) {
-			if ( m.is_vmethod ( (Vala.Method)velement ) ) {
-				return m;
-			}
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_construction_method ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] == null )
-			return null;
-
-		if ( params[pos+2] != null )
-			return null;
-
-		string name = params[pos] + "." + params[pos+1];
-
-		foreach ( Method m in this.construction_methods ) {
-			if ( m.name == name )
-				return m;
-		}
-		return null;
-	}
-
-	public Gee.Collection<Method> get_construction_method_list ( ) {
-		var lst = new Gee.ArrayList<Method> ();
-		foreach ( Method cm in this.construction_methods ) {
-			if ( !cm.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( cm );
-		}
-
-		return lst.read_only_view;
-	}
-
-	protected void parse_construction_method_comments ( DocumentationParser docparser ) {
-		foreach ( Method cm in this.construction_methods ) {
-			cm.parse_comment ( docparser );
-		}
-	}
-
-	protected void set_construction_method_references ( ) {
-		foreach ( Method cm in this.construction_methods ) {
-			cm.set_type_references ( );
-		}
+	public Gee.Collection<Method> get_construction_method_list () {
+		return get_children_by_type (Api.NodeType.CREATION_METHOD);
 	}
 
 	public void visit_construction_methods ( Doclet doclet ) {
-		foreach ( Method m in this.get_construction_method_list() ) {
-			m.visit ( doclet, this );
-		}
+		accept_children_by_type (Api.NodeType.CREATION_METHOD, doclet);
 	}
 
 	protected void add_construction_method ( Vala.CreationMethod vm ) {
 		var tmp = new Method ( this.settings, vm, this, this.head );
-		this.construction_methods.add ( tmp );
+		add_child ( tmp );
 	}
 
 	protected void add_methods_and_construction_methods ( Gee.Collection<Vala.Method> vmethods ) {
diff --git a/src/libvaladoc/apitree/delegate.vala b/src/libvaladoc/apitree/delegate.vala
index 9e46310..d2a113e 100644
--- a/src/libvaladoc/apitree/delegate.vala
+++ b/src/libvaladoc/apitree/delegate.vala
@@ -23,20 +23,13 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Delegate : DocumentedElement, SymbolAccessibility, Visitable, ParameterListHandler, ReturnTypeHandler, TemplateParameterListHandler, ExceptionHandler {
+public class Valadoc.Delegate : Api.TypeSymbolNode, ParameterListHandler, ReturnTypeHandler, TemplateParameterListHandler, ExceptionHandler {
 	private Vala.Delegate vdelegate;
 
-	public Delegate ( Valadoc.Settings settings, Vala.Delegate vdelegate, DelegateHandler parent, Tree head ) {
-		this.template_param_lst = new Gee.ArrayList<TypeParameter> ();
-		this.param_list = new Gee.ArrayList<FormalParameter>();
-		this.err_domains = new Gee.ArrayList<DocumentedElement>();
+	public Delegate (Valadoc.Settings settings, Vala.Delegate symbol, DelegateHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 
-		this.vcomment = vdelegate.comment;
-		this.settings = settings;
-		this.vdelegate = vdelegate;
-		this.vsymbol = vdelegate;
-		this.parent = parent;
-		this.head = head;
+		this.vdelegate = symbol;
 
 		var ret = this.vdelegate.return_type;
 		this.set_ret_type ( ret );
@@ -61,19 +54,10 @@ public class Valadoc.Delegate : DocumentedElement, SymbolAccessibility, Visitabl
 		doclet.visit_delegate ( this );
 	}
 
-	public Gee.ArrayList<TypeParameter> template_param_lst {
-		protected set;
-		get;
-	}
+	public override Api.NodeType node_type { get { return Api.NodeType.DELEGATE; } }
 
-	protected Gee.ArrayList<FormalParameter> param_list {
-		protected set;
-		get;
-	}
-
-	protected Gee.ArrayList<DocumentedElement> err_domains {
-		protected set;
-		get;
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
 	public bool is_static {
@@ -82,22 +66,13 @@ public class Valadoc.Delegate : DocumentedElement, SymbolAccessibility, Visitabl
 		}
 	}
 
-	internal void set_type_references ( ) {
+	protected override void resolve_type_references () {
 		this.set_return_type_references ( );
-		this.set_parameter_list_type_references ( );
 
 		var vexceptionlst = this.vdelegate.get_error_types ();
 		this.add_exception_list ( vexceptionlst );
 	}
 
-	internal void parse_comment ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-	}
-
-	internal bool is_vdelegate (Vala.Delegate vdel) {
-		return (this.vdelegate == vdel);
-	}
-
 	public void write (Langlet langlet, void* ptr) {
 		langlet.write_delegate (this, ptr);
 	}
diff --git a/src/libvaladoc/apitree/delegatehandler.vala b/src/libvaladoc/apitree/delegatehandler.vala
index cf98391..a4ac4f4 100644
--- a/src/libvaladoc/apitree/delegatehandler.vala
+++ b/src/libvaladoc/apitree/delegatehandler.vala
@@ -17,60 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.DelegateHandler : Basic {
-	protected abstract Gee.ArrayList<Delegate> delegates {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_delegate_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Delegate == false )
-			return null;
-
-		foreach ( Delegate del in this.delegates ) {
-			if ( del.is_vdelegate ( (Vala.Delegate)velement ) ) {
-				return del;
-			}
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_delegate ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Delegate del in this.delegates ) {
-			if ( del.name == params[pos] )
-				return del;
-		}
-		return null;
-	}
-
+public interface Valadoc.DelegateHandler : Api.Node {
 	public Gee.Collection<Delegate> get_delegate_list ( ) {
-		var lst = new Gee.ArrayList<Delegate> ();
-		foreach ( Delegate del in this.delegates ) {
-			if ( !del.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( del );
-		}
-
-		return lst.read_only_view;
+		return get_children_by_type (Api.NodeType.DELEGATE);
 	}
 
 	public void visit_delegates ( Doclet doclet ) {
-		foreach ( Delegate del in this.delegates ) {
-			del.visit ( doclet );
-		}
+		accept_children_by_type (Api.NodeType.DELEGATE, doclet);
 	}
 
 	public void add_delegates ( Gee.Collection<Vala.Delegate> vdels ) {
@@ -81,19 +38,6 @@ public interface Valadoc.DelegateHandler : Basic {
 
 	public void add_delegate ( Vala.Delegate vdel ) {
 		var tmp = new Delegate ( this.settings, vdel, this, this.head );
-		this.delegates.add ( tmp );
-	}
-
-	public void set_delegate_type_references ( ) {
-		foreach ( Delegate del in this.delegates ) {
-			del.set_type_references ( );
-		}
-	}
-
-	public void parse_delegate_comments ( DocumentationParser docparser ) {
-		foreach ( Delegate del in this.delegates ) {
-			del.parse_comment ( docparser );
-		}
+		add_child ( tmp );
 	}
 }
-
diff --git a/src/libvaladoc/apitree/documentedelement.vala b/src/libvaladoc/apitree/documentedelement.vala
index db94184..20f34e6 100644
--- a/src/libvaladoc/apitree/documentedelement.vala
+++ b/src/libvaladoc/apitree/documentedelement.vala
@@ -29,6 +29,8 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 	private string _full_name = null;
 	private int _line = -1;
 
+	public abstract string? name { owned get; }
+
 	public Namespace? nspace {
 		get {
 			if (this._nspace == null) {
@@ -59,7 +61,7 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 			return this._package;
 		}
 	}
-
+/*
 	public int line {
 		get {
 			if (this._line == -1) {
@@ -69,22 +71,13 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 			return this._line;
 		}
 	}
-
-	protected Vala.Comment vcomment {
-		get; set;
-	}
+*/
 
 	public Content.Comment? documentation {
 		protected set;
 		get;
 	}
 
-	public virtual string? name {
-		owned get {
-			return this.vsymbol.name;
-		}
-	}
-
 	// rename to get_full_name
 	public string? full_name () {
 		if (this._full_name == null) {
@@ -107,29 +100,6 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 		return this._full_name;
 	}
 
-	public string? get_filename () {
-		SourceReference? sref = this.vsymbol.source_reference;
-		if ( sref == null )
-			return null;
-
-		Vala.SourceFile? file = sref.file;
-		if ( file == null )
-			return null;
-
-		string path = sref.file.filename;
-		return GLib.Path.get_basename ( path );
-	}
-
-	protected void parse_comment_helper ( DocumentationParser docparser ) {
-		this.documentation = docparser.parse ( this );
-	}
-
-	internal virtual DocumentedElement? search_element ( string[] params, int pos ) {
-		return null;
-	}
-
-	internal virtual DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> list, int pos ) {
-		return null;
-	}
+	public abstract string? get_filename ();
 }
 
diff --git a/src/libvaladoc/apitree/enum.vala b/src/libvaladoc/apitree/enum.vala
index f798d2f..563a01c 100644
--- a/src/libvaladoc/apitree/enum.vala
+++ b/src/libvaladoc/apitree/enum.vala
@@ -23,23 +23,15 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Enum : DocumentedElement, SymbolAccessibility, Visitable, MethodHandler {
-	private Gee.ArrayList<EnumValue> en_values;
-
-	public Enum ( Valadoc.Settings settings, Vala.Enum venum, EnumHandler parent, Tree head ) {
-		this.vcomment = venum.comment;
-		this.settings = settings;
-		this.vsymbol = venum;
-		this.venum = venum;
-		this.parent = parent;
-		this.head = head;
+public class Valadoc.Enum : Api.TypeSymbolNode, MethodHandler {
+	public Enum (Valadoc.Settings settings, Vala.Enum symbol, EnumHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.venum = symbol;
 
 		Gee.Collection<Vala.Method> vmethods = this.venum.get_methods ();
-		this.methods = new Gee.ArrayList<Method> ();
 		this.add_methods ( vmethods );
 
 		Gee.Collection<Vala.EnumValue> venvals = this.venum.get_values ();
-		this.en_values = new Gee.ArrayList<EnumValue> ();
 		this.add_enum_values ( venvals );
 	}
 
@@ -47,113 +39,20 @@ public class Valadoc.Enum : DocumentedElement, SymbolAccessibility, Visitable, M
 		return this.venum.get_cname();
 	}
 
-	private DocumentedElement? search_enum_value_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.EnumValue == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( EnumValue env in this.en_values ) {
-			if ( env.is_venumvalue ( (Vala.EnumValue)velement ) ) {
-				return env;
-			}
-		}
-		return null;
-	}
-
-	private DocumentedElement? search_enum_value ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( EnumValue enval in this.en_values ) {
-			if ( enval.name == params[pos] )
-				return enval;
-		}
-		return null;
-	}
-
-	internal override DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos];
-
-		if ( velement is Vala.Enum == false )
-			return null;
-
-		if ( this.is_venum ( (Vala.Enum)velement ) == false )
-			return null;
-
-		if ( params.size == pos+1 )
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if ( velement is Vala.EnumValue ) {
-			element = this.search_enum_value_vala ( params, pos );
-		}
-		else if ( velement is Vala.Method ) {
-			element = this.search_method_vala ( params, pos );
-		}
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( this.name != params[pos] )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-
-		DocumentedElement? element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_enum_value ( params, pos );
-		if ( element != null )
-			return element;
-
-		return null;
-	}
-
-	internal void set_type_references () {
-		this.set_method_type_references ();
-	}
-
-	protected Gee.ArrayList<Method> methods {
-		protected set;
-		get;
-	}
-
 	// rename: get_enum_value_list
 	public Gee.Collection<EnumValue> get_enum_values () {
-		return this.en_values.read_only_view;
-	}
-
-	internal void parse_comments ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-
-		foreach ( EnumValue enval in this.en_values ) {
-			enval.parse_comment ( docparser );
-		}
-
-		this.parse_method_comments ( docparser );
+		return get_children_by_type (Api.NodeType.ENUM_VALUE);
 	}
 
 	private inline void add_enum_values ( Gee.Collection<Vala.EnumValue> venvals ) {
 		foreach ( Vala.EnumValue venval in venvals ) {
 			var tmp = new EnumValue ( this.settings, venval, this, this.head );
-			this.en_values.add ( tmp );
+			add_child ( tmp );
 		}
 	}
 
 	public void visit_enum_values ( Doclet doclet ) {
-		foreach ( EnumValue enval in this.en_values )
-			enval.visit ( doclet );
+		accept_children_by_type (Api.NodeType.ENUM_VALUE, doclet);
 	}
 
 	public void visit ( Doclet doclet ) {
@@ -163,12 +62,14 @@ public class Valadoc.Enum : DocumentedElement, SymbolAccessibility, Visitable, M
 		doclet.visit_enum ( this );
 	}
 
-	private Vala.Enum venum;
+	public override Api.NodeType node_type { get { return Api.NodeType.ENUM; } }
 
-	internal bool is_venum ( Vala.Enum ven ) {
-		return ( this.venum == ven );
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
+	private Vala.Enum venum;
+
 	public void write ( Langlet langlet, void* ptr ) {
 		langlet.write_enum ( this, ptr );
 	}
diff --git a/src/libvaladoc/apitree/enumhandler.vala b/src/libvaladoc/apitree/enumhandler.vala
index 03b3974..89bd17e 100644
--- a/src/libvaladoc/apitree/enumhandler.vala
+++ b/src/libvaladoc/apitree/enumhandler.vala
@@ -17,58 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.EnumHandler : Basic {
-	protected abstract Gee.ArrayList<Enum> enums {
-		set;
-		get;
-	}
-
-	protected void set_enum_type_references ( ) {
-		foreach ( Enum en in this.enums ) {
-			en.set_type_references ( );
-		}
-	}
-
-	protected DocumentedElement? search_enum_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		foreach ( Enum en in this.enums ) {
-			DocumentedElement element = en.search_element_vala ( params, pos+1 );
-			if ( element != null )
-				return element;			
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_enum ( string[] params, int pos ) {
-		foreach ( Enum en in this.enums ) {
-			DocumentedElement element = en.search_element ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
-	public Gee.Collection<Enum> get_enum_list ( ) {
-		var lst = new Gee.ArrayList<Enum> ();
-		foreach ( Enum en in this.enums ) {
-			if ( !en.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( en );
-		}
-
-		return lst.read_only_view;
+public interface Valadoc.EnumHandler : Api.Node {
+	public Gee.Collection<Enum> get_enum_list () {
+		return get_children_by_type (Api.NodeType.ENUM);
 	}
 
 	public void visit_enums ( Doclet doclet ) {
-		foreach ( Enum en in this.enums ) {
-			en.visit( doclet );
-		}
+		accept_children_by_type (Api.NodeType.ENUM, doclet);
 	}
 
 	public void add_enums ( Gee.Collection<Vala.Enum> venums ) {
@@ -79,13 +38,6 @@ public interface Valadoc.EnumHandler : Basic {
 
 	public void add_enum ( Vala.Enum venum ) {
 		Enum tmp = new Enum ( this.settings, venum, this, this.head );
-		this.enums.add( tmp );
-	}
-
-	protected void parse_enum_comments ( DocumentationParser docparser ) {
-		foreach ( Enum en in this.enums ) {
-			en.parse_comments ( docparser );
-		}
+		add_child (tmp);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/enumvalue.vala b/src/libvaladoc/apitree/enumvalue.vala
index e7f4053..fbdded9 100644
--- a/src/libvaladoc/apitree/enumvalue.vala
+++ b/src/libvaladoc/apitree/enumvalue.vala
@@ -23,16 +23,21 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.EnumValue: DocumentedElement {
+public class Valadoc.EnumValue: Api.SymbolNode {
 	private Vala.EnumValue venval;
 
-	public EnumValue ( Valadoc.Settings settings, Vala.EnumValue venval, Enum parent, Tree head ) {
-		this.vcomment = venval.comment;
-		this.settings = settings;
-		this.vsymbol = venval;
-		this.venval = venval;
-		this.parent = parent;
-		this.head = head;
+	public EnumValue (Valadoc.Settings settings, Vala.EnumValue symbol, Enum parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.venval = symbol;
+	}
+
+	protected override void parse_comments (DocumentationParser parser) {
+		var source_comment = ((Vala.EnumValue) symbol).comment;
+		if (source_comment != null) {
+			documentation = parser.parse (this, source_comment);
+		}
+
+		base.parse_comments (parser);
 	}
 
 	public string get_cname () {
@@ -43,10 +48,6 @@ public class Valadoc.EnumValue: DocumentedElement {
 		return ( this.venval == venval );
 	}
 
-	public void parse_comment ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-	}
-
 	public void write ( Langlet langlet, void* ptr ) {
 		langlet.write_enum_value ( this, ptr );
 	}
@@ -54,5 +55,11 @@ public class Valadoc.EnumValue: DocumentedElement {
 	public void visit ( Doclet doclet ) {
 		doclet.visit_enum_value ( this );
 	}
+
+	public override Api.NodeType node_type { get { return Api.NodeType.ENUM_VALUE; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
 }
 
diff --git a/src/libvaladoc/apitree/errorcode.vala b/src/libvaladoc/apitree/errorcode.vala
index 29d38ab..a524883 100644
--- a/src/libvaladoc/apitree/errorcode.vala
+++ b/src/libvaladoc/apitree/errorcode.vala
@@ -23,16 +23,12 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.ErrorCode : DocumentedElement {
+public class Valadoc.ErrorCode : Api.TypeSymbolNode {
 	private Vala.ErrorCode verrcode;
 
-	public ErrorCode ( Valadoc.Settings settings, Vala.ErrorCode verrcode, ErrorDomain parent, Tree head ) {
-		this.vcomment = verrcode.comment;
-		this.settings = settings;
-		this.verrcode = verrcode;
-		this.vsymbol = verrcode;
-		this.parent = parent;
-		this.head = head;
+	public ErrorCode (Valadoc.Settings settings, Vala.ErrorCode symbol, ErrorDomain parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.verrcode = symbol;
 	}
 
 	public string get_cname () {
@@ -47,12 +43,14 @@ public class Valadoc.ErrorCode : DocumentedElement {
 		langlet.write_error_code ( this, ptr );
 	}
 
-	public void parse_comment ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-	}
-
 	public void visit ( Doclet doclet ) {
 		doclet.visit_error_code ( this );
 	}
+
+	public override Api.NodeType node_type { get { return Api.NodeType.ERROR_CODE; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
 }
 
diff --git a/src/libvaladoc/apitree/errordomain.vala b/src/libvaladoc/apitree/errordomain.vala
index 71794f6..283de0c 100644
--- a/src/libvaladoc/apitree/errordomain.vala
+++ b/src/libvaladoc/apitree/errordomain.vala
@@ -23,20 +23,14 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.ErrorDomain : DocumentedElement, SymbolAccessibility, Visitable, MethodHandler {
-	private Gee.ArrayList<ErrorCode> errcodes = new Gee.ArrayList<ErrorCode> ();
+public class Valadoc.ErrorDomain : Api.TypeSymbolNode, MethodHandler {
 	private Vala.ErrorDomain verrdom;
 
-	public ErrorDomain ( Valadoc.Settings settings, Vala.ErrorDomain verrdom, ErrorDomainHandler parent, Tree head ) {
-		this.vcomment = verrdom.comment;
-		this.settings = settings;
-		this.vsymbol = verrdom;
-		this.verrdom = verrdom;
-		this.parent = parent;
-		this.head = head;
+	public ErrorDomain (Valadoc.Settings settings, Vala.ErrorDomain symbol, ErrorDomainHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.verrdom = symbol;
 
 		Gee.Collection<Vala.Method> vmethods = this.verrdom.get_methods ();
-		this.methods = new Gee.ArrayList<Method> ();
 		this.add_methods ( vmethods );
 
 		Gee.Collection<Vala.ErrorCode> verrcodes = this.verrdom.get_codes ();
@@ -47,103 +41,12 @@ public class Valadoc.ErrorDomain : DocumentedElement, SymbolAccessibility, Visit
 		return this.verrdom.get_cname();
 	}
 
-	protected Gee.ArrayList<Method> methods {
-		protected set;
-		get;
-	}
-
-	internal bool is_verrordomain ( Vala.ErrorDomain ver ) {
-		return ( this.verrdom == ver );
-	}
-
-	private DocumentedElement? search_error_code ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( ErrorCode errcode in this.errcodes ) {
-			if ( errcode.name == params[pos] )
-				return errcode;
-		}
-		return null;
-	}
-
-	private DocumentedElement? search_error_code_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.ErrorCode == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( ErrorCode errc in this.errcodes ) {
-			if ( errc.is_verrorcode ( (Vala.ErrorCode)velement ) ) {
-				return errc;
-			}
-		}
-		return null;
-	}
-
-	internal override DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos];
-
-		if ( velement is Vala.ErrorDomain == false )
-			return null;
-
-		if ( !this.is_verrordomain ( (Vala.ErrorDomain)velement ) )
-			return null;
-
-		if ( params.size == pos+1 )
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if ( velement is Vala.ErrorCode ) {
-			element = this.search_error_code_vala ( params, pos );
-		}
-		else if ( velement is Vala.Method ) {
-			element = this.search_method_vala ( params, pos );
-		}
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( this.name != params[pos] )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-		DocumentedElement? element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_error_code ( params, pos );
-		if ( element != null )
-			return element;
-
-		return null;
-	}
-
-	internal void parse_comments ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-		this.parse_method_comments ( docparser );
-
-		foreach ( ErrorCode errcode in this.errcodes ) {
-			errcode.parse_comment ( docparser );
-		}
-	}
-
 	public void visit_error_codes ( Doclet doclet ) {
-		foreach ( ErrorCode errcode in this.errcodes )
-			errcode.visit ( doclet );
+		accept_children_by_type (Api.NodeType.ERROR_CODE, doclet);
 	}
 
-	public Gee.Collection<ErrorCode> get_error_code_list ( ) {
-		return this.errcodes.read_only_view;
+	public Gee.Collection<ErrorCode> get_error_code_list () {
+		return get_children_by_type (Api.NodeType.ERROR_CODE);
 	}
 
 	public void visit ( Doclet doclet ) {
@@ -153,6 +56,12 @@ public class Valadoc.ErrorDomain : DocumentedElement, SymbolAccessibility, Visit
 		doclet.visit_error_domain ( this );
 	}
 
+	public override Api.NodeType node_type { get { return Api.NodeType.ERROR_DOMAIN; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
+
 	public void write ( Langlet langlet, void* ptr ) {
 		langlet.write_error_domain ( this, ptr );
 	}
@@ -160,12 +69,8 @@ public class Valadoc.ErrorDomain : DocumentedElement, SymbolAccessibility, Visit
 	private inline void append_error_code ( Gee.Collection<Vala.ErrorCode> verrcodes ) {
 		foreach ( Vala.ErrorCode verrcode in verrcodes ) {
 			var tmp = new ErrorCode ( this.settings, verrcode, this, this.head );
-			this.errcodes.add ( tmp );
+			add_child ( tmp );
 		}
 	}
-
-	internal void set_type_references ( ) {
-		this.set_method_type_references ( );
-	}
 }
 
diff --git a/src/libvaladoc/apitree/errordomainhandler.vala b/src/libvaladoc/apitree/errordomainhandler.vala
index 6a8f391..168e5e0 100644
--- a/src/libvaladoc/apitree/errordomainhandler.vala
+++ b/src/libvaladoc/apitree/errordomainhandler.vala
@@ -17,63 +17,20 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.ErrorDomainHandler : Basic {
-	protected abstract Gee.ArrayList<ErrorDomain> errdoms {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_error_domain_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			DocumentedElement? element = errdom.search_element_vala ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_error_domain ( string[] params, int pos ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			DocumentedElement? element = errdom.search_element ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
-	public Gee.Collection<ErrorDomain> get_error_domain_list ( ) {
-		var lst = new Gee.ArrayList<ErrorDomain> ();
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			if ( !errdom.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( errdom );
-		}
-
-		return lst.read_only_view;
-	}
-
-	internal ErrorDomain? find_errordomain ( Vala.ErrorDomain ver ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			if ( errdom.is_verrordomain( ver ) )
-				return errdom;
-		}
-		return null;
+public interface Valadoc.ErrorDomainHandler : Api.Node {
+	public Gee.Collection<ErrorDomain> get_error_domain_list () {
+		return get_children_by_type (Api.NodeType.ERROR_DOMAIN);
 	}
 
-	public void visit_error_domains ( Doclet doclet ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			errdom.visit ( doclet );
-		}
+	public void visit_error_domains (Doclet doclet) {
+		accept_children_by_type (Api.NodeType.ERROR_DOMAIN, doclet);
 	}
 
-	public void add_error_domains ( Gee.Collection<Vala.ErrorDomain> verrdoms ) {
+	public void add_error_domains (Gee.Collection<Vala.ErrorDomain> verrdoms) {
 		foreach ( Vala.ErrorDomain verrdom in  verrdoms ) {
 			this.add_error_domain ( verrdom );
 		}
@@ -81,19 +38,6 @@ public interface Valadoc.ErrorDomainHandler : Basic {
 
 	public void add_error_domain ( Vala.ErrorDomain verrdom ) {
 		var tmp = new ErrorDomain ( this.settings, verrdom, this, this.head );
-		this.errdoms.add ( tmp );
-	}
-
-	protected void set_errordomain_type_referenes ( ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			errdom.set_type_references ( );
-		}
-	}
-
-	protected void parse_errordomain_comments ( DocumentationParser docparser ) {
-		foreach ( ErrorDomain errdom in this.errdoms ) {
-			errdom.parse_comments ( docparser );
-		}
+		add_child ( tmp );
 	}
 }
-
diff --git a/src/libvaladoc/apitree/exceptionlisthandler.vala b/src/libvaladoc/apitree/exceptionlisthandler.vala
index 7c3a15a..71736d4 100644
--- a/src/libvaladoc/apitree/exceptionlisthandler.vala
+++ b/src/libvaladoc/apitree/exceptionlisthandler.vala
@@ -17,33 +17,25 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
 // rename to ExceptionListHandler
-public interface Valadoc.ExceptionHandler : Basic {
-	protected abstract Gee.ArrayList<DocumentedElement> err_domains {
-		protected set;
-		get;
-	}
+public interface Valadoc.ExceptionHandler : Api.Node {
 
-	public Gee.Collection<DocumentedElement> get_error_domains ( ) {
-		return this.err_domains.read_only_view;
+	public Gee.Collection<DocumentedElement> get_error_domains () {
+		return get_children_by_type (Api.NodeType.ERROR_DOMAIN);
 	}
 
-	public void add_exception_list ( Gee.Collection<Vala.DataType> vexceptions ) {
-		foreach ( Vala.DataType vtype in vexceptions  ) {
-				if ( ((Vala.ErrorType)vtype).error_domain == null ) {
-					this.err_domains.add ( glib_error );
-				}
-				else {
-					ErrorDomain type = (ErrorDomain)this.head.search_vala_symbol ( ((Vala.ErrorType)vtype).error_domain );
-					this.err_domains.add ( type );
-				}
+	public void add_exception_list (Gee.Collection<Vala.DataType> vexceptions) {
+		foreach (Vala.DataType vtype in vexceptions) {
+			if (((Vala.ErrorType) vtype).error_domain == null) {
+				add_child ( glib_error );
+			} else {
+				ErrorDomain type = (ErrorDomain) this.head.search_vala_symbol (((Vala.ErrorType) vtype).error_domain);
+				add_child (type);
+			}
 		}
 	}
 }
-
diff --git a/src/libvaladoc/apitree/field.vala b/src/libvaladoc/apitree/field.vala
index 80f51f4..646fc7e 100644
--- a/src/libvaladoc/apitree/field.vala
+++ b/src/libvaladoc/apitree/field.vala
@@ -23,25 +23,17 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Field : DocumentedElement, SymbolAccessibility, ReturnTypeHandler, Visitable {
+public class Valadoc.Field : Api.MemberNode, ReturnTypeHandler {
 	private Vala.Field vfield;
 
-	public Field ( Valadoc.Settings settings, Vala.Field vfield, FieldHandler parent, Tree head ) {
-		this.vcomment = vfield.comment;
-		this.settings = settings;
-		this.vsymbol = vfield;
-		this.vfield = vfield;
-		this.parent = parent;
-		this.head = head;
+	public Field (Valadoc.Settings settings, Vala.Field symbol, FieldHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vfield = symbol;
 
 		var vret = this.vfield.field_type;
 		this.set_ret_type ( vret );
 	}
 
-	internal bool is_vfield ( Vala.Field vfield ) {
-		return ( this.vfield == vfield );
-	}
-
 	public string? get_cname () {
 		return this.vfield.get_cname();
 	}
@@ -66,12 +58,10 @@ public class Valadoc.Field : DocumentedElement, SymbolAccessibility, ReturnTypeH
 		}
 	}
 
-	internal void set_type_references ( ) {
-		((ReturnTypeHandler)this).set_return_type_references ( );
-	}
+	protected override void resolve_type_references () {
+		this.set_return_type_references ();
 
-	internal void parse_comment ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
+		base.resolve_type_references ();
 	}
 
 	public void visit ( Doclet doclet, FieldHandler? parent ) {
@@ -81,6 +71,12 @@ public class Valadoc.Field : DocumentedElement, SymbolAccessibility, ReturnTypeH
 		doclet.visit_field ( this, parent );
 	}
 
+	public override Api.NodeType node_type { get { return Api.NodeType.FIELD; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet, (FieldHandler) parent);
+	}
+
 	public void write ( Langlet langlet, void* ptr, FieldHandler parent ) {
 		langlet.write_field ( this, parent, ptr );
 	}
diff --git a/src/libvaladoc/apitree/fieldhandler.vala b/src/libvaladoc/apitree/fieldhandler.vala
index 5474af7..0b867bb 100644
--- a/src/libvaladoc/apitree/fieldhandler.vala
+++ b/src/libvaladoc/apitree/fieldhandler.vala
@@ -17,57 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.FieldHandler : Basic {
-	protected abstract Gee.ArrayList<Field> fields {
-		protected set;
-		get;
-	}
-
-	protected DocumentedElement? search_field_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Field == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Field f in this.fields ) {
-			if ( f.is_vfield ( (Vala.Field)velement ) ) {
-				return f;
-			}
-		}
-		return null;
-	}
-
-	internal DocumentedElement? search_field ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Field f in this.fields ) {
-			if ( f.name == params[pos] )
-				return f;
-		}
-		return null;
-	}
-
+public interface Valadoc.FieldHandler : Api.Node {
 	public Gee.Collection<Field> get_field_list ( ) {
-		var lstd = new Gee.ArrayList<Field> ();
-		foreach ( Field f in this.fields ) {
-			if ( !f.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lstd.add ( f );
-		}
-
-		return lstd.read_only_view;
+		return get_children_by_type (Api.NodeType.FIELD);
 	}
 
 	internal void add_fields ( Gee.Collection<Vala.Field> vfields ) {
@@ -77,29 +33,11 @@ public interface Valadoc.FieldHandler : Basic {
 	}
 
 	internal void add_field ( Vala.Field vf ) {
-		//if ( vf.generated == true )
-		//	return ;
-
 		var tmp = new Field ( this.settings, vf, this, this.head );
-		this.fields.add ( tmp );
-	}
-
-	internal void set_field_type_references ( ) {
-		foreach ( Field field in this.fields ) {
-			field.set_type_references ( );
-		}
-	}
-
-	internal void parse_field_comments ( DocumentationParser docparser ) {
-		foreach ( Field field in this.fields ) {
-			field.parse_comment ( docparser );
-		}
+		add_child ( tmp );
 	}
 
 	public void visit_fields ( Doclet doclet ) {
-		foreach ( Field field in this.get_field_list() ) {
-			field.visit ( doclet, this );
-		}
+		accept_children_by_type (Api.NodeType.FIELD, doclet);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/formalparameter.vala b/src/libvaladoc/apitree/formalparameter.vala
index 948c0af..4887a1c 100644
--- a/src/libvaladoc/apitree/formalparameter.vala
+++ b/src/libvaladoc/apitree/formalparameter.vala
@@ -17,21 +17,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public class Valadoc.FormalParameter : Basic, ReturnTypeHandler {
+public class Valadoc.FormalParameter : Api.SymbolNode, ReturnTypeHandler {
 	private Vala.FormalParameter vformalparam;
 
-	public FormalParameter ( Valadoc.Settings settings, Vala.FormalParameter vformalparam, Basic parent, Tree head ) {
-		this.settings = settings;
-		this.vformalparam = vformalparam;
-		this.vsymbol = vformalparam;
-		this.parent = parent;
-		this.head = head;
+	public FormalParameter (Valadoc.Settings settings, Vala.FormalParameter symbol, ParameterListHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vformalparam = symbol;
 
 		var vformparam = this.vformalparam.parameter_type;
 		this.set_ret_type ( vformparam );
@@ -66,17 +61,18 @@ public class Valadoc.FormalParameter : Basic, ReturnTypeHandler {
 		}
 	}
 
-	public string? name {
-		owned get {
-			return ( this.vformalparam.name == null )? "" : this.vformalparam.name;
-		}
+	public override Api.NodeType node_type { get { return Api.NodeType.FORMAL_PARAMETER; } }
+
+	public override void accept (Doclet doclet) {
 	}
 
-	internal void set_type_references ( ) {
-		if ( this.vformalparam.ellipsis )
+	protected override void resolve_type_references () {
+		if (this.vformalparam.ellipsis)
 			return ;
 
-		((ReturnTypeHandler)this).set_return_type_references ( );
+		this.set_return_type_references ();
+
+		base.resolve_type_references ();
 	}
 
 	public void write ( Langlet langlet, void* ptr ) {
diff --git a/src/libvaladoc/apitree/interface.vala b/src/libvaladoc/apitree/interface.vala
index 6f0a532..f078674 100644
--- a/src/libvaladoc/apitree/interface.vala
+++ b/src/libvaladoc/apitree/interface.vala
@@ -23,55 +23,39 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Interface : DocumentedElement, SymbolAccessibility, Visitable, SignalHandler, PropertyHandler, FieldHandler, ConstantHandler, TemplateParameterListHandler, MethodHandler, DelegateHandler, EnumHandler, StructHandler, ClassHandler {
-	public Interface (Valadoc.Settings settings, Vala.Interface vinterface, InterfaceHandler parent, Tree head) {
-		this.vcomment = vinterface.comment;
-		this.settings = settings;
-		this.vinterface = vinterface;
-		this.vsymbol = vinterface;
-		this.parent = parent;
-		this.head = head;
-
-		this.template_param_lst = new Gee.ArrayList<TypeParameter> ();
-		this.methods = new Gee.ArrayList<Method> ();
+public class Valadoc.Interface : Api.TypeSymbolNode, SignalHandler, PropertyHandler, FieldHandler, ConstantHandler, TemplateParameterListHandler, MethodHandler, DelegateHandler, EnumHandler, StructHandler, ClassHandler {
+	public Interface (Valadoc.Settings settings, Vala.Interface symbol, InterfaceHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vinterface = symbol;
 
 		var vtparams = this.vinterface.get_type_parameters ();
 		this.set_template_parameter_list (vtparams);
 
 		Gee.Collection<Vala.Method> methods = this.vinterface.get_methods ();
-		this.methods = new Gee.ArrayList<Method>();
 		this.add_methods (methods);
 
 		Gee.Collection<Vala.Delegate> delegates = this.vinterface.get_delegates ();
-		this.delegates = new Gee.ArrayList<Delegate>();
 		this.add_delegates (delegates);
 
 		Gee.Collection<Vala.Signal> signals = this.vinterface.get_signals();
-		this.signals = new Gee.ArrayList<Signal>();
 		this.add_signals (signals);
 
 		Gee.Collection<Vala.Property> properties = this.vinterface.get_properties();
-		this.properties = new Gee.ArrayList<Property>();
 		this.add_properties (properties);
 
 		Gee.Collection<Vala.Field> fields = this.vinterface.get_fields();
-		this.fields = new Gee.ArrayList<Field>();
 		this.add_fields (fields);
 
 		Gee.Collection<Vala.Struct> structs = this.vinterface.get_structs();
-		this.structs = new Gee.ArrayList<Struct>();
 		this.add_structs (structs);
 
 		Gee.Collection<Vala.Class> classes = this.vinterface.get_classes();
-		this.classes = new Gee.ArrayList<Class>();
 		this.add_classes (classes);
 
 		Gee.Collection<Vala.Enum> enums = this.vinterface.get_enums();
-		this.enums = new Gee.ArrayList<Enum>();
 		this.add_enums (enums);
 
 		Gee.Collection<Vala.Constant> constants = this.vinterface.get_constants();
-		this.constants = new Gee.ArrayList<Constant>();
 		this.add_constants ( constants );
 	}
 
@@ -90,151 +74,8 @@ public class Valadoc.Interface : DocumentedElement, SymbolAccessibility, Visitab
 		get;
 	}
 
-	protected Gee.ArrayList<TypeParameter> template_param_lst {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> methods {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Property> properties {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Field> fields {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Signal> signals {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Enum> enums {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Delegate> delegates {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Struct> structs {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Class> classes {
-		get;
-		set;
-	}
-
-	protected Gee.ArrayList<Constant> constants {
-		get;
-		set;
-	}
-
 	private Vala.Interface vinterface;
 
-	internal override DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos];
-
-		if ( velement is Vala.Interface == false )
-			return null;
-
-		if ( this.is_vinterface ( (Vala.Interface)velement ) == false )
-			return null;
-
-		if ( params.size == pos+1 )
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if ( velement is Vala.Field ) {
-			element = this.search_field_vala ( params, pos );
-		}
-		else if ( velement is Vala.Method ) {
-			element = this.search_method_vala ( params, pos );
-		}
-		else if ( velement is Vala.Signal ) {
-			element = this.search_signal_vala ( params, pos );
-		}
-		else if ( velement is Vala.Property ) {
-			element = this.search_property_vala ( params, pos );
-		}
-		else if ( velement is Vala.Delegate ) {
-			element = this.search_delegate_vala ( params, pos );
-		}
-		else if ( velement is Vala.Struct ) {
-			element = this.search_struct_vala ( params, pos );
-		}
-		else if ( velement is Vala.Enum ) {
-			element = this.search_enum_vala ( params, pos );
-		}
-		else if ( velement is Vala.Class ) {
-			element = this.search_class_vala ( params, pos );
-		}
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( !(this.name == params[pos] || params[0] == "this") )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-		DocumentedElement? element = this.search_field ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_signal ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_property ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_delegate ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_struct ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_enum ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_class ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_constant ( params, pos );
-		if ( element != null )
-			return element;
-
-		return null;
-	}
-
-	internal bool is_vinterface ( Vala.Interface viface ) {
-		return ( this.vinterface == viface );
-	}
-
 	public void visit ( Doclet doclet ) {
 		if ( !this.is_visitor_accessible ( ) )
 			return ;
@@ -242,20 +83,14 @@ public class Valadoc.Interface : DocumentedElement, SymbolAccessibility, Visitab
 		doclet.visit_interface ( this );
 	}
 
-	public void write ( Langlet langlet, void* ptr ) {
-		langlet.write_interface ( this, ptr );
+	public override Api.NodeType node_type { get { return Api.NodeType.INTERFACE; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
-	internal void parse_comments ( DocumentationParser docparser ) {
-		this.parse_comment_helper ( docparser );
-		this.parse_delegate_comments ( docparser );
-		this.parse_property_comments ( docparser );
-		this.parse_signal_comments ( docparser );
-		this.parse_method_comments ( docparser );
-		this.parse_struct_comments ( docparser );
-		this.parse_field_comments ( docparser );
-		this.parse_class_comments ( docparser );
-		this.parse_enum_comments ( docparser );
+	public void write ( Langlet langlet, void* ptr ) {
+		langlet.write_interface ( this, ptr );
 	}
 
 	private void set_prerequisites ( Gee.Collection<Vala.DataType> lst ) {
@@ -271,19 +106,11 @@ public class Valadoc.Interface : DocumentedElement, SymbolAccessibility, Visitab
 		}
 	}
 
-	internal void set_type_references ( ) {
-		this.set_template_parameter_list_references ( );
-		this.set_delegate_type_references ();
-		this.set_property_type_references ();
-		this.set_signal_type_references ();
-		this.set_method_type_references ();
-		this.set_struct_type_references ();
-		this.set_field_type_references ();
-		this.set_enum_type_references ();
-		this.set_class_type_references ();
-
+	protected override void resolve_type_references () {
 		var lst = this.vinterface.get_prerequisites ( );
 		this.set_prerequisites ( lst );
+
+		base.resolve_type_references ();
 	}
 }
 
diff --git a/src/libvaladoc/apitree/interfacehandler.vala b/src/libvaladoc/apitree/interfacehandler.vala
index 6624417..c2c1455 100644
--- a/src/libvaladoc/apitree/interfacehandler.vala
+++ b/src/libvaladoc/apitree/interfacehandler.vala
@@ -17,52 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.InterfaceHandler : Basic {
-	protected abstract Gee.ArrayList<Interface> interfaces {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_interface_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		foreach ( Interface iface in this.interfaces ) {
-			DocumentedElement? element = iface.search_element_vala ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_interface ( string[] params, int pos ) {
-		foreach ( Interface iface in this.interfaces ) {
-			DocumentedElement? element = iface.search_element ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
+public interface Valadoc.InterfaceHandler : Api.Node {
 	public Gee.Collection<Interface> get_interface_list ( ) {
-		var lst = new Gee.ArrayList<Interface> ();
-		foreach ( Interface iface in this.interfaces ) {
-			if ( !iface.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( iface );
-		}
-
-		return lst.read_only_view;
+		return get_children_by_type (Api.NodeType.INTERFACE);
 	}
 
 	public void visit_interfaces ( Doclet doclet ) {
-		foreach ( Interface iface in this.interfaces ) {
-			iface.visit( doclet );
-		}
+		accept_children_by_type (Api.NodeType.INTERFACE, doclet);
 	}
 
 	protected void add_interfaces ( Gee.Collection<Vala.Interface> vifaces ) {
@@ -73,19 +38,6 @@ public interface Valadoc.InterfaceHandler : Basic {
 
 	internal void add_interface ( Vala.Interface viface ) {
 		var tmp = new Interface ( this.settings, viface, this, this.head );
-		this.interfaces.add ( tmp );
-	}
-
-	protected void set_interface_type_references ( ) {
-		foreach ( Interface iface in this.interfaces ) {
-			iface.set_type_references ( );
-		}
-	}
-
-	protected void parse_interface_comments ( DocumentationParser docparser ) {
-		foreach ( Interface iface in this.interfaces ) {
-			iface.parse_comments ( docparser );
-		}
+		add_child (tmp);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/method.vala b/src/libvaladoc/apitree/method.vala
index 75ae1cb..1367aba 100644
--- a/src/libvaladoc/apitree/method.vala
+++ b/src/libvaladoc/apitree/method.vala
@@ -23,20 +23,12 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Method : DocumentedElement, ParameterListHandler, ExceptionHandler, TemplateParameterListHandler, SymbolAccessibility, ReturnTypeHandler, Visitable {
+public class Valadoc.Method : Api.MemberNode, ParameterListHandler, ExceptionHandler, TemplateParameterListHandler, ReturnTypeHandler {
 	private Vala.Method vmethod;
 
-	public Method (Valadoc.Settings settings, Vala.Method vmethod, MethodHandler parent, Tree head) {
-		this.template_param_lst = new Gee.ArrayList<TypeParameter> ();
-		this.param_list = new Gee.ArrayList<FormalParameter> ();
-		this.err_domains = new Gee.ArrayList<DocumentedElement> ();
-
-		this.vcomment = vmethod.comment;
-		this.settings = settings;
-		this.vsymbol = vmethod;
-		this.vmethod = vmethod;
-		this.parent = parent;
-		this.head = head;
+	public Method (Valadoc.Settings settings, Vala.Method symbol, MethodHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vmethod = symbol;
 
 		var vret = this.vmethod.return_type;
 		this.set_ret_type (vret);
@@ -48,10 +40,6 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 		this.set_template_parameter_list (vtparams);
 	}
 
-	internal bool is_vmethod (Vala.Method vm) {
-		return (this.vmethod == vm);
-	}
-
 	public string? get_cname () {
 		return this.vmethod.get_cname ();
 	}
@@ -66,35 +54,6 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 		get;
 	}
 
-	public Gee.ArrayList<TypeParameter> template_param_lst {
-		protected set;
-		get;
-	}
-
-	public Gee.ArrayList<FormalParameter> param_list {
-		protected set;
-		get;
-	}
-
-	public Gee.ArrayList<DocumentedElement> err_domains {
-		protected set;
-		get;
-	}
-
-	internal bool equals (Method m) {
-		return (m.vmethod == this.vmethod);
-	}
-
-	internal void parse_comment (DocumentationParser docparser) {
-		if (this.documentation != null)
-			return ;
-
-		if (this.vcomment == null)
-			return ;
-
-		this.parse_comment_helper (docparser);
-	}
-
 	public bool is_yields {
 		get {
 			return this.vmethod.coroutine;
@@ -154,7 +113,7 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 		}
 	}
 
-	internal void set_type_references ( ) {
+	protected override void resolve_type_references () {
 		Vala.Method? vm = null;
 		if (vmethod.base_method != null) {
 			vm = vmethod.base_method;
@@ -168,12 +127,12 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 			this.base_method = (Method?) this.head.search_vala_symbol (vm);
 		}
 
-		this.set_return_type_references ();
-		this.set_parameter_list_type_references ();
-		this.set_template_parameter_list_references ();
-
 		var vexceptionlst = this.vmethod.get_error_types ();
 		this.add_exception_list ( vexceptionlst );
+
+		this.set_return_type_references ();
+
+		base.resolve_type_references ( );
 	}
 
 	public void visit ( Doclet doclet, Valadoc.MethodHandler in_type ) {
@@ -183,6 +142,16 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 		doclet.visit_method ( this, in_type );
 	}
 
+	public override Api.NodeType node_type {
+		get {
+			return is_constructor ? Api.NodeType.CREATION_METHOD : Api.NodeType.METHOD;
+		}
+	}
+
+	public override void accept (Doclet doclet) {
+		visit (doclet, (MethodHandler) parent);
+	}
+
 	public void write ( Langlet langlet, void* ptr, Valadoc.MethodHandler parent ) {
 		langlet.write_method ( ptr, this, parent );
 	}
diff --git a/src/libvaladoc/apitree/methodhandler.vala b/src/libvaladoc/apitree/methodhandler.vala
index fc2c1a7..20e1b75 100644
--- a/src/libvaladoc/apitree/methodhandler.vala
+++ b/src/libvaladoc/apitree/methodhandler.vala
@@ -17,62 +17,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.MethodHandler : Basic {
-	protected abstract Gee.ArrayList<Method> methods {
-		set;
-		get;
-	}
-
-	protected DocumentedElement? search_method_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Method == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Method m in this.methods ) {
-			if ( m.is_vmethod ( (Vala.Method)velement ) ) {
-				return m;
-			}
-		}
-		return null;
-	}
-
-	internal DocumentedElement? search_method ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Method m in this.methods ) {
-			if ( m.name == params[pos] )
-				return m;
-		}
-		return null;
-	}
-
-	internal void set_method_type_references ( ) {
-		foreach ( Method m in this.methods ) {
-			m.set_type_references ( );
-		}
-	}
-
-	internal void parse_method_comments ( DocumentationParser docparser ) {
-		foreach ( Method m in this.methods ) {
-			m.parse_comment ( docparser );
-		}
-	}
-
+public interface Valadoc.MethodHandler : Api.Node {
 	protected void add_method ( Vala.Method vmethod ) {
 		var tmp = new Method ( this.settings, vmethod, this, this.head );
-		this.methods.add ( tmp );
+		add_child ( tmp );
 	}
 
 	protected void add_methods ( Gee.Collection<Vala.Method> vmethods ) {
@@ -82,22 +34,10 @@ public interface Valadoc.MethodHandler : Basic {
 	}
 
 	public void visit_methods ( Doclet doclet ) {
-		foreach ( Method m in this.get_method_list() ) {
-			m.visit ( doclet, this );
-		}
+		accept_children_by_type (Api.NodeType.METHOD, doclet);
 	}
 
 	public Gee.Collection<Method> get_method_list ( ) {
-		var lst = new Gee.ArrayList<Method> ();
-		foreach ( Method m in this.methods ) {
-			if ( !m.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( m );
-		}
-
-		return lst.read_only_view;
+		return get_children_by_type (Api.NodeType.METHOD);
 	}
 }
-
-
diff --git a/src/libvaladoc/apitree/namespace.vala b/src/libvaladoc/apitree/namespace.vala
index 101c4ed..67f777f 100644
--- a/src/libvaladoc/apitree/namespace.vala
+++ b/src/libvaladoc/apitree/namespace.vala
@@ -23,242 +23,48 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Namespace : DocumentedElement, MethodHandler, FieldHandler, NamespaceHandler, ErrorDomainHandler,
+public class Valadoc.Namespace : Api.SymbolNode, MethodHandler, FieldHandler, NamespaceHandler, ErrorDomainHandler,
                                  EnumHandler, ClassHandler, StructHandler, InterfaceHandler,
                                  DelegateHandler, ConstantHandler
 {
-	protected Gee.ArrayList<Constant> constants {
-		protected set;
-		get;
-	}
-
-	protected Gee.ArrayList<Enum> enums {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Interface> interfaces {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Delegate> delegates {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<ErrorDomain> errdoms {
-		private set;
-		get;
-	}
-
-	public Gee.ArrayList<Namespace> namespaces {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Class> classes {
-		private set;
-		get;
-	}
-
-	protected Gee.ArrayList<Struct> structs {
-		private set;
-		get;
-	}
-
-	internal DocumentedElement? search_namespace (string[] params, int pos) {
-		foreach (Namespace ns in this.namespaces) {
-			DocumentedElement? element = ns.search_element (params, pos+1);
-			if (element != null)
-				return element;
-		}
-		return null;
-	}
-
-	internal DocumentedElement? search_namespace_vala (Gee.ArrayList<Vala.Symbol> params, int pos) {
-		foreach (Namespace ns in this.namespaces) {
-			DocumentedElement? element = ns.search_element_vala (params, pos+1);
-			if (element != null)
-				return element;
-		}
-		return null;
-	}
-
-	internal override DocumentedElement? search_element_vala (Gee.ArrayList<Vala.Symbol> params, int pos) {
-		Vala.Symbol velement = params[pos];
-
-		if (velement is Vala.Namespace == false)
-			return null;
-
-		if (this.is_vnspace ((Vala.Namespace)velement) == false)
-			return null;
-
-		if (params.size == pos+1)
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if (velement is Vala.Namespace) {
-			element = this.search_namespace_vala (params, pos);
-		}
-		else if (velement is Vala.Class) {
-			element = this.search_class_vala (params, pos);
-		}
-		else if (velement is Vala.Interface) {
-			element = this.search_interface_vala (params, pos);
-		}
-		else if (velement is Vala.Struct) {
-			element = this.search_struct_vala (params, pos);
-		}
-		else if (velement is Vala.Enum) {
-			element = this.search_enum_vala (params, pos);
-		}
-		else if (velement is Vala.ErrorDomain) {
-			element = this.search_error_domain_vala (params, pos);
-		}
-		else if (velement is Vala.Method) {
-			element = this.search_method_vala (params, pos);
-		}
-		else if (velement is Vala.Field) {
-			element = this.search_field_vala (params, pos);
-		}
-		else if (velement is Vala.DelegateType || velement is Vala.Delegate) {
-			element = this.search_delegate_vala (params, pos);
-		}
-		else if (velement is Vala.Constant) {
-			element = this.search_constant_vala (params, pos);
-		}
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( this.name != params[pos] )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-
-		DocumentedElement? element = this.search_namespace ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_class ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_interface ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_struct ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_enum ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_error_domain ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_field ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_delegate ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = search_constant ( params, pos );
-		if ( element != null )
-			return element;
-
-		return null;
-	}
+	private Comment source_comment;
 
-	protected Gee.ArrayList<Field> fields {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> methods {
-		set;
-		get;
-	}
+	public Namespace (Valadoc.Settings settings, Vala.Namespace symbol, NamespaceHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 
-	public Namespace ( Valadoc.Settings settings, Vala.Namespace vnspace, NamespaceHandler parent, Tree head ) {
-		this.settings = settings;
-		this.vsymbol = vnspace;
-		this.vnspace = vnspace;
-		this.parent = parent;
-		this.head = head;
-
-		this.namespaces = new Gee.ArrayList<Namespace> ();
-		this.structs = new Gee.ArrayList<Struct>();
-		this.classes = new Gee.ArrayList<Class>();
-
-		this.constants = new Gee.ArrayList<Constant> ();
-		this.interfaces = new Gee.ArrayList<Interface>();
-		this.methods = new Gee.ArrayList<Method> ();
-		this.delegates = new Gee.ArrayList<Delegate>();
-		this.errdoms = new Gee.ArrayList<ErrorDomain>();
-		this.enums = new Gee.ArrayList<Enum>();
-		this.fields = new Gee.ArrayList<Field> ();
+		this.vnspace = symbol;
 
 		if (vnspace.source_reference != null) {
-			var vfile = vnspace.source_reference.file;
 			foreach (Comment c in vnspace.get_comments()) {
 				if (this.package.is_vpackage (c.source_reference.file)) {
-					this.vcomment = c;
+					this.source_comment = c;
 					break;
 				}
 			}
 		}
 	}
 
+	protected override void parse_comments (DocumentationParser parser) {
+		if (source_comment != null) {
+			documentation = parser.parse (this, source_comment);
+		}
+
+		base.parse_comments (parser);
+	}
+
 	public void visit (Doclet doclet) {
 		doclet.visit_namespace (this);
 	}
 
-	public Vala.Namespace vnspace {
-		private get;
-		set;
-	}
+	public override Api.NodeType node_type { get { return Api.NodeType.NAMESPACE; } }
 
-	internal void set_type_references ( ) {
-		this.set_errordomain_type_referenes ();
-		this.set_namespace_type_references ();
-		this.set_interface_type_references ();
-		this.set_delegate_type_references ();
-		this.set_constant_type_references ();
-		this.set_method_type_references ();
-		this.set_field_type_references ();
-		this.set_struct_type_references ();
-		this.set_class_type_references ();
-		this.set_enum_type_references ();
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
-	internal void parse_comments (DocumentationParser docparser) {
-		this.parse_comment_helper (docparser);
-		this.parse_enum_comments (docparser);
-		this.parse_field_comments (docparser);
-		this.parse_class_comments (docparser);
-		this.parse_method_comments (docparser);
-		this.parse_struct_comments (docparser);
-		this.parse_constant_comments (docparser);
-		this.parse_delegate_comments (docparser);
-		this.parse_interface_comments (docparser);
-		this.parse_namespace_comments (docparser);
- 		this.parse_errordomain_comments (docparser);
+	public Vala.Namespace vnspace {
+		private get;
+		set;
 	}
 
 	internal bool is_vnspace ( Vala.Namespace vns ) {
diff --git a/src/libvaladoc/apitree/namespacehandler.vala b/src/libvaladoc/apitree/namespacehandler.vala
index 8ff6d9f..d08b4e4 100644
--- a/src/libvaladoc/apitree/namespacehandler.vala
+++ b/src/libvaladoc/apitree/namespacehandler.vala
@@ -17,26 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.NamespaceHandler : Basic {
-	public abstract Gee.ArrayList<Namespace> namespaces {
-		set;
-		get;
-	}
-
+public interface Valadoc.NamespaceHandler : Api.Node {
 	public Gee.Collection<Namespace> get_namespace_list () {
-			return this.namespaces.read_only_view;
+		return get_children_by_type (Api.NodeType.NAMESPACE);
 	}
 
 	public void visit_namespaces ( Doclet doclet ) {
-		foreach ( Namespace ns in this.namespaces ) {
-			ns.visit ( doclet );
-		}
+		accept_children_by_type (Api.NodeType.NAMESPACE, doclet);
 	}
 
 	private Gee.ArrayList<Vala.Namespace> create_parent_vnamespace_list ( Vala.Symbol vsymbol ) {
@@ -57,7 +48,7 @@ public interface Valadoc.NamespaceHandler : Basic {
 		Namespace ns = this.find_namespace_without_childs ( vns );
 		if ( ns == null ) {
 			ns = new Namespace( this.settings, vns, this, this.head );
-			this.namespaces.add ( ns );
+			add_child ( ns );
 		}
 
 		if ( vnspaces.size == pos+1 ) {
@@ -84,7 +75,7 @@ public interface Valadoc.NamespaceHandler : Basic {
 		}
 		else {
 			var ns = new Namespace( this.settings, vnspace, this, this.head );
-			this.namespaces.add( ns );
+			add_child ( ns );
 			return ns;
 		}
 	}
@@ -94,7 +85,7 @@ public interface Valadoc.NamespaceHandler : Basic {
 		if ( vns == null )
 			return null;
 
-		foreach ( Namespace ns in this.namespaces ) {
+		foreach ( Namespace ns in get_namespace_list () ) {
 			if ( !ns.is_vnspace( vns ) )
 				continue ;
 
@@ -110,7 +101,7 @@ public interface Valadoc.NamespaceHandler : Basic {
 	internal Namespace find_namespace_without_childs ( Vala.Namespace vns ) {
 		Namespace ns2 = null;
 
-		foreach ( Namespace ns in this.namespaces ) {
+		foreach ( Namespace ns in get_namespace_list () ) {
 			if ( ns.is_vnspace(vns) )
 				ns2 = ns;
 		}
@@ -123,17 +114,4 @@ public interface Valadoc.NamespaceHandler : Basic {
 
 		return this.find_vnamespace_helper ( vnspaces, vnspaces.index_of( vns ) );
 	}
-
-	internal void set_namespace_type_references ( ) {
-		foreach ( Namespace ns in this.namespaces ){
-			ns.set_type_references ();
-		}
-	}
-
-	internal void parse_namespace_comments ( DocumentationParser docparser ) {
-		foreach ( Namespace ns in this.namespaces ){
-			ns.parse_comments ( docparser );
-		}
-	}
 }
-
diff --git a/src/libvaladoc/apitree/package.vala b/src/libvaladoc/apitree/package.vala
index c54f08d..ad80b5b 100644
--- a/src/libvaladoc/apitree/package.vala
+++ b/src/libvaladoc/apitree/package.vala
@@ -24,19 +24,13 @@ using Gee;
 
 
 
-public class Valadoc.Package : DocumentedElement, NamespaceHandler {
+public class Valadoc.Package : Api.Node, NamespaceHandler {
 	private Gee.ArrayList<Vala.SourceFile> vfiles = new Gee.ArrayList<Vala.SourceFile> ();
 
 	internal void add_file (Vala.SourceFile vfile) {
 		this.vfiles.add (vfile);
 	}
 
-	public Gee.ArrayList<Namespace> namespaces {
-		default = new Gee.ArrayList<Namespace>();
-		private set;
-		private get;
-	}
-
 	public bool is_package {
 		 private set;
 		 get;
@@ -91,10 +85,9 @@ public class Valadoc.Package : DocumentedElement, NamespaceHandler {
 		}
 	}
 
-	public Package.with_name (Valadoc.Settings settings, Vala.SourceFile vfile, string name, Tree head, bool is_package = false) {
+	public Package.with_name (Valadoc.Settings settings, Vala.SourceFile vfile, string name, Tree root, bool is_package = false) {
+		base (settings, null, root);
 		this.is_package = is_package;
-		this.settings = settings;
-		this.head = head;
 
 		this.package_name = name;
 
@@ -114,31 +107,15 @@ public class Valadoc.Package : DocumentedElement, NamespaceHandler {
 		}
 	}
 
-	internal override DocumentedElement? search_element (string[] params, int pos) {
-		foreach (Namespace ns in this.namespaces) {
-			DocumentedElement? element = ns.search_element ( params, pos );
-			if (element != null) {
-				return element;
-			}
-		}
-		return null;
-	}
-
-	internal override DocumentedElement? search_element_vala (Gee.ArrayList<Vala.Symbol> params, int pos) {
-		foreach (Namespace ns in this.namespaces) {
-			DocumentedElement? element = ns.search_element_vala (params, pos);
-			if (element != null) {
-				return element;
-			}
-		}
-		return null;
-	}
-
 	internal bool is_vpackage (Vala.SourceFile vfile) {
 		return this.vfiles.contains (vfile);
 	}
 
-	public bool is_visitor_accessible () {
+	protected override bool is_type_visitor_accessible (Valadoc.Basic element) {
+		return true;
+	}
+
+	public override bool is_visitor_accessible () {
 		return !( this.is_package && this.settings.with_deps == false );
 	}
 
@@ -149,12 +126,10 @@ public class Valadoc.Package : DocumentedElement, NamespaceHandler {
 		doclet.visit_package ( this );
 	}
 
-	internal void parse_comments ( DocumentationParser docparser ) {
-		this.parse_namespace_comments ( docparser );
-	}
+	public override Api.NodeType node_type { get { return Api.NodeType.PACKAGE; } }
 
-	internal void set_type_references ( ) {
-		this.set_namespace_type_references ( );
+	public override void accept (Doclet doclet) {
+		visit (doclet);
 	}
 
 	public void write (Langlet langlet, void* ptr) {
diff --git a/src/libvaladoc/apitree/parameterlisthandler.vala b/src/libvaladoc/apitree/parameterlisthandler.vala
index 6d68bfe..10ff9c4 100644
--- a/src/libvaladoc/apitree/parameterlisthandler.vala
+++ b/src/libvaladoc/apitree/parameterlisthandler.vala
@@ -17,33 +17,24 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.ParameterListHandler : Basic {
-	protected abstract Gee.ArrayList<FormalParameter> param_list {
-		protected set;
-		get;
-	}
-
-	public Gee.Collection<FormalParameter> get_parameter_list ( ) {
-		return this.param_list.read_only_view;
+// TODO Rename FormalParameters
+public interface Valadoc.ParameterListHandler : Api.Node {
+	public Gee.List<FormalParameter> param_list {
+		owned get { return get_parameter_list (); }
 	}
 
-	protected void add_parameter_list ( Gee.Collection<Vala.FormalParameter> vparams ) {
-		foreach ( Vala.FormalParameter vfparam in vparams ) {
-			var tmp = new FormalParameter ( this.settings, vfparam, this, this.head );
-			this.param_list.add ( tmp );
-		}
+	public Gee.List<FormalParameter> get_parameter_list () {
+		return (Gee.List<FormalParameter>) get_children_by_type (Api.NodeType.FORMAL_PARAMETER);
 	}
 
-	internal void set_parameter_list_type_references ( ) {
-		foreach ( FormalParameter fparam in this.param_list ) {
-			fparam.set_type_references ( );
+	protected void add_parameter_list (Gee.Collection<Vala.FormalParameter> vparams) {
+		foreach (Vala.FormalParameter vfparam in vparams) {
+			var tmp = new FormalParameter (this.settings, vfparam, this, this.head);
+			add_child (tmp);
 		}
 	}
 }
-
diff --git a/src/libvaladoc/apitree/pointer.vala b/src/libvaladoc/apitree/pointer.vala
index 55d285b..8358d34 100644
--- a/src/libvaladoc/apitree/pointer.vala
+++ b/src/libvaladoc/apitree/pointer.vala
@@ -51,16 +51,16 @@ public class Valadoc.Pointer : Basic {
 		langlet.write_pointer (this, ptr, parent);
 	}
 
-	public void set_type_references () {
+	protected override void resolve_type_references () {
 		Basic type = this.data_type;
 		if ( type == null )
 			;
 		else if ( type is Array )
-			((Array)type).set_type_references ();
+			((Array)type).resolve_type_references ();
 		else if ( type is Pointer )
-			((Pointer)type ).set_type_references ();
+			((Pointer)type ).resolve_type_references ();
 		else
-			((TypeReference)type).set_type_references ();
+			((TypeReference)type).resolve_type_references ();
 	}
 }
 
diff --git a/src/libvaladoc/apitree/property.vala b/src/libvaladoc/apitree/property.vala
index 35551ea..0817a2c 100644
--- a/src/libvaladoc/apitree/property.vala
+++ b/src/libvaladoc/apitree/property.vala
@@ -23,17 +23,13 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Property : DocumentedElement, SymbolAccessibility, ReturnTypeHandler, Visitable {
+public class Valadoc.Property : Api.MemberNode, ReturnTypeHandler {
 	private Vala.Property vproperty;
 
-	public Property (Valadoc.Settings settings, Vala.Property vproperty, PropertyHandler parent, Tree head) {
-		this.vcomment = vproperty.comment;
-		this.settings = settings;
-		this.parent = parent;
-		this.head = head;
+	public Property (Valadoc.Settings settings, Vala.Property symbol, PropertyHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 
-		this.vsymbol = vproperty;
-		this.vproperty = vproperty;
+		this.vproperty = symbol;
 
 		var ret = this.vproperty.property_type;
 		this.set_ret_type (ret);
@@ -97,7 +93,8 @@ public class Valadoc.Property : DocumentedElement, SymbolAccessibility, ReturnTy
 		get;
 	}
 
-	internal void set_type_references ( ) {
+
+	protected override void resolve_type_references () {
 		Vala.Property? vp = null;
 		if (vproperty.base_property != null) {
 			vp = vproperty.base_property;
@@ -113,16 +110,6 @@ public class Valadoc.Property : DocumentedElement, SymbolAccessibility, ReturnTy
 		this.set_return_type_references ( );
 	}
 
-	public void parse_comment (DocumentationParser docparser) {
-		if (this.documentation != null)
-			return ;
-
-		if (this.vcomment == null)
-			return ;
-
-		this.parse_comment_helper (docparser);
-	}
-
 	public void visit (Doclet doclet) {
 		if (!this.is_visitor_accessible ())
 			return ;
@@ -130,6 +117,12 @@ public class Valadoc.Property : DocumentedElement, SymbolAccessibility, ReturnTy
 		doclet.visit_property (this);
 	}
 
+	public override Api.NodeType node_type { get { return Api.NodeType.PROPERTY; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
+
 	public void write (Langlet langlet, void* ptr) {
 		langlet.write_property (this, ptr);
 	}
diff --git a/src/libvaladoc/apitree/propertyaccessor.vala b/src/libvaladoc/apitree/propertyaccessor.vala
index 9178407..02d0f30 100644
--- a/src/libvaladoc/apitree/propertyaccessor.vala
+++ b/src/libvaladoc/apitree/propertyaccessor.vala
@@ -23,34 +23,17 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.PropertyAccessor : Object {
+public class Valadoc.PropertyAccessor : Api.SymbolNode {
 	private Vala.PropertyAccessor vpropacc;
 
-	public PropertyAccessor ( Valadoc.Settings settings, Vala.PropertyAccessor vpropacc, Property parent, Tree head ) {
-		this.settings = settings;
-		this.vpropacc = vpropacc;
-		this.parent = parent;
-		this.head = head;
+	public PropertyAccessor (Valadoc.Settings settings, Vala.PropertyAccessor symbol, Property parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vpropacc = symbol;
 	}
 
-	public Tree head {
-		set;
-		get;
-	}
-
-	public Settings settings {
-		set;
-		get;
-	}
+	public override Api.NodeType node_type { get { return Api.NodeType.PROPERTY_ACCESSOR; } }
 
-	public Property parent {
-		private set;
-		get;
-	}
-
-	public Tree tree {
-		set;
-		get;
+	public override void accept (Doclet doclet) {
 	}
 
 	public bool is_construct {
@@ -59,30 +42,6 @@ public class Valadoc.PropertyAccessor : Object {
 		}
 	}
 
-	public bool is_protected {
-		get {
-			return this.vpropacc.access == Vala.SymbolAccessibility.PROTECTED;
-		}
-	}
-
-	public bool is_public {
-		get {
-			return this.vpropacc.access == Vala.SymbolAccessibility.PUBLIC;
-		}
-	}
-
-	public bool is_private {
-		get {
-			return this.vpropacc.access == Vala.SymbolAccessibility.PRIVATE;
-		}
-	}
-
-	public bool is_internal {
-		get {
-			return this.vpropacc.access == Vala.SymbolAccessibility.INTERNAL;
-		}
-	}
-
 	public bool is_set {
 		get {
 			return this.vpropacc.writable;
diff --git a/src/libvaladoc/apitree/propertyhandler.vala b/src/libvaladoc/apitree/propertyhandler.vala
index d7872c5..3b7fa2c 100644
--- a/src/libvaladoc/apitree/propertyhandler.vala
+++ b/src/libvaladoc/apitree/propertyhandler.vala
@@ -17,49 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.PropertyHandler : Basic {
-	protected abstract Gee.ArrayList<Property> properties {
-		get;
-		set;
-	}
-
-	protected DocumentedElement? search_property_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Property == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Property prop in this.properties ) {
-			if ( prop.is_vproperty ( (Vala.Property)velement ) ) {
-				return prop;
-			}
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_property ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Property prop in this.properties ) {
-			if ( prop.name == params[pos] )
-				return prop;
-		}
-		return null;
-	}
-
+public interface Valadoc.PropertyHandler : Api.Node {
 	protected bool is_overwritten_property ( Property prop ) {
-		foreach ( Property p in this.properties ) {
+		foreach ( Property p in get_property_list () ) {
 			if ( p.parent != this )
 				continue ;
 
@@ -73,39 +37,17 @@ public interface Valadoc.PropertyHandler : Basic {
 	}
 
 	public Gee.Collection<Property> get_property_list ( ) {
-		var lst = new Gee.ArrayList<Property> ();
-		foreach ( Property p in this.properties ) {
-			if ( !p.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( p );
-		}
-
-		return lst.read_only_view;
-	}
-
-	protected void parse_property_comments ( DocumentationParser docparser ) {
-		foreach ( Property prop in this.properties ) {
-			prop.parse_comment ( docparser );
-		}
+		return get_children_by_type (Api.NodeType.PROPERTY);
 	}
 
 	public void visit_properties ( Doclet doclet ) {
-		foreach ( Property prop in this.get_property_list () )
-			prop.visit ( doclet );
-	}
-
-	protected void set_property_type_references () {
-		foreach ( Property prop in this.properties ) {
-			prop.set_type_references ( );
-		}
+		accept_children_by_type (Api.NodeType.PROPERTY, doclet);
 	}
 
 	protected void add_properties ( Gee.Collection<Vala.Property> vproperties ) {
 		foreach ( Vala.Property vprop in vproperties ) {
 			var tmp = new Property ( this.settings, vprop, this, this.head );
-			this.properties.add ( tmp );
+			add_child ( tmp );
 		}
 	}
 }
-
diff --git a/src/libvaladoc/apitree/returntypehandler.vala b/src/libvaladoc/apitree/returntypehandler.vala
index 00dbd3a..bc3b5b2 100644
--- a/src/libvaladoc/apitree/returntypehandler.vala
+++ b/src/libvaladoc/apitree/returntypehandler.vala
@@ -17,23 +17,21 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
 public interface Valadoc.ReturnTypeHandler : Basic {
 	public abstract TypeReference? type_reference {
 		protected set;
 		get;
 	}
 
-	internal void set_return_type_references ( ) {
+	internal void set_return_type_references () {
 		if ( this.type_reference == null )
 			return ;
 
-		this.type_reference.set_type_references ( );
+		this.type_reference.resolve_type_references ();
 	}
 
 	// rename
@@ -42,4 +40,3 @@ public interface Valadoc.ReturnTypeHandler : Basic {
 		this.type_reference = tmp;
 	}
 }
-
diff --git a/src/libvaladoc/apitree/signal.vala b/src/libvaladoc/apitree/signal.vala
index f6c54e8..2af364d 100644
--- a/src/libvaladoc/apitree/signal.vala
+++ b/src/libvaladoc/apitree/signal.vala
@@ -23,19 +23,15 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Signal : DocumentedElement, ParameterListHandler, SymbolAccessibility, ReturnTypeHandler, Visitable {
+public class Valadoc.Signal : Api.MemberNode, ParameterListHandler, ReturnTypeHandler {
 	private Vala.Signal vsignal;
 
-	public Signal (Valadoc.Settings settings, Vala.Signal vsignal, SignalHandler parent, Tree head) {
-		this.param_list = new Gee.ArrayList<FormalParameter> ();
+	public Signal (Valadoc.Settings settings, Vala.Signal symbol, SignalHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 
-		this.vcomment = vsignal.comment;
-		this.settings = settings;
-		this.vsymbol = vsignal;
-		this.vsignal = vsignal;
-		this.parent = parent;
-		this.head = head;
+		this.vsignal = symbol;
 
+		this.param_list = new Gee.ArrayList<FormalParameter> ();
 		var vparamlst = this.vsignal.get_parameters ();
 		this.add_parameter_list (vparamlst);
 
@@ -43,10 +39,6 @@ public class Valadoc.Signal : DocumentedElement, ParameterListHandler, SymbolAcc
 		this.set_ret_type (ret);
 	}
 
-	internal bool is_vsignal (Vala.Signal vsig) {
-		return (this.vsignal == vsig);
-	}
-
 	public string? get_cname () {
 		return this.vsignal.get_cname();
 	}
@@ -61,13 +53,10 @@ public class Valadoc.Signal : DocumentedElement, ParameterListHandler, SymbolAcc
 		get;
 	}
 
-	internal void set_type_references ( ) {
-		this.set_parameter_list_type_references ( );
+	protected override void resolve_type_references () {
 		this.set_return_type_references ( );
-	}
 
-	internal void parse_comment (DocumentationParser docparser) {
-		this.parse_comment_helper (docparser);
+		base.resolve_type_references ( );
 	}
 
 	public bool is_virtual {
@@ -83,6 +72,12 @@ public class Valadoc.Signal : DocumentedElement, ParameterListHandler, SymbolAcc
 		doclet.visit_signal (this);
 	}
 
+	public override Api.NodeType node_type { get { return Api.NodeType.SIGNAL; } }
+
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
+
 	public void write (Langlet langlet, void* ptr) {
 		langlet.write_signal (this, ptr);
 	}
diff --git a/src/libvaladoc/apitree/signalhandler.vala b/src/libvaladoc/apitree/signalhandler.vala
index 2886551..834b06c 100644
--- a/src/libvaladoc/apitree/signalhandler.vala
+++ b/src/libvaladoc/apitree/signalhandler.vala
@@ -17,82 +17,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.SignalHandler : Basic {
-	protected abstract Gee.ArrayList<Signal> signals {
-		get;
-		set;
-	}
-
-	protected DocumentedElement? search_signal_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos+1];
-		if ( velement is Vala.Signal == false )
-			return null;
-
-		if ( params.size != pos+2 )
-			return null;
-
-		foreach ( Signal sig in this.signals ) {
-			if ( sig.is_vsignal ( (Vala.Signal)velement ) ) {
-				return sig;
-			}
-		}
-		return null;
-	}
-
-	protected DocumentedElement? search_signal ( string[] params, int pos ) {
-		pos++;
-
-		if ( params[pos+1] != null )
-			return null;
-
-		foreach ( Signal sig in this.signals ) {
-			if ( sig.name == params[pos] )
-				return sig;
-		}
-		return null;
-	}
-
+public interface Valadoc.SignalHandler : Api.Node {
 	internal void add_signals ( Gee.Collection<Vala.Signal> vsignals ) {
 		foreach ( Vala.Signal vsig in vsignals ) {
 			var tmp = new Signal ( this.settings, vsig, this, this.head );
-			this.signals.add ( tmp );
+			add_child ( tmp );
 		}
 	}
 
 	public void visit_signals ( Doclet doclet ) {
-		foreach ( Signal sig in this.get_signal_list ( ) ) {
-			sig.visit ( doclet );
-		}
+		accept_children_by_type (Api.NodeType.SIGNAL, doclet);
 	}
 
 	public Gee.Collection<Signal> get_signal_list () {
-		var lst = new Gee.ArrayList<Signal> ();
-		foreach ( Signal sig in this.signals ) {
-			if ( !sig.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( sig );
-		}
-
-		return lst.read_only_view;
-	}
-
-	internal void set_signal_type_references () {
-		foreach ( Signal sig in this.signals ) {
-			sig.set_type_references ( );
-		}
-	}
-
-	internal void parse_signal_comments ( DocumentationParser docparser ) {
-		foreach ( Signal sig in this.signals ) {
-			sig.parse_comment ( docparser );
-		}
+		return get_children_by_type (Api.NodeType.SIGNAL);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/struct.vala b/src/libvaladoc/apitree/struct.vala
index 96712a5..b84ed98 100644
--- a/src/libvaladoc/apitree/struct.vala
+++ b/src/libvaladoc/apitree/struct.vala
@@ -23,33 +23,23 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.Struct : DocumentedElement, SymbolAccessibility, Visitable, MethodHandler, ConstructionMethodHandler, FieldHandler, ConstantHandler, TemplateParameterListHandler {
+public class Valadoc.Struct : Api.TypeSymbolNode, MethodHandler, ConstructionMethodHandler, FieldHandler, ConstantHandler, TemplateParameterListHandler {
 	private Vala.Struct vstruct;
 
-	public Struct (Valadoc.Settings settings, Vala.Struct vstruct, StructHandler parent, Tree head) {
-		this.vcomment = vstruct.comment;
-		this.settings = settings;
-		this.vstruct = vstruct;
-		this.vsymbol = vstruct;
-		this.parent = parent;
-		this.head = head;
-
-		this.template_param_lst = new Gee.ArrayList<TypeParameter> ();
-		this.methods = new Gee.ArrayList<Method> ();
+	public Struct (Valadoc.Settings settings, Vala.Struct symbol, StructHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
+		this.vstruct = symbol;
 
 		var vtparams = this.vstruct.get_type_parameters ();
 		this.set_template_parameter_list (vtparams);
 
 		Gee.Collection<Vala.Field> vfields = this.vstruct.get_fields();
-		this.fields = new Gee.ArrayList<Field> ();
 		this.add_fields (vfields);
 
 		Gee.Collection<Vala.Constant> vconstants = this.vstruct.get_constants();
-		this.constants = new Gee.ArrayList<Constant> ();
 		this.add_constants (vconstants);
 
 		Gee.Collection<Vala.Method> vmethods = this.vstruct.get_methods ();
-		this.construction_methods = new Gee.ArrayList<Method>();
 		this.add_methods_and_construction_methods (vmethods);
 	}
 
@@ -62,89 +52,6 @@ public class Valadoc.Struct : DocumentedElement, SymbolAccessibility, Visitable,
 		return this.vstruct.get_cname();
 	}
 
-	protected Gee.ArrayList<TypeParameter> template_param_lst {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> methods {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Field> fields {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Method> construction_methods {
-		set;
-		get;
-	}
-
-	protected Gee.ArrayList<Constant> constants {
-		set;
-		get;
-	}
-
-	internal override DocumentedElement? search_element_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		Vala.Symbol velement = params[pos];
-
-		if ( velement is Vala.Struct == false )
-			return null;
-
-		if ( this.is_vstruct ( (Vala.Struct)velement ) == false )
-			return null;
-
-		if ( params.size == pos+1 )
-			return this;
-
-		velement = params[pos+1];
-
-		DocumentedElement? element = null;
-
-		if ( velement is Vala.Field ) {
-			element = this.search_field_vala ( params, pos );
-		}
-		else if ( velement is Vala.CreationMethod ) {
-			element = this.search_construction_method_vala ( params, pos );
-		}
-		else if ( velement is Vala.Method ) {
-			element = this.search_method_vala ( params, pos );
-		}
-		else if ( velement is Vala.Constant ) {
-			element = this.search_constant_vala ( params, pos );
-		}
-
-		return element;
-	}
-
-	internal override DocumentedElement? search_element ( string[] params, int pos ) {
-		if ( this.name != params[pos] )
-			return null;
-
-		if ( params[pos] == this.name && params[pos+1] == null )
-			return this;
-
-		DocumentedElement? element = this.search_field ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_method ( params, pos );
-		if ( element != null )
-			return element;
-
-		element = this.search_constant ( params, pos );
-		if ( element != null )
-			return element;
-
-		return this.search_construction_method ( params, pos );
-	}
-
-	internal bool is_vstruct ( Vala.Struct vstru ) {
-		return ( this.vstruct == vstru );
-	}
-
 	public void visit ( Doclet doclet ) {
 		if ( !this.is_visitor_accessible ( ) )
 			return ;
@@ -152,22 +59,14 @@ public class Valadoc.Struct : DocumentedElement, SymbolAccessibility, Visitable,
 		doclet.visit_struct (this);
 	}
 
-	public void write (Langlet langlet, void* ptr) {
-		langlet.write_struct (this, ptr);
-	}
-
-	internal void parse_comments (DocumentationParser docparser) {
-		if (this.documentation != null)
-			return ;
+	public override Api.NodeType node_type { get { return Api.NodeType.STRUCT; } }
 
-		if (this.vcomment != null) {
-			this.parse_comment_helper (docparser);
-		}
+	public override void accept (Doclet doclet) {
+		visit (doclet);
+	}
 
-		this.parse_construction_method_comments (docparser);
-		this.parse_constant_comments (docparser);
-		this.parse_method_comments (docparser);
-		this.parse_field_comments (docparser);
+	public void write (Langlet langlet, void* ptr) {
+		langlet.write_struct (this, ptr);
 	}
 
 	private void set_parent_references ( ) {
@@ -178,13 +77,10 @@ public class Valadoc.Struct : DocumentedElement, SymbolAccessibility, Visitable,
 		this.base_type = (Struct?)this.head.search_vala_symbol ( (Vala.Struct)basetype.type_symbol );
 	}
 
-	internal void set_type_references ( ) {
-		this.set_template_parameter_list_references ( );
-		this.set_construction_method_references ( );
-		this.set_constant_type_references ( );
-		this.set_method_type_references ( );
-		this.set_field_type_references ( );
+	protected override void resolve_type_references () {
 		this.set_parent_references ( );
+
+		base.resolve_type_references ( );
 	}
 }
 
diff --git a/src/libvaladoc/apitree/structhandler.vala b/src/libvaladoc/apitree/structhandler.vala
index 6b4e727..dbc49e0 100644
--- a/src/libvaladoc/apitree/structhandler.vala
+++ b/src/libvaladoc/apitree/structhandler.vala
@@ -17,52 +17,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.StructHandler : Basic {
-	protected abstract Gee.ArrayList<Struct> structs {
-		set;
-		get;
-	} 
-
-	protected DocumentedElement? search_struct_vala ( Gee.ArrayList<Vala.Symbol> params, int pos ) {
-		foreach ( Struct stru in this.structs ) {
-			DocumentedElement? element = stru.search_element_vala ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
-
-	protected DocumentedElement? search_struct ( string[] params, int pos ) {
-		foreach ( Struct stru in this.structs ) {
-			DocumentedElement? element = stru.search_element ( params, pos+1 );
-			if ( element != null )
-				return element;
-		}
-		return null;
-	}
-
+public interface Valadoc.StructHandler : Api.Node {
 	public Gee.Collection<Struct> get_struct_list ( ) {
-		var lst = new Gee.ArrayList<Struct> ();
-		foreach ( Struct stru in this.structs ) {
-			if ( !stru.is_type_visitor_accessible ( this ) )
-				continue ;
-
-			lst.add ( stru );
-		}
-
-		return lst.read_only_view;
+		return get_children_by_type (Api.NodeType.STRUCT);
 	}
 
 	public void add_struct ( Vala.Struct vstru ) {
 		Struct stru = new Struct ( this.settings, vstru, this, this.head );
-		this.structs.add( stru );
+		add_child (stru);
 	}
 
 	public void add_structs ( Gee.Collection<Vala.Struct> vstructs ) {
@@ -72,21 +38,6 @@ public interface Valadoc.StructHandler : Basic {
 	}
 
 	public void visit_structs ( Doclet doclet ) {
-		foreach ( Struct stru in this.get_struct_list() ) {
-			stru.visit ( doclet );
-		}
-	}
-
-	protected void set_struct_type_references ( ) {
-		foreach ( Struct stru in this.structs ) {
-			stru.set_type_references ( );
-		}
-	}
-
-	protected void parse_struct_comments ( DocumentationParser docparser ) {
-		foreach ( Struct stru in this.structs ) {
-			stru.parse_comments ( docparser );
-		}
+		accept_children_by_type (Api.NodeType.STRUCT, doclet);
 	}
 }
-
diff --git a/src/libvaladoc/apitree/symbolaccessibility.vala b/src/libvaladoc/apitree/symbolaccessibility.vala
index 6ff4f73..17c2695 100644
--- a/src/libvaladoc/apitree/symbolaccessibility.vala
+++ b/src/libvaladoc/apitree/symbolaccessibility.vala
@@ -17,39 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
+public interface Valadoc.SymbolAccessibility {
 
-public interface Valadoc.SymbolAccessibility : Basic {
-	public bool is_public {
-		get {
-			Vala.SymbolAccessibility access = vsymbol.access;
-			return ( access == Vala.SymbolAccessibility.PUBLIC );
-		}
-	}
+	public abstract bool is_public { get; }
 
-	public bool is_protected {
-		get {
-			Vala.SymbolAccessibility access = vsymbol.access;
-			return (access == Vala.SymbolAccessibility.PROTECTED);
-		}
-	}
+	public abstract bool is_protected { get; }
 
-	public bool is_internal {
-		get {
-			Vala.SymbolAccessibility access = vsymbol.access;
-			return (access == Vala.SymbolAccessibility.INTERNAL);
-		}
-	}
+	public abstract bool is_internal { get; }
 
-	public bool is_private {
-		get {
-			Vala.SymbolAccessibility access = vsymbol.access;
-			return (access == Vala.SymbolAccessibility.PRIVATE);
-		}
-	}
+	public abstract bool is_private { get; }
 }
-
diff --git a/src/libvaladoc/apitree/templateparameterlisthandler.vala b/src/libvaladoc/apitree/templateparameterlisthandler.vala
index 02d849a..6c2a490 100644
--- a/src/libvaladoc/apitree/templateparameterlisthandler.vala
+++ b/src/libvaladoc/apitree/templateparameterlisthandler.vala
@@ -17,45 +17,19 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
-
-public interface Valadoc.TemplateParameterListHandler : Basic {
-	protected abstract Gee.ArrayList<TypeParameter> template_param_lst {
-		set;
-		get;
-	}
-
-	public TypeParameter? find_vtemplateparameter ( Vala.GenericType vttype ) {
-		foreach ( TypeParameter tparam in this.template_param_lst ) {
-			if ( tparam.is_vtypeparam ( vttype.type_parameter ) )
-				return tparam;
-		}
-
-		if ( this.parent is TemplateParameterListHandler )
-			return ((TemplateParameterListHandler)this.parent).find_vtemplateparameter ( vttype );
-
-		return null;
+public interface Valadoc.TemplateParameterListHandler : Api.Node {
+	public Gee.Collection<TypeParameter> get_template_param_list () {
+		return get_children_by_type (Api.NodeType.TYPE_PARAMETER);
 	}
 
-	public Gee.Collection<TypeParameter> get_template_param_list ( ) {
-		return this.template_param_lst.read_only_view;
-	} 
-
-	internal void set_template_parameter_list ( Gee.Collection<Vala.TypeParameter> vtparams ) {
+	internal void set_template_parameter_list (Gee.Collection<Vala.TypeParameter> vtparams) {
 		foreach ( Vala.TypeParameter vtparam in vtparams ) {
-			var tmp = new TypeParameter ( this.settings, vtparam, this, this.head );
-			this.template_param_lst.add ( tmp );
-		}
-	}
-
-	internal void set_template_parameter_list_references ( ) {
-		foreach ( TypeParameter tparam in this.template_param_lst ) {
-			tparam.set_type_reference ( );
+			var tmp = new TypeParameter (this.settings, vtparam, this, this.head);
+			add_child (tmp);
 		}
 	}
 }
-
diff --git a/src/libvaladoc/apitree/typeparameter.vala b/src/libvaladoc/apitree/typeparameter.vala
index a8e438a..b4da003 100644
--- a/src/libvaladoc/apitree/typeparameter.vala
+++ b/src/libvaladoc/apitree/typeparameter.vala
@@ -23,19 +23,10 @@ using GLib;
 using Gee;
 
 
-public class Valadoc.TypeParameter : Basic, ReturnTypeHandler {
-	private Vala.TypeParameter vtypeparam;
+public class Valadoc.TypeParameter : Api.SymbolNode, ReturnTypeHandler {
 
-	public bool is_vtypeparam ( Vala.TypeParameter vtypeparam ) {
-		return this.vtypeparam == vtypeparam;
-	}
-
-	public TypeParameter ( Valadoc.Settings settings, Vala.TypeParameter vtypeparam, Basic parent, Tree head ) {
-		this.vtypeparam = vtypeparam;
-		this.vsymbol = vtypeparam;
-		this.settings = settings;
-		this.parent = parent;
-		this.head = head;
+	public TypeParameter (Valadoc.Settings settings, Vala.TypeParameter symbol, TemplateParameterListHandler parent, Tree root) {
+		base (settings, symbol, parent, root);
 	}
 
 	public TypeReference? type_reference {
@@ -43,17 +34,12 @@ public class Valadoc.TypeParameter : Basic, ReturnTypeHandler {
 		get;
 	}
 
-	public void write ( Langlet langlet, void* ptr ) {
-		langlet.write_type_parameter ( this, ptr );
-	}
+	public override Api.NodeType node_type { get { return Api.NodeType.TYPE_PARAMETER; } }
 
-	public string? name {
-		owned get {
-			return this.vtypeparam.name;
-		}
+	public override void accept (Doclet doclet) {
 	}
 
-	internal void set_type_reference ( ) {
+	public void write ( Langlet langlet, void* ptr ) {
+		langlet.write_type_parameter ( this, ptr );
 	}
 }
-
diff --git a/src/libvaladoc/apitree/typereference.vala b/src/libvaladoc/apitree/typereference.vala
index 0c920d5..c17a6b7 100644
--- a/src/libvaladoc/apitree/typereference.vala
+++ b/src/libvaladoc/apitree/typereference.vala
@@ -41,7 +41,7 @@ public class Valadoc.TypeReference : Basic {
 	private void set_template_argument_list ( Gee.Collection<Vala.DataType> varguments ) {
 		foreach ( Vala.DataType vdtype in varguments ) {
 			var dtype = new TypeReference ( this.settings, vdtype, this, this.head );
-			dtype.set_type_references ( );
+			dtype.resolve_type_references ( );
 			this.type_arguments.add ( dtype );
 		}
 	}
@@ -185,26 +185,14 @@ public class Valadoc.TypeReference : Basic {
 		}
 	}
 
-	private TypeParameter? find_template_parameter ( GenericType vtyperef ) {
-		Basic? element = this.parent;
-		while ( !(element is TemplateParameterListHandler || element == null) ) {
-			element = element.parent;
-		}
-
-		if ( element == null )
-			return null;
-
-		return ((TemplateParameterListHandler)element).find_vtemplateparameter ( (GenericType)vtyperef );
-	}
-
-	internal void set_type_references ( ) {
+	protected override void resolve_type_references () {
 		if ( this.vtyperef != null ) {
 			if ( this.vtyperef is PointerType )
 				this.data_type = new Pointer ( settings, (Vala.PointerType)this.vtyperef, this, head );
 			else if ( vtyperef is ArrayType )
 				this.data_type = new Array ( settings, (Vala.ArrayType)this.vtyperef, this, head );
 			else if ( vtyperef is GenericType )
-				 this.data_type = find_template_parameter ( (GenericType)vtyperef );
+				 this.data_type = (TypeParameter) this.head.search_vala_symbol (((Vala.ArrayType) this.vtyperef).type_parameter);
 		}
 
 
@@ -228,10 +216,10 @@ public class Valadoc.TypeReference : Basic {
 			}
 		}
 		else if ( this.data_type is Pointer ) {
-			((Pointer)this.data_type).set_type_references ();
+			((Pointer)this.data_type).resolve_type_references ();
 		}
 		else if ( this.data_type is Array ) {
-			((Array)this.data_type).set_type_references ();
+			((Array)this.data_type).resolve_type_references ();
 		}
 	}
 
diff --git a/src/libvaladoc/apitree/visitable.vala b/src/libvaladoc/apitree/visitable.vala
index 5ea1fcb..012d4a5 100644
--- a/src/libvaladoc/apitree/visitable.vala
+++ b/src/libvaladoc/apitree/visitable.vala
@@ -17,41 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using Vala;
 using GLib;
 using Gee;
 
+public interface Valadoc.Visitable : Api.Item {
 
+	protected abstract bool is_type_visitor_accessible (Valadoc.Basic element);
 
-public interface Valadoc.Visitable : Basic, SymbolAccessibility {
-	protected bool is_type_visitor_accessible (Valadoc.Basic element) {
-		if (!this.settings._private && this.is_private)
-			return false;
-
-		if (!this.settings._internal && this.is_internal)
-			return false;
-
-		if (!this.settings._protected && this.is_protected)
-			return false;
-
-		if (this.parent != element && !this.settings.add_inherited)
-				return false;
-
-		return true;
-	}
-
-	public bool is_visitor_accessible ( ) {
-		if (!this.settings._private && this.is_private)
-			return false;
-
-		if (!this.settings._internal && this.is_internal)
-			return false;
-
-		if (!this.settings._protected && this.is_protected)
-			return false;
-
-		return true;
-	}
+	public abstract bool is_visitor_accessible ();
 }
-
diff --git a/src/libvaladoc/documentation/documentationparser.vala b/src/libvaladoc/documentation/documentationparser.vala
index 91b25fb..6e3f24b 100644
--- a/src/libvaladoc/documentation/documentationparser.vala
+++ b/src/libvaladoc/documentation/documentationparser.vala
@@ -59,18 +59,9 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
 	private Parser _parser;
 	private WikiScanner _scanner;
 
-	public Comment? parse (DocumentedElement element) {
-		if (element.documentation != null) {
-			return element.documentation;
-		}
-
-		var comment = element.vcomment as Vala.Comment;
-		if (comment == null) {
-			return null;
-		}
-
-		weak string content = element.vcomment.content;
-		var source_ref = comment.source_reference;
+	public Comment? parse (DocumentedElement element, Vala.Comment source_comment) {
+		weak string content = source_comment.content;
+		var source_ref = source_comment.source_reference;
 		try {
 			Comment doc_comment = parse_comment (content, source_ref.file.filename, source_ref.first_line, source_ref.first_column);
 			doc_comment.check (_tree, element, _reporter);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]