diff --git a/src/Bridge/ASTVisitor.cs b/src/Bridge/ASTVisitor.cs
new file mode 100644
index 00000000..e6a29206
--- /dev/null
+++ b/src/Bridge/ASTVisitor.cs
@@ -0,0 +1,150 @@
+using System.Collections.Generic;
+
+namespace Cxxi
+{
+ ///
+ /// Base class for AST visitors.
+ /// You can override the methods to customize the behaviour, by default
+ /// this will visit all the nodes in a default way that should be useful
+ /// for a lot of applications.
+ ///
+ public abstract class AstVisitor : ITypeVisitor, IDeclVisitor
+ {
+ private readonly ISet Visited;
+
+ protected AstVisitor()
+ {
+ Visited = new HashSet();
+ }
+
+ public bool AlreadyVisited(Type type)
+ {
+ return !Visited.Add(type);
+ }
+
+ public bool AlreadyVisited(Declaration decl)
+ {
+ return !Visited.Add(decl);
+ }
+
+ public virtual bool VisitTagType(TagType tag, TypeQualifiers quals)
+ {
+ return tag.Declaration.Visit(this);
+ }
+
+ public virtual bool VisitArrayType(ArrayType array, TypeQualifiers quals)
+ {
+ return array.Type.Visit(this, quals);
+ }
+
+ public virtual bool VisitFunctionType(FunctionType function, TypeQualifiers quals)
+ {
+ if (function.ReturnType != null)
+ function.ReturnType.Visit(this);
+
+ foreach (var param in function.Arguments)
+ param.Visit(this);
+
+ return true;
+ }
+
+ public virtual bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
+ {
+ if (pointer.Pointee == null)
+ return false;
+
+ return pointer.Pointee.Visit(this, quals);
+ }
+
+ public virtual bool VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals)
+ {
+ return member.Pointee.Visit(this, quals);
+ }
+
+ public virtual bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
+ {
+ return true;
+ }
+
+ public virtual bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
+ {
+ return typedef.Declaration.Visit(this);
+ }
+
+ public virtual bool VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals)
+ {
+ return template.Template.Visit(this);
+ }
+
+ public virtual bool VisitDeclaration(Declaration decl, TypeQualifiers quals)
+ {
+ return VisitDeclaration(decl);
+ }
+
+ public virtual bool VisitDeclaration(Declaration decl)
+ {
+ return true;
+ }
+
+ public virtual bool VisitClassDecl(Class @class)
+ {
+ if (AlreadyVisited(@class))
+ return true;
+
+ return VisitDeclaration(@class);
+ }
+
+ public virtual bool VisitFieldDecl(Field field)
+ {
+ return field.Type.Visit(this);
+ }
+
+ public virtual bool VisitFunctionDecl(Function function)
+ {
+ if (function.ReturnType != null)
+ function.ReturnType.Visit(this);
+
+ foreach (var param in function.Parameters)
+ param.Visit(this);
+
+ return true;
+ }
+
+ public virtual bool VisitMethodDecl(Method method)
+ {
+ return VisitFunctionDecl(method);
+ }
+
+ public virtual bool VisitParameterDecl(Parameter parameter)
+ {
+ return parameter.Type.Visit(this);
+ }
+
+ public virtual bool VisitTypedefDecl(TypedefDecl typedef)
+ {
+ if (typedef.Type == null)
+ return false;
+ return typedef.Type.Visit(this);
+ }
+
+ public virtual bool VisitEnumDecl(Enumeration @enum)
+ {
+ return VisitDeclaration(@enum);
+ }
+
+ public virtual bool VisitClassTemplateDecl(ClassTemplate template)
+ {
+ return template.TemplatedClass.Visit(this);
+ }
+
+ public virtual bool VisitFunctionTemplateDecl(FunctionTemplate template)
+ {
+ return template.TemplatedFunction.Visit(this);
+ }
+
+ public virtual bool VisitMacroDefinition(MacroDefinition macro)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file