diff --git a/.gitignore b/.gitignore
index 9fd4eb1..83e3aca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 /_install/
+Makefile.config
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..a5b012a
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,6 @@
+*.svg
+*.uml
+*.pdf
+*.dot
+*.png
+.*
\ No newline at end of file
diff --git a/examples/Makefile b/examples/Makefile
index 3bca110..d3f16e2 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -5,11 +5,14 @@ LLVM_CONFIG ?= llvm-config
 .PHONY: all clean
 
 PDF = test.pdf StopWatch.pdf main.pdf Camera/Main.pdf Keyboard.pdf
+SVG = $(PDF:.pdf=.svg)
 
-all: $(PDF)
+# .SECONDARY: StopWatch.dot StopWatch.uml # may be used to say make not to delete these intermediate files
+
+all: $(PDF) $(SVG)
 
 clean:
-	rm -f $(PDF)
+	rm -f $(PDF) $(SVG)
 
 CLANG++ ?= $(shell $(LLVM_CONFIG) --bindir)/clang++
 ifeq ($(wildcard $(CLANG++)),)
@@ -20,11 +23,17 @@ VISUALIZER = -Xclang -load -Xclang ../src/visualizer.so -Xclang -plugin -Xclang
 %.o %.dot: %.cpp ../src/visualizer.so
 	$(CLANG++) $(VISUALIZER) $(CXXFLAGS) -c -o $(<:.cpp=.o) $<
 
+%.o %.uml: %.cpp ../src/visualizer.so
+	$(CLANG++) $(VISUALIZER) -Xclang -plugin-arg-visualize-statechart -Xclang -uml $(CXXFLAGS) -c -o $(<:.cpp=.o) $<
+
 %.eps: %.dot
 	dot -Tps $< > $@
 
 %.pdf: %.eps
 	epstopdf $< > $@
 
+%.svg: %.uml
+	java -jar /opt/plantuml/plantuml.jar $< -Tsvg
+
 ../src/visualizer:
 	$(MAKE) -C ../src
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..343e801
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,3 @@
+.*
+*.so
+boost-statechart-viewer
\ No newline at end of file
diff --git a/src/Makefile b/src/Makefile
index 71e2dce..1579f2c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,8 +18,8 @@ endif
 
 all: visualizer.so boost-statechart-viewer
 
-visualizer.so: visualizer.cpp
-	$(CXX) -g -fno-rtti -shared -Wall $(CLANG_LIBS) $(LLVM_FLAGS) -o $@ $<
+visualizer.so: visualizer.cpp printer.cpp
+	$(CXX) -g -fno-rtti -shared -Wall $(CLANG_LIBS) $(LLVM_FLAGS) -o $@ $^
 
 boost-statechart-viewer: boost-statechart-viewer.sh
 	sed -e s,@libdir@,$(LIBDIR), $< > $@
diff --git a/src/printer.cpp b/src/printer.cpp
new file mode 100644
index 0000000..8ea9e0f
--- /dev/null
+++ b/src/printer.cpp
@@ -0,0 +1,167 @@
+/** @file */
+////////////////////////////////////////////////////////////////////////////////////////
+//
+//    This file is part of Boost Statechart Viewer.
+//
+//    Boost Statechart Viewer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    Boost Statechart Viewer 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 Boost Statechart Viewer.  If not, see <http://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <iomanip>
+#include "printer.h"
+
+namespace Model
+{
+
+int getIndentLevelIdx() {
+	static int i = std::ios_base::xalloc();
+	return i;
+}
+
+std::ostream& indent(std::ostream& os) { os << std::setw(2*os.iword(getIndentLevelIdx())) << ""; return os; }
+std::ostream& indent_inc(std::ostream& os) { os.iword(getIndentLevelIdx())++; return os; }
+std::ostream& indent_dec(std::ostream& os) { os.iword(getIndentLevelIdx())--; return os; }
+
+struct DotModelPrinter : public IModelPrinter
+{
+    virtual void print(std::ostream &stream, const Model& model);
+    virtual const char* fileExtension() { return "dot"; }
+    void print(std::ostream &stream, const Machine& machine);
+    void print(std::ostream &stream, const Context& context);
+    void print(std::ostream &stream, const State& state);
+    void print(std::ostream &stream, const Transition& transition);
+};
+
+void DotModelPrinter::print(std::ostream &f, const Model& model)
+{
+    f << "digraph statecharts {\n" << indent_inc;
+    for (Model::const_iterator i = model.begin(), e = model.end(); i != e; i++)
+	print(f, i->second);
+    for (std::list<Transition*>::const_iterator t = model.transitions.begin(), e = model.transitions.end(); t != e; ++t)
+	print(f, **t);
+    f << indent_dec << "}\n";
+}
+
+void DotModelPrinter::print(std::ostream &os, const Machine& m)
+{
+    os << indent << "subgraph " << m.name << " {\n" << indent_inc;
+    os << indent << m.initial_state << " [peripheries=2]\n";
+    print(os, static_cast<Context>(m));
+    os << indent_dec << indent << "}\n";
+}
+
+void DotModelPrinter::print(std::ostream &os, const Context& c)
+{
+    for (Context::const_iterator i = c.begin(), e = c.end(); i != e; i++) {
+	print(os, *i->second);
+    }
+}
+
+void DotModelPrinter::print(std::ostream &os, const State& s)
+{
+    std::string label = s.name;
+    for (std::list<std::string>::const_iterator i = s.defferedEvents.begin(), e = s.defferedEvents.end(); i != e; ++i)
+	label.append("<br />").append(*i).append(" / defer");
+    for (std::list<std::string>::const_iterator i = s.inStateEvents.begin(), e = s.inStateEvents.end(); i != e; ++i)
+	label.append("<br />").append(*i).append(" / in state");
+    if (s.noTypedef) os << indent << s.name << " [label=<" << label << ">, color=\"red\"]\n";
+    else os << indent << s.name << " [label=<" << label << ">]\n";
+    if (s.size()) {
+	os << indent << s.name << " -> " << s.initialInnerState << " [style = dashed]\n";
+	os << indent << "subgraph cluster_" << s.name << " {\n" << indent_inc;
+	os << indent << "label = \"" << s.name << "\"\n";
+	os << indent << s.initialInnerState << " [peripheries=2]\n";
+	print(os, static_cast<Context>(s));
+	os << indent_dec << indent << "}\n";
+    }
+}
+
+void DotModelPrinter::print(std::ostream &os, const Transition& t)
+{
+    os << indent << t.src << " -> " << t.dst << " [label = \"" << t.event << "\"]\n";
+}
+
+
+struct PlantUMLModelPrinter : public IModelPrinter
+{
+    virtual void print(std::ostream &stream, const Model& model);
+    virtual const char* fileExtension() { return "uml"; }
+    void print(std::ostream &stream, const Machine& machine);
+    void print(std::ostream &stream, const Context& context);
+    void print(std::ostream &stream, const State& state);
+    void print(std::ostream &stream, const Transition& transition);
+};
+
+
+void PlantUMLModelPrinter::print(std::ostream &stream, const Model& model)
+{
+    stream << "@startuml" << std::endl;
+    stream << "skinparam shadowing false" << std::endl; // shadowing is beautiful but too resource-consuming
+    for (Model::const_iterator i = model.begin(), e = model.end(); i != e; i++)
+	print(stream, i->second);
+    for (std::list<Transition*>::const_iterator t = model.transitions.begin(), e = model.transitions.end(); t != e; ++t)
+	print(stream, **t);
+    stream << "@enduml" << std::endl;
+}
+
+void PlantUMLModelPrinter::print(std::ostream &stream, const Machine& machine)
+{
+    print(stream, static_cast<Context>(machine));
+}
+
+void PlantUMLModelPrinter::print(std::ostream &stream, const Context& context)
+{
+    for (Context::const_iterator i = context.begin(), e = context.end(); i != e; i++) {
+	print(stream, *i->second);
+    }
+}
+
+void PlantUMLModelPrinter::print(std::ostream &stream, const State& state)
+{
+    if (!state.empty()) {
+	stream << indent << "state " << state.name << " {" << indent_inc << std::endl;
+	if (state.initialInnerState != "")
+	    stream << indent << "[*] --> " << state.initialInnerState << std::endl;
+	print(stream, static_cast<Context>(state));
+	stream << indent_dec << indent << "}" << std::endl;
+    } else {
+	stream << indent << state.name << ":" << std::endl;
+    }
+    for (std::list<std::string>::const_iterator i = state.defferedEvents.begin(), e = state.defferedEvents.end(); i != e; ++i)
+	stream << indent << state.name << ":" << *i << " / defer" << std::endl;
+    for (std::list<std::string>::const_iterator i = state.inStateEvents.begin(), e = state.inStateEvents.end(); i != e; ++i)
+	stream << indent << state.name << ":" << *i << " / do" << std::endl;
+}
+
+void PlantUMLModelPrinter::print(std::ostream &stream, const Transition& transition)
+{
+    stream << indent << transition.src << " --> " << transition.dst << ": " << transition.event << std::endl;
+}
+
+
+
+
+
+
+boost::shared_ptr<IModelPrinter> IModelPrinter::create(ModelPrinterKind kind)
+{
+    switch (kind) {
+    case MODEL_PRINTER_DOT:		return boost::shared_ptr<IModelPrinter>(new DotModelPrinter());
+    case MODEL_PRINTER_PLANTUML:	return boost::shared_ptr<IModelPrinter>(new PlantUMLModelPrinter());
+    default:				return boost::shared_ptr<IModelPrinter>(new DotModelPrinter());
+    }
+}
+
+};
+
diff --git a/src/printer.h b/src/printer.h
new file mode 100644
index 0000000..6893e29
--- /dev/null
+++ b/src/printer.h
@@ -0,0 +1,28 @@
+#ifndef PRINTER_H_
+#define PRINTER_H_
+
+#include <ostream>
+#include <boost/shared_ptr.hpp>
+#include "visualizer.h"
+
+namespace Model
+{
+
+enum ModelPrinterKind
+{
+    MODEL_PRINTER_DOT,
+    MODEL_PRINTER_PLANTUML
+};
+
+struct IModelPrinter
+{
+    virtual ~IModelPrinter() {}
+    static boost::shared_ptr<IModelPrinter> create(ModelPrinterKind kind);
+
+    virtual void print(std::ostream &stream, const Model& model) = 0;
+    virtual const char* fileExtension() = 0;
+};
+
+}; //namespace
+
+#endif /* PRINTER_H_ */
diff --git a/src/visualizer.cpp b/src/visualizer.cpp
index f1c3e6b..848ffab 100644
--- a/src/visualizer.cpp
+++ b/src/visualizer.cpp
@@ -19,10 +19,7 @@
 ////////////////////////////////////////////////////////////////////////////////////////
 
 //standard header files
-#include <iomanip>
 #include <fstream>
-#include <map>
-#include <vector>
 
 //LLVM Header files
 #include "llvm/Support/raw_ostream.h"
@@ -36,45 +33,19 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 
+#include "visualizer.h"
+#include "printer.h"
+
 using namespace clang;
 using namespace std;
 
 namespace Model
 {
-
-    inline int getIndentLevelIdx() {
-	static int i = ios_base::xalloc();
-	return i;
-    }
-
-    ostream& indent(ostream& os) { os << setw(2*os.iword(getIndentLevelIdx())) << ""; return os; }
-    ostream& indent_inc(ostream& os) { os.iword(getIndentLevelIdx())++; return os; }
-    ostream& indent_dec(ostream& os) { os.iword(getIndentLevelIdx())--; return os; }
-
-    class State;
-
-    class Context : public map<string, State*> {
-    public:
-	iterator add(State *state);
-	Context *findContext(const string &name);
-    };
-
-    class State : public Context
-    {
-	string initialInnerState;
-	list<string> defferedEvents;
-	list<string> inStateEvents;
-	bool noTypedef;
-    public:
-	const string name;
-	explicit State(string name) : noTypedef(false), name(name) {}
-	void setInitialInnerState(string name) { initialInnerState = name; }
-	void addDeferredEvent(const string &name) { defferedEvents.push_back(name); }
-	void addInStateEvent(const string &name) { inStateEvents.push_back(name); }
-	void setNoTypedef() { noTypedef = true;}
-	friend ostream& operator<<(ostream& os, const State& s);
-    };
-
+    State::State(string name) : noTypedef(false), name(name) {}
+    void State::setInitialInnerState(string name) { initialInnerState = name; }
+    void State::addDeferredEvent(const string &name) { defferedEvents.push_back(name); }
+    void State::addInStateEvent(const string &name) { inStateEvents.push_back(name); }
+    void State::setNoTypedef() { noTypedef = true;}
 
     Context::iterator Context::add(State *state)
     {
@@ -95,140 +66,65 @@ namespace Model
 	return 0;
     }
 
-    ostream& operator<<(ostream& os, const Context& c);
+    Transition::Transition(string src, string dst, string event) : src(src), dst(dst), event(event) {}
 
-    ostream& operator<<(ostream& os, const State& s)
-    {
-	string label = s.name;
-	for (list<string>::const_iterator i = s.defferedEvents.begin(), e = s.defferedEvents.end(); i != e; ++i)
-	    label.append("<br />").append(*i).append(" / defer");
-	for (list<string>::const_iterator i = s.inStateEvents.begin(), e = s.inStateEvents.end(); i != e; ++i)
-	    label.append("<br />").append(*i).append(" / in state");
-	if (s.noTypedef) os << indent << s.name << " [label=<" << label << ">, color=\"red\"]\n";
-	else os << indent << s.name << " [label=<" << label << ">]\n";
-	if (s.size()) {
-	    os << indent << s.name << " -> " << s.initialInnerState << " [style = dashed]\n";
-	    os << indent << "subgraph cluster_" << s.name << " {\n" << indent_inc;
-	    os << indent << "label = \"" << s.name << "\"\n";
-	    os << indent << s.initialInnerState << " [peripheries=2]\n";
-	    os << static_cast<Context>(s);
-	    os << indent_dec << indent << "}\n";
-	}
-	return os;
-    }
+    Machine::Machine(string name) : name(name) {}
 
+    void Machine::setInitialState(string name) { initial_state = name; }
 
-    ostream& operator<<(ostream& os, const Context& c)
+    Model::iterator Model::add(const Machine &m)
     {
-	for (Context::const_iterator i = c.begin(), e = c.end(); i != e; i++) {
-	    os << *i->second;
-	}
-	return os;
+	pair<iterator, bool> ret =  insert(value_type(m.name, m));
+	return ret.first;
     }
 
-
-    class Transition
-    {
-    public:
-	const string src, dst, event;
-	Transition(string src, string dst, string event) : src(src), dst(dst), event(event) {}
-    };
-
-    ostream& operator<<(ostream& os, const Transition& t)
+    void Model::addUndefinedState(State *m)
     {
-	os << indent << t.src << " -> " << t.dst << " [label = \"" << t.event << "\"]\n";
-	return os;
+	undefined[m->name] = m;
     }
 
 
-    class Machine : public Context
-    {
-    protected:
-	string initial_state;
-    public:
-	const string name;
-	explicit Machine(string name) : name(name) {}
-
-	void setInitialState(string name) { initial_state = name; }
-
-	friend ostream& operator<<(ostream& os, const Machine& m);
-    };
-
-    ostream& operator<<(ostream& os, const Machine& m)
+    Context *Model::findContext(const string &name)
     {
-	os << indent << "subgraph " << m.name << " {\n" << indent_inc;
-	os << indent << m.initial_state << " [peripheries=2]\n";
-	os << static_cast<Context>(m);
-	os << indent_dec << indent << "}\n";
-	return os;
+	Context::iterator ci = undefined.find(name);
+	if (ci != undefined.end())
+	    return ci->second;
+	iterator i = find(name), e;
+	if (i != end())
+	    return &i->second;
+	for (i = begin(), e = end(); i != e; ++i) {
+	    Context *c = i->second.findContext(name);
+	    if (c)
+		return c;
+	}
+	return 0;
     }
 
-
-    class Model : public map<string, Machine>
+    State *Model::findState(const string &name)
     {
-	Context undefined;	// For forward-declared state classes
-    public:
-	list< Transition*> transitions;
-
-	iterator add(const Machine &m)
-	{
-	    pair<iterator, bool> ret =  insert(value_type(m.name, m));
-	    return ret.first;
-	}
-
-	void addUndefinedState(State *m)
-	{
-	    undefined[m->name] = m;
+	for (iterator i = begin(), e = end(); i != e; ++i) {
+	    Context *c = i->second.findContext(name);
+	    if (c)
+		return static_cast<State*>(c);
 	}
+	return 0;
+    }
 
 
-	Context *findContext(const string &name)
-	{
-	    Context::iterator ci = undefined.find(name);
-	    if (ci != undefined.end())
-		return ci->second;
-	    iterator i = find(name), e;
-	    if (i != end())
-		return &i->second;
-	    for (i = begin(), e = end(); i != e; ++i) {
-		Context *c = i->second.findContext(name);
-		if (c)
-		    return c;
-	    }
-	    return 0;
-	}
-
-	State *findState(const string &name)
-	{
-	    for (iterator i = begin(), e = end(); i != e; ++i) {
-		Context *c = i->second.findContext(name);
-		if (c)
-		    return static_cast<State*>(c);
-	    }
+    State *Model::removeFromUndefinedContexts(const string &name)
+    {
+	Context::iterator ci = undefined.find(name);
+	if (ci == undefined.end())
 	    return 0;
-	}
-
-
-	State *removeFromUndefinedContexts(const string &name)
-	{
-	    Context::iterator ci = undefined.find(name);
-	    if (ci == undefined.end())
-		return 0;
-	    undefined.erase(ci);
-	    return ci->second;
-	}
+	undefined.erase(ci);
+	return ci->second;
+    }
 
-	void write_as_dot_file(string fn)
-	{
-	    ofstream f(fn.c_str());
-	    f << "digraph statecharts {\n" << indent_inc;
-	    for (iterator i = begin(), e = end(); i != e; i++)
-		f << i->second;
-	    for (list<Transition*>::iterator t = transitions.begin(), e = transitions.end(); t != e; ++t)
-		f << **t;
-	    f << indent_dec << "}\n";
-	}
-    };
+    void Model::write_as_dot_file(string fn, boost::shared_ptr<IModelPrinter> printer)
+    {
+	ofstream f(fn.c_str());
+	printer->print(f, *this);
+    }
 };
 
 
@@ -572,50 +468,48 @@ class VisualizeStatechartConsumer : public clang::ASTConsumer
     Model::Model model;
     Visitor visitor;
     string destFileName;
+    boost::shared_ptr<Model::IModelPrinter> printer;
 public:
-    explicit VisualizeStatechartConsumer(ASTContext *Context, std::string destFileName,
+    explicit VisualizeStatechartConsumer(ASTContext *Context, std::string destFileName, boost::shared_ptr<Model::IModelPrinter> _printer,
 					 DiagnosticsEngine &D)
-	: visitor(Context, model, D), destFileName(destFileName) {}
+	: visitor(Context, model, D), destFileName(destFileName), printer(_printer) {}
 
     virtual void HandleTranslationUnit(clang::ASTContext &Context) {
 	visitor.TraverseDecl(Context.getTranslationUnitDecl());
 	visitor.printUnusedEventDefinitions();
-	model.write_as_dot_file(destFileName);
+	model.write_as_dot_file(destFileName, printer);
     }
 };
 
-class VisualizeStatechartAction : public PluginASTAction
-{
+class VisualizeStatechartAction: public PluginASTAction {
+    Model::ModelPrinterKind printerKind;
+public:
+    VisualizeStatechartAction() : printerKind(Model::MODEL_PRINTER_DOT) {}
 protected:
-  ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
-    size_t dot = getCurrentFile().find_last_of('.');
-    std::string dest = getCurrentFile().substr(0, dot);
-    dest.append(".dot");
-    return new VisualizeStatechartConsumer(&CI.getASTContext(), dest, CI.getDiagnostics());
-  }
-
-  bool ParseArgs(const CompilerInstance &CI,
-                 const std::vector<std::string>& args) {
-    for (unsigned i = 0, e = args.size(); i != e; ++i) {
-      llvm::errs() << "Visualizer arg = " << args[i] << "\n";
-
-      // Example error handling.
-      if (args[i] == "-an-error") {
-        DiagnosticsEngine &D = CI.getDiagnostics();
-        unsigned DiagID = D.getCustomDiagID(
-          DiagnosticsEngine::Error, "invalid argument '" + args[i] + "'");
-        D.Report(DiagID);
-        return false;
-      }
+    ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
+	size_t dot = getCurrentFile().find_last_of('.');
+	std::string dest = getCurrentFile().substr(0, dot);
+	boost::shared_ptr<Model::IModelPrinter> printer = Model::IModelPrinter::create(printerKind);
+	dest.append(".").append(printer->fileExtension());
+	return new VisualizeStatechartConsumer(&CI.getASTContext(), dest, printer, CI.getDiagnostics());
+    }
+
+    bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string>& args) {
+	for (unsigned i = 0, e = args.size(); i != e; ++i) {
+	    //llvm::errs() << "Visualizer arg = " << args[i] << "\n";
+	    if (args[i] == "-uml") {
+		printerKind = Model::MODEL_PRINTER_PLANTUML;
+	    }
+	}
+	if (args.size() && args[0] == "help")
+	    PrintHelp(llvm::errs());
+
+	return true;
+    }
+    void PrintHelp(llvm::raw_ostream& ros) {
+	ros << "Visualize Statechart plugin produces the graph files for all found boost::statechart statecharts\n";
+	ros  << "By default a dot file is produced, but you may specify -uml option to produce plantuml format\n";
     }
-    if (args.size() && args[0] == "help")
-      PrintHelp(llvm::errs());
-
-    return true;
-  }
-  void PrintHelp(llvm::raw_ostream& ros) {
-    ros << "Help for Visualize Statechart plugin goes here\n";
-  }
 
 };
 
diff --git a/src/visualizer.h b/src/visualizer.h
new file mode 100644
index 0000000..a8cc5dd
--- /dev/null
+++ b/src/visualizer.h
@@ -0,0 +1,83 @@
+#ifndef VISUALIZER_H_
+#define VISUALIZER_H_
+
+//standard header files
+#include <map>
+#include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+namespace Model
+{
+    class State;
+
+    class Context : public std::map<std::string, State*> {
+    public:
+	iterator add(State *state);
+	Context *findContext(const std::string &name);
+    };
+
+    class State : public Context
+    {
+	std::string initialInnerState;
+	std::list<std::string> defferedEvents;
+	std::list<std::string> inStateEvents;
+	bool noTypedef;
+    public:
+	const std::string name;
+	explicit State(std::string name);
+	void setInitialInnerState(std::string name);
+	void addDeferredEvent(const std::string &name);
+	void addInStateEvent(const std::string &name);
+	void setNoTypedef();
+
+	friend class DotModelPrinter;
+	friend class PlantUMLModelPrinter;
+    };
+
+    class Transition
+    {
+    public:
+	const std::string src, dst, event;
+	Transition(std::string src, std::string dst, std::string event);
+    };
+
+
+    class Machine : public Context
+    {
+    protected:
+	std::string initial_state;
+    public:
+	const std::string name;
+	explicit Machine(std::string name);
+
+	void setInitialState(std::string name);
+
+	friend class DotModelPrinter;
+	friend class PlantUMLModelPrinter;
+    };
+
+    struct IModelPrinter;
+
+    class Model : public std::map<std::string, Machine>
+    {
+	Context undefined;	// For forward-declared state classes
+    public:
+	std::list< Transition*> transitions;
+
+	iterator add(const Machine &m);
+
+	void addUndefinedState(State *m);
+
+	Context *findContext(const std::string &name);
+	State *findState(const std::string &name);
+
+	State *removeFromUndefinedContexts(const std::string &name);
+
+	void write_as_dot_file(std::string fn, boost::shared_ptr<IModelPrinter> printer);
+    };
+};
+
+
+
+#endif /* VISUALIZER_H_ */
