[gnote] Split Note and NoteManager into two



commit 1485784c68e8c50e8001bd06791a3bf9e3e337e9
Author: Aurimas Černius <aurisc4 gmail com>
Date:   Sat Feb 15 23:50:34 2014 +0200

    Split Note and NoteManager into two
    
    *Base classes will have non-gui code.
    Old classes extend new and add gui stuff.

 po/POTFILES.in                                     |    2 +
 src/Makefile.am                                    |    2 +
 src/addinmanager.cpp                               |    3 +-
 src/addins/backlinks/backlinkmenuitem.cpp          |    7 +-
 src/addins/backlinks/backlinkmenuitem.hpp          |   10 +-
 src/addins/backlinks/backlinksnoteaddin.cpp        |    4 +-
 src/addins/exporttohtml/notenameresolver.hpp       |    7 +-
 .../notedirectorywatcherapplicationaddin.cpp       |   12 +-
 .../notedirectorywatcherapplicationaddin.hpp       |    3 +-
 .../notedirectorywatcherpreferences.cpp            |    1 +
 src/addins/noteoftheday/noteoftheday.cpp           |   57 +-
 src/addins/noteoftheday/noteoftheday.hpp           |   11 +-
 .../noteoftheday/noteofthedaypreferences.cpp       |    6 +-
 src/addins/statistics/statisticswidget.cpp         |   10 +-
 .../stickynoteimport/stickynoteimportnoteaddin.cpp |    5 +-
 src/addins/tomboyimport/tomboyimportaddin.cpp      |    6 +-
 src/dbus/remotecontrol.cpp                         |   91 +--
 src/dbus/remotecontrol.hpp                         |   10 +-
 src/dbus/searchprovider.cpp                        |    8 +-
 src/note.cpp                                       |  666 ++------------------
 src/note.hpp                                       |  283 +-------
 src/noteaddin.hpp                                  |    4 +-
 src/notebase.cpp                                   |  675 ++++++++++++++++++++
 src/notebase.hpp                                   |  301 +++++++++
 src/notebooks/notebook.cpp                         |   26 +-
 src/notebooks/notebook.hpp                         |    4 +-
 src/notebooks/notebookapplicationaddin.cpp         |   26 +-
 src/notebooks/notebookapplicationaddin.hpp         |   10 +-
 src/notebooks/notebookmanager.cpp                  |   10 +-
 src/notebooks/notebookmanager.hpp                  |    4 +-
 src/notebooks/notebooknoteaddin.cpp                |   12 +-
 src/notebooks/notebooknoteaddin.hpp                |    6 +-
 src/notebooks/notebookstreeview.cpp                |    6 +-
 src/notemanager.cpp                                |  562 ++---------------
 src/notemanager.hpp                                |  110 +---
 src/notemanagerbase.cpp                            |  547 ++++++++++++++++
 src/notemanagerbase.hpp                            |  126 ++++
 src/noterenamedialog.cpp                           |   24 +-
 src/noterenamedialog.hpp                           |   12 +-
 src/notetag.hpp                                    |    9 +-
 src/notewindow.cpp                                 |   20 +-
 src/notewindow.hpp                                 |    6 +-
 src/preferencesdialog.cpp                          |    6 +-
 src/prefskeybinder.cpp                             |    8 +-
 src/recentchanges.cpp                              |    4 +-
 src/search.cpp                                     |    7 +-
 src/searchnoteswidget.cpp                          |   27 +-
 src/searchnoteswidget.hpp                          |   10 +-
 src/synchronization/gnotesyncclient.cpp            |    4 +-
 src/synchronization/gnotesyncclient.hpp            |    4 +-
 src/synchronization/silentui.cpp                   |   12 +-
 src/synchronization/syncdialog.cpp                 |    8 +-
 src/synchronization/syncmanager.cpp                |   73 ++-
 src/synchronization/syncmanager.hpp                |   10 +-
 src/synchronization/syncutils.cpp                  |    6 +-
 src/tag.cpp                                        |    6 +-
 src/tag.hpp                                        |   17 +-
 src/tagmanager.cpp                                 |    7 +-
 src/tray.cpp                                       |   13 +-
 src/watchers.cpp                                   |   40 +-
 src/watchers.hpp                                   |   16 +-
 61 files changed, 2132 insertions(+), 1850 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 49d12a5..6678587 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -63,7 +63,9 @@ src/notebooks/notebooknewnotemenuitem.cpp
 src/notebooks/notebooknoteaddin.cpp
 src/notebuffer.cpp
 src/note.cpp
+src/notebase.cpp
 src/notemanager.cpp
+src/notemanagerbase.cpp
 src/noterenamedialog.cpp
 src/notewindow.cpp
 src/preferencesdialog.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index f31985c..a9c3084 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -121,9 +121,11 @@ libgnote_la_SOURCES = \
        mainwindow.hpp mainwindow.cpp \
        mainwindowembeds.hpp mainwindowembeds.cpp \
        noteaddin.hpp noteaddin.cpp \
+       notebase.hpp notebase.cpp \
        notebuffer.hpp notebuffer.cpp \
        noteeditor.hpp noteeditor.cpp \
        notemanager.hpp notemanager.cpp \
+       notemanagerbase.hpp notemanagerbase.cpp \
        noterenamedialog.hpp noterenamedialog.cpp \
        notetag.hpp notetag.cpp \
        note.hpp note.cpp \
diff --git a/src/addinmanager.cpp b/src/addinmanager.cpp
index 9eb8530..0e7f988 100644
--- a/src/addinmanager.cpp
+++ b/src/addinmanager.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2009, 2010 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -37,6 +37,7 @@
 #include "addinpreferencefactory.hpp"
 #include "debug.hpp"
 #include "ignote.hpp"
+#include "preferences.hpp"
 #include "watchers.hpp"
 #include "notebooks/notebookapplicationaddin.hpp"
 #include "notebooks/notebooknoteaddin.hpp"
diff --git a/src/addins/backlinks/backlinkmenuitem.cpp b/src/addins/backlinks/backlinkmenuitem.cpp
index 7a43bca..c7882ab 100644
--- a/src/addins/backlinks/backlinkmenuitem.cpp
+++ b/src/addins/backlinks/backlinkmenuitem.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -24,6 +24,7 @@
 
 #include "ignote.hpp"
 #include "iconmanager.hpp"
+#include "note.hpp"
 #include "notewindow.hpp"
 
 #include "backlinkmenuitem.hpp"
@@ -81,7 +82,7 @@ Glib::RefPtr<Gdk::Pixbuf> BacklinkMenuItem::get_note_icon()
 }
 
 
-BacklinkMenuItem::BacklinkMenuItem(const gnote::Note::Ptr & note,
+BacklinkMenuItem::BacklinkMenuItem(const gnote::NoteBase::Ptr & note,
                                    const std::string & title_search)
   : Gtk::ImageMenuItem(note->get_title())
   , m_note(note)
@@ -97,7 +98,7 @@ void BacklinkMenuItem::on_activate()
     return;
   }
 
-  gnote::MainWindow::present_in_new_window(m_note,
+  gnote::MainWindow::present_in_new_window(static_pointer_cast<gnote::Note>(m_note),
     gnote::Preferences::obj().get_schema_settings(gnote::Preferences::SCHEMA_GNOTE)->
       get_boolean(gnote::Preferences::ENABLE_CLOSE_NOTE_ON_ESCAPE));
 }
diff --git a/src/addins/backlinks/backlinkmenuitem.hpp b/src/addins/backlinks/backlinkmenuitem.hpp
index ea1fae4..0bc710a 100644
--- a/src/addins/backlinks/backlinkmenuitem.hpp
+++ b/src/addins/backlinks/backlinkmenuitem.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -26,7 +26,7 @@
 #include <gtkmm/imagemenuitem.h>
 
 #include "base/macros.hpp"
-#include "note.hpp"
+#include "notebase.hpp"
 #include "notewindow.hpp"
 
 namespace backlinks {
@@ -54,14 +54,14 @@ class BacklinkMenuItem
   : public Gtk::ImageMenuItem
 {
 public:
-  BacklinkMenuItem(const gnote::Note::Ptr &, const std::string &);
+  BacklinkMenuItem(const gnote::NoteBase::Ptr &, const std::string &);
   
-  gnote::Note::Ptr get_note()
+  gnote::NoteBase::Ptr get_note()
     { return m_note; }
 protected:
   virtual void on_activate() override;
 private:
-  gnote::Note::Ptr   m_note;
+  gnote::NoteBase::Ptr   m_note;
   std::string m_title_search;
   
   static Glib::RefPtr<Gdk::Pixbuf> get_note_icon();
diff --git a/src/addins/backlinks/backlinksnoteaddin.cpp b/src/addins/backlinks/backlinksnoteaddin.cpp
index 0796c37..91de10a 100644
--- a/src/addins/backlinks/backlinksnoteaddin.cpp
+++ b/src/addins/backlinks/backlinksnoteaddin.cpp
@@ -93,8 +93,8 @@ void BacklinksNoteAddin::update_menu(Gtk::Menu *menu)
 
 void BacklinksNoteAddin::get_backlink_menu_items(std::list<BacklinkMenuItem*> & items)
 {
-  gnote::Note::List notes = get_note()->manager().get_notes_linking_to(get_note()->get_title());
-  FOREACH(const gnote::Note::Ptr & note, notes) {
+  gnote::NoteBase::List notes = get_note()->manager().get_notes_linking_to(get_note()->get_title());
+  FOREACH(const gnote::NoteBase::Ptr & note, notes) {
     if(note != get_note()) { // don't match ourself
       BacklinkMenuItem *item = manage(new BacklinkMenuItem(note, get_note()->get_title()));
 
diff --git a/src/addins/exporttohtml/notenameresolver.hpp b/src/addins/exporttohtml/notenameresolver.hpp
index 173009a..3c29b50 100644
--- a/src/addins/exporttohtml/notenameresolver.hpp
+++ b/src/addins/exporttohtml/notenameresolver.hpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -21,8 +22,8 @@
 
 
 #include "sharp/xmlresolver.hpp"
-#include "note.hpp"
-#include "notemanager.hpp"
+#include "notebase.hpp"
+#include "notemanagerbase.hpp"
 
 namespace exporttohtml {
 
@@ -30,7 +31,7 @@ class NoteNameResolver
   : public sharp::XmlResolver
 {
 public:
-  NoteNameResolver(const gnote::NoteManager &, const gnote::Note::Ptr &)
+  NoteNameResolver(const gnote::NoteManagerBase &, const gnote::NoteBase::Ptr &)
     {}
 };
 
diff --git a/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.cpp 
b/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.cpp
index a8d8fa8..c0d3dd6 100644
--- a/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.cpp
+++ b/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.cpp
@@ -26,6 +26,7 @@
 #include "notedirectorywatcherapplicationaddin.hpp"
 #include "notedirectorywatcherpreferencesfactory.hpp"
 #include "notemanager.hpp"
+#include "preferences.hpp"
 #include "sharp/files.hpp"
 #include "sharp/string.hpp"
 
@@ -49,7 +50,7 @@ NoteDirectoryWatcherApplicationAddin::NoteDirectoryWatcherApplicationAddin()
 void NoteDirectoryWatcherApplicationAddin::initialize()
 {
   gnote::NoteManager & manager(note_manager());
-  std::string note_path = manager.get_notes_dir();
+  const Glib::ustring & note_path = manager.notes_dir();
   m_signal_note_saved_cid = manager.signal_note_saved
     .connect(sigc::mem_fun(*this, &NoteDirectoryWatcherApplicationAddin::handle_note_saved));
 
@@ -82,7 +83,7 @@ bool NoteDirectoryWatcherApplicationAddin::initialized()
   return m_initialized;
 }
 
-void NoteDirectoryWatcherApplicationAddin::handle_note_saved(const gnote::Note::Ptr & note)
+void NoteDirectoryWatcherApplicationAddin::handle_note_saved(const gnote::NoteBase::Ptr & note)
 {
   m_note_save_times[note->id()] = sharp::DateTime::now();
 }
@@ -202,7 +203,7 @@ void NoteDirectoryWatcherApplicationAddin::delete_note(const std::string & note_
 
   std::string note_uri = make_uri(note_id);
 
-  gnote::Note::Ptr note_to_delete = note_manager().find_by_uri(note_uri);
+  gnote::NoteBase::Ptr note_to_delete = note_manager().find_by_uri(note_uri);
   if(note_to_delete != 0) {
     note_manager().delete_note(note_to_delete);
   }
@@ -213,8 +214,7 @@ void NoteDirectoryWatcherApplicationAddin::delete_note(const std::string & note_
 
 void NoteDirectoryWatcherApplicationAddin::add_or_update_note(const std::string & note_id)
 {
-  std::string note_path = Glib::build_filename(
-    note_manager().get_notes_dir(), note_id + ".note");
+  const Glib::ustring & note_path = Glib::build_filename(note_manager().notes_dir(), note_id + ".note");
   if (!sharp::file_exists(note_path)) {
     DBG_OUT("NoteDirectoryWatcher: Not processing update of %s because file does not exist.", 
note_path.c_str());
     return;
@@ -244,7 +244,7 @@ void NoteDirectoryWatcherApplicationAddin::add_or_update_note(const std::string
 
   std::string note_uri = make_uri(note_id);
 
-  gnote::Note::Ptr note = note_manager().find_by_uri(note_uri);
+  gnote::NoteBase::Ptr note = note_manager().find_by_uri(note_uri);
 
   bool is_new_note = false;
 
diff --git a/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.hpp 
b/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.hpp
index 6885cc6..b3ef84a 100644
--- a/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.hpp
+++ b/src/addins/notedirectorywatcher/notedirectorywatcherapplicationaddin.hpp
@@ -25,6 +25,7 @@
 
 #include <glibmm/threads.h>
 #include <giomm/filemonitor.h>
+#include <giomm/settings.h>
 
 #include "base/macros.hpp"
 #include "applicationaddin.hpp"
@@ -68,7 +69,7 @@ private:
   static std::string make_uri(const std::string & note_id);
 
   NoteDirectoryWatcherApplicationAddin();
-  void handle_note_saved(const gnote::Note::Ptr &);
+  void handle_note_saved(const gnote::NoteBase::Ptr &);
   void handle_file_system_change_event(const Glib::RefPtr<Gio::File> & file,
                                        const Glib::RefPtr<Gio::File> & other_file,
                                        Gio::FileMonitorEvent event_type);
diff --git a/src/addins/notedirectorywatcher/notedirectorywatcherpreferences.cpp 
b/src/addins/notedirectorywatcher/notedirectorywatcherpreferences.cpp
index 309c182..85e53ba 100644
--- a/src/addins/notedirectorywatcher/notedirectorywatcherpreferences.cpp
+++ b/src/addins/notedirectorywatcher/notedirectorywatcherpreferences.cpp
@@ -21,6 +21,7 @@
 #include <glibmm/i18n.h>
 
 #include "notedirectorywatcherpreferences.hpp"
+#include "preferences.hpp"
 
 namespace notedirectorywatcher {
 
diff --git a/src/addins/noteoftheday/noteoftheday.cpp b/src/addins/noteoftheday/noteoftheday.cpp
index 9320332..bafe6c5 100644
--- a/src/addins/noteoftheday/noteoftheday.cpp
+++ b/src/addins/noteoftheday/noteoftheday.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2013 Aurimas Cernius
+ * Copyright (C) 2013-2014 Aurimas Cernius
  * Copyright (C) 2009-2010 Debarshi Ray
  *
  * This program is free software: you can redistribute it and/or modify
@@ -29,18 +29,18 @@
 
 namespace noteoftheday {
 
-const std::string NoteOfTheDay::s_template_title
+const Glib::ustring NoteOfTheDay::s_template_title
                                   = _("Today: Template");
-const std::string NoteOfTheDay::s_title_prefix
+const Glib::ustring NoteOfTheDay::s_title_prefix
                                   = _("Today: ");
 
-gnote::Note::Ptr NoteOfTheDay::create(gnote::NoteManager & manager,
+gnote::NoteBase::Ptr NoteOfTheDay::create(gnote::NoteManager & manager,
                                       const Glib::Date & date)
 {
   const std::string title = get_title(date);
   const std::string xml = get_content(date, manager);
 
-  gnote::Note::Ptr notd;
+  gnote::NoteBase::Ptr notd;
   try {
     notd = manager.create(title, xml);
   }
@@ -49,7 +49,7 @@ gnote::Note::Ptr NoteOfTheDay::create(gnote::NoteManager & manager,
     ERR_OUT(_("NoteOfTheDay could not create %s: %s"),
             title.c_str(),
             e.what());
-    return gnote::Note::Ptr();
+    return gnote::NoteBase::Ptr();
   }
 
   // Automatically tag all new Note of the Day notes
@@ -61,16 +61,15 @@ gnote::Note::Ptr NoteOfTheDay::create(gnote::NoteManager & manager,
 
 void NoteOfTheDay::cleanup_old(gnote::NoteManager & manager)
 {
-  gnote::Note::List kill_list;
-  const gnote::Note::List & notes = manager.get_notes();
+  gnote::NoteBase::List kill_list;
+  const gnote::NoteBase::List & notes = manager.get_notes();
 
   Glib::Date date;
   date.set_time_current(); // time set to 00:00:00
 
-  for (gnote::Note::List::const_iterator iter = notes.begin();
-       notes.end() != iter; iter++) {
-    const std::string & title = (*iter)->get_title();
-    const sharp::DateTime & date_time = (*iter)->create_date();
+  FOREACH(const gnote::NoteBase::Ptr & note, notes) {
+    const Glib::ustring & title = note->get_title();
+    const sharp::DateTime & date_time = note->create_date();
 
     if (true == Glib::str_has_prefix(title, s_title_prefix)
         && s_template_title != title
@@ -78,16 +77,14 @@ void NoteOfTheDay::cleanup_old(gnote::NoteManager & manager)
              date_time.day(),
              static_cast<Glib::Date::Month>(date_time.month()),
              date_time.year()) != date
-        && !has_changed(*iter)) {
-      kill_list.push_back(*iter);
+        && !has_changed(note)) {
+      kill_list.push_back(note);
     }
   }
 
-  for (gnote::Note::List::const_iterator iter = kill_list.begin();
-       kill_list.end() != iter; iter++) {
-    DBG_OUT("NoteOfTheDay: Deleting old unmodified '%s'",
-            (*iter)->get_title().c_str());
-    manager.delete_note(*iter);
+  FOREACH(gnote::NoteBase::Ptr & note, kill_list) {
+    DBG_OUT("NoteOfTheDay: Deleting old unmodified '%s'", note->get_title().c_str());
+    manager.delete_note(note);
   }
 }
 
@@ -98,8 +95,7 @@ std::string NoteOfTheDay::get_content(
   const std::string title = get_title(date);
 
   // Attempt to load content from template
-  const gnote::Note::Ptr template_note = manager.find(
-                                                   s_template_title);
+  const gnote::NoteBase::Ptr template_note = manager.find(s_template_title);
 
   if (0 != template_note) {
     std::string xml_content = template_note->xml_content();
@@ -123,16 +119,15 @@ std::string NoteOfTheDay::get_content_without_title(
     return std::string();
 }
 
-gnote::Note::Ptr NoteOfTheDay::get_note_by_date(
+gnote::NoteBase::Ptr NoteOfTheDay::get_note_by_date(
                                  gnote::NoteManager & manager,
                                  const Glib::Date & date)
 {
-  const gnote::Note::List & notes = manager.get_notes();
+  const gnote::NoteBase::List & notes = manager.get_notes();
 
-  for (gnote::Note::List::const_iterator iter = notes.begin();
-       notes.end() != iter; iter++) {
-    const std::string & title = (*iter)->get_title();
-    const sharp::DateTime & date_time = (*iter)->create_date();
+  FOREACH(gnote::NoteBase::Ptr note, notes) {
+    const Glib::ustring & title = note->get_title();
+    const sharp::DateTime & date_time = note->create_date();
 
     if (true == Glib::str_has_prefix(title, s_title_prefix)
         && s_template_title != title
@@ -140,7 +135,7 @@ gnote::Note::Ptr NoteOfTheDay::get_note_by_date(
              date_time.day(),
              static_cast<Glib::Date::Month>(date_time.month()),
              date_time.year()) == date) {
-      return *iter;
+      return note;
     }
   }
 
@@ -167,7 +162,7 @@ std::string NoteOfTheDay::get_title(const Glib::Date & date)
   return s_title_prefix + date.format_string(_("%A, %B %d %Y"));
 }
 
-bool NoteOfTheDay::has_changed(const gnote::Note::Ptr & note)
+bool NoteOfTheDay::has_changed(const gnote::NoteBase::Ptr & note)
 {
   const sharp::DateTime & date_time = note->create_date();
   const std::string original_xml
@@ -175,9 +170,9 @@ bool NoteOfTheDay::has_changed(const gnote::Note::Ptr & note)
                     date_time.day(),
                     static_cast<Glib::Date::Month>(date_time.month()),
                     date_time.year()),
-                  note->manager());
+                    *static_cast<gnote::NoteManager*>(&note->manager()));
 
-  return get_content_without_title(note->text_content())
+  return get_content_without_title(static_pointer_cast<gnote::Note>(note)->text_content())
            == get_content_without_title(
                 gnote::utils::XmlDecoder::decode(original_xml))
          ? false
diff --git a/src/addins/noteoftheday/noteoftheday.hpp b/src/addins/noteoftheday/noteoftheday.hpp
index 17c17c1..1fe261c 100644
--- a/src/addins/noteoftheday/noteoftheday.hpp
+++ b/src/addins/noteoftheday/noteoftheday.hpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2014 Aurimas Cernius
  * Copyright (C) 2009 Debarshi Ray
  *
  * This program is free software: you can redistribute it and/or modify
@@ -40,27 +41,27 @@ class NoteOfTheDay
 {
 public:
 
-  static gnote::Note::Ptr create(gnote::NoteManager & manager,
+  static gnote::NoteBase::Ptr create(gnote::NoteManager & manager,
                                  const Glib::Date & date);
   static void cleanup_old(gnote::NoteManager & manager);
   static std::string get_content(const Glib::Date & date,
                                  const gnote::NoteManager & manager);
-  static gnote::Note::Ptr get_note_by_date(
+  static gnote::NoteBase::Ptr get_note_by_date(
                             gnote::NoteManager & manager,
                             const Glib::Date & date);
   static std::string get_template_content(
                        const std::string & title);
   static std::string get_title(const Glib::Date & date);
-  static bool has_changed(const gnote::Note::Ptr & note);
+  static bool has_changed(const gnote::NoteBase::Ptr & note);
 
-  static const std::string s_template_title;
+  static const Glib::ustring s_template_title;
 
 private:
 
   static std::string get_content_without_title(
                        const std::string & content);
 
-  static const std::string s_title_prefix;
+  static const Glib::ustring s_title_prefix;
 };
 
 }
diff --git a/src/addins/noteoftheday/noteofthedaypreferences.cpp 
b/src/addins/noteoftheday/noteofthedaypreferences.cpp
index 4218147..3432a76 100644
--- a/src/addins/noteoftheday/noteofthedaypreferences.cpp
+++ b/src/addins/noteoftheday/noteofthedaypreferences.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Debarshi Ray
  *
  * This program is free software: you can redistribute it and/or modify
@@ -57,7 +57,7 @@ NoteOfTheDayPreferences::~NoteOfTheDayPreferences()
 
 void NoteOfTheDayPreferences::open_template_button_clicked() const
 {
-  gnote::Note::Ptr template_note = m_note_manager.find(NoteOfTheDay::s_template_title);
+  gnote::NoteBase::Ptr template_note = m_note_manager.find(NoteOfTheDay::s_template_title);
 
   if (0 == template_note) {
     try {
@@ -76,7 +76,7 @@ void NoteOfTheDayPreferences::open_template_button_clicked() const
   }
 
   if(0 != template_note) {
-    gnote::IGnote::obj().open_note(template_note);
+    gnote::IGnote::obj().open_note(static_pointer_cast<gnote::Note>(template_note));
   }
 }
 
diff --git a/src/addins/statistics/statisticswidget.cpp b/src/addins/statistics/statisticswidget.cpp
index 495461f..bebbaed 100644
--- a/src/addins/statistics/statisticswidget.cpp
+++ b/src/addins/statistics/statisticswidget.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2013 Aurimas Cernius
+ * Copyright (C) 2013-2014 Aurimas Cernius
  *
  * 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
@@ -85,7 +85,7 @@ private:
   void build_stats()
     {
       clear();
-      gnote::Note::List notes = m_note_manager.get_notes();
+      gnote::NoteBase::List notes = m_note_manager.get_notes();
 
       Gtk::TreeIter iter = append();
       std::string stat = _("Total Notes:");
@@ -108,10 +108,10 @@ private:
       }
       gnote::Tag::Ptr template_tag = gnote::ITagManager::obj().get_or_create_system_tag(
         gnote::ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
-      for(gnote::Note::List::iterator note = notes.begin(); note != notes.end(); ++note) {
+      FOREACH(gnote::NoteBase::Ptr note, notes) {
         for(std::map<gnote::notebooks::Notebook::Ptr, int>::iterator nb = notebook_notes.begin();
             nb != notebook_notes.end(); ++nb) {
-          if((*note)->contains_tag(nb->first->get_tag()) && !(*note)->contains_tag(template_tag)) {
+          if(note->contains_tag(nb->first->get_tag()) && !note->contains_tag(template_tag)) {
             ++nb->second;
           }
         }
@@ -131,7 +131,7 @@ private:
       DBG_OUT("Statistics updated");
     }
 
-  void on_note_list_changed(const gnote::Note::Ptr &)
+  void on_note_list_changed(const gnote::NoteBase::Ptr &)
     {
       update();
     }
diff --git a/src/addins/stickynoteimport/stickynoteimportnoteaddin.cpp 
b/src/addins/stickynoteimport/stickynoteimportnoteaddin.cpp
index 0ddfb73..2e9d055 100644
--- a/src/addins/stickynoteimport/stickynoteimportnoteaddin.cpp
+++ b/src/addins/stickynoteimport/stickynoteimportnoteaddin.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2011,2013 Aurimas Cernius
+ * Copyright (C) 2010-2011,2013-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -296,9 +296,8 @@ bool StickyNoteImportNoteAddin::create_note_from_sticky(const char * stickyTitle
                                           % gnote::utils::XmlEncoder::encode(content));
 
   try {
-    Note::Ptr newNote = manager.create(title, noteXml);
+    gnote::NoteBase::Ptr newNote = manager.create(title, noteXml);
     newNote->queue_save (gnote::NO_CHANGE);
-    newNote->save();
     return true;
   } 
   catch (const std::exception & e) {
diff --git a/src/addins/tomboyimport/tomboyimportaddin.cpp b/src/addins/tomboyimport/tomboyimportaddin.cpp
index e8072ae..7aa66a2 100644
--- a/src/addins/tomboyimport/tomboyimportaddin.cpp
+++ b/src/addins/tomboyimport/tomboyimportaddin.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2011,2013 Aurimas Cernius
+ * Copyright (C) 2010-2011,2013-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -76,11 +76,11 @@ bool TomboyImportAddin::first_run(gnote::NoteManager & manager)
 
     for(std::list<std::string>::const_iterator iter = files.begin();
         iter != files.end(); ++iter) {
-      const std::string & file_path(*iter);
+      const Glib::ustring & file_path(*iter);
 
       to_import++;
 
-      Note::Ptr note = manager.import_note(file_path);
+      gnote::NoteBase::Ptr note = manager.import_note(file_path);
 
       if(note) {
         DBG_OUT("success");
diff --git a/src/dbus/remotecontrol.cpp b/src/dbus/remotecontrol.cpp
index 99a78f4..995df82 100644
--- a/src/dbus/remotecontrol.cpp
+++ b/src/dbus/remotecontrol.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -58,7 +58,7 @@ namespace gnote {
 
   bool RemoteControl::AddTagToNote(const std::string& uri, const std::string& tag_name)
   {
-    Note::Ptr note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note) {
       return false;
     }
@@ -70,9 +70,7 @@ namespace gnote {
 
   std::string RemoteControl::CreateNamedNote(const std::string& linked_title)
   {
-    Note::Ptr note;
-
-    note = m_manager.find (linked_title);
+    NoteBase::Ptr note = m_manager.find(linked_title);
     if (note)
       return "";
 
@@ -89,7 +87,7 @@ namespace gnote {
   std::string RemoteControl::CreateNote()
   {
     try {
-      Note::Ptr note = m_manager.create ();
+      NoteBase::Ptr note = m_manager.create ();
       return note->uri();
     } 
     catch(...)
@@ -100,9 +98,7 @@ namespace gnote {
 
   bool RemoteControl::DeleteNote(const std::string& uri)
   {
-    Note::Ptr note;
-
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note) {
       return false;
     }
@@ -114,9 +110,7 @@ namespace gnote {
 
   bool RemoteControl::DisplayNote(const std::string& uri)
   {
-    Note::Ptr note;
-
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note) {
       return false;
     }
@@ -128,9 +122,7 @@ namespace gnote {
 
   bool RemoteControl::DisplayNoteWithSearch(const std::string& uri, const std::string& search)
   {
-    Note::Ptr note;
-
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note) {
       return false;
     }
@@ -160,14 +152,14 @@ namespace gnote {
 
   std::string RemoteControl::FindNote(const std::string& linked_title)
   {
-    Note::Ptr note = m_manager.find (linked_title);
+    NoteBase::Ptr note = m_manager.find(linked_title);
     return (!note) ? "" : note->uri();
   }
 
 
   std::string RemoteControl::FindStartHereNote()
   {
-    Note::Ptr note = m_manager.find_by_uri (m_manager.start_note_uri());
+    NoteBase::Ptr note = m_manager.find_by_uri(m_manager.start_note_uri());
     return (!note) ? "" : note->uri();
   }
 
@@ -179,11 +171,10 @@ namespace gnote {
       return std::vector< std::string >();
 
     std::vector< std::string > tagged_note_uris;
-    std::list<Note *> notes;
+    std::list<NoteBase*> notes;
     tag->get_notes(notes);
-    for (std::list<Note *>::const_iterator iter = notes.begin();
-         iter != notes.end(); ++iter) {
-      tagged_note_uris.push_back((*iter)->uri());
+    FOREACH(NoteBase *iter, notes) {
+      tagged_note_uris.push_back(iter->uri());
     }
     return tagged_note_uris;
   }
@@ -191,8 +182,7 @@ namespace gnote {
 
   int32_t RemoteControl::GetNoteChangeDate(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return -1;
     return note->metadata_change_date().sec();
@@ -201,8 +191,7 @@ namespace gnote {
 
   std::string RemoteControl::GetNoteCompleteXml(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return "";
     return note->get_complete_note_xml();
@@ -212,18 +201,16 @@ namespace gnote {
 
   std::string RemoteControl::GetNoteContents(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return "";
-    return note->text_content();
+    return static_pointer_cast<Note>(note)->text_content();
   }
 
 
   std::string RemoteControl::GetNoteContentsXml(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return "";
     return note->xml_content();
@@ -232,8 +219,7 @@ namespace gnote {
 
   int32_t RemoteControl::GetNoteCreateDate(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return -1;
     return note->create_date().sec();
@@ -242,8 +228,7 @@ namespace gnote {
 
   std::string RemoteControl::GetNoteTitle(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return "";
     return note->get_title();
@@ -252,8 +237,7 @@ namespace gnote {
 
   std::vector< std::string > RemoteControl::GetTagsForNote(const std::string& uri)
   {
-    Note::Ptr note;
-    note = m_manager.find_by_uri (uri);
+    NoteBase::Ptr note = m_manager.find_by_uri(uri);
     if (!note)
       return std::vector< std::string >();
 
@@ -270,12 +254,11 @@ namespace gnote {
 
 bool RemoteControl::HideNote(const std::string& uri)
 {
-  Note::Ptr note;
-  note = m_manager.find_by_uri (uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   if (!note)
     return false;
 
-  NoteWindow *window = note->get_window();
+  NoteWindow *window = static_pointer_cast<Note>(note)->get_window();
   if(window == NULL) {
     return true;
   }
@@ -290,9 +273,8 @@ bool RemoteControl::HideNote(const std::string& uri)
 std::vector< std::string > RemoteControl::ListAllNotes()
 {
   std::vector< std::string > uris;
-  for(Note::List::const_iterator iter = m_manager.get_notes().begin();
-      iter != m_manager.get_notes().end(); ++iter) {
-    uris.push_back((*iter)->uri());
+  FOREACH(const NoteBase::Ptr & iter, m_manager.get_notes()) {
+    uris.push_back(iter->uri());
   }
   return uris;
 }
@@ -300,7 +282,7 @@ std::vector< std::string > RemoteControl::ListAllNotes()
 
 bool RemoteControl::NoteExists(const std::string& uri)
 {
-  Note::Ptr note = m_manager.find_by_uri (uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   return note != NULL;
 }
 
@@ -308,7 +290,7 @@ bool RemoteControl::NoteExists(const std::string& uri)
 bool RemoteControl::RemoveTagFromNote(const std::string& uri, 
                                       const std::string& tag_name)
 {
-  Note::Ptr note = m_manager.find_by_uri (uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   if (!note)
     return false;
   Tag::Ptr tag = ITagManager::obj().get_tag(tag_name);
@@ -343,8 +325,7 @@ std::vector< std::string > RemoteControl::SearchNotes(const std::string& query,
 bool RemoteControl::SetNoteCompleteXml(const std::string& uri, 
                                        const std::string& xml_contents)
 {
-  Note::Ptr note;
-  note = m_manager.find_by_uri(uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   if(!note) {
     return false;
   }
@@ -357,13 +338,12 @@ bool RemoteControl::SetNoteCompleteXml(const std::string& uri,
 bool RemoteControl::SetNoteContents(const std::string& uri, 
                                     const std::string& text_contents)
 {
-  Note::Ptr note;
-  note = m_manager.find_by_uri(uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   if(!note) {
     return false;
   }
 
-  note->set_text_content(text_contents);
+  static_pointer_cast<Note>(note)->set_text_content(text_contents);
   return true;
 }
 
@@ -371,8 +351,7 @@ bool RemoteControl::SetNoteContents(const std::string& uri,
 bool RemoteControl::SetNoteContentsXml(const std::string& uri, 
                                        const std::string& xml_contents)
 {
-  Note::Ptr note;
-  note = m_manager.find_by_uri(uri);
+  NoteBase::Ptr note = m_manager.find_by_uri(uri);
   if(!note) {
     return false;
   }
@@ -388,7 +367,7 @@ std::string RemoteControl::Version()
 
 
 
-void RemoteControl::on_note_added(const Note::Ptr & note)
+void RemoteControl::on_note_added(const NoteBase::Ptr & note)
 {
   if(note) {
     NoteAdded(note->uri());
@@ -396,7 +375,7 @@ void RemoteControl::on_note_added(const Note::Ptr & note)
 }
 
 
-void RemoteControl::on_note_deleted(const Note::Ptr & note)
+void RemoteControl::on_note_deleted(const NoteBase::Ptr & note)
 {
   if(note) {
     NoteDeleted(note->uri(), note->get_title());
@@ -404,7 +383,7 @@ void RemoteControl::on_note_deleted(const Note::Ptr & note)
 }
 
 
-void RemoteControl::on_note_saved(const Note::Ptr & note)
+void RemoteControl::on_note_saved(const NoteBase::Ptr & note)
 {
   if(note) {
     NoteSaved(note->uri());
@@ -412,10 +391,10 @@ void RemoteControl::on_note_saved(const Note::Ptr & note)
 }
 
 
-MainWindow & RemoteControl::present_note(const Note::Ptr & note)
+MainWindow & RemoteControl::present_note(const NoteBase::Ptr & note)
 {
   MainWindow & window = IGnote::obj().get_window_for_note();
-  MainWindow::present_in(window, note);
+  MainWindow::present_in(window, static_pointer_cast<Note>(note));
   return window;
 }
 
diff --git a/src/dbus/remotecontrol.hpp b/src/dbus/remotecontrol.hpp
index 04a816d..acccb5b 100644
--- a/src/dbus/remotecontrol.hpp
+++ b/src/dbus/remotecontrol.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -73,10 +73,10 @@ public:
   virtual std::string Version() override;
 
 private:
-  void on_note_added(const Note::Ptr &);
-  void on_note_deleted(const Note::Ptr &);
-  void on_note_saved(const Note::Ptr &);
-  MainWindow & present_note(const Note::Ptr &);
+  void on_note_added(const NoteBase::Ptr &);
+  void on_note_deleted(const NoteBase::Ptr &);
+  void on_note_saved(const NoteBase::Ptr &);
+  MainWindow & present_note(const NoteBase::Ptr &);
 
   NoteManager & m_manager;
 };
diff --git a/src/dbus/searchprovider.cpp b/src/dbus/searchprovider.cpp
index 4646e82..c9e8cba 100644
--- a/src/dbus/searchprovider.cpp
+++ b/src/dbus/searchprovider.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2013 Aurimas Cernius
+ * Copyright (C) 2013-2014 Aurimas Cernius
  *
  * 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
@@ -152,7 +152,7 @@ std::vector<std::map<Glib::ustring, Glib::ustring> > SearchProvider::GetResultMe
 {
   std::vector<std::map<Glib::ustring, Glib::ustring> > ret;
   for(std::vector<Glib::ustring>::const_iterator iter = identifiers.begin(); iter != identifiers.end(); 
++iter) {
-    gnote::Note::Ptr note = m_manager.find_by_uri(*iter);
+    gnote::NoteBase::Ptr note = m_manager.find_by_uri(*iter);
     if(note == 0) {
       continue;
     }
@@ -196,9 +196,9 @@ void SearchProvider::ActivateResult(const Glib::ustring & identifier,
                                     const std::vector<Glib::ustring> & /*terms*/,
                                     guint32 /*timestamp*/)
 {
-  gnote::Note::Ptr note = m_manager.find_by_uri(identifier);
+  gnote::NoteBase::Ptr note = m_manager.find_by_uri(identifier);
   if(note != 0) {
-    gnote::IGnote::obj().open_note(note);
+    gnote::IGnote::obj().open_note(static_pointer_cast<gnote::Note>(note));
   }
 }
 
diff --git a/src/note.cpp b/src/note.cpp
index c98a982..737e3fd 100644
--- a/src/note.cpp
+++ b/src/note.cpp
@@ -28,8 +28,6 @@
 #include <boost/bind.hpp>
 #include <boost/algorithm/string/find.hpp>
 
-#include <libxml/parser.h>
-
 #include <glibmm/i18n.h>
 #include <gtkmm/button.h>
 #include <gtkmm/stock.h>
@@ -40,27 +38,12 @@
 #include "noterenamedialog.hpp"
 #include "notetag.hpp"
 #include "notewindow.hpp"
-#include "itagmanager.hpp"
 #include "utils.hpp"
 #include "debug.hpp"
 #include "notebooks/notebookmanager.hpp"
 #include "sharp/exception.hpp"
 #include "sharp/fileinfo.hpp"
-#include "sharp/files.hpp"
-#include "sharp/map.hpp"
 #include "sharp/string.hpp"
-#include "sharp/xml.hpp"
-#include "sharp/xmlconvert.hpp"
-#include "sharp/xmlreader.hpp"
-#include "sharp/xmlwriter.hpp"
-
-#if HAVE_CXX11
-  #include <functional>
-  using std::hash;
-#else
-  #include <tr1/functional>
-  using std::tr1::hash;
-#endif
 
 
 namespace gnote {
@@ -181,11 +164,6 @@ namespace gnote {
     return (m_width != 0) && (m_height != 0);
   }
 
-  NoteDataBufferSynchronizer::~NoteDataBufferSynchronizer()
-  {
-    delete m_data;
-  }
-
   void NoteDataBufferSynchronizer::set_buffer(const Glib::RefPtr<NoteBuffer> & b)
   {
     m_buffer = b;
@@ -203,29 +181,29 @@ namespace gnote {
   const Glib::ustring & NoteDataBufferSynchronizer::text()
   {
     synchronize_text();
-    return m_data->text();
+    return data().text();
   }
 
   void NoteDataBufferSynchronizer::set_text(const Glib::ustring & t)
   {
-    m_data->text() = t;
+    data().text() = t;
     synchronize_buffer();
   }
 
   void NoteDataBufferSynchronizer::invalidate_text()
   {
-    m_data->text() = "";
+    data().text() = "";
   }
 
   bool NoteDataBufferSynchronizer::is_text_invalid() const
   {
-    return m_data->text().empty();
+    return data().text().empty();
   }
 
   void NoteDataBufferSynchronizer::synchronize_text() const
   {
     if(is_text_invalid() && m_buffer) {
-      m_data->text() = NoteBufferArchiver::serialize(m_buffer);
+      const_cast<NoteData&>(data()).text() = NoteBufferArchiver::serialize(m_buffer);
     }
   }
 
@@ -240,10 +218,10 @@ namespace gnote {
       // Load the stored xml text
       NoteBufferArchiver::deserialize (m_buffer,
                                        m_buffer->begin(),
-                                       m_data->text());
+                                       data().text());
       m_buffer->set_modified(false);
 
-      place_cursor_and_selection(*m_data, m_buffer);
+      place_cursor_and_selection(data(), m_buffer);
 
       // New events should create Undo actions
       m_buffer->undoer().thaw_undo ();
@@ -273,15 +251,13 @@ namespace gnote {
     }
   }
 
-  Note::Note(NoteData * _data, const std::string & filepath, NoteManager & _manager)
-    : m_data(_data)
-    , m_filepath(filepath)
+  Note::Note(NoteData * _data, const Glib::ustring & filepath, NoteManager & _manager)
+    : NoteBase(_data, filepath, _manager)
+    , m_data(_data)
     , m_save_needed(false)
     , m_is_deleting(false)
-    , m_enabled(true)
     , m_note_window_embedded(false)
     , m_focus_widget(NULL)
-    , m_manager(_manager)
     , m_window(NULL)
     , m_tag_table(NULL)
   {
@@ -300,26 +276,6 @@ namespace gnote {
   }
 
   /// <summary>
-  /// Returns a Tomboy URL from the given path.
-  /// </summary>
-  /// <param name="filepath">
-  /// A <see cref="System.String"/>
-  /// </param>
-  /// <returns>
-  /// A <see cref="System.String"/>
-  /// </returns>
-  std::string Note::url_from_path(const std::string & filepath)
-  {
-    return "note://gnote/" + sharp::file_basename(filepath);
-  }
-
-  int Note::get_hash_code() const
-  {
-    hash<std::string> h;
-    return h(get_title());
-  }
-
-  /// <summary>
   /// Creates a New Note with the given values.
   /// </summary>
   /// <param name="title">
@@ -334,8 +290,8 @@ namespace gnote {
   /// <returns>
   /// A <see cref="Note"/>
   /// </returns>
-  Note::Ptr Note::create_new_note(const std::string & title,
-                                  const std::string & filename,
+  Note::Ptr Note::create_new_note(const Glib::ustring & title,
+                                  const Glib::ustring & filename,
                                   NoteManager & manager)
   {
     NoteData * note_data = new NoteData(url_from_path(filename));
@@ -398,8 +354,9 @@ namespace gnote {
   
   Note::Ptr Note::load(const std::string & read_file, NoteManager & manager)
   {
-    NoteData *data = NoteArchiver::read(read_file, url_from_path(read_file));
-    return create_existing_note (data, read_file, manager);
+    NoteData *data = new NoteData(url_from_path(read_file));
+    NoteArchiver::read(read_file, *data);
+    return create_existing_note(data, read_file, manager);
   }
 
   
@@ -418,7 +375,7 @@ namespace gnote {
     DBG_OUT("Saving '%s'...", m_data.data().title().c_str());
 
     try {
-      NoteArchiver::write(m_filepath, m_data.synchronized_data());
+      NoteArchiver::write(file_path(), m_data.synchronized_data());
     } 
     catch (const sharp::Exception & e) {
       // Probably IOException or UnauthorizedAccessException?
@@ -426,7 +383,7 @@ namespace gnote {
       show_io_error_dialog(dynamic_cast<Gtk::Window*>(m_window->host()));
     }
 
-    m_signal_saved(shared_from_this());
+    signal_saved(shared_from_this());
   }
 
   
@@ -503,23 +460,7 @@ namespace gnote {
     m_save_timeout->reset(4000);
     if (!m_is_deleting)
       m_save_needed = true;
-      
-    switch (changeType)
-    {
-    case CONTENT_CHANGED:
-      // NOTE: Updating ChangeDate automatically updates MetdataChangeDate to match.
-      m_data.data().set_change_date(sharp::DateTime::now());
-      break;
-    case OTHER_DATA_CHANGED:
-      // Only update MetadataChangeDate.  Used by sync/etc
-      // to know when non-content note data has changed,
-      // but order of notes in menu and search UI is
-      // unaffected.
-      m_data.data().metadata_change_date() = sharp::DateTime::now();
-      break;
-    default:
-      break;
-    }
+    set_change_type(changeType);
   }
 
   void Note::on_save_timeout()
@@ -534,24 +475,6 @@ namespace gnote {
     }
   }
 
-  void Note::add_tag(const Tag::Ptr & tag)
-  {
-    if(!tag) {
-      throw sharp::Exception ("note::add_tag() called with a NULL tag.");
-    }
-    tag->add_note (*this);
-
-    NoteData::TagMap & thetags(m_data.data().tags());
-    if (thetags.find(tag->normalized_name()) == thetags.end()) {
-      thetags[tag->normalized_name()] = tag;
-
-      m_signal_tag_added(*this, tag);
-
-      DBG_OUT ("Tag added, queueing save");
-      queue_save(OTHER_DATA_CHANGED);
-    }
-  }
-
   void Note::remove_tag(Tag & tag)
   {
     std::string tag_name = tag.normalized_name();
@@ -567,7 +490,7 @@ namespace gnote {
       }
     }
 
-    m_signal_tag_removing(*this, tag);
+    signal_tag_removing(*this, tag);
 
     // don't erase the tag if we are deleting the note. 
     // This will invalidate the iterator.
@@ -577,29 +500,12 @@ namespace gnote {
     }
     tag.remove_note(*this);
 
-    m_signal_tag_removed(shared_from_this(), tag_name);
+    signal_tag_removed(shared_from_this(), tag_name);
 
     DBG_OUT("Tag removed, queueing save");
     queue_save(OTHER_DATA_CHANGED);
   }
 
-
-  void Note::remove_tag(const Tag::Ptr & tag)
-  {
-    if (!tag)
-      throw sharp::Exception ("Note.RemoveTag () called with a null tag.");
-    remove_tag(*tag);
-  }
-    
-  bool Note::contains_tag(const Tag::Ptr & tag) const
-  {
-    if(!tag) {
-      return false;
-    }
-    const NoteData::TagMap & thetags(m_data.data().tags());
-    return (thetags.find(tag->normalized_name()) != thetags.end());
-  }
-
   void Note::add_child_widget(const Glib::RefPtr<Gtk::TextChildAnchor> & child_anchor,
                               Gtk::Widget * widget)
   {
@@ -623,30 +529,6 @@ namespace gnote {
     }
   }
 
-  const std::string & Note::uri() const
-  {
-    return m_data.data().uri();
-  }
-
-  const std::string Note::id() const
-  {
-    // TODO: Store on Note instantiation
-    return sharp::string_replace_first(m_data.data().uri(), "note://gnote/","");
-  }
-
-
-  const Glib::ustring & Note::get_title() const
-  {
-    return m_data.data().title();
-  }
-
-
-  void Note::set_title(const Glib::ustring & new_title)
-  {
-    set_title(new_title, false);
-  }
-
-
   void Note::set_title(const Glib::ustring & new_title,
                        bool from_user_action)
   {
@@ -662,7 +544,7 @@ namespace gnote {
         process_rename_link_update(old_title);
       }
       else {
-        m_signal_renamed(shared_from_this(), old_title);
+        signal_renamed(shared_from_this(), old_title);
         queue_save(CONTENT_CHANGED);
       }
     }
@@ -671,8 +553,8 @@ namespace gnote {
 
   void Note::process_rename_link_update(const std::string & old_title)
   {
-    Note::List linking_notes = m_manager.get_notes_linking_to(old_title);
-    const Note::Ptr self = shared_from_this();
+    NoteBase::List linking_notes = manager().get_notes_linking_to(old_title);
+    const Note::Ptr self = static_pointer_cast<Note>(shared_from_this());
 
     if (!linking_notes.empty()) {
       Glib::RefPtr<Gio::Settings> settings = 
Preferences::obj().get_schema_settings(Preferences::SCHEMA_GNOTE);
@@ -687,18 +569,14 @@ namespace gnote {
         get_window()->editor()->set_editable(false);
       }
       else if (NOTE_RENAME_ALWAYS_REMOVE_LINKS == behavior) {
-        for (Note::List::const_iterator iter = linking_notes.begin();
-             linking_notes.end() != iter;
-             iter++) {
-          (*iter)->remove_links(old_title, self);
+        FOREACH(NoteBase::Ptr & iter, linking_notes) {
+          iter->remove_links(old_title, self);
           process_rename_link_update_end(Gtk::RESPONSE_NO, NULL, old_title, self);
         }
       }
       else if (NOTE_RENAME_ALWAYS_RENAME_LINKS == behavior) {
-        for (Note::List::const_iterator iter = linking_notes.begin();
-             linking_notes.end() != iter;
-             iter++) {
-          (*iter)->rename_links(old_title, self);
+        FOREACH(NoteBase::Ptr & iter, linking_notes) {
+          iter->rename_links(old_title, self);
           process_rename_link_update_end(Gtk::RESPONSE_NO, NULL, old_title, self);
         }
       }
@@ -718,9 +596,9 @@ namespace gnote {
 
       const NoteRenameDialog::MapPtr notes = dlg->get_notes();
 
-      for(std::map<Note::Ptr, bool>::const_iterator iter = notes->begin();
+      for(std::map<NoteBase::Ptr, bool>::const_iterator iter = notes->begin();
           notes->end() != iter; iter++) {
-        const std::pair<Note::Ptr, bool> p = *iter;
+        const std::pair<NoteBase::Ptr, bool> p = *iter;
         if(p.second && response == Gtk::RESPONSE_YES) { // Rename
           p.first->rename_links(old_title, self);
         }
@@ -732,7 +610,7 @@ namespace gnote {
       get_window()->editor()->set_editable(true);
     }
 
-    m_signal_renamed(shared_from_this(), old_title);
+    signal_renamed(shared_from_this(), old_title);
     queue_save(CONTENT_CHANGED);
   }
 
@@ -745,22 +623,8 @@ namespace gnote {
   }
 
 
-  void Note::rename_links(const Glib::ustring & old_title,
-                          const Ptr & renamed)
-  {
-    handle_link_rename(old_title, renamed, true);
-  }
-
-
-  void Note::remove_links(const Glib::ustring & old_title,
-                          const Ptr & renamed)
-  {
-    handle_link_rename(old_title, renamed, false);
-  }
-
-
   void Note::handle_link_rename(const Glib::ustring & old_title,
-                                const Ptr & renamed,
+                                const NoteBase::Ptr & renamed,
                                 bool rename)
   {
     // Check again, things may have changed
@@ -797,21 +661,14 @@ namespace gnote {
     }
   }
 
-
   void Note::rename_without_link_update(const Glib::ustring & newTitle)
   {
-    if (m_data.data().title() != newTitle) {
-      if (m_window) {
+    if(data_synchronizer().data().title() != newTitle) {
+      if(m_window) {
         m_window->set_name(newTitle);
       }
-
-      m_data.data().title() = newTitle;
-
-      // HACK:
-      m_signal_renamed(shared_from_this(), newTitle);
-
-      queue_save(CONTENT_CHANGED); // TODO: Right place for this?
     }
+    NoteBase::rename_without_link_update(newTitle);
   }
 
   void Note::set_xml_content(const Glib::ustring & xml)
@@ -821,123 +678,7 @@ namespace gnote {
       NoteBufferArchiver::deserialize(m_buffer, xml);
     } 
     else {
-      m_data.set_text(xml);
-    }
-  }
-
-  std::string Note::get_complete_note_xml()
-  {
-    return NoteArchiver::write_string(m_data.synchronized_data());
-  }
-
-  void Note::load_foreign_note_xml(const std::string & foreignNoteXml, ChangeType changeType)
-  {
-    if (foreignNoteXml.empty())
-      throw sharp::Exception ("foreignNoteXml");
-
-    // Arguments to this method cannot be trusted.  If this method
-    // were to throw an XmlException in the middle of processing,
-    // a note could be damaged.  Therefore, we check for parseability
-    // ahead of time, and throw early.
-    xmlDocPtr doc = xmlParseDoc((const xmlChar *)foreignNoteXml.c_str());
-
-    if(!doc) {
-      throw sharp::Exception("invalid XML in foreignNoteXml");
-    }
-    xmlFreeDoc(doc);
-
-    sharp::XmlReader xml;
-    xml.load_buffer(foreignNoteXml);
-
-    // Remove tags now, since a note with no tags has
-    // no "tags" element in the XML
-    std::list<Tag::Ptr> new_tags;
-    std::string name;
-
-    while (xml.read()) {
-      switch (xml.get_node_type()) {
-      case XML_READER_TYPE_ELEMENT:
-        name = xml.get_name();
-        if (name == "title") {
-          set_title(xml.read_string());
-        }
-        else if (name == "text") {
-          set_xml_content(xml.read_inner_xml());
-        }
-        else if (name == "last-change-date") {
-          m_data.data().set_change_date(
-            sharp::XmlConvert::to_date_time(xml.read_string()));
-        }
-        else if(name == "last-metadata-change-date") {
-          m_data.data().metadata_change_date() =
-            sharp::XmlConvert::to_date_time(xml.read_string());
-        }
-        else if(name == "create-date") {
-          m_data.data().create_date() =
-            sharp::XmlConvert::to_date_time(xml.read_string ());
-        }
-        else if(name == "tags") {
-          xmlDocPtr doc2 = xmlParseDoc((const xmlChar*)xml.read_outer_xml().c_str());
-          if(doc2) {
-            std::list<std::string> tag_strings;
-            parse_tags (doc2->children, tag_strings);
-            for(std::list<std::string>::const_iterator iter = tag_strings.begin();
-                iter != tag_strings.end(); ++iter) {
-              Tag::Ptr tag = ITagManager::obj().get_or_create_tag(*iter);
-              new_tags.push_back(tag);
-            }
-            xmlFreeDoc(doc2);
-          }
-          else {
-            DBG_OUT("loading tag subtree failed");
-          }
-        }
-        break;
-      default:
-        break;
-      }
-    }
-
-    xml.close ();
-
-    std::list<Tag::Ptr> tag_list;
-    get_tags(tag_list);
-    
-    for(std::list<Tag::Ptr>::const_iterator iter = tag_list.begin();
-        iter != tag_list.end(); ++iter) {
-      if(find(new_tags.begin(), new_tags.end(), *iter) == new_tags.end()) {
-        remove_tag(*iter);
-      }
-    }
-    for(std::list<Tag::Ptr>::const_iterator iter = new_tags.begin();
-        iter != new_tags.end(); ++iter) {
-      add_tag(*iter);
-    }
-    
-    // Allow method caller to specify ChangeType (mostly needed by sync)
-    queue_save (changeType);
-  }
-
-
-  void Note::parse_tags(const xmlNodePtr tagnodes, std::list<std::string> & tags)
-  {
-    sharp::XmlNodeSet nodes = sharp::xml_node_xpath_find(tagnodes, "//*");
-    
-    if(nodes.empty()) {
-      return;
-    }
-    for(sharp::XmlNodeSet::const_iterator iter = nodes.begin();
-        iter != nodes.end(); ++iter) {
-
-      const xmlNodePtr node = *iter;
-      if(xmlStrEqual(node->name, (const xmlChar*)"tag") && (node->type == XML_ELEMENT_NODE)) {
-        xmlChar * content = xmlNodeGetContent(node);
-        if(content) {
-          DBG_OUT("found tag %s", content);
-          tags.push_back((const char*)content);
-          xmlFree(content);
-        }
-      }
+      NoteBase::set_xml_content(xml);
     }
   }
 
@@ -959,31 +700,6 @@ namespace gnote {
     }
   }
 
-  const NoteData & Note::data() const
-  {
-    return m_data.synchronized_data();
-  }
-
-  NoteData & Note::data()
-  {
-    return m_data.synchronized_data();
-  }
-
-  const sharp::DateTime & Note::create_date() const
-  {
-    return m_data.data().create_date();
-  }
-
-  const sharp::DateTime & Note::change_date() const
-  {
-    return m_data.data().change_date();
-  }
-
-  const sharp::DateTime & Note::metadata_change_date() const
-  {
-    return m_data.data().metadata_change_date();
-  }
-
   const Glib::RefPtr<NoteTagTable> & Note::get_tag_table()
   {
     if (!m_tag_table) {
@@ -1048,7 +764,7 @@ namespace gnote {
       m_note_window_embedded = true;
     }
 
-    notebooks::NotebookManager::obj().active_notes_notebook()->add_note(shared_from_this());
+    
notebooks::NotebookManager::obj().active_notes_notebook()->add_note(static_pointer_cast<Note>(shared_from_this()));
   }
 
   void Note::on_note_window_foregrounded()
@@ -1064,13 +780,7 @@ namespace gnote {
 
   bool Note::is_special() const
   { 
-    return (m_manager.start_note_uri() == m_data.data().uri());
-  }
-
-
-  bool Note::is_new() const
-  {
-    return m_data.data().create_date().is_valid() && (m_data.data().create_date() > 
sharp::DateTime::now().add_hours(-24));
+    return manager().start_note_uri() == m_data.data().uri();
   }
 
   bool Note::is_pinned() const
@@ -1109,315 +819,21 @@ namespace gnote {
     notebooks::NotebookManager::obj().signal_note_pin_status_changed(*this, pinned);
   }
 
-  void Note::get_tags(std::list<Tag::Ptr> & l) const
-  {
-    sharp::map_get_values(m_data.data().tags(), l);
-  }
-
   void Note::enabled(bool is_enabled)
   {
-    m_enabled = is_enabled;
+    NoteBase::enabled(is_enabled);
     if(m_window) {
       Gtk::Window *window = dynamic_cast<Gtk::Window*>(m_window->host());
       if(window) {
-        if(!m_enabled) {
+        if(!enabled()) {
           m_focus_widget = window->get_focus();
         }
-        m_window->enabled(m_enabled);
-        if(m_enabled) {
+        m_window->enabled(enabled());
+        if(enabled()) {
           window->set_focus(*m_focus_widget);
         }
       }
     }
   }
 
-  const char *NoteArchiver::CURRENT_VERSION = "0.3";
-//  const char *NoteArchiver::DATE_TIME_FORMAT = "%Y-%m-%dT%T  7f@%z"; //"yyyy-MM-ddTHH:mm:ss.fffffffzzz";
-
-  //instance
-  NoteArchiver NoteArchiver::s_obj;
-
-
-  NoteData *NoteArchiver::read(const std::string & read_file, const std::string & uri)
-  {
-    return obj().read_file(read_file, uri);
-  }
-
-
-  NoteData *NoteArchiver::read_file(const std::string & file, const std::string & uri)
-  {
-    std::string version;
-    sharp::XmlReader xml(file);
-    NoteData *data = _read(xml, uri, version);
-    if(version != NoteArchiver::CURRENT_VERSION) {
-      try {
-        // Note has old format, so rewrite it.  No need
-        // to reread, since we are not adding anything.
-        DBG_OUT("Updating note XML from %s to newest format...", version.c_str());
-        NoteArchiver::write(file, *data);
-      }
-      catch(sharp::Exception & e) {
-        // write failure, but not critical
-        ERR_OUT(_("Failed to update note format: %s"), e.what());
-      }
-    }
-    return data;
-  }
-
-
-  NoteData *NoteArchiver::read(sharp::XmlReader & xml, const std::string & uri)
-  {
-    std::string version; // discarded
-    return _read(xml, uri, version);
-  }
-
-
-  NoteData *NoteArchiver::_read(sharp::XmlReader & xml, const std::string & uri, std::string & version)
-  {
-    NoteData *note = new NoteData(uri);
-
-    std::string name;
-
-    while (xml.read ()) {
-      switch (xml.get_node_type()) {
-      case XML_READER_TYPE_ELEMENT:
-        name = xml.get_name();
-        
-        if(name == "note") {
-          version = xml.get_attribute("version");
-        }
-        else if(name == "title") {
-          note->title() = xml.read_string();
-        } 
-        else if(name == "text") {
-          // <text> is just a wrapper around <note-content>
-          // NOTE: Use .text here to avoid triggering a save.
-          note->text() = xml.read_inner_xml();
-        }
-        else if(name == "last-change-date") {
-          note->set_change_date(
-            sharp::XmlConvert::to_date_time (xml.read_string()));
-        }
-        else if(name == "last-metadata-change-date") {
-          note->metadata_change_date() =
-            sharp::XmlConvert::to_date_time(xml.read_string());
-        }
-        else if(name == "create-date") {
-          note->create_date() =
-            sharp::XmlConvert::to_date_time (xml.read_string());
-        }
-        else if(name == "cursor-position") {
-          note->set_cursor_position(STRING_TO_INT(xml.read_string()));
-        }
-        else if(name == "selection-bound-position") {
-          note->set_selection_bound_position(STRING_TO_INT(xml.read_string()));
-        }
-        else if(name == "width") {
-          note->width() = STRING_TO_INT(xml.read_string());
-        }
-        else if(name == "height") {
-          note->height() = STRING_TO_INT(xml.read_string());
-        }
-        else if(name == "tags") {
-          xmlDocPtr doc2 = xmlParseDoc((const xmlChar*)xml.read_outer_xml().c_str());
-
-          if(doc2) {
-            std::list<std::string> tag_strings;
-            Note::parse_tags(doc2->children, tag_strings);
-            for(std::list<std::string>::const_iterator iter = tag_strings.begin();
-                iter != tag_strings.end(); ++iter) {
-              Tag::Ptr tag = ITagManager::obj().get_or_create_tag(*iter);
-              note->tags()[tag->normalized_name()] = tag;
-            }
-            xmlFreeDoc(doc2);
-          }
-          else {
-            DBG_OUT("loading tag subtree failed");
-          }
-        }
-        break;
-
-      default:
-        break;
-      }
-    }
-    xml.close ();
-
-    return note;
-  }
-
-  std::string NoteArchiver::write_string(const NoteData & note)
-  {
-    std::string str;
-    sharp::XmlWriter xml;
-    obj().write(xml, note);
-    xml.close();
-    str = xml.to_string();
-    return str;
-  }
-  
-
-  void NoteArchiver::write(const std::string & write_file, const NoteData & data)
-  {
-    obj().write_file(write_file, data);
-  }
-
-  void NoteArchiver::write_file(const std::string & _write_file, const NoteData & note)
-  {
-    try {
-      std::string tmp_file = _write_file + ".tmp";
-      // TODO Xml doc settings
-      sharp::XmlWriter xml(tmp_file); //, XmlEncoder::DocumentSettings);
-      write(xml, note);
-      xml.close();
-
-      if (sharp::file_exists(_write_file)) {
-        std::string backup_path = _write_file + "~";
-        if (sharp::file_exists(backup_path)) {
-          sharp::file_delete(backup_path);
-        }
-      
-        // Backup the to a ~ file, just in case
-        sharp::file_move(_write_file, backup_path);
-      
-        // Move the temp file to write_file
-        sharp::file_move(tmp_file, _write_file);
-
-        // Delete the ~ file
-        sharp::file_delete(backup_path);
-      } 
-      else {
-        // Move the temp file to write_file
-        sharp::file_move(tmp_file, _write_file);
-      }
-    }
-    catch(const std::exception & e)
-    {
-      ERR_OUT(_("Filesystem error: %s"), e.what());
-    }
-  }
-
-  void NoteArchiver::write(sharp::XmlWriter & xml, const NoteData & note)
-  {
-    xml.write_start_document();
-    xml.write_start_element("", "note", "http://beatniksoftware.com/tomboy";);
-    xml.write_attribute_string("",
-                             "version",
-                             "",
-                             CURRENT_VERSION);
-    xml.write_attribute_string("xmlns",
-                             "link",
-                             "",
-                             "http://beatniksoftware.com/tomboy/link";);
-    xml.write_attribute_string("xmlns",
-                             "size",
-                             "",
-                             "http://beatniksoftware.com/tomboy/size";);
-
-    xml.write_start_element ("", "title", "");
-    xml.write_string (note.title());
-    xml.write_end_element ();
-
-    xml.write_start_element ("", "text", "");
-    xml.write_attribute_string ("xml", "space", "", "preserve");
-    // Insert <note-content> blob...
-    xml.write_raw (note.text());
-    xml.write_end_element ();
-
-    xml.write_start_element ("", "last-change-date", "");
-    xml.write_string (
-      sharp::XmlConvert::to_string (note.change_date()));
-    xml.write_end_element ();
-
-    xml.write_start_element ("", "last-metadata-change-date", "");
-    xml.write_string (
-      sharp::XmlConvert::to_string (note.metadata_change_date()));
-    xml.write_end_element ();
-
-    if (note.create_date().is_valid()) {
-      xml.write_start_element ("", "create-date", "");
-      xml.write_string (
-        sharp::XmlConvert::to_string (note.create_date()));
-      xml.write_end_element ();
-    }
-
-    xml.write_start_element ("", "cursor-position", "");
-    xml.write_string(TO_STRING(note.cursor_position()));
-    xml.write_end_element ();
-
-    xml.write_start_element("", "selection-bound-position", "");
-    xml.write_string(TO_STRING(note.selection_bound_position()));
-    xml.write_end_element();
-
-    xml.write_start_element ("", "width", "");
-    xml.write_string(TO_STRING(note.width()));
-    xml.write_end_element ();
-
-    xml.write_start_element("", "height", "");
-    xml.write_string(TO_STRING(note.height()));
-    xml.write_end_element();
-
-    if (note.tags().size() > 0) {
-      xml.write_start_element ("", "tags", "");
-      for(NoteData::TagMap::const_iterator iter = note.tags().begin();
-          iter != note.tags().end(); ++iter) {
-        xml.write_start_element("", "tag", "");
-        xml.write_string(iter->second->name());
-        xml.write_end_element();
-      }
-      xml.write_end_element();
-    }
-
-    xml.write_end_element(); // Note
-    xml.write_end_document();
-
-  }
-  
-  std::string NoteArchiver::get_renamed_note_xml(const std::string & note_xml, 
-                                                 const std::string & old_title,
-                                                 const std::string & new_title) const
-  {
-    std::string updated_xml;
-    // Replace occurences of oldTitle with newTitle in noteXml
-    std::string titleTagPattern =  
-      str(boost::format("<title>%1%</title>") % old_title);
-    std::string titleTagReplacement =
-      str(boost::format("<title>%1%</title>") % new_title);
-    updated_xml = sharp::string_replace_regex(note_xml, titleTagPattern, titleTagReplacement);
-
-    std::string titleContentPattern =
-      str(boost::format("<note-content([^>]*)>\\s*%1%") % old_title);
-    std::string titleContentReplacement =
-      str(boost::format("<note-content\\1>%1%") % new_title);
-    std::string updated_xml2 = sharp::string_replace_regex(updated_xml, titleContentPattern, 
-                                                           titleContentReplacement);
-
-    return updated_xml2;
-
-  }
-
-  std::string NoteArchiver::get_title_from_note_xml(const std::string & noteXml) const
-  {
-    if (!noteXml.empty()) {
-      sharp::XmlReader xml;
-
-      xml.load_buffer(noteXml);
-
-      while (xml.read ()) {
-        switch (xml.get_node_type()) {
-        case XML_READER_TYPE_ELEMENT:
-          if (xml.get_name() == "title") {
-            return xml.read_string ();
-          }
-          break;
-        default:
-          break;
-        }
-      }
-    }
-
-    return "";
-  }
-  
-
 }
diff --git a/src/note.hpp b/src/note.hpp
index e6a5e9b..616c5f8 100644
--- a/src/note.hpp
+++ b/src/note.hpp
@@ -27,22 +27,12 @@
 #include <list>
 #include <string>
 #include <queue>
-#include <memory>
 
-#include <libxml/tree.h>
-
-#include <sigc++/signal.h>
 #include <gtkmm/textbuffer.h>
 
-#include "base/singleton.hpp"
-#include "tag.hpp"
+#include "notebase.hpp"
 #include "notebuffer.hpp"
 #include "utils.hpp"
-#include "sharp/datetime.hpp"
-
-namespace sharp {
-  class XmlWriter;
-}
 
 namespace gnote {
 
@@ -52,153 +42,33 @@ class NoteWindow;
 class NoteTagTable;
 
 
-class NoteData
-{
-public:
-  typedef std::map<std::string, Tag::Ptr> TagMap;
-  static const int s_noPosition;
-
-  NoteData(const std::string & _uri);
-
-  const std::string & uri() const
-    {
-      return m_uri;
-    }
-  const Glib::ustring & title() const
-    {
-      return m_title;
-    }
-  Glib::ustring & title()
-    {
-      return m_title;
-    }
-  const Glib::ustring & text() const
-    { 
-      return m_text;
-    }
-  Glib::ustring & text()
-    { 
-      return m_text;
-    }
-  const sharp::DateTime & create_date() const
-    {
-      return m_create_date;
-    }
-  sharp::DateTime & create_date()
-    {
-      return m_create_date;
-    }
-  const sharp::DateTime & change_date() const
-    {
-      return m_change_date;
-    }
-  void set_change_date(const sharp::DateTime & date)
-    {
-      m_change_date = date;
-      m_metadata_change_date = date;
-    }
-  const sharp::DateTime & metadata_change_date() const
-    {
-      return m_metadata_change_date;
-    }
-  sharp::DateTime & metadata_change_date()
-    {
-      return m_metadata_change_date;
-    }
-  int cursor_position() const
-    {
-      return m_cursor_pos;
-    }
-  void set_cursor_position(int new_pos)
-    {
-      m_cursor_pos = new_pos;
-    }
-  int selection_bound_position() const
-    {
-      return m_selection_bound_pos;
-    }
-  void set_selection_bound_position(int pos)
-    {
-      m_selection_bound_pos = pos;
-    }
-  int width() const
-    {
-      return m_width;
-    }
-  int & width()
-    {
-      return m_width;
-    }
-  int height() const
-    {
-      return m_height;
-    }
-  int & height()
-    {
-      return m_height;
-    }
-  const TagMap & tags() const
-    {
-      return m_tags;
-    }
-  TagMap & tags()
-    {
-      return m_tags;
-    }
-
-  void set_extent(int width, int height);
-  bool has_extent();
-
-private:
-  const std::string m_uri;
-  Glib::ustring     m_title;
-  Glib::ustring     m_text;
-  sharp::DateTime             m_create_date;
-  sharp::DateTime             m_change_date;
-  sharp::DateTime             m_metadata_change_date;
-  int               m_cursor_pos;
-  int               m_selection_bound_pos;
-  int               m_width, m_height;
-
-  TagMap m_tags;
-};
-
-
 class NoteDataBufferSynchronizer
+  : public NoteDataBufferSynchronizerBase
 {
 public:
   // takes ownership
   NoteDataBufferSynchronizer(NoteData * _data)
-    : m_data(_data)
+    : NoteDataBufferSynchronizerBase(_data)
     {
     }
-  ~NoteDataBufferSynchronizer();
 
-  const NoteData & synchronized_data() const
+  virtual const NoteData & synchronized_data() const override
     {
       synchronize_text();
-      return *m_data;
+      return data();
     }
-  NoteData & synchronized_data()
+  virtual NoteData & synchronized_data() override
     {
       synchronize_text();
-      return *m_data;
-    }
-  const NoteData & data() const
-    {
-      return *m_data;
-    }
-  NoteData & data()
-    {
-      return *m_data;
+      return data();
     }
   const Glib::RefPtr<NoteBuffer> & buffer() const
     {
       return m_buffer;
     }
   void set_buffer(const Glib::RefPtr<NoteBuffer> & b);
-  const Glib::ustring & text();
-  void set_text(const Glib::ustring & t);
+  virtual const Glib::ustring & text() override;
+  virtual void set_text(const Glib::ustring & t) override;
 
 private:
   void invalidate_text();
@@ -213,83 +83,44 @@ private:
                           const Gtk::TextBuffer::iterator &,
                           const Gtk::TextBuffer::iterator &);
 
-  NoteData * m_data;
   Glib::RefPtr<NoteBuffer> m_buffer;
 };
 
 
 class Note 
-  : public enable_shared_from_this<Note>
-  , public sigc::trackable
+  : public NoteBase
 {
 public:
   typedef shared_ptr<Note> Ptr;
   typedef weak_ptr<Note> WeakPtr;
   typedef std::list<Ptr> List;
 
-  typedef sigc::signal<void, const Note::Ptr&, const std::string& > RenamedHandler;
-  typedef sigc::signal<void, const Note::Ptr&>                      SavedHandler;
-  typedef sigc::signal<void, const Note&, const Tag::Ptr&>     TagAddedHandler;
-  typedef sigc::signal<void, const Note&, const Tag &>         TagRemovingHandler;  
-  typedef sigc::signal<void, const Note::Ptr&, const std::string&>  TagRemovedHandler;  
-
   ~Note();
 
 
-  static std::string url_from_path(const std::string &);
-  int get_hash_code() const;
-  static Note::Ptr create_new_note(const std::string & title,
-                                   const std::string & filename,
+  static Note::Ptr create_new_note(const Glib::ustring & title,
+                                   const Glib::ustring & filename,
                                    NoteManager & manager);
 
   static Note::Ptr create_existing_note(NoteData *data,
                                         std::string filepath,
                                         NoteManager & manager);
-  void delete_note();
+  virtual void delete_note() override;
   static Note::Ptr load(const std::string &, NoteManager &);
-  void save();
-  void queue_save(ChangeType c);
-  void add_tag(const Tag::Ptr &);
-  void remove_tag(Tag &);
-  void remove_tag(const Tag::Ptr &);
-  bool contains_tag(const Tag::Ptr &) const;
+  virtual void save() override;
+  virtual void queue_save(ChangeType c) override;
+  using NoteBase::remove_tag;
+  virtual void remove_tag(Tag &) override;
   void add_child_widget(const Glib::RefPtr<Gtk::TextChildAnchor> & child_anchor,
                         Gtk::Widget * widget);
 
-  const std::string & uri() const;
-  const std::string id() const;
-  const std::string & file_path() const
-    {
-      return m_filepath;
-    }
-  const Glib::ustring & get_title() const;
-  void set_title(const Glib::ustring & new_tile);
-  void set_title(const Glib::ustring & new_title, bool from_user_action);
-  void rename_without_link_update(const Glib::ustring & newTitle);
-  const Glib::ustring & xml_content()
-    {
-      return m_data.text();
-    }
-  void set_xml_content(const Glib::ustring & xml);
-  std::string get_complete_note_xml();
-  void load_foreign_note_xml(const std::string & foreignNoteXml, ChangeType changeType);
-  static void parse_tags(const xmlNodePtr tagnodes, std::list<std::string> & tags);
+  using NoteBase::set_title;
+  virtual void set_title(const Glib::ustring & new_title, bool from_user_action) override;
+  virtual void rename_without_link_update(const Glib::ustring & newTitle) override;
+  virtual void set_xml_content(const Glib::ustring & xml) override;
   Glib::ustring text_content();
   void set_text_content(const std::string & text);
-  const NoteData & data() const;
-  NoteData & data();
 
-  const sharp::DateTime & create_date() const;
-  const sharp::DateTime & change_date() const;
-  const sharp::DateTime & metadata_change_date() const;
-  NoteManager & manager()
-    {
-      return m_manager;
-    }
-  const NoteManager & manager() const
-    {
-      return m_manager;
-    }
   const Glib::RefPtr<NoteTagTable> & get_tag_table();
   bool has_buffer() const
     {
@@ -302,7 +133,6 @@ public:
     }
   NoteWindow * get_window();
   bool is_special() const;
-  bool is_new() const;
   bool is_loaded() const
     {
       return (m_buffer);
@@ -313,31 +143,24 @@ public:
     }
   bool is_pinned() const;
   void set_pinned(bool pinned) const;
-  void get_tags(std::list<Tag::Ptr> &) const;
-  bool enabled() const
-    {
-      return m_enabled;
-    }
-  void enabled(bool is_enabled);
+  using NoteBase::enabled;
+  virtual void enabled(bool is_enabled) override;
 
   sigc::signal<void,Note&> & signal_opened()
     { return m_signal_opened; }
-  RenamedHandler & signal_renamed()
-    { return m_signal_renamed; }
-  SavedHandler & signal_saved()
-    { return m_signal_saved; }
-  TagAddedHandler    & signal_tag_added()
-    { return m_signal_tag_added; }
-  TagRemovingHandler & signal_tag_removing()
-    { return m_signal_tag_removing; }
-  TagRemovedHandler  & signal_tag_removed()
-    { return m_signal_tag_removed; }
-
+protected:
+  virtual const NoteDataBufferSynchronizerBase & data_synchronizer() const override
+  {
+    return m_data;
+  }
+  virtual NoteDataBufferSynchronizerBase & data_synchronizer() override
+  {
+    return m_data;
+  }
 private:
   bool contains_text(const Glib::ustring & text);
-  void handle_link_rename(const Glib::ustring & old_title,
-                          const Ptr & renamed,
-                          bool rename);
+  virtual void handle_link_rename(const Glib::ustring & old_title,
+                                  const NoteBase::Ptr & renamed, bool rename) override;
   void on_buffer_changed();
   void on_buffer_tag_applied(const Glib::RefPtr<Gtk::TextTag> &tag, 
                              const Gtk::TextBuffer::iterator &, 
@@ -354,14 +177,10 @@ private:
   void process_rename_link_update(const std::string & old_title);
   void process_rename_link_update_end(int response, Gtk::Dialog *dialog,
                                       const std::string & old_title, const Note::Ptr & self);
-  void rename_links(const Glib::ustring & old_title,
-                    const Ptr & renamed);
-  void remove_links(const Glib::ustring & old_title,
-                    const Ptr & renamed);
   void on_note_window_embedded();
   void on_note_window_foregrounded();
 
-  Note(NoteData * data, const std::string & filepath, NoteManager & manager);
+  Note(NoteData * data, const Glib::ustring & filepath, NoteManager & manager);
 
   struct ChildWidgetData
   {
@@ -376,14 +195,11 @@ private:
   };
 
   NoteDataBufferSynchronizer m_data;
-  std::string                m_filepath;
   bool                       m_save_needed;
   bool                       m_is_deleting;
-  bool                       m_enabled;
   bool                       m_note_window_embedded;
 
   Gtk::Widget               *m_focus_widget;
-  NoteManager               &m_manager;
   NoteWindow                *m_window;
   Glib::RefPtr<NoteBuffer>   m_buffer;
   Glib::RefPtr<NoteTagTable> m_tag_table;
@@ -392,40 +208,11 @@ private:
   std::queue<ChildWidgetData> m_child_widget_queue;
 
   sigc::signal<void,Note&> m_signal_opened;
-  RenamedHandler     m_signal_renamed;
-  SavedHandler       m_signal_saved;
-  TagAddedHandler    m_signal_tag_added;
-  TagRemovingHandler m_signal_tag_removing;
-  TagRemovedHandler  m_signal_tag_removed;
 
   sigc::connection m_mark_set_conn;
   sigc::connection m_mark_deleted_conn;
 };
 
-class NoteArchiver
-  : public base::Singleton<NoteArchiver>
-{
-public:
-  static const char *CURRENT_VERSION;
-
-  static NoteData *read(const std::string & read_file, const std::string & uri);
-  static std::string write_string(const NoteData & data);
-  static void write(const std::string & write_file, const NoteData & data);
-  NoteData *read_file(const std::string & file, const std::string & uri);
-  NoteData *read(sharp::XmlReader & xml, const std::string & uri);
-  void write_file(const std::string & write_file, const NoteData & data);
-  void write(sharp::XmlWriter & xml, const NoteData & note);
-
-  std::string get_renamed_note_xml(const std::string &, const std::string &,
-                                   const std::string &) const;
-  std::string get_title_from_note_xml(const std::string & noteXml) const;
-
-protected:
-  NoteData *_read(sharp::XmlReader & xml, const std::string & uri, std::string & version);
-
-  static NoteArchiver s_obj;
-};
-
 namespace noteutils {
   void show_deletion_dialog (const std::list<Note::Ptr> & notes, Gtk::Window * parent);
 }
diff --git a/src/noteaddin.hpp b/src/noteaddin.hpp
index 21b396a..40c7f3b 100644
--- a/src/noteaddin.hpp
+++ b/src/noteaddin.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -101,7 +101,7 @@ public:
       return m_note->get_window();
     }
   Gtk::Window *get_host_window() const;
-  NoteManager & manager() const
+  NoteManagerBase & manager() const
     {
       return m_note->manager();
     }
diff --git a/src/notebase.cpp b/src/notebase.cpp
new file mode 100644
index 0000000..e15fe9b
--- /dev/null
+++ b/src/notebase.cpp
@@ -0,0 +1,675 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2011-2014 Aurimas Cernius
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <boost/format.hpp>
+#include <glibmm/i18n.h>
+
+#include "debug.hpp"
+#include "itagmanager.hpp"
+#include "notebase.hpp"
+#include "notemanagerbase.hpp"
+#include "sharp/exception.hpp"
+#include "sharp/files.hpp"
+#include "sharp/map.hpp"
+#include "sharp/string.hpp"
+#include "sharp/xml.hpp"
+#include "sharp/xmlconvert.hpp"
+
+#if HAVE_CXX11
+  #include <functional>
+  using std::hash;
+#else
+  #include <tr1/functional>
+  using std::tr1::hash;
+#endif
+
+
+
+namespace gnote {
+
+NoteDataBufferSynchronizerBase::~NoteDataBufferSynchronizerBase()
+{
+  delete m_data;
+}
+
+const Glib::ustring & NoteDataBufferSynchronizerBase::text()
+{
+  return data().text();
+}
+
+void NoteDataBufferSynchronizerBase::set_text(const Glib::ustring & t)
+{
+  data().text() = t;
+}
+
+
+
+Glib::ustring NoteBase::url_from_path(const Glib::ustring & filepath)
+{
+  return "note://gnote/" + sharp::file_basename(filepath);
+}
+
+void NoteBase::parse_tags(const xmlNodePtr tagnodes, std::list<Glib::ustring> & tags)
+{
+  sharp::XmlNodeSet nodes = sharp::xml_node_xpath_find(tagnodes, "//*");
+
+  if(nodes.empty()) {
+    return;
+  }
+  for(sharp::XmlNodeSet::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
+    const xmlNodePtr node = *iter;
+    if(xmlStrEqual(node->name, (const xmlChar*)"tag") && (node->type == XML_ELEMENT_NODE)) {
+      xmlChar * content = xmlNodeGetContent(node);
+      if(content) {
+        DBG_OUT("found tag %s", content);
+        tags.push_back((const char*)content);
+        xmlFree(content);
+      }
+    }
+  }
+}
+
+
+NoteBase::NoteBase(NoteData *, const Glib::ustring & filepath, NoteManagerBase & _manager)
+  : m_manager(_manager)
+  , m_file_path(filepath)
+  , m_enabled(true)
+{
+}
+
+int NoteBase::get_hash_code() const
+{
+  hash<std::string> h;
+  return h(get_title());
+}
+
+const std::string & NoteBase::uri() const
+{
+  return data_synchronizer().data().uri();
+}
+
+const std::string NoteBase::id() const
+{
+  return sharp::string_replace_first(data_synchronizer().data().uri(), "note://gnote/","");
+}
+
+const Glib::ustring & NoteBase::get_title() const
+{
+  return data_synchronizer().data().title();
+}
+
+void NoteBase::set_title(const Glib::ustring & new_title)
+{
+  set_title(new_title, false);
+}
+
+void NoteBase::set_title(const Glib::ustring & new_title, bool from_user_action)
+{
+  if(data_synchronizer().data().title() != new_title) {
+    Glib::ustring old_title = data_synchronizer().data().title();
+    data_synchronizer().data().title() = new_title;
+
+    if(from_user_action) {
+      process_rename_link_update(old_title);
+    }
+    else {
+      signal_renamed(shared_from_this(), old_title);
+      queue_save(CONTENT_CHANGED);
+    }
+  }
+}
+
+void NoteBase::process_rename_link_update(const Glib::ustring & old_title)
+{
+  NoteBase::List linking_notes = m_manager.get_notes_linking_to(old_title);
+  const NoteBase::Ptr self = shared_from_this();
+
+  if(!linking_notes.empty()) {
+    FOREACH(NoteBase::Ptr & note, linking_notes) {
+      note->rename_links(old_title, self);
+      signal_renamed(shared_from_this(), old_title);
+      queue_save(CONTENT_CHANGED);
+    }
+  }
+}
+
+void NoteBase::rename_without_link_update(const Glib::ustring & newTitle)
+{
+  if(data_synchronizer().data().title() != newTitle) {
+    data_synchronizer().data().title() = newTitle;
+
+    // HACK:
+    signal_renamed(shared_from_this(), newTitle);
+
+    queue_save(CONTENT_CHANGED); // TODO: Right place for this?
+  }
+}
+
+void NoteBase::queue_save(ChangeType c)
+{
+  set_change_type(c);
+  save();
+}
+
+void NoteBase::set_change_type(ChangeType c)
+{
+  switch(c)
+  {
+  case CONTENT_CHANGED:
+    // NOTE: Updating ChangeDate automatically updates MetdataChangeDate to match.
+    data_synchronizer().data().set_change_date(sharp::DateTime::now());
+    break;
+  case OTHER_DATA_CHANGED:
+    // Only update MetadataChangeDate.  Used by sync/etc
+    // to know when non-content note data has changed,
+    // but order of notes in menu and search UI is
+    // unaffected.
+    data_synchronizer().data().metadata_change_date() = sharp::DateTime::now();
+    break;
+  default:
+    break;
+  }
+}
+
+void NoteBase::save()
+{
+  try {
+    NoteArchiver::write(m_file_path, data_synchronizer().data());
+  } 
+  catch (const sharp::Exception & e) {
+    // Probably IOException or UnauthorizedAccessException?
+    ERR_OUT(_("Exception while saving note: %s"), e.what());
+  }
+
+  signal_saved(shared_from_this());
+}
+
+void NoteBase::rename_links(const Glib::ustring & old_title, const Ptr & renamed)
+{
+  handle_link_rename(old_title, renamed, true);
+}
+
+void NoteBase::remove_links(const Glib::ustring & old_title, const Ptr & renamed)
+{
+  handle_link_rename(old_title, renamed, false);
+}
+
+void NoteBase::handle_link_rename(const Glib::ustring &, const Ptr &, bool)
+{
+}
+
+void NoteBase::delete_note()
+{
+  // Remove the note from all the tags
+  for(NoteData::TagMap::const_iterator iter = data_synchronizer().data().tags().begin();
+      iter != data_synchronizer().data().tags().end(); ++iter) {
+    remove_tag(iter->second);
+  }
+}
+
+void NoteBase::add_tag(const Tag::Ptr & tag)
+{
+  if(!tag) {
+    throw sharp::Exception ("note::add_tag() called with a NULL tag.");
+  }
+  tag->add_note(*this);
+
+  NoteData::TagMap & thetags(data_synchronizer().data().tags());
+  if(thetags.find(tag->normalized_name()) == thetags.end()) {
+    thetags[tag->normalized_name()] = tag;
+
+    signal_tag_added(*this, tag);
+
+    DBG_OUT ("Tag added, queueing save");
+    queue_save(OTHER_DATA_CHANGED);
+  }
+}
+
+void NoteBase::remove_tag(Tag & tag)
+{
+  std::string tag_name = tag.normalized_name();
+  NoteData::TagMap & thetags(data_synchronizer().data().tags());
+  NoteData::TagMap::iterator iter;
+
+  iter = thetags.find(tag_name);
+  if(iter == thetags.end())  {
+    return;
+  }
+
+  signal_tag_removing(*this, tag);
+
+  thetags.erase(iter);
+  tag.remove_note(*this);
+
+  signal_tag_removed(shared_from_this(), tag_name);
+
+  DBG_OUT("Tag removed, queueing save");
+  queue_save(OTHER_DATA_CHANGED);
+}
+
+void NoteBase::remove_tag(const Tag::Ptr & tag)
+{
+  if(!tag)
+    throw sharp::Exception("Note.RemoveTag () called with a null tag.");
+  remove_tag(*tag);
+}
+
+bool NoteBase::contains_tag(const Tag::Ptr & tag) const
+{
+  if(!tag) {
+    return false;
+  }
+  const NoteData::TagMap & thetags(data_synchronizer().data().tags());
+  return (thetags.find(tag->normalized_name()) != thetags.end());
+}
+
+Glib::ustring NoteBase::get_complete_note_xml()
+{
+  return NoteArchiver::write_string(data_synchronizer().synchronized_data());
+}
+
+void NoteBase::set_xml_content(const Glib::ustring & xml)
+{
+  data_synchronizer().set_text(xml);
+}
+
+void NoteBase::load_foreign_note_xml(const Glib::ustring & foreignNoteXml, ChangeType changeType)
+{
+  if(foreignNoteXml.empty())
+    throw sharp::Exception("foreignNoteXml");
+
+  // Arguments to this method cannot be trusted.  If this method
+  // were to throw an XmlException in the middle of processing,
+  // a note could be damaged.  Therefore, we check for parseability
+  // ahead of time, and throw early.
+  xmlDocPtr doc = xmlParseDoc((const xmlChar *)foreignNoteXml.c_str());
+
+  if(!doc) {
+    throw sharp::Exception("invalid XML in foreignNoteXml");
+  }
+  xmlFreeDoc(doc);
+
+  sharp::XmlReader xml;
+  xml.load_buffer(foreignNoteXml);
+
+  // Remove tags now, since a note with no tags has
+  // no "tags" element in the XML
+  std::list<Tag::Ptr> new_tags;
+  std::string name;
+
+  while(xml.read()) {
+    switch(xml.get_node_type()) {
+    case XML_READER_TYPE_ELEMENT:
+      name = xml.get_name();
+      if(name == "title") {
+        set_title(xml.read_string());
+      }
+      else if(name == "text") {
+        set_xml_content(xml.read_inner_xml());
+      }
+      else if(name == "last-change-date") {
+        data_synchronizer().data().set_change_date(sharp::XmlConvert::to_date_time(xml.read_string()));
+      }
+      else if(name == "last-metadata-change-date") {
+        data_synchronizer().data().metadata_change_date() = 
sharp::XmlConvert::to_date_time(xml.read_string());
+      }
+      else if(name == "create-date") {
+        data_synchronizer().data().create_date() = sharp::XmlConvert::to_date_time(xml.read_string());
+      }
+      else if(name == "tags") {
+        xmlDocPtr doc2 = xmlParseDoc((const xmlChar*)xml.read_outer_xml().c_str());
+        if(doc2) {
+          std::list<Glib::ustring> tag_strings;
+          parse_tags(doc2->children, tag_strings);
+          FOREACH(Glib::ustring & tag_str, tag_strings) {
+            Tag::Ptr tag = ITagManager::obj().get_or_create_tag(tag_str);
+            new_tags.push_back(tag);
+          }
+          xmlFreeDoc(doc2);
+        }
+        else {
+          DBG_OUT("loading tag subtree failed");
+        }
+      }
+      break;
+    default:
+      break;
+    }
+  }
+
+  xml.close();
+
+  std::list<Tag::Ptr> tag_list;
+  get_tags(tag_list);
+
+  FOREACH(Tag::Ptr & iter, tag_list) {
+    if(find(new_tags.begin(), new_tags.end(), iter) == new_tags.end()) {
+      remove_tag(iter);
+    }
+  }
+  FOREACH(Tag::Ptr & iter, new_tags) {
+    add_tag(iter);
+  }
+    
+  // Allow method caller to specify ChangeType (mostly needed by sync)
+  queue_save(changeType);
+}
+
+void NoteBase::get_tags(std::list<Tag::Ptr> & l) const
+{
+  sharp::map_get_values(data_synchronizer().data().tags(), l);
+}
+
+const NoteData & NoteBase::data() const
+{
+  return data_synchronizer().synchronized_data();
+}
+
+NoteData & NoteBase::data()
+{
+  return data_synchronizer().synchronized_data();
+}
+
+const sharp::DateTime & NoteBase::create_date() const
+{
+  return data_synchronizer().data().create_date();
+}
+
+const sharp::DateTime & NoteBase::change_date() const
+{
+  return data_synchronizer().data().change_date();
+}
+
+const sharp::DateTime & NoteBase::metadata_change_date() const
+{
+  return data_synchronizer().data().metadata_change_date();
+}
+
+bool NoteBase::is_new() const
+{
+  const NoteDataBufferSynchronizerBase & sync(data_synchronizer());
+  return sync.data().create_date().is_valid() && (sync.data().create_date() > 
sharp::DateTime::now().add_hours(-24));
+}
+
+void NoteBase::enabled(bool is_enabled)
+{
+  m_enabled = is_enabled;
+}
+
+
+
+const char *NoteArchiver::CURRENT_VERSION = "0.3";
+
+//instance
+NoteArchiver NoteArchiver::s_obj;
+
+void NoteArchiver::read(const Glib::ustring & read_file, NoteData & data)
+{
+  return obj().read_file(read_file, data);
+}
+
+void NoteArchiver::read_file(const Glib::ustring & file, NoteData & data)
+{
+  Glib::ustring version;
+  sharp::XmlReader xml(file);
+  _read(xml, data, version);
+  if(version != NoteArchiver::CURRENT_VERSION) {
+    try {
+      // Note has old format, so rewrite it.  No need
+      // to reread, since we are not adding anything.
+      DBG_OUT("Updating note XML from %s to newest format...", version.c_str());
+      NoteArchiver::write(file, data);
+    }
+    catch(sharp::Exception & e) {
+      // write failure, but not critical
+      ERR_OUT(_("Failed to update note format: %s"), e.what());
+    }
+  }
+}
+
+void NoteArchiver::read(sharp::XmlReader & xml, NoteData & data)
+{
+  Glib::ustring version; // discarded
+  _read(xml, data, version);
+}
+
+
+void NoteArchiver::_read(sharp::XmlReader & xml, NoteData & data, Glib::ustring & version)
+{
+  std::string name;
+
+  while(xml.read ()) {
+    switch(xml.get_node_type()) {
+    case XML_READER_TYPE_ELEMENT:
+      name = xml.get_name();
+
+      if(name == "note") {
+        version = xml.get_attribute("version");
+      }
+      else if(name == "title") {
+        data.title() = xml.read_string();
+      } 
+      else if(name == "text") {
+        // <text> is just a wrapper around <note-content>
+        // NOTE: Use .text here to avoid triggering a save.
+        data.text() = xml.read_inner_xml();
+      }
+      else if(name == "last-change-date") {
+        data.set_change_date(sharp::XmlConvert::to_date_time (xml.read_string()));
+      }
+      else if(name == "last-metadata-change-date") {
+        data.metadata_change_date() = sharp::XmlConvert::to_date_time(xml.read_string());
+      }
+      else if(name == "create-date") {
+        data.create_date() = sharp::XmlConvert::to_date_time (xml.read_string());
+      }
+      else if(name == "cursor-position") {
+        data.set_cursor_position(STRING_TO_INT(xml.read_string()));
+      }
+      else if(name == "selection-bound-position") {
+        data.set_selection_bound_position(STRING_TO_INT(xml.read_string()));
+      }
+      else if(name == "width") {
+        data.width() = STRING_TO_INT(xml.read_string());
+      }
+      else if(name == "height") {
+        data.height() = STRING_TO_INT(xml.read_string());
+      }
+      else if(name == "tags") {
+        xmlDocPtr doc2 = xmlParseDoc((const xmlChar*)xml.read_outer_xml().c_str());
+
+        if(doc2) {
+          std::list<Glib::ustring> tag_strings;
+          NoteBase::parse_tags(doc2->children, tag_strings);
+          FOREACH(Glib::ustring & tag_str, tag_strings) {
+            Tag::Ptr tag = ITagManager::obj().get_or_create_tag(tag_str);
+            data.tags()[tag->normalized_name()] = tag;
+          }
+          xmlFreeDoc(doc2);
+        }
+        else {
+          DBG_OUT("loading tag subtree failed");
+        }
+      }
+      break;
+
+    default:
+      break;
+    }
+  }
+  xml.close ();
+}
+
+Glib::ustring NoteArchiver::write_string(const NoteData & note)
+{
+  std::string str;
+  sharp::XmlWriter xml;
+  obj().write(xml, note);
+  xml.close();
+  str = xml.to_string();
+  return str;
+}
+  
+
+void NoteArchiver::write(const Glib::ustring & write_file, const NoteData & data)
+{
+  obj().write_file(write_file, data);
+}
+
+void NoteArchiver::write_file(const Glib::ustring & _write_file, const NoteData & data)
+{
+  try {
+    std::string tmp_file = _write_file + ".tmp";
+    // TODO Xml doc settings
+    sharp::XmlWriter xml(tmp_file); //, XmlEncoder::DocumentSettings);
+    write(xml, data);
+    xml.close();
+
+    if(sharp::file_exists(_write_file)) {
+      std::string backup_path = _write_file + "~";
+      if(sharp::file_exists(backup_path)) {
+        sharp::file_delete(backup_path);
+      }
+
+      // Backup the to a ~ file, just in case
+      sharp::file_move(_write_file, backup_path);
+
+      // Move the temp file to write_file
+      sharp::file_move(tmp_file, _write_file);
+
+      // Delete the ~ file
+      sharp::file_delete(backup_path);
+    } 
+    else {
+      // Move the temp file to write_file
+      sharp::file_move(tmp_file, _write_file);
+    }
+  }
+  catch(const std::exception & e) {
+    ERR_OUT(_("Filesystem error: %s"), e.what());
+  }
+}
+
+void NoteArchiver::write(sharp::XmlWriter & xml, const NoteData & data)
+{
+  xml.write_start_document();
+  xml.write_start_element("", "note", "http://beatniksoftware.com/tomboy";);
+  xml.write_attribute_string("", "version", "", CURRENT_VERSION);
+  xml.write_attribute_string("xmlns", "link", "", "http://beatniksoftware.com/tomboy/link";);
+  xml.write_attribute_string("xmlns", "size", "", "http://beatniksoftware.com/tomboy/size";);
+
+  xml.write_start_element("", "title", "");
+  xml.write_string(data.title());
+  xml.write_end_element();
+
+  xml.write_start_element("", "text", "");
+  xml.write_attribute_string("xml", "space", "", "preserve");
+  // Insert <note-content> blob...
+  xml.write_raw(data.text());
+  xml.write_end_element();
+
+  xml.write_start_element("", "last-change-date", "");
+  xml.write_string(sharp::XmlConvert::to_string(data.change_date()));
+  xml.write_end_element();
+
+  xml.write_start_element("", "last-metadata-change-date", "");
+  xml.write_string(sharp::XmlConvert::to_string(data.metadata_change_date()));
+  xml.write_end_element();
+
+  if(data.create_date().is_valid()) {
+    xml.write_start_element("", "create-date", "");
+    xml.write_string(sharp::XmlConvert::to_string(data.create_date()));
+    xml.write_end_element();
+  }
+
+  xml.write_start_element("", "cursor-position", "");
+  xml.write_string(TO_STRING(data.cursor_position()));
+  xml.write_end_element();
+
+  xml.write_start_element("", "selection-bound-position", "");
+  xml.write_string(TO_STRING(data.selection_bound_position()));
+  xml.write_end_element();
+
+  xml.write_start_element ("", "width", "");
+  xml.write_string(TO_STRING(data.width()));
+  xml.write_end_element ();
+
+  xml.write_start_element("", "height", "");
+  xml.write_string(TO_STRING(data.height()));
+  xml.write_end_element();
+
+  if(data.tags().size() > 0) {
+    xml.write_start_element("", "tags", "");
+    for(NoteData::TagMap::const_iterator iter = data.tags().begin();
+        iter != data.tags().end(); ++iter) {
+      xml.write_start_element("", "tag", "");
+      xml.write_string(iter->second->name());
+      xml.write_end_element();
+    }
+    xml.write_end_element();
+  }
+
+  xml.write_end_element(); // Note
+  xml.write_end_document();
+}
+  
+Glib::ustring NoteArchiver::get_renamed_note_xml(const Glib::ustring & note_xml, 
+                                                 const Glib::ustring & old_title,
+                                                 const Glib::ustring & new_title) const
+{
+  std::string updated_xml;
+  // Replace occurences of oldTitle with newTitle in noteXml
+  std::string titleTagPattern =  str(boost::format("<title>%1%</title>") % old_title);
+  std::string titleTagReplacement = str(boost::format("<title>%1%</title>") % new_title);
+  updated_xml = sharp::string_replace_regex(note_xml, titleTagPattern, titleTagReplacement);
+
+  std::string titleContentPattern = str(boost::format("<note-content([^>]*)>\\s*%1%") % old_title);
+  std::string titleContentReplacement = str(boost::format("<note-content\\1>%1%") % new_title);
+  std::string updated_xml2 = sharp::string_replace_regex(updated_xml, titleContentPattern, 
titleContentReplacement);
+
+  return updated_xml2;
+}
+
+Glib::ustring NoteArchiver::get_title_from_note_xml(const Glib::ustring & noteXml) const
+{
+  if(!noteXml.empty()) {
+    sharp::XmlReader xml;
+
+    xml.load_buffer(noteXml);
+
+    while(xml.read ()) {
+      switch(xml.get_node_type()) {
+      case XML_READER_TYPE_ELEMENT:
+        if(xml.get_name() == "title") {
+          return xml.read_string ();
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  return "";
+}
+ 
+}
+
diff --git a/src/notebase.hpp b/src/notebase.hpp
new file mode 100644
index 0000000..a5352bc
--- /dev/null
+++ b/src/notebase.hpp
@@ -0,0 +1,301 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2011-2014 Aurimas Cernius
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _NOTEBASE_HPP_
+#define _NOTEBASE_HPP_
+
+#include <map>
+
+#include <glibmm/ustring.h>
+#include <sigc++/signal.h>
+
+#include "base/macros.hpp"
+#include "base/singleton.hpp"
+#include "tag.hpp"
+#include "sharp/datetime.hpp"
+#include "sharp/xmlreader.hpp"
+#include "sharp/xmlwriter.hpp"
+
+
+namespace gnote {
+
+class NoteManagerBase;
+
+
+class NoteData
+{
+public:
+  typedef std::map<std::string, Tag::Ptr> TagMap;
+
+  static const int s_noPosition;
+
+  NoteData(const std::string & _uri);
+
+  const std::string & uri() const
+    {
+      return m_uri;
+    }
+  const Glib::ustring & title() const
+    {
+      return m_title;
+    }
+  Glib::ustring & title()
+    {
+      return m_title;
+    }
+  const Glib::ustring & text() const
+    { 
+      return m_text;
+    }
+  Glib::ustring & text()
+    { 
+      return m_text;
+    }
+  const sharp::DateTime & create_date() const
+    {
+      return m_create_date;
+    }
+  sharp::DateTime & create_date()
+    {
+      return m_create_date;
+    }
+  const sharp::DateTime & change_date() const
+    {
+      return m_change_date;
+    }
+  void set_change_date(const sharp::DateTime & date)
+    {
+      m_change_date = date;
+      m_metadata_change_date = date;
+    }
+  const sharp::DateTime & metadata_change_date() const
+    {
+      return m_metadata_change_date;
+    }
+  sharp::DateTime & metadata_change_date()
+    {
+      return m_metadata_change_date;
+    }
+  int cursor_position() const
+    {
+      return m_cursor_pos;
+    }
+  void set_cursor_position(int new_pos)
+    {
+      m_cursor_pos = new_pos;
+    }
+  int selection_bound_position() const
+    {
+      return m_selection_bound_pos;
+    }
+  void set_selection_bound_position(int pos)
+    {
+      m_selection_bound_pos = pos;
+    }
+  int width() const
+    {
+      return m_width;
+    }
+  int & width()
+    {
+      return m_width;
+    }
+  int height() const
+    {
+      return m_height;
+    }
+  int & height()
+    {
+      return m_height;
+    }
+  const TagMap & tags() const
+    {
+      return m_tags;
+    }
+  TagMap & tags()
+    {
+      return m_tags;
+    }
+
+  void set_extent(int width, int height);
+  bool has_extent();
+
+private:
+  const std::string m_uri;
+  Glib::ustring     m_title;
+  Glib::ustring     m_text;
+  sharp::DateTime             m_create_date;
+  sharp::DateTime             m_change_date;
+  sharp::DateTime             m_metadata_change_date;
+  int               m_cursor_pos;
+  int               m_selection_bound_pos;
+  int               m_width, m_height;
+
+  TagMap m_tags;
+};
+
+
+class NoteDataBufferSynchronizerBase
+{
+public:
+  NoteDataBufferSynchronizerBase(NoteData *_data)
+    : m_data(_data)
+    {}
+  virtual ~NoteDataBufferSynchronizerBase();
+  const NoteData & data() const
+    {
+      return *m_data;
+    }
+  NoteData & data()
+    {
+      return *m_data;
+    }
+  virtual const NoteData & synchronized_data() const
+    {
+      return *m_data;
+    }
+  virtual NoteData & synchronized_data()
+    {
+      return *m_data;
+    }
+  virtual const Glib::ustring & text();
+  virtual void set_text(const Glib::ustring & t);
+private:
+  NoteData *m_data;
+};
+
+
+class NoteBase
+  : public enable_shared_from_this<NoteBase>
+  , public sigc::trackable
+{
+public:
+  typedef shared_ptr<NoteBase> Ptr;
+  typedef weak_ptr<NoteBase> WeakPtr;
+  typedef std::list<Ptr> List;
+
+  static Glib::ustring url_from_path(const Glib::ustring &);
+  static void parse_tags(const xmlNodePtr tagnodes, std::list<Glib::ustring> & tags);
+
+  NoteBase(NoteData *_data, const Glib::ustring & filepath, NoteManagerBase & manager);
+
+  NoteManagerBase & manager()
+    {
+      return m_manager;
+    }
+  const NoteManagerBase & manager() const
+    {
+      return m_manager;
+    }
+
+  int get_hash_code() const;
+  const std::string & uri() const;
+  const std::string id() const;
+  const Glib::ustring & get_title() const;
+  void set_title(const Glib::ustring & new_title);
+  virtual void set_title(const Glib::ustring & new_title, bool from_user_action);
+  virtual void rename_without_link_update(const Glib::ustring & newTitle);
+
+  virtual void queue_save(ChangeType c);
+  virtual void save();
+  void rename_links(const Glib::ustring & old_title, const Ptr & renamed);
+  void remove_links(const Glib::ustring & old_title, const Ptr & renamed);
+  virtual void delete_note();
+  void add_tag(const Tag::Ptr &);
+  virtual void remove_tag(Tag &);
+  void remove_tag(const Tag::Ptr &);
+  bool contains_tag(const Tag::Ptr &) const;
+
+  const Glib::ustring & file_path() const
+    {
+      return m_file_path;
+    }
+  Glib::ustring get_complete_note_xml();
+  const Glib::ustring & xml_content()
+    {
+      return data_synchronizer().text();
+    }
+  virtual void set_xml_content(const Glib::ustring & xml);
+  void load_foreign_note_xml(const Glib::ustring & foreignNoteXml, ChangeType changeType);
+  void get_tags(std::list<Tag::Ptr> &) const;
+  const NoteData & data() const;
+  NoteData & data();
+
+  const sharp::DateTime & create_date() const;
+  const sharp::DateTime & change_date() const;
+  const sharp::DateTime & metadata_change_date() const;
+  bool is_new() const;
+  bool enabled() const
+    {
+      return m_enabled;
+    }
+  virtual void enabled(bool is_enabled);
+
+  typedef sigc::signal<void, const NoteBase::Ptr &> SavedHandler;
+  SavedHandler signal_saved;
+  typedef sigc::signal<void, const NoteBase::Ptr&, const std::string& > RenamedHandler;
+  RenamedHandler signal_renamed;
+  typedef sigc::signal<void, const NoteBase&, const Tag::Ptr&> TagAddedHandler;
+  TagAddedHandler signal_tag_added;
+  typedef sigc::signal<void, const NoteBase&, const Tag &> TagRemovingHandler;  
+  TagRemovingHandler signal_tag_removing;
+  typedef sigc::signal<void, const NoteBase::Ptr&, const std::string&> TagRemovedHandler;  
+  TagRemovedHandler signal_tag_removed;
+protected:
+  virtual const NoteDataBufferSynchronizerBase & data_synchronizer() const = 0;
+  virtual NoteDataBufferSynchronizerBase & data_synchronizer() = 0;
+  virtual void process_rename_link_update(const Glib::ustring & old_title);
+  void set_change_type(ChangeType c);
+  virtual void handle_link_rename(const Glib::ustring & old_title, const Ptr & renamed, bool rename);
+private:
+  NoteManagerBase & m_manager;
+  Glib::ustring m_file_path;
+  bool m_enabled;
+};
+
+
+class NoteArchiver
+  : public base::Singleton<NoteArchiver>
+{
+public:
+  static const char *CURRENT_VERSION;
+
+  static void read(const Glib::ustring & read_file, NoteData & data);
+  static Glib::ustring write_string(const NoteData & data);
+  static void write(const Glib::ustring & write_file, const NoteData & data);
+  void read_file(const Glib::ustring & file, NoteData & data);
+  void read(sharp::XmlReader & xml, NoteData & data);
+  void write_file(const Glib::ustring & write_file, const NoteData & data);
+  void write(sharp::XmlWriter & xml, const NoteData & data);
+
+  Glib::ustring get_renamed_note_xml(const Glib::ustring &, const Glib::ustring &, const Glib::ustring &) 
const;
+  Glib::ustring get_title_from_note_xml(const Glib::ustring & noteXml) const;
+protected:
+  void _read(sharp::XmlReader & xml, NoteData & data, Glib::ustring & version);
+
+  static NoteArchiver s_obj;
+};
+
+
+}
+
+#endif
+
diff --git a/src/notebooks/notebook.cpp b/src/notebooks/notebook.cpp
index 36a6541..7e5a72e 100644
--- a/src/notebooks/notebook.cpp
+++ b/src/notebooks/notebook.cpp
@@ -133,11 +133,11 @@ namespace notebooks {
     if(!templ_tag || !notebook_tag) {
       return note;
     }
-    std::list<Note*> notes;
+    std::list<NoteBase*> notes;
     templ_tag->get_notes(notes);
-    FOREACH(Note *n, notes) {
+    FOREACH(NoteBase *n, notes) {
       if(n->contains_tag(notebook_tag)) {
-        note = n->shared_from_this();
+        note = static_pointer_cast<Note>(n->shared_from_this());
         break;
       }
     }
@@ -147,19 +147,19 @@ namespace notebooks {
 
   Note::Ptr Notebook::get_template_note() const
   {
-    Note::Ptr note = find_template_note();
+    NoteBase::Ptr note = find_template_note();
 
     if (!note) {
       std::string title = m_default_template_note_title;
       if(m_note_manager.find(title)) {
-        std::list<Note*> tag_notes;
+        std::list<NoteBase*> tag_notes;
         m_tag->get_notes(tag_notes);
         title = m_note_manager.get_unique_name(title);
       }
       note = m_note_manager.create(title, NoteManager::get_note_template_content (title));
           
       // Select the initial text
-      NoteBuffer::Ptr buffer = note->get_buffer();
+      NoteBuffer::Ptr buffer = static_pointer_cast<Note>(note)->get_buffer();
       buffer->select_note_body();
 
       // Flag this as a template note
@@ -175,21 +175,21 @@ namespace notebooks {
       note->queue_save (CONTENT_CHANGED);
     }
 
-    return note;
+    return static_pointer_cast<Note>(note);
   }
 
   Note::Ptr Notebook::create_notebook_note()
   {
-    std::string temp_title;
+    Glib::ustring temp_title;
     Note::Ptr note_template = get_template_note();
 
     temp_title = m_note_manager.get_unique_name(_("New Note"));
-    Note::Ptr note = m_note_manager.create_note_from_template(temp_title, note_template);
+    NoteBase::Ptr note = m_note_manager.create_note_from_template(temp_title, note_template);
 
     // Add the notebook tag
     note->add_tag(m_tag);
 
-    return note;
+    return static_pointer_cast<Note>(note);
   }
 
   /// <summary>
@@ -233,7 +233,7 @@ namespace notebooks {
 
   Note::Ptr SpecialNotebook::get_template_note() const
   {
-    return m_note_manager.get_or_create_template_note();
+    return static_pointer_cast<Note>(m_note_manager.get_or_create_template_note());
   }
 
 
@@ -365,9 +365,9 @@ namespace notebooks {
     return IconManager::obj().get_icon(IconManager::ACTIVE_NOTES, 22);
   }
 
-  void ActiveNotesNotebook::on_note_deleted(const Note::Ptr & note)
+  void ActiveNotesNotebook::on_note_deleted(const NoteBase::Ptr & note)
   {
-    std::set<Note::Ptr>::iterator iter = m_notes.find(note);
+    std::set<Note::Ptr>::iterator iter = m_notes.find(static_pointer_cast<Note>(note));
     if(iter != m_notes.end()) {
       m_notes.erase(iter);
       signal_size_changed();
diff --git a/src/notebooks/notebook.hpp b/src/notebooks/notebook.hpp
index 575d3ad..c9f4293 100644
--- a/src/notebooks/notebook.hpp
+++ b/src/notebooks/notebook.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -161,7 +161,7 @@ public:
   bool empty();
   sigc::signal<void> signal_size_changed;
 private:
-  void on_note_deleted(const Note::Ptr & note);
+  void on_note_deleted(const NoteBase::Ptr & note);
 
   std::set<Note::Ptr> m_notes;
 };
diff --git a/src/notebooks/notebookapplicationaddin.cpp b/src/notebooks/notebookapplicationaddin.cpp
index 51b9127..7cb2fe3 100644
--- a/src/notebooks/notebookapplicationaddin.cpp
+++ b/src/notebooks/notebookapplicationaddin.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -78,12 +78,10 @@ namespace gnote {
 
       NoteManager & nm(note_manager());
 
-      for(Note::List::const_iterator iter = nm.get_notes().begin();
-          iter != nm.get_notes().end(); ++iter) {
-        const Note::Ptr & note(*iter);
-        note->signal_tag_added().connect(
+      FOREACH(const NoteBase::Ptr & note, nm.get_notes()) {
+        note->signal_tag_added.connect(
           sigc::mem_fun(*this, &NotebookApplicationAddin::on_tag_added));
-        note->signal_tag_removed().connect(
+        note->signal_tag_removed.connect(
           sigc::mem_fun(*this, &NotebookApplicationAddin::on_tag_removed));
       }
        
@@ -197,7 +195,7 @@ namespace gnote {
     }
 
 
-    void NotebookApplicationAddin::on_tag_added(const Note & note, const Tag::Ptr& tag)
+    void NotebookApplicationAddin::on_tag_added(const NoteBase & note, const Tag::Ptr& tag)
     {
       if (NotebookManager::obj().is_adding_notebook()) {
         return;
@@ -215,12 +213,12 @@ namespace gnote {
       Notebook::Ptr notebook =
         NotebookManager::obj().get_or_create_notebook (notebookName);
         
-      NotebookManager::obj().signal_note_added_to_notebook() (note, notebook);
+      NotebookManager::obj().signal_note_added_to_notebook() (static_cast<const Note&>(note), notebook);
     }
 
     
 
-    void NotebookApplicationAddin::on_tag_removed(const Note::Ptr& note, 
+    void NotebookApplicationAddin::on_tag_removed(const NoteBase::Ptr& note, 
                                                   const std::string& normalizedTagName)
     {
       std::string megaPrefix(Tag::SYSTEM_TAG_PREFIX);
@@ -239,19 +237,19 @@ namespace gnote {
         return;
       }
       
-      NotebookManager::obj().signal_note_removed_from_notebook() (*note, notebook);
+      NotebookManager::obj().signal_note_removed_from_notebook() (*static_pointer_cast<Note>(note), 
notebook);
     }
 
-    void NotebookApplicationAddin::on_note_added(const Note::Ptr & note)
+    void NotebookApplicationAddin::on_note_added(const NoteBase::Ptr & note)
     {
-        note->signal_tag_added().connect(
+        note->signal_tag_added.connect(
           sigc::mem_fun(*this, &NotebookApplicationAddin::on_tag_added));
-        note->signal_tag_removed().connect(
+        note->signal_tag_removed.connect(
           sigc::mem_fun(*this, &NotebookApplicationAddin::on_tag_removed));
     }
 
 
-    void NotebookApplicationAddin::on_note_deleted(const Note::Ptr &)
+    void NotebookApplicationAddin::on_note_deleted(const NoteBase::Ptr &)
     {
       // remove the signal to the note...
     }
diff --git a/src/notebooks/notebookapplicationaddin.hpp b/src/notebooks/notebookapplicationaddin.hpp
index c05378b..41a8920 100644
--- a/src/notebooks/notebookapplicationaddin.hpp
+++ b/src/notebooks/notebookapplicationaddin.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -50,10 +50,10 @@ namespace gnote {
       void add_menu_items(Gtk::Menu *, std::list<Gtk::MenuItem*> & menu_items);
       void remove_menu_items(Gtk::Menu *, std::list<Gtk::MenuItem*> & menu_items);
       void on_new_notebook_menu_item();
-      void on_tag_added(const Note&, const Tag::Ptr&);
-      void on_tag_removed(const Note::Ptr&, const std::string&);
-      void on_note_added(const Note::Ptr &);
-      void on_note_deleted(const Note::Ptr &);
+      void on_tag_added(const NoteBase&, const Tag::Ptr&);
+      void on_tag_removed(const NoteBase::Ptr&, const std::string&);
+      void on_note_added(const NoteBase::Ptr &);
+      void on_note_deleted(const NoteBase::Ptr &);
       void on_new_notebook_action(const Glib::VariantBase&);
 
       bool m_initialized;
diff --git a/src/notebooks/notebookmanager.cpp b/src/notebooks/notebookmanager.cpp
index 9c8d042..76fcc26 100644
--- a/src/notebooks/notebookmanager.cpp
+++ b/src/notebooks/notebookmanager.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -188,14 +188,14 @@ namespace gnote {
         m_notebookMap.erase (map_iter);
         
         // Remove the notebook tag from every note that's in the notebook
-        std::list<Note *> notes;
+        std::list<NoteBase*> notes;
         Tag::Ptr tag = notebook->get_tag();
         if(tag) {
           tag->get_notes(notes);
         }
-        FOREACH(Note *note, notes) {
+        FOREACH(NoteBase *note, notes) {
           note->remove_tag (notebook->get_tag());
-          m_note_removed_from_notebook (*note, notebook);
+          m_note_removed_from_notebook (*static_cast<Note*>(note), notebook);
         }
 //      }
     }
@@ -242,7 +242,7 @@ namespace gnote {
     /// <returns>
     /// A <see cref="Notebook"/>
     /// </returns>
-    Notebook::Ptr NotebookManager::get_notebook_from_note(const Note::Ptr & note)
+    Notebook::Ptr NotebookManager::get_notebook_from_note(const NoteBase::Ptr & note)
     {
       std::list<Tag::Ptr> tags;
       note->get_tags(tags);
diff --git a/src/notebooks/notebookmanager.hpp b/src/notebooks/notebookmanager.hpp
index 0da5bdf..336af5a 100644
--- a/src/notebooks/notebookmanager.hpp
+++ b/src/notebooks/notebookmanager.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -78,7 +78,7 @@ public:
   bool add_notebook(const Notebook::Ptr &);
   void delete_notebook(const Notebook::Ptr &);
   bool get_notebook_iter(const Notebook::Ptr &, Gtk::TreeIter & );
-  Notebook::Ptr get_notebook_from_note(const Note::Ptr &);
+  Notebook::Ptr get_notebook_from_note(const NoteBase::Ptr &);
   Notebook::Ptr get_notebook_from_tag(const Tag::Ptr &);
   static bool is_notebook_tag(const Tag::Ptr &);
   static Notebook::Ptr prompt_create_new_notebook(Gtk::Window *);
diff --git a/src/notebooks/notebooknoteaddin.cpp b/src/notebooks/notebooknoteaddin.cpp
index e3fe0f6..ab98d3c 100644
--- a/src/notebooks/notebooknoteaddin.cpp
+++ b/src/notebooks/notebooknoteaddin.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -91,25 +91,25 @@ namespace notebooks {
     m_note_removed_cid = NotebookManager::obj().signal_note_removed_from_notebook()
       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_note_removed_from_notebook));
 
-    get_note()->signal_tag_added()
+    get_note()->signal_tag_added
       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_note_tag_added));
 
     // TODO: Make sure this is handled in NotebookNoteAddin, too
-    get_note()->signal_tag_removed()
+    get_note()->signal_tag_removed
       .connect(sigc::mem_fun(*this, &NotebookNoteAddin::on_note_tag_removed));
   }
 
 
-  void NotebookNoteAddin::on_note_tag_added(const Note & note, const Tag::Ptr & tag)
+  void NotebookNoteAddin::on_note_tag_added(const NoteBase & note, const Tag::Ptr & tag)
   {
-    Note::Ptr taggedNote = const_cast<Note&>(note).shared_from_this();
+    Note::Ptr taggedNote = static_pointer_cast<Note>(const_cast<NoteBase&>(note).shared_from_this());
     if(taggedNote == get_note() && tag == get_template_tag()) {
       update_button_sensitivity(true);
     }
   }
 
 
-  void NotebookNoteAddin::on_note_tag_removed(const Note::Ptr & taggedNote, const std::string & tag)
+  void NotebookNoteAddin::on_note_tag_removed(const NoteBase::Ptr & taggedNote, const std::string & tag)
   {
     if(taggedNote == get_note() && tag == get_template_tag()->normalized_name()) {
       update_button_sensitivity(false);
diff --git a/src/notebooks/notebooknoteaddin.hpp b/src/notebooks/notebooknoteaddin.hpp
index 6d53bd3..cabe7cf 100644
--- a/src/notebooks/notebooknoteaddin.hpp
+++ b/src/notebooks/notebooknoteaddin.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -52,8 +52,8 @@ namespace notebooks {
 
   private:
     void initialize_tool_button();
-    void on_note_tag_added(const Note &, const Tag::Ptr &);
-    void on_note_tag_removed(const Note::Ptr &, const std::string &);
+    void on_note_tag_added(const NoteBase &, const Tag::Ptr &);
+    void on_note_tag_removed(const NoteBase::Ptr &, const std::string &);
     void update_button_sensitivity(bool);
     void on_menu_shown();
     void on_note_added_to_notebook(const Note &, const Notebook::Ptr &);
diff --git a/src/notebooks/notebookstreeview.cpp b/src/notebooks/notebookstreeview.cpp
index ba6d062..d475630 100644
--- a/src/notebooks/notebookstreeview.cpp
+++ b/src/notebooks/notebookstreeview.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -81,13 +81,13 @@ namespace gnote {
       for(utils::UriList::const_iterator uri_iter = uriList.begin();
           uri_iter != uriList.end(); ++uri_iter) {
         const sharp::Uri & uri(*uri_iter);
-        Note::Ptr note = m_note_manager.find_by_uri (uri.to_string ());
+        NoteBase::Ptr note = m_note_manager.find_by_uri(uri.to_string());
         if (!note)
           continue;
 
         DBG_OUT ("Dropped into notebook: %s", note->get_title().c_str());
 
-        destNotebook->add_note(note);
+        destNotebook->add_note(static_pointer_cast<Note>(note));
       }
 
       context->drag_finish (true, false, time_);
diff --git a/src/notemanager.cpp b/src/notemanager.cpp
index bd1b4be..1bd7aa9 100644
--- a/src/notemanager.cpp
+++ b/src/notemanager.cpp
@@ -23,62 +23,21 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
-#include <exception>
-
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-#include <glib.h>
 #include <glibmm/i18n.h>
-#include <gtkmm/main.h>
 
 #include "applicationaddin.hpp"
 #include "debug.hpp"
 #include "notemanager.hpp"
-#include "notewindow.hpp"
 #include "addinmanager.hpp"
 #include "ignote.hpp"
 #include "itagmanager.hpp"
-#include "trie.hpp"
+#include "preferences.hpp"
 #include "sharp/directory.hpp"
-#include "sharp/exception.hpp"
-#include "sharp/files.hpp"
-#include "sharp/uuid.hpp"
-#include "sharp/string.hpp"
-#include "sharp/datetime.hpp"
-#include "notebooks/notebookmanager.hpp"
 
 namespace gnote {
 
-  class TrieController
-  {
-  public:
-    TrieController(NoteManager &);
-    ~TrieController();
-
-    void add_note(const Note::Ptr & note);
-    void update();
-    TrieTree<Note::WeakPtr> *title_trie() const
-      {
-        return m_title_trie;
-      }
-  private:
-    void on_note_added (const Note::Ptr & added);
-    void on_note_deleted (const Note::Ptr & deleted);
-    void on_note_renamed (const Note::Ptr & renamed, const std::string & old_title);
-      
-    NoteManager & m_manager;
-    TrieTree<Note::WeakPtr> *    m_title_trie;
-  };
-
-  bool compare_dates(const Note::Ptr & a, const Note::Ptr & b)
-  {
-    return (a->change_date() > b->change_date());
-  }
-
-  NoteManager::NoteManager(const std::string & directory)
+  NoteManager::NoteManager(const Glib::ustring & directory)
+    : NoteManagerBase(directory)
   {
     std::string backup = directory + "/Backup";
     
@@ -86,10 +45,12 @@ namespace gnote {
   }
 
 
-  void NoteManager::_common_init(const std::string & directory, const std::string & backup_directory)
+  void NoteManager::_common_init(const Glib::ustring & directory, const Glib::ustring & backup_directory)
   {
     m_addin_mgr = NULL;
-    m_trie_controller = NULL;
+    bool is_first_run = first_run();
+
+    NoteManagerBase::_common_init(directory, backup_directory);
 
     Glib::RefPtr<Gio::Settings> settings = Preferences::obj()
       .get_schema_settings(Preferences::SCHEMA_GNOTE);
@@ -98,28 +59,7 @@ namespace gnote {
     // Preferences.Get () each time it's accessed.
     m_start_note_uri = settings->get_string(Preferences::START_NOTE_URI);
     settings->signal_changed().connect(sigc::mem_fun(*this, &NoteManager::on_setting_changed));
-    m_default_note_template_title = _("New Note Template");
-
 
-    DBG_OUT("NoteManager created with note path \"%s\".", directory.c_str());
-
-    m_notes_dir = directory;
-    m_backup_dir = backup_directory;
-
-    bool is_first_run = first_run ();
-    create_notes_dir ();
-
-    const std::string old_note_dir = IGnote::old_note_dir();
-    const bool migration_needed
-                 = is_first_run
-                   && sharp::directory_exists(old_note_dir);
-
-    if (migration_needed) {
-      migrate_notes(old_note_dir);
-      is_first_run = false;
-    }
-
-    m_trie_controller = create_trie_controller ();
     m_addin_mgr = create_addin_manager ();
 
     if (is_first_run) {
@@ -155,7 +95,6 @@ namespace gnote {
 
   NoteManager::~NoteManager()
   {
-    delete m_trie_controller;
     delete m_addin_mgr;
   }
 
@@ -167,62 +106,11 @@ namespace gnote {
     }
   }
 
-
-  // Create the TrieController. For overriding in test methods.
-  TrieController *NoteManager::create_trie_controller()
-  {
-    return new TrieController(*this);
-  }
-
   AddinManager *NoteManager::create_addin_manager()
   {
     return new AddinManager(*this, IGnote::conf_dir());
   }
 
-  // For overriding in test methods.
-  bool NoteManager::directory_exists(const std::string & directory) const
-  {
-    return sharp::directory_exists(directory);
-  }
-
-  // For overriding in test methods.
-  bool NoteManager::create_directory(const std::string & directory) const
-  {
-    return g_mkdir_with_parents(directory.c_str(), S_IRWXU) == 0;
-  }
-
-  bool NoteManager::first_run() const
-  {
-    return !directory_exists(m_notes_dir);
-  }
-
-  // Create the notes directory if it doesn't exist yet.
-  void NoteManager::create_notes_dir() const
-  {
-    if (!directory_exists(m_notes_dir)) {
-      // First run. Create storage directory.
-      create_directory(m_notes_dir);
-    }
-    if (!directory_exists(m_backup_dir)) {
-      create_directory(m_backup_dir);
-    }
-  }
-  
-
-  void NoteManager::on_note_rename (const Note::Ptr & note, const std::string & old_title)
-  {
-//    if (NoteRenamed != null)
-    signal_note_renamed(note, old_title);
-    m_notes.sort(boost::bind(&compare_dates, _1, _2));
-  }
-
-  void NoteManager::on_note_save (const Note::Ptr & note)
-  {
-//    if (NoteSaved != null)
-    signal_note_saved(note);
-    m_notes.sort(boost::bind(&compare_dates, _1, _2));
-  }
-
   void NoteManager::create_start_notes ()
   {
     // FIXME: Delay the creation of the start notes so the panel/tray
@@ -269,13 +157,13 @@ namespace gnote {
         "</note-content>");
 
     try {
-      Note::Ptr start_note = create (_("Start Here"),
+      NoteBase::Ptr start_note = create (_("Start Here"),
                                 start_note_content);
       start_note->queue_save (CONTENT_CHANGED);
       Preferences::obj().get_schema_settings(Preferences::SCHEMA_GNOTE)->set_string(
           Preferences::START_NOTE_URI, start_note->uri());
 
-      Note::Ptr links_note = create (_("Using Links in Gnote"),
+      NoteBase::Ptr links_note = create (_("Using Links in Gnote"),
                                 links_note_content);
       links_note->queue_save (CONTENT_CHANGED);
     } 
@@ -284,20 +172,10 @@ namespace gnote {
     }
   }
 
-
-  void NoteManager::add_note(const Note::Ptr & note)
-  {
-    if (note) {
-      note->signal_renamed().connect(sigc::mem_fun(*this, &NoteManager::on_note_rename));
-      note->signal_saved().connect(sigc::mem_fun(*this, &NoteManager::on_note_save));
-      m_notes.push_back(note);
-    }
-  }
-  
   void NoteManager::load_notes()
   {
     std::list<std::string> files;
-    sharp::directory_get_files_with_ext(m_notes_dir, ".note", files);
+    sharp::directory_get_files_with_ext(notes_dir(), ".note", files);
 
     for(std::list<std::string>::const_iterator iter = files.begin();
         iter != files.end(); ++iter) {
@@ -320,7 +198,7 @@ namespace gnote {
     if (start_note_uri().empty() ||
         !find_by_uri(start_note_uri())) {
       // Attempt to find an existing Start Here note
-      Note::Ptr start_note = find (_("Start Here"));
+      NoteBase::Ptr start_note = find (_("Start Here"));
       if (start_note) {
         Preferences::obj().get_schema_settings(Preferences::SCHEMA_GNOTE)->set_string(
             Preferences::START_NOTE_URI, start_note->uri());
@@ -331,18 +209,14 @@ namespace gnote {
 
   void NoteManager::post_load()
   {
-    m_notes.sort (boost::bind(&compare_dates, _1, _2));
-
-    // Update the trie so addins can access it, if they want.
-    m_trie_controller->update ();
+    NoteManagerBase::post_load();
 
     // Load all the addins for our notes.
     // Iterating through copy of notes list, because list may be
     // changed when loading addins.
-    Note::List notesCopy(m_notes);
-    for(Note::List::const_iterator iter = notesCopy.begin();
-        iter != notesCopy.end(); ++iter) {
-      const Note::Ptr & note(*iter);
+    NoteBase::List notesCopy(m_notes);
+    FOREACH(const NoteBase::Ptr & iter, notesCopy) {
+      Note::Ptr note(static_pointer_cast<Note>(iter));
 
       m_addin_mgr->load_addins_for_note (note);
     }
@@ -358,7 +232,7 @@ namespace gnote {
       const Glib::RefPtr<Gio::File> src = Gio::File::create_for_path(
                                                        *iter);
       const std::string dest_path
-          = Glib::build_filename(m_notes_dir,
+          = Glib::build_filename(notes_dir(),
                                  Glib::path_get_basename(*iter));
       const Glib::RefPtr<Gio::File> dest = Gio::File::create_for_path(
                                                         dest_path);
@@ -393,339 +267,69 @@ namespace gnote {
       
     // Use a copy of the notes to prevent bug #510442 (crash on exit
     // when iterating the notes to save them.
-    Note::List notesCopy(m_notes);
-    for(Note::List::const_iterator iter = notesCopy.begin();
-        iter != notesCopy.end(); ++iter) {
-      const Note::Ptr & note(*iter);
+    NoteBase::List notesCopy(m_notes);
+    FOREACH(const NoteBase::Ptr & note, notesCopy) {
       note->save();
     }
   }
 
-  void NoteManager::delete_note(const Note::Ptr & note)
+  NoteBase::Ptr NoteManager::note_load(const Glib::ustring & file_name)
   {
-    if (sharp::file_exists(note->file_path())) {
-      if (!m_backup_dir.empty()) {
-        if (!sharp::directory_exists(m_backup_dir)) {
-          sharp::directory_create(m_backup_dir);
-        }
-        std::string backup_path 
-          = Glib::build_filename(m_backup_dir, sharp::file_filename(note->file_path()));
-
-        if (sharp::file_exists(backup_path))
-          sharp::file_delete(backup_path);
-
-        sharp::file_move(note->file_path(), backup_path);
-      } 
-      else {
-        sharp::file_delete(note->file_path());
-      }
-    }
-
-    m_notes.remove(note);
-    note->delete_note();
-
-    DBG_OUT("Deleting note '%s'.", note->get_title().c_str());
-
-//    if (NoteDeleted != null)
-    signal_note_deleted(note);
-  }
-
-  std::string NoteManager::make_new_file_name() const
-  {
-    return make_new_file_name (sharp::uuid().string());
-  }
-
-  std::string NoteManager::make_new_file_name(const std::string & guid) const
-  {
-    return Glib::build_filename(m_notes_dir, guid + ".note");
-  }
-
-  Note::Ptr NoteManager::create()
-  {
-    return create("");
-  }
-
-  std::string NoteManager::split_title_from_content(std::string title, std::string & body)
-  {
-    body = "";
-
-    if (title.empty())
-      return "";
-
-    title = sharp::string_trim(title);
-    if (title.empty())
-      return "";
-
-    std::vector<std::string> lines;
-    sharp::string_split(lines, title, "\n\r");
-    if (lines.size() > 0) {
-      title = lines [0];
-      title = sharp::string_trim(title);
-      title = sharp::string_trim(title, ".,;");
-      if (title.empty())
-        return "";
-    }
-
-    if (lines.size() > 1)
-      body = lines [1];
-
-    return title;
-  }
-
-
-  Note::Ptr NoteManager::create (const std::string & title)
-  {
-    return create_new_note(title, "");
+    return Note::load(file_name, *this);
   }
 
 
-  Note::Ptr NoteManager::create(const std::string & title, const std::string & xml_content)
-  {
-    return create_new_note(title, xml_content, "");
-  }
-
-  Note::Ptr NoteManager::import_note(const std::string & file_path)
-  {
-    std::string dest_file = Glib::build_filename(m_notes_dir, 
-                                                 sharp::file_filename(file_path));
-    
-    if(sharp::file_exists(dest_file)) {
-      dest_file = make_new_file_name();
-    }
-    Note::Ptr note;
-    try {
-      sharp::file_copy(file_path, dest_file);
-
-      // TODO: make sure the title IS unique.
-      note = Note::load(dest_file, *this);
-      add_note(note);
-    }
-    catch(...)
-    {
-    }
-    return note;
-  }
-
-
-  Note::Ptr NoteManager::create_with_guid (const std::string & title, const std::string & guid)
-  {
-    return create_new_note(title, guid);
-  }
-
   // Create a new note with the specified title from the default
   // template note. Optionally the body can be overridden.
-  Note::Ptr NoteManager::create_new_note (std::string title, const std::string & guid)
+  NoteBase::Ptr NoteManager::create_new_note(Glib::ustring title, const std::string & guid)
   {
-    std::string body;
-
-    title = split_title_from_content (title, body);
-      
-    if (title.empty()) {
-      title = get_unique_name(_("New Note"));
-    }
-
-    Note::Ptr template_note = get_or_create_template_note();
-
-    if (body.empty()) {
-      return create_note_from_template(title, template_note, guid);
-    }
-
-    // Use a simple "Describe..." body and highlight
-    // it so it can be easily overwritten
-    std::string content = get_note_template_content(title);
-    Note::Ptr new_note = create_new_note (title, content, guid);
+    NoteBase::Ptr new_note = NoteManagerBase::create_new_note(title, guid);
 
     // Select the inital text so typing will overwrite the body text
-    new_note->get_buffer()->select_note_body();
+    static_pointer_cast<Note>(new_note)->get_buffer()->select_note_body();
 
     return new_note;
   }
 
   // Create a new note with the specified Xml content
-  Note::Ptr NoteManager::create_new_note(const std::string & title, const std::string & xml_content, 
+  NoteBase::Ptr NoteManager::create_new_note(const Glib::ustring & title, const Glib::ustring & xml_content, 
                                         const std::string & guid)
-  { 
-    if (title.empty())
-      throw sharp::Exception("Invalid title");
-
-    if (find(title))
-      throw sharp::Exception("A note with this title already exists: " + title);
-
-    std::string filename;
-    if (!guid.empty())
-      filename = make_new_file_name (guid);
-    else
-      filename = make_new_file_name ();
-
-    Note::Ptr new_note = Note::create_new_note (title, filename, *this);
-    new_note->set_xml_content(xml_content);
-    new_note->signal_renamed().connect(sigc::mem_fun(*this, &NoteManager::on_note_rename));
-    new_note->signal_saved().connect(sigc::mem_fun(*this, &NoteManager::on_note_save));
-
-    m_notes.push_back(new_note);
+  {
+    NoteBase::Ptr new_note = NoteManagerBase::create_new_note(title, xml_content, guid);
 
     // Load all the addins for the new note
-    m_addin_mgr->load_addins_for_note (new_note);
-
-    signal_note_added(new_note);
+    m_addin_mgr->load_addins_for_note(static_pointer_cast<Note>(new_note));
 
     return new_note;
   }
 
-  Note::Ptr NoteManager::find_template_note() const
+  NoteBase::Ptr NoteManager::note_create_new(const Glib::ustring & title, const Glib::ustring & file_name)
   {
-    Note::Ptr template_note;
-    Tag::Ptr template_tag = ITagManager::obj().get_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
-    if(!template_tag) {
-      return template_note;
-    }
-    std::list<Note*> notes;
-    template_tag->get_notes(notes);
-    for (std::list<Note*>::iterator iter = notes.begin(); iter != notes.end(); ++iter) {
-      Note::Ptr note = (*iter)->shared_from_this();
-      if (!notebooks::NotebookManager::obj().get_notebook_from_note(note)) {
-        template_note = note;
-        break;
-      }
-    }
-
-    return template_note;
+    return Note::create_new_note(title, file_name, *this);
   }
 
-  /// <summary>
-  /// Get the existing template note or create a new one
-  /// if it doesn't already exist.
-  /// </summary>
-  /// <returns>
-  /// A <see cref="Note"/>
-  /// </returns>
-  Note::Ptr NoteManager::get_or_create_template_note()
-  {
-    Note::Ptr template_note = find_template_note();
-    if (!template_note) {
-      std::string title = m_default_note_template_title;
-      if (find(title)) {
-        title = get_unique_name(title);
-      }
-      template_note =
-        create (title,
-                get_note_template_content(title));
-          
-      // Select the initial text
-      Glib::RefPtr<NoteBuffer> buffer = template_note->get_buffer();
-      buffer->select_note_body();
-
-      // Flag this as a template note
-      Tag::Ptr template_tag = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
-      template_note->add_tag(template_tag);
-
-      template_note->queue_save(CONTENT_CHANGED);
-    }
-      
-    return template_note;
-  }
-    
-  std::string NoteManager::get_note_template_content(const std::string & title)
+  NoteBase::Ptr NoteManager::get_or_create_template_note()
   {
-    return str(boost::format("<note-content>"
-                             "<note-title>%1%</note-title>\n\n"
-                             "%2%"
-                             "</note-content>") 
-               % utils::XmlEncoder::encode (title)
-               % _("Describe your new note here."));
-  }
-
-  size_t NoteManager::trie_max_length()
-  {
-    return m_trie_controller->title_trie()->max_length();
-  }
-
-
-  TrieHit<Note::WeakPtr>::ListPtr NoteManager::find_trie_matches(const std::string & match)
-  {
-    return m_trie_controller->title_trie()->find_matches(match);
-  }
+    NoteBase::Ptr template_note = NoteManagerBase::get_or_create_template_note();
 
-  Note::Ptr NoteManager::find(const Glib::ustring & linked_title) const
-  {
-    for(Note::List::const_iterator iter = m_notes.begin();
-        iter != m_notes.end(); ++iter) {
-      const Note::Ptr & note(*iter);
-      if (note->get_title().lowercase() == linked_title.lowercase())
-        return note;
-    }
-    return Note::Ptr();
-  }
+    // Select the initial text
+    Glib::RefPtr<NoteBuffer> buffer = static_pointer_cast<Note>(template_note)->get_buffer();
+    buffer->select_note_body();
 
-  Note::Ptr NoteManager::find_by_uri(const std::string & uri) const
-  {
-    for(Note::List::const_iterator iter = m_notes.begin();
-        iter != m_notes.end(); ++iter) {
-      const Note::Ptr & note(*iter);
-      if (note->uri() == uri) {
-        return note;
-      }
-    }
-    return Note::Ptr();
-  }
-
-  std::string NoteManager::sanitize_xml_content(const std::string & xml_content)
-  {
-    std::string::size_type pos = xml_content.find('\n');
-    int i = (pos == std::string::npos) ? -1 : pos;
-    std::string result(xml_content);
-
-    while (--i >= 0) {
-      if(xml_content[i] == '\r') {
-        continue;
-      }
-
-      if(std::isspace(result[i])) {
-        result.erase(i, 1);
-      }
-      else {
-        break;
-      }
-    }
-
-    return result;
-  }
-
-  /// <summary>
-  /// Creates a new note with the given titel based on the template note.
-  /// </summary>
-  /// <param name="title">
-  /// A <see cref="System.String"/>
-  /// </param>
-  /// <param name="template_note">
-  /// A <see cref="Note"/>
-  /// </param>
-  /// <returns>
-  /// A <see cref="Note"/>
-  /// </returns>
-  Note::Ptr NoteManager::create_note_from_template(const std::string & title, const Note::Ptr & 
template_note)
-  {
-    return create_note_from_template(title, template_note, "");
+    return template_note;
   }
 
   // Creates a new note with the given title and guid with body based on
   // the template note.
-  Note::Ptr NoteManager::create_note_from_template(const std::string & title, const Note::Ptr & 
template_note, const std::string & guid)
+  NoteBase::Ptr NoteManager::create_note_from_template(const Glib::ustring & title,
+                                                       const NoteBase::Ptr & template_note,
+                                                       const std::string & guid)
   {
-    std::string new_title(title);
-    Tag::Ptr template_save_title = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SAVE_TITLE_SYSTEM_TAG);
-    if(template_note->contains_tag(template_save_title)) {
-      new_title = get_unique_name(template_note->get_title());
+    NoteBase::Ptr new_note = NoteManagerBase::create_note_from_template(title, template_note, guid);
+    if(new_note == 0) {
+      return new_note;
     }
 
-    // Use the body from the template note
-    std::string xml_content = sharp::string_replace_first(template_note->xml_content(),
-                                                          
utils::XmlEncoder::encode(template_note->get_title()),
-                                                          utils::XmlEncoder::encode(new_title));
-    xml_content = sanitize_xml_content(xml_content);
-
-    Note::Ptr new_note = create_new_note(new_title, xml_content, guid);
-
     // Copy template note's properties
     Tag::Ptr template_save_size = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SAVE_SIZE_SYSTEM_TAG);
     if(template_note->data().has_extent() && template_note->contains_tag(template_save_size)) {
@@ -733,7 +337,7 @@ namespace gnote {
       new_note->data().width() = template_note->data().width();
     }
 
-    Glib::RefPtr<Gtk::TextBuffer> buffer = new_note->get_buffer();
+    Glib::RefPtr<Gtk::TextBuffer> buffer = static_pointer_cast<Note>(new_note)->get_buffer();
     Gtk::TextIter cursor, selection;
     Tag::Ptr template_save_selection = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SAVE_SELECTION_SYSTEM_TAG);
     if(template_note->contains_tag(template_save_selection)) {
@@ -781,86 +385,4 @@ namespace gnote {
     return new_note;
   }
 
-  // Find a title that does not exist using basename
-  std::string NoteManager::get_unique_name(const std::string & basename) const
-  {
-    int id = 1;  // starting point
-    std::string title;
-    while (true) {
-      title = str(boost::format("%1% %2%") % basename % id++);
-      if (!find (title)) {
-        break;
-      }
-    }
-
-    return title;
-  }
-
-  Note::List NoteManager::get_notes_linking_to(const std::string & title) const
-  {
-    std::string tag = "<link:internal>" + utils::XmlEncoder::encode(title) + "</link:internal>";
-    Note::List result;
-    FOREACH(const Note::Ptr & note, m_notes) {
-      if(note->get_title() != title) {
-        if(note->get_complete_note_xml().find(tag) != std::string::npos) {
-          result.push_back(note);
-        }
-      }
-    }
-    return result;
-  }
-
-
-  TrieController::TrieController (NoteManager & manager)
-    : m_manager(manager)
-    ,  m_title_trie(NULL)
-  {
-    m_manager.signal_note_deleted.connect(sigc::mem_fun(*this, &TrieController::on_note_deleted));
-    m_manager.signal_note_added.connect(sigc::mem_fun(*this, &TrieController::on_note_added));
-    m_manager.signal_note_renamed.connect(sigc::mem_fun(*this, &TrieController::on_note_renamed));
-
-    update ();
-  }
-
-  TrieController::~TrieController()
-  {
-    delete m_title_trie;
-  }
-
-  void TrieController::on_note_added (const Note::Ptr & note)
-  {
-    add_note (note);
-  }
-
-  void TrieController::on_note_deleted (const Note::Ptr & )
-  {
-    update ();
-  }
-
-  void TrieController::on_note_renamed (const Note::Ptr & , const std::string & )
-  {
-    update ();
-  }
-
-  void TrieController::add_note(const Note::Ptr & note)
-  {
-    m_title_trie->add_keyword (note->get_title(), note);
-    m_title_trie->compute_failure_graph();
-  }
-
-  void TrieController::update ()
-  {
-    if(m_title_trie) {
-      delete m_title_trie;
-    }
-    m_title_trie = new TrieTree<Note::WeakPtr>(false /* !case_sensitive */);
-
-    for(Note::List::const_iterator iter =  m_manager.get_notes().begin();
-        iter !=  m_manager.get_notes().end(); ++iter) {
-      const Note::Ptr & note(*iter);
-      m_title_trie->add_keyword (note->get_title(), note);
-    }
-    m_title_trie->compute_failure_graph();
-  }
-
 }
diff --git a/src/notemanager.hpp b/src/notemanager.hpp
index 4d27299..125399c 100644
--- a/src/notemanager.hpp
+++ b/src/notemanager.hpp
@@ -23,124 +23,54 @@
 #ifndef _NOTEMANAGER_HPP__
 #define _NOTEMANAGER_HPP__
 
-#include <string>
-#include <list>
-#include <memory>
-
-#include <sigc++/signal.h>
-
-#include "preferences.hpp"
+#include "notemanagerbase.hpp"
 #include "note.hpp"
-#include "triehit.hpp"
 
 namespace gnote {
 
   class AddinManager;
-  class TrieController;
 
   class NoteManager 
+    : public NoteManagerBase
   {
   public:
     typedef shared_ptr<NoteManager> Ptr;
-    typedef sigc::signal<void, const Note::Ptr &> ChangedHandler;
     typedef sigc::slot<void, const Note::Ptr &> NoteChangedSlot;
     
-    NoteManager(const std::string &);
+    NoteManager(const Glib::ustring &);
     ~NoteManager();
 
     void on_setting_changed(const Glib::ustring & key);
-    const Note::List & get_notes() const
-      { 
-        return m_notes;
-      }
-
-    // the trie for the note names
-    size_t trie_max_length();
-    TrieHit<Note::WeakPtr>::ListPtr find_trie_matches(const std::string &);
 
     AddinManager & get_addin_manager()
       {
         return *m_addin_mgr;
       }
-    const std::string & get_notes_dir() const
-      {
-        return m_notes_dir;
-      }
-    const std::string & start_note_uri() const
-      { 
-        return m_start_note_uri; 
-      }
-    void read_only(bool ro)
-      {
-        m_read_only = ro;
-      }
-    bool read_only() const
-      {
-        return m_read_only;
-      }
-    Note::Ptr find(const Glib::ustring &) const;
-    Note::Ptr find_by_uri(const std::string &) const;
-    static std::string sanitize_xml_content(const std::string & xml_content);
-    Note::Ptr create_note_from_template(const std::string & title, const Note::Ptr & template_note);
-    std::string get_unique_name (const std::string & basename) const;
-    void delete_note(const Note::Ptr & note);
-
-    Note::Ptr create();
-    Note::Ptr create(const std::string & title);
-    Note::Ptr create(const std::string & title, const std::string & xml_content);
-    // Import a note read from file_path
-    // Will ensure the sanity including the unique title.
-    Note::Ptr import_note(const std::string & file_path);
-    Note::Ptr create_with_guid(const std::string & title, const std::string & guid);
-    Note::Ptr find_template_note() const;
-    Note::Ptr get_or_create_template_note();
-    static std::string get_note_template_content(const std::string & title);
-    static std::string split_title_from_content (std::string title, std::string & body);
-    Note::List get_notes_linking_to(const std::string & title) const;
-
-    ChangedHandler signal_note_deleted;
-    ChangedHandler signal_note_added;
-    ChangedHandler signal_note_buffer_changed;
-    /** this signal is emitted when the start note has been created
-     *  This is supposed to happen once in a life time *sigh*
-     *  This to avoid relying a the Gnote class for that.
-     */
 
-    Note::RenamedHandler   signal_note_renamed;
-    Note::SavedHandler     signal_note_saved;
+    virtual NoteBase::Ptr get_or_create_template_note() override;
 
+    ChangedHandler signal_note_buffer_changed;
+
+    using NoteManagerBase::create_note_from_template;
+  protected:
+    virtual void _common_init(const Glib::ustring & directory, const Glib::ustring & backup) override;
+    virtual void post_load() override;
+    virtual void migrate_notes(const std::string & old_note_dir) override;
+    virtual NoteBase::Ptr create_note_from_template(const Glib::ustring & title,
+                                                    const NoteBase::Ptr & template_note,
+                                                    const std::string & guid) override;
+    virtual NoteBase::Ptr create_new_note(Glib::ustring title, const std::string & guid) override;
+    virtual NoteBase::Ptr create_new_note(const Glib::ustring & title, const Glib::ustring & xml_content,
+                                          const std::string & guid) override;
+    virtual NoteBase::Ptr note_create_new(const Glib::ustring & title, const Glib::ustring & file_name) 
override;
+    virtual NoteBase::Ptr note_load(const Glib::ustring & file_name) override;
   private:
-    TrieController *create_trie_controller();
     AddinManager *create_addin_manager();
-    bool directory_exists(const std::string & directory) const;
-    bool create_directory(const std::string & directory) const;
-    void on_note_rename(const Note::Ptr & note, const std::string & old_title);
     void create_start_notes();
-    void on_note_save(const Note::Ptr & note);
     void load_notes();
-    void migrate_notes(const std::string & old_note_dir);
-    void post_load();
-    bool first_run() const;
-    void create_notes_dir() const;
     void on_exiting_event();
-    std::string make_new_file_name() const;
-    std::string make_new_file_name(const std::string & guid) const;
-    Note::Ptr create_new_note (std::string title, const std::string & guid);
-    Note::Ptr create_new_note (const std::string & title, const std::string & xml_content, 
-                             const std::string & guid);
-    Note::Ptr create_note_from_template(const std::string & title, const Note::Ptr & template_note, const 
std::string & guid);
-    /** add the note to the manager and setup signals */
-    void add_note(const Note::Ptr &);
-    void _common_init(const std::string & directory, const std::string & backup);
-
-    std::string m_notes_dir;
-    std::string m_backup_dir;
-    Note::List m_notes;
+
     AddinManager   *m_addin_mgr;
-    TrieController *m_trie_controller;
-    std::string m_default_note_template_title;
-    std::string m_start_note_uri;
-    bool m_read_only;
   };
 
 
diff --git a/src/notemanagerbase.cpp b/src/notemanagerbase.cpp
new file mode 100644
index 0000000..b0a2ee9
--- /dev/null
+++ b/src/notemanagerbase.cpp
@@ -0,0 +1,547 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2010-2014 Aurimas Cernius
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <boost/bind.hpp>
+#include <boost/format.hpp>
+#include <glibmm/i18n.h>
+
+#include "debug.hpp"
+#include "ignote.hpp"
+#include "itagmanager.hpp"
+#include "notemanagerbase.hpp"
+#include "utils.hpp"
+#include "trie.hpp"
+#include "notebooks/notebookmanager.hpp"
+#include "sharp/directory.hpp"
+#include "sharp/files.hpp"
+#include "sharp/string.hpp"
+#include "sharp/uuid.hpp"
+
+
+namespace gnote {
+
+bool compare_dates(const NoteBase::Ptr & a, const NoteBase::Ptr & b)
+{
+  return (static_pointer_cast<Note>(a)->change_date() > static_pointer_cast<Note>(b)->change_date());
+}
+
+
+class TrieController
+{
+public:
+  TrieController(NoteManagerBase &);
+  ~TrieController();
+
+  void add_note(const NoteBase::Ptr & note);
+  void update();
+  TrieTree<NoteBase::WeakPtr> *title_trie() const
+    {
+      return m_title_trie;
+    }
+private:
+  void on_note_added(const NoteBase::Ptr & added);
+  void on_note_deleted (const NoteBase::Ptr & deleted);
+  void on_note_renamed(const NoteBase::Ptr & renamed, const Glib::ustring & old_title);
+
+  NoteManagerBase & m_manager;
+  TrieTree<NoteBase::WeakPtr> *m_title_trie;
+};
+
+
+
+Glib::ustring NoteManagerBase::sanitize_xml_content(const Glib::ustring & xml_content)
+{
+  Glib::ustring::size_type pos = xml_content.find('\n');
+  int i = (pos == Glib::ustring::npos) ? -1 : pos;
+  Glib::ustring result(xml_content);
+
+  while(--i >= 0) {
+    if(xml_content[i] == '\r') {
+      continue;
+    }
+
+    if(std::isspace(result[i])) {
+      result.erase(i, 1);
+    }
+    else {
+      break;
+    }
+  }
+
+  return result;
+}
+
+
+NoteManagerBase::NoteManagerBase(const Glib::ustring & directory)
+  : m_notes_dir(directory)
+{
+}
+
+NoteManagerBase::~NoteManagerBase()
+{
+  delete m_trie_controller;
+}
+
+void NoteManagerBase::_common_init(const Glib::ustring & /*directory*/, const Glib::ustring & 
backup_directory)
+{
+  m_default_note_template_title = _("New Note Template");
+  m_backup_dir = backup_directory;
+  bool is_first_run = first_run();
+
+  const std::string old_note_dir = IGnote::old_note_dir();
+  const bool migration_needed = is_first_run && sharp::directory_exists(old_note_dir);
+
+  if(migration_needed) {
+    migrate_notes(old_note_dir);
+    is_first_run = false;
+  }
+
+  m_trie_controller = create_trie_controller();
+
+  create_notes_dir();
+}
+
+bool NoteManagerBase::first_run() const
+{
+  return !sharp::directory_exists(notes_dir());
+}
+
+// Create the notes directory if it doesn't exist yet.
+void NoteManagerBase::create_notes_dir() const
+{
+  if(!sharp::directory_exists(notes_dir())) {
+    // First run. Create storage directory.
+    create_directory(notes_dir());
+  }
+  if(!sharp::directory_exists(m_backup_dir)) {
+    create_directory(m_backup_dir);
+  }
+}
+
+bool NoteManagerBase::create_directory(const Glib::ustring & directory) const
+{
+  return g_mkdir_with_parents(directory.c_str(), S_IRWXU) == 0;
+}
+
+void NoteManagerBase::migrate_notes(const std::string & /*old_note_dir*/)
+{
+}
+
+// Create the TrieController. For overriding in test methods.
+TrieController *NoteManagerBase::create_trie_controller()
+{
+  return new TrieController(*this);
+}
+
+void NoteManagerBase::post_load()
+{
+  m_notes.sort(boost::bind(&compare_dates, _1, _2));
+
+  // Update the trie so addins can access it, if they want.
+  m_trie_controller->update ();
+}
+
+size_t NoteManagerBase::trie_max_length()
+{
+  return m_trie_controller->title_trie()->max_length();
+}
+
+TrieHit<NoteBase::WeakPtr>::ListPtr NoteManagerBase::find_trie_matches(const Glib::ustring & match)
+{
+  return m_trie_controller->title_trie()->find_matches(match);
+}
+
+NoteBase::List NoteManagerBase::get_notes_linking_to(const Glib::ustring & title) const
+{
+  Glib::ustring tag = "<link:internal>" + utils::XmlEncoder::encode(title) + "</link:internal>";
+  NoteBase::List result;
+  FOREACH(const NoteBase::Ptr & note, m_notes) {
+    if(note->get_title() != title) {
+      if(note->get_complete_note_xml().find(tag) != std::string::npos) {
+        result.push_back(note);
+      }
+    }
+  }
+  return result;
+}
+
+void NoteManagerBase::add_note(const NoteBase::Ptr & note)
+{
+  if(note) {
+    note->signal_renamed.connect(sigc::mem_fun(*this, &NoteManagerBase::on_note_rename));
+    note->signal_saved.connect(sigc::mem_fun(*this, &NoteManagerBase::on_note_save));
+    m_notes.push_back(note);
+  }
+}
+
+void NoteManagerBase::on_note_rename(const NoteBase::Ptr & note, const Glib::ustring & old_title)
+{
+  signal_note_renamed(note, old_title);
+  m_notes.sort(boost::bind(&compare_dates, _1, _2));
+}
+
+void NoteManagerBase::on_note_save (const NoteBase::Ptr & note)
+{
+  signal_note_saved(note);
+  m_notes.sort(boost::bind(&compare_dates, _1, _2));
+}
+
+NoteBase::Ptr NoteManagerBase::find(const Glib::ustring & linked_title) const
+{
+  FOREACH(const NoteBase::Ptr & note, m_notes) {
+    if(note->get_title().lowercase() == linked_title.lowercase()) {
+      return note;
+    }
+  }
+  return NoteBase::Ptr();
+}
+
+NoteBase::Ptr NoteManagerBase::find_by_uri(const std::string & uri) const
+{
+  FOREACH(const NoteBase::Ptr & note, m_notes) {
+    if (note->uri() == uri) {
+      return note;
+    }
+  }
+  return NoteBase::Ptr();
+}
+
+NoteBase::Ptr NoteManagerBase::create_note_from_template(const Glib::ustring & title, const NoteBase::Ptr & 
template_note)
+{
+  return create_note_from_template(title, template_note, "");
+}
+
+NoteBase::Ptr NoteManagerBase::create()
+{
+  return create("");
+}
+
+NoteBase::Ptr NoteManagerBase::create(const Glib::ustring & title)
+{
+  return create_new_note(title, "");
+}
+
+NoteBase::Ptr NoteManagerBase::create(const Glib::ustring & title, const Glib::ustring & xml_content)
+{
+  return create_new_note(title, xml_content, "");
+}
+
+// Creates a new note with the given title and guid with body based on
+// the template note.
+NoteBase::Ptr NoteManagerBase::create_note_from_template(const Glib::ustring & title,
+                                                         const NoteBase::Ptr & template_note,
+                                                         const std::string & guid)
+{
+  Glib::ustring new_title(title);
+  Tag::Ptr template_save_title = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SAVE_TITLE_SYSTEM_TAG);
+  if(template_note->contains_tag(template_save_title)) {
+    new_title = get_unique_name(template_note->get_title());
+  }
+
+  // Use the body from the template note
+  Glib::ustring xml_content = sharp::string_replace_first(template_note->xml_content(),
+                                                          
utils::XmlEncoder::encode(template_note->get_title()),
+                                                          utils::XmlEncoder::encode(new_title));
+  xml_content = sanitize_xml_content(xml_content);
+
+  NoteBase::Ptr new_note = create_new_note(new_title, xml_content, guid);
+
+  // Copy template note's properties
+  Tag::Ptr template_save_size = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SAVE_SIZE_SYSTEM_TAG);
+  if(template_note->data().has_extent() && template_note->contains_tag(template_save_size)) {
+    new_note->data().height() = template_note->data().height();
+    new_note->data().width() = template_note->data().width();
+  }
+
+  return new_note;
+}
+
+// Find a title that does not exist using basename
+Glib::ustring NoteManagerBase::get_unique_name(const Glib::ustring & basename) const
+{
+  int id = 1;  // starting point
+  Glib::ustring title;
+  while(true) {
+    title = str(boost::format("%1% %2%") % basename % id++);
+    if(!find (title)) {
+      break;
+    }
+  }
+
+  return title;
+}
+
+// Create a new note with the specified title from the default
+// template note. Optionally the body can be overridden.
+NoteBase::Ptr NoteManagerBase::create_new_note(Glib::ustring title, const std::string & guid)
+{
+  Glib::ustring body;
+
+  title = split_title_from_content(title, body);
+
+  if(title.empty()) {
+    title = get_unique_name(_("New Note"));
+  }
+
+  NoteBase::Ptr template_note = get_or_create_template_note();
+
+  if(body.empty()) {
+    return create_note_from_template(title, template_note, guid);
+  }
+
+  // Use a simple "Describe..." body and highlight
+  // it so it can be easily overwritten
+  Glib::ustring content = get_note_template_content(title);
+  NoteBase::Ptr new_note = create_new_note(title, content, guid);
+
+  // Select the inital text so typing will overwrite the body text
+  static_pointer_cast<Note>(new_note)->get_buffer()->select_note_body();
+
+  return new_note;
+}
+
+// Create a new note with the specified Xml content
+NoteBase::Ptr NoteManagerBase::create_new_note(const Glib::ustring & title, const Glib::ustring & 
xml_content, 
+                                               const std::string & guid)
+{ 
+  if(title.empty())
+    throw sharp::Exception("Invalid title");
+
+  if(find(title))
+    throw sharp::Exception("A note with this title already exists: " + title);
+
+  Glib::ustring filename;
+  if(!guid.empty())
+    filename = make_new_file_name(guid);
+  else
+    filename = make_new_file_name();
+
+  NoteBase::Ptr new_note = note_create_new(title, filename);
+  new_note->set_xml_content(xml_content);
+  new_note->signal_renamed.connect(sigc::mem_fun(*this, &NoteManagerBase::on_note_rename));
+  new_note->signal_saved.connect(sigc::mem_fun(*this, &NoteManagerBase::on_note_save));
+
+  m_notes.push_back(new_note);
+
+  signal_note_added(new_note);
+
+  return new_note;
+}
+
+Glib::ustring NoteManagerBase::get_note_template_content(const Glib::ustring & title)
+{
+  return str(boost::format("<note-content>"
+                           "<note-title>%1%</note-title>\n\n"
+                           "%2%"
+                           "</note-content>") 
+             % utils::XmlEncoder::encode(title)
+             % _("Describe your new note here."));
+}
+
+NoteBase::Ptr NoteManagerBase::get_or_create_template_note()
+{
+  NoteBase::Ptr template_note = find_template_note();
+  if(!template_note) {
+    Glib::ustring title = m_default_note_template_title;
+    if(find(title)) {
+      title = get_unique_name(title);
+    }
+    template_note = create(title, get_note_template_content(title));
+
+    // Flag this as a template note
+    Tag::Ptr template_tag = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
+    template_note->add_tag(template_tag);
+
+    template_note->queue_save(CONTENT_CHANGED);
+  }
+      
+  return template_note;
+}
+
+Glib::ustring NoteManagerBase::split_title_from_content(Glib::ustring title, Glib::ustring & body)
+{
+  body = "";
+
+  if(title.empty())
+    return "";
+
+  title = sharp::string_trim(title);
+  if(title.empty())
+    return "";
+
+  std::vector<std::string> lines;
+  sharp::string_split(lines, title, "\n\r");
+  if(lines.size() > 0) {
+    title = lines [0];
+    title = sharp::string_trim(title);
+    title = sharp::string_trim(title, ".,;");
+    if(title.empty())
+      return "";
+  }
+
+  if(lines.size() > 1)
+    body = lines [1];
+
+  return title;
+}
+
+Glib::ustring NoteManagerBase::make_new_file_name() const
+{
+  return make_new_file_name(sharp::uuid().string());
+}
+
+Glib::ustring NoteManagerBase::make_new_file_name(const Glib::ustring & guid) const
+{
+  return Glib::build_filename(notes_dir(), guid + ".note");
+}
+
+NoteBase::Ptr NoteManagerBase::find_template_note() const
+{
+  NoteBase::Ptr template_note;
+  Tag::Ptr template_tag = ITagManager::obj().get_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
+  if(!template_tag) {
+    return template_note;
+  }
+  std::list<NoteBase*> notes;
+  template_tag->get_notes(notes);
+  FOREACH(NoteBase *iter, notes) {
+    NoteBase::Ptr note = iter->shared_from_this();
+    if(!notebooks::NotebookManager::obj().get_notebook_from_note(note)) {
+      template_note = note;
+      break;
+    }
+  }
+
+  return template_note;
+}
+
+void NoteManagerBase::delete_note(const NoteBase::Ptr & note)
+{
+  if(sharp::file_exists(note->file_path())) {
+    if(!m_backup_dir.empty()) {
+      if(!sharp::directory_exists(m_backup_dir)) {
+        sharp::directory_create(m_backup_dir);
+      }
+      Glib::ustring backup_path 
+        = Glib::build_filename(m_backup_dir, sharp::file_filename(note->file_path()));
+
+      if(sharp::file_exists(backup_path)) {
+        sharp::file_delete(backup_path);
+      }
+
+      sharp::file_move(note->file_path(), backup_path);
+    } 
+    else {
+      sharp::file_delete(note->file_path());
+    }
+  }
+
+  m_notes.remove(note);
+  note->delete_note();
+
+  DBG_OUT("Deleting note '%s'.", note->get_title().c_str());
+
+  signal_note_deleted(note);
+}
+
+NoteBase::Ptr NoteManagerBase::import_note(const Glib::ustring & file_path)
+{
+  Glib::ustring dest_file = Glib::build_filename(notes_dir(), 
+                                                 sharp::file_filename(file_path));
+
+  if(sharp::file_exists(dest_file)) {
+    dest_file = make_new_file_name();
+  }
+  NoteBase::Ptr note;
+  try {
+    sharp::file_copy(file_path, dest_file);
+
+    // TODO: make sure the title IS unique.
+    note = note_load(dest_file);
+    add_note(note);
+  }
+  catch(...)
+  {
+  }
+  return note;
+}
+
+
+NoteBase::Ptr NoteManagerBase::create_with_guid(const Glib::ustring & title, const std::string & guid)
+{
+  return create_new_note(title, guid);
+}
+
+
+
+TrieController::TrieController(NoteManagerBase & manager)
+  : m_manager(manager)
+  ,  m_title_trie(NULL)
+{
+  m_manager.signal_note_deleted.connect(sigc::mem_fun(*this, &TrieController::on_note_deleted));
+  m_manager.signal_note_added.connect(sigc::mem_fun(*this, &TrieController::on_note_added));
+  m_manager.signal_note_renamed.connect(sigc::mem_fun(*this, &TrieController::on_note_renamed));
+
+  update();
+}
+
+TrieController::~TrieController()
+{
+  delete m_title_trie;
+}
+
+void TrieController::on_note_added(const NoteBase::Ptr & note)
+{
+  add_note(note);
+}
+
+void TrieController::on_note_deleted(const NoteBase::Ptr &)
+{
+  update();
+}
+
+void TrieController::on_note_renamed(const NoteBase::Ptr &, const Glib::ustring &)
+{
+  update();
+}
+
+void TrieController::add_note(const NoteBase::Ptr & note)
+{
+  m_title_trie->add_keyword(note->get_title(), note);
+  m_title_trie->compute_failure_graph();
+}
+
+void TrieController::update()
+{
+  if(m_title_trie) {
+    delete m_title_trie;
+  }
+  m_title_trie = new TrieTree<NoteBase::WeakPtr>(false /* !case_sensitive */);
+
+  FOREACH(const NoteBase::Ptr & note, m_manager.get_notes()) {
+    m_title_trie->add_keyword(note->get_title(), note);
+  }
+  m_title_trie->compute_failure_graph();
+}
+
+
+}
+
diff --git a/src/notemanagerbase.hpp b/src/notemanagerbase.hpp
new file mode 100644
index 0000000..0eab487
--- /dev/null
+++ b/src/notemanagerbase.hpp
@@ -0,0 +1,126 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2010-2014 Aurimas Cernius
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _NOTEMANAGERBASE_HPP_
+#define _NOTEMANAGERBASE_HPP_
+
+#include "notebase.hpp"
+#include "triehit.hpp"
+
+
+namespace gnote {
+
+class TrieController;
+
+class NoteManagerBase
+{
+public:
+  typedef sigc::signal<void, const NoteBase::Ptr &> ChangedHandler;
+
+  static Glib::ustring sanitize_xml_content(const Glib::ustring & xml_content);
+  static Glib::ustring get_note_template_content(const Glib::ustring & title);
+  static Glib::ustring split_title_from_content(Glib::ustring title, Glib::ustring & body);
+
+  NoteManagerBase(const Glib::ustring & directory);
+  virtual ~NoteManagerBase();
+
+  size_t trie_max_length();
+  TrieHit<NoteBase::WeakPtr>::ListPtr find_trie_matches(const Glib::ustring &);
+
+  void read_only(bool ro)
+    {
+      m_read_only = ro;
+    }
+  bool read_only() const
+    {
+      return m_read_only;
+    }
+  NoteBase::Ptr find(const Glib::ustring &) const;
+  NoteBase::Ptr find_by_uri(const std::string &) const;
+  NoteBase::List get_notes_linking_to(const Glib::ustring & title) const;
+  NoteBase::Ptr create();
+  NoteBase::Ptr create(const Glib::ustring & title);
+  NoteBase::Ptr create(const Glib::ustring & title, const Glib::ustring & xml_content);
+  NoteBase::Ptr create_note_from_template(const Glib::ustring & title, const NoteBase::Ptr & template_note);
+  virtual NoteBase::Ptr get_or_create_template_note();
+  NoteBase::Ptr find_template_note() const;
+  Glib::ustring get_unique_name(const Glib::ustring & basename) const;
+  void delete_note(const NoteBase::Ptr & note);
+  // Import a note read from file_path
+  // Will ensure the sanity including the unique title.
+  NoteBase::Ptr import_note(const Glib::ustring & file_path);
+  NoteBase::Ptr create_with_guid(const Glib::ustring & title, const std::string & guid);
+
+  const Glib::ustring & notes_dir() const
+    {
+      return m_notes_dir;
+    }
+  const NoteBase::List & get_notes() const
+    { 
+      return m_notes;
+    }
+
+  const std::string & start_note_uri() const
+    { 
+      return m_start_note_uri; 
+    }
+
+  ChangedHandler signal_note_deleted;
+  ChangedHandler signal_note_added;
+  NoteBase::RenamedHandler signal_note_renamed;
+  NoteBase::SavedHandler signal_note_saved;
+protected:
+  virtual void _common_init(const Glib::ustring & directory, const Glib::ustring & backup);
+  bool first_run() const;
+  virtual void post_load();
+  virtual void migrate_notes(const std::string & old_note_dir);
+  /** add the note to the manager and setup signals */
+  void add_note(const NoteBase::Ptr &);
+  void on_note_rename(const NoteBase::Ptr & note, const Glib::ustring & old_title);
+  void on_note_save(const NoteBase::Ptr & note);
+  virtual NoteBase::Ptr create_note_from_template(const Glib::ustring & title,
+                                                  const NoteBase::Ptr & template_note,
+                                                  const std::string & guid);
+  virtual NoteBase::Ptr create_new_note(Glib::ustring title, const std::string & guid);
+  virtual NoteBase::Ptr create_new_note(const Glib::ustring & title, const Glib::ustring & xml_content, 
+                                        const std::string & guid);
+  virtual NoteBase::Ptr note_create_new(const Glib::ustring & title, const Glib::ustring & file_name) = 0;
+  Glib::ustring make_new_file_name() const; //temp
+  Glib::ustring make_new_file_name(const Glib::ustring & guid) const; //temp
+  virtual NoteBase::Ptr note_load(const Glib::ustring & file_name) = 0;
+
+  NoteBase::List m_notes;
+  std::string m_start_note_uri;
+  Glib::ustring m_backup_dir; //temp
+  Glib::ustring m_default_note_template_title;  // temp
+private:
+  void create_notes_dir() const;
+  bool create_directory(const Glib::ustring & directory) const;
+  TrieController *create_trie_controller();
+
+  TrieController *m_trie_controller;
+  Glib::ustring m_notes_dir;
+  bool m_read_only;
+};
+
+}
+
+#endif
diff --git a/src/noterenamedialog.cpp b/src/noterenamedialog.cpp
index 86b80bf..dc38001 100644
--- a/src/noterenamedialog.cpp
+++ b/src/noterenamedialog.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  *
  * This program is free software: you can redistribute it and/or modify
@@ -72,7 +72,7 @@ gint ModelColumnRecord::get_column_title_num() const
     return COLUMN_TITLE;
 }
 
-const Gtk::TreeModelColumn<Note::Ptr> & ModelColumnRecord::get_column_note()
+const Gtk::TreeModelColumn<NoteBase::Ptr> & ModelColumnRecord::get_column_note()
                                           const
 {
     return m_column_note;
@@ -84,12 +84,12 @@ gint ModelColumnRecord::get_column_note_num() const
 }
 
 class ModelFiller
-  : public std::unary_function<const Note::Ptr &, void>
+  : public std::unary_function<const NoteBase::Ptr &, void>
 {
 public:
 
   ModelFiller(const Glib::RefPtr<Gtk::ListStore> & list_store);
-  void operator()(const Note::Ptr & note);
+  void operator()(const NoteBase::Ptr & note);
 
 private:
 
@@ -98,12 +98,12 @@ private:
 
 ModelFiller::ModelFiller(
                const Glib::RefPtr<Gtk::ListStore> & list_store)
-  : std::unary_function<const Note::Ptr &, void>()
+  : std::unary_function<const NoteBase::Ptr &, void>()
   , m_list_store(list_store)
 {
 }
 
-void ModelFiller::operator()(const Note::Ptr & note)
+void ModelFiller::operator()(const NoteBase::Ptr & note)
 {
   if (!note)
     return;
@@ -117,11 +117,11 @@ void ModelFiller::operator()(const Note::Ptr & note)
   row[model_column_record.get_column_note()] = note;
 }
 
-NoteRenameDialog::NoteRenameDialog(const Note::List & notes,
+NoteRenameDialog::NoteRenameDialog(const NoteBase::List & notes,
                                    const std::string & old_title,
-                                   const Note::Ptr & renamed_note)
+                                   const NoteBase::Ptr & renamed_note)
   : Gtk::Dialog(_("Rename Note Links?"),
-                *dynamic_cast<Gtk::Window*>(renamed_note->get_window()->host()),
+                *dynamic_cast<Gtk::Window*>(static_pointer_cast<Note>(renamed_note)->get_window()->host()),
                 false)
   , m_notes_model(Gtk::ListStore::create(m_model_column_record))
   , m_dont_rename_button(_("_Don't Rename Links"), true)
@@ -272,7 +272,7 @@ NoteRenameDialog::NoteRenameDialog(const Note::List & notes,
 
 NoteRenameDialog::MapPtr NoteRenameDialog::get_notes() const
 {
-  const MapPtr notes(new std::map<Note::Ptr, bool>);
+  const MapPtr notes(new std::map<NoteBase::Ptr, bool>);
 
   m_notes_model->foreach_iter(
     sigc::bind(
@@ -357,11 +357,11 @@ void NoteRenameDialog::on_notes_view_row_activated(
 
   ModelColumnRecord model_column_record;
   Gtk::TreeModel::Row row = *iter;
-  const Note::Ptr note = row[model_column_record.get_column_note()];
+  const NoteBase::Ptr note = row[model_column_record.get_column_note()];
   if (!note)
     return;
 
-  MainWindow *window = MainWindow::present_default(note);
+  MainWindow *window = MainWindow::present_default(static_pointer_cast<Note>(note));
   if(window) {
     window->set_search_text(Glib::ustring::compose("\"%1\"", old_title));
     window->show_search_bar();
diff --git a/src/noterenamedialog.hpp b/src/noterenamedialog.hpp
index 29fe3e1..7888c72 100644
--- a/src/noterenamedialog.hpp
+++ b/src/noterenamedialog.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011,2013 Aurimas Cernius
+ * Copyright (C) 2011,2013-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  *
  * This program is free software: you can redistribute it and/or modify
@@ -56,7 +56,7 @@ public:
   const Gtk::TreeModelColumn<std::string> & get_column_title() const;
   gint get_column_title_num() const;
 
-  const Gtk::TreeModelColumn<Note::Ptr> & get_column_note() const;
+  const Gtk::TreeModelColumn<NoteBase::Ptr> & get_column_note() const;
   gint get_column_note_num() const;
 
 private:
@@ -70,7 +70,7 @@ private:
 
   Gtk::TreeModelColumn<bool> m_column_selected;
   Gtk::TreeModelColumn<std::string> m_column_title;
-  Gtk::TreeModelColumn<Note::Ptr> m_column_note;
+  Gtk::TreeModelColumn<NoteBase::Ptr> m_column_note;
 };
 
 class NoteRenameDialog
@@ -78,11 +78,11 @@ class NoteRenameDialog
 {
 public:
 
-  typedef shared_ptr<std::map<Note::Ptr, bool> > MapPtr;
+  typedef shared_ptr<std::map<NoteBase::Ptr, bool> > MapPtr;
 
-  NoteRenameDialog(const Note::List & notes,
+  NoteRenameDialog(const NoteBase::List & notes,
                    const std::string & old_title,
-                   const Note::Ptr & renamed_note);
+                   const NoteBase::Ptr & renamed_note);
   MapPtr get_notes() const;
   NoteRenameBehavior get_selected_behavior() const;
 
diff --git a/src/notetag.hpp b/src/notetag.hpp
index cf9b945..4ee40ef 100644
--- a/src/notetag.hpp
+++ b/src/notetag.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011,2013 Aurimas Cernius
+ * Copyright (C) 2011,2013-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -34,6 +34,7 @@
 
 #include "base/macros.hpp"
 #include "contrast.hpp"
+#include "tag.hpp"
 #include "sharp/exception.hpp"
 
 namespace sharp {
@@ -51,12 +52,6 @@ enum TagSaveType {
   CONTENT
 };
 
-enum ChangeType {
-  NO_CHANGE,
-  CONTENT_CHANGED,
-  OTHER_DATA_CHANGED
-};
-
 
 
 class NoteTag
diff --git a/src/notewindow.cpp b/src/notewindow.cpp
index f42d0dd..6de97dc 100644
--- a/src/notewindow.cpp
+++ b/src/notewindow.cpp
@@ -331,7 +331,7 @@ namespace gnote {
   {
     // Prompt for note deletion
     std::list<Note::Ptr> single_note_list;
-    single_note_list.push_back(m_note.shared_from_this());
+    single_note_list.push_back(static_pointer_cast<Note>(m_note.shared_from_this()));
     noteutils::show_deletion_dialog(single_note_list, dynamic_cast<Gtk::Window*>(host()));
   }
 
@@ -492,8 +492,8 @@ namespace gnote {
       bar->show_all();
     }
 
-    m_note.signal_tag_added().connect(sigc::mem_fun(*this, &NoteWindow::on_note_tag_added));
-    m_note.signal_tag_removed().connect(sigc::mem_fun(*this, &NoteWindow::on_note_tag_removed));
+    m_note.signal_tag_added.connect(sigc::mem_fun(*this, &NoteWindow::on_note_tag_added));
+    m_note.signal_tag_removed.connect(sigc::mem_fun(*this, &NoteWindow::on_note_tag_removed));
 
     return bar;
   }
@@ -538,7 +538,7 @@ namespace gnote {
   }
 
 
-  void NoteWindow::on_note_tag_added(const Note&, const Tag::Ptr & tag)
+  void NoteWindow::on_note_tag_added(const NoteBase&, const Tag::Ptr & tag)
   {
     if(tag == m_template_tag) {
       m_template_widget->show_all();
@@ -546,7 +546,7 @@ namespace gnote {
   }
 
 
-  void NoteWindow::on_note_tag_removed(const Note::Ptr&, const std::string & tag)
+  void NoteWindow::on_note_tag_removed(const NoteBase::Ptr&, const std::string & tag)
   {
     if(tag == m_template_tag->normalized_name()) {
       m_template_widget->hide();
@@ -562,16 +562,16 @@ namespace gnote {
   //
   void NoteWindow::link_button_clicked()
   {
-    std::string select = m_note.get_buffer()->get_selection();
+    Glib::ustring select = m_note.get_buffer()->get_selection();
     if (select.empty())
       return;
     
-    std::string body_unused;
-    std::string title = NoteManager::split_title_from_content(select, body_unused);
+    Glib::ustring body_unused;
+    Glib::ustring title = NoteManagerBase::split_title_from_content(select, body_unused);
     if (title.empty())
       return;
 
-    Note::Ptr match = m_note.manager().find(title);
+    NoteBase::Ptr match = m_note.manager().find(title);
     if (!match) {
       try {
         match = m_note.manager().create(select);
@@ -592,7 +592,7 @@ namespace gnote {
       m_note.get_buffer()->apply_tag(m_note.get_tag_table()->get_link_tag(), start, end);
     }
 
-    host()->embed_widget(*match->get_window());
+    host()->embed_widget(*static_pointer_cast<Note>(match)->get_window());
   }
 
   void NoteWindow::open_help_activate()
diff --git a/src/notewindow.hpp b/src/notewindow.hpp
index 993885e..0814005 100644
--- a/src/notewindow.hpp
+++ b/src/notewindow.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -246,8 +246,8 @@ private:
   void on_save_size_check_button_toggled();
   void on_save_selection_check_button_toggled();
   void on_save_title_check_button_toggled();
-  void on_note_tag_added(const Note&, const Tag::Ptr&);
-  void on_note_tag_removed(const Note::Ptr&, const std::string&);
+  void on_note_tag_added(const NoteBase&, const Tag::Ptr&);
+  void on_note_tag_removed(const NoteBase::Ptr&, const std::string&);
   void link_button_clicked();
   void open_help_activate();
   void change_depth_right_handler();
diff --git a/src/preferencesdialog.cpp b/src/preferencesdialog.cpp
index 41b443f..d8c333a 100644
--- a/src/preferencesdialog.cpp
+++ b/src/preferencesdialog.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2009 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -1092,10 +1092,10 @@ namespace gnote {
 
   void  PreferencesDialog::open_template_button_clicked()
   {
-    Note::Ptr template_note = m_note_manager.get_or_create_template_note ();
+    NoteBase::Ptr template_note = m_note_manager.get_or_create_template_note();
 
     // Open the template note
-    IGnote::obj().open_note(template_note);
+    IGnote::obj().open_note(static_pointer_cast<Note>(template_note));
   }
 
 
diff --git a/src/prefskeybinder.cpp b/src/prefskeybinder.cpp
index 37050d5..02a4ed4 100644
--- a/src/prefskeybinder.cpp
+++ b/src/prefskeybinder.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2011-2013 Aurimas Cernius
+ * Copyright (C) 2011-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -205,9 +205,9 @@ namespace gnote {
 
   void GnotePrefsKeybinder::key_openstart_here()
   {
-    Note::Ptr note = m_manager.find_by_uri (m_manager.start_note_uri());
+    NoteBase::Ptr note = m_manager.find_by_uri(m_manager.start_note_uri());
     if (note) {
-      IGnote::obj().open_note(note);
+      IGnote::obj().open_note(static_pointer_cast<Note>(note));
     }
   }
 
@@ -215,7 +215,7 @@ namespace gnote {
   void GnotePrefsKeybinder::key_create_new_note()
   {
     try {
-      Note::Ptr new_note = m_manager.create();
+      Note::Ptr new_note = static_pointer_cast<Note>(m_manager.create());
       IGnote::obj().open_note(new_note);
     } 
     catch (...) {
diff --git a/src/recentchanges.cpp b/src/recentchanges.cpp
index ed4d08f..d4d5a4d 100644
--- a/src/recentchanges.cpp
+++ b/src/recentchanges.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -291,7 +291,7 @@ namespace gnote {
       search_wgt->new_note();
     }
     else {
-      present_note(m_note_manager.create());
+      present_note(static_pointer_cast<Note>(m_note_manager.create()));
     }
   }
 
diff --git a/src/search.cpp b/src/search.cpp
index 80b3959..04fe696 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -55,9 +55,8 @@ namespace gnote {
       // Skip over notes that are template notes
     Tag::Ptr template_tag = 
ITagManager::obj().get_or_create_system_tag(ITagManager::TEMPLATE_NOTE_SYSTEM_TAG);
 
-    for(Note::List::const_iterator iter = m_manager.get_notes().begin();
-        iter != m_manager.get_notes().end(); ++iter) {
-      const Note::Ptr & note(*iter);
+    FOREACH(const NoteBase::Ptr & iter, m_manager.get_notes()) {
+      Note::Ptr note(static_pointer_cast<Note>(iter));
 
       // Skip template notes
       if (note->contains_tag (template_tag)) {
@@ -66,7 +65,7 @@ namespace gnote {
         
       // Skip notes that are not in the
       // selected notebook
-      if (selected_notebook && !selected_notebook->contains_note (note))
+      if (selected_notebook && !selected_notebook->contains_note(note))
         continue;
         
       // First check the note's title for a match,
diff --git a/src/searchnoteswidget.cpp b/src/searchnoteswidget.cpp
index 153975e..b9f3b33 100644
--- a/src/searchnoteswidget.cpp
+++ b/src/searchnoteswidget.cpp
@@ -339,11 +339,11 @@ void SearchNotesWidget::on_notebook_row_edited(const Glib::ustring& /*tree_path*
     .get_or_create_notebook(new_text);
   DBG_OUT("Renaming notebook '{%s}' to '{%s}'", old_notebook->get_name().c_str(),
           new_text.c_str());
-  std::list<Note *> notes;
+  std::list<NoteBase*> notes;
   old_notebook->get_tag()->get_notes(notes);
-  for(std::list<Note *>::const_iterator note = notes.begin(); note != notes.end(); ++note) {
+  FOREACH(NoteBase *note, notes) {
     notebooks::NotebookManager::obj().move_note_to_notebook(
-      (*note)->shared_from_this(), new_notebook);
+      static_pointer_cast<Note>(note->shared_from_this()), new_notebook);
   }
   notebooks::NotebookManager::obj().delete_notebook(old_notebook);
   Gtk::TreeIter iter;
@@ -509,9 +509,8 @@ void SearchNotesWidget::update_results()
 
   int cnt = 0;
 
-  for(Note::List::const_iterator note_iter = m_manager.get_notes().begin();
-      note_iter != m_manager.get_notes().end(); ++note_iter) {
-    const Note::Ptr & note(*note_iter);
+  FOREACH(const NoteBase::Ptr & note_iter, m_manager.get_notes()) {
+    Note::Ptr note(static_pointer_cast<Note>(note_iter));
     std::string nice_date = utils::get_pretty_print_date(note->change_date(), true);
 
     Gtk::TreeIter iter = m_store->append();
@@ -1148,26 +1147,26 @@ int SearchNotesWidget::compare_search_hits(const Gtk::TreeIter & a, const Gtk::T
   return result;
 }
 
-void SearchNotesWidget::on_note_deleted(const Note::Ptr & note)
+void SearchNotesWidget::on_note_deleted(const NoteBase::Ptr & note)
 {
   restore_matches_window();
-  delete_note(note);
+  delete_note(static_pointer_cast<Note>(note));
 }
 
-void SearchNotesWidget::on_note_added(const Note::Ptr & note)
+void SearchNotesWidget::on_note_added(const NoteBase::Ptr & note)
 {
   restore_matches_window();
-  add_note(note);
+  add_note(static_pointer_cast<Note>(note));
 }
 
-void SearchNotesWidget::on_note_renamed(const Note::Ptr & note,
+void SearchNotesWidget::on_note_renamed(const NoteBase::Ptr & note,
                                         const std::string &)
 {
   restore_matches_window();
-  rename_note(note);
+  rename_note(static_pointer_cast<Note>(note));
 }
 
-void SearchNotesWidget::on_note_saved(const Note::Ptr&)
+void SearchNotesWidget::on_note_saved(const NoteBase::Ptr&)
 {
   restore_matches_window();
   update_results();
@@ -1317,7 +1316,7 @@ void SearchNotesWidget::new_note()
   notebooks::Notebook::Ptr notebook = get_selected_notebook();
   if(!notebook || dynamic_pointer_cast<notebooks::SpecialNotebook>(notebook)) {
     // Just create a standard note (not in a notebook)
-    note = m_manager.create();
+    note = static_pointer_cast<Note>(m_manager.create());
   }
   else {
     // Look for the template note and create a new note
diff --git a/src/searchnoteswidget.hpp b/src/searchnoteswidget.hpp
index 634441e..995f329 100644
--- a/src/searchnoteswidget.hpp
+++ b/src/searchnoteswidget.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2010 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
@@ -107,10 +107,10 @@ private:
   bool show_all_search_results();
   void matches_column_data_func(Gtk::CellRenderer *, const Gtk::TreeIter &);
   int compare_search_hits(const Gtk::TreeIter & , const Gtk::TreeIter &);
-  void on_note_deleted(const Note::Ptr & note);
-  void on_note_added(const Note::Ptr & note);
-  void on_note_renamed(const Note::Ptr&, const std::string&);
-  void on_note_saved(const Note::Ptr&);
+  void on_note_deleted(const NoteBase::Ptr & note);
+  void on_note_added(const NoteBase::Ptr & note);
+  void on_note_renamed(const NoteBase::Ptr&, const std::string&);
+  void on_note_saved(const NoteBase::Ptr&);
   void delete_note(const Note::Ptr & note);
   void add_note(const Note::Ptr & note);
   void rename_note(const Note::Ptr & note);
diff --git a/src/synchronization/gnotesyncclient.cpp b/src/synchronization/gnotesyncclient.cpp
index 3046a1d..6cbea58 100644
--- a/src/synchronization/gnotesyncclient.cpp
+++ b/src/synchronization/gnotesyncclient.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -56,7 +56,7 @@ namespace sync {
   }
 
 
-  void GnoteSyncClient::note_deleted_handler(const Note::Ptr & deletedNote)
+  void GnoteSyncClient::note_deleted_handler(const NoteBase::Ptr & deletedNote)
   {
     m_deleted_notes[deletedNote->id()] = deletedNote->get_title();
     m_file_revisions.erase(deletedNote->id());
diff --git a/src/synchronization/gnotesyncclient.hpp b/src/synchronization/gnotesyncclient.hpp
index 3164fb5..9c579f6 100644
--- a/src/synchronization/gnotesyncclient.hpp
+++ b/src/synchronization/gnotesyncclient.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -59,7 +59,7 @@ namespace sync {
   private:
     static const char *LOCAL_MANIFEST_FILE_NAME;
 
-    void note_deleted_handler(const Note::Ptr &);
+    void note_deleted_handler(const NoteBase::Ptr &);
     void on_changed(const Glib::RefPtr<Gio::File>&, const Glib::RefPtr<Gio::File>&,
                     Gio::FileMonitorEvent);
     void parse(const std::string & manifest_path);
diff --git a/src/synchronization/silentui.cpp b/src/synchronization/silentui.cpp
index d26ef2a..593ef6a 100644
--- a/src/synchronization/silentui.cpp
+++ b/src/synchronization/silentui.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -96,9 +96,8 @@ namespace sync {
   void SilentUI::on_connecting()
   {
     m_manager.read_only(true);
-    std::list<Note::Ptr> notes = m_manager.get_notes();
-    for(std::list<Note::Ptr>::iterator iter = notes.begin(); iter != notes.end(); ++iter) {
-      (*iter)->enabled(false);
+    FOREACH(const NoteBase::Ptr & iter, m_manager.get_notes()) {
+      iter->enabled(false);
     }
   }
 
@@ -106,9 +105,8 @@ namespace sync {
   void SilentUI::on_idle()
   {
     m_manager.read_only(false);
-    std::list<Note::Ptr> notes = m_manager.get_notes();
-    for(std::list<Note::Ptr>::iterator iter = notes.begin(); iter != notes.end(); ++iter) {
-      (*iter)->enabled(true);
+    FOREACH(const NoteBase::Ptr & iter, m_manager.get_notes()) {
+      iter->enabled(true);
     }
     m_ui_disabled = false;
   }
diff --git a/src/synchronization/syncdialog.cpp b/src/synchronization/syncdialog.cpp
index 791cdf4..d4b2878 100644
--- a/src/synchronization/syncdialog.cpp
+++ b/src/synchronization/syncdialog.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -421,9 +421,9 @@ void SyncDialog::on_row_activated(const Gtk::TreeModel::Path & path, Gtk::TreeVi
   std::string noteTitle;
   iter->get_value(0, noteTitle);
 
-  Note::Ptr note = m_manager.find(noteTitle);
+  NoteBase::Ptr note = m_manager.find(noteTitle);
   if(note != 0) {
-    present_note(note);
+    present_note(static_pointer_cast<Note>(note));
   }
 }
 
@@ -728,7 +728,7 @@ void SyncDialog::rename_note(const Note::Ptr & note, const std::string & newTitl
 
   // Create note with old XmlContent just in case GetCompleteNoteXml failed
   DBG_OUT("RenameNote: about to create %s", newTitle.c_str());
-  Note::Ptr renamedNote = m_manager.create(newTitle, newContent);
+  Note::Ptr renamedNote = static_pointer_cast<Note>(m_manager.create(newTitle, newContent));
   if(newCompleteContent != "") {// TODO: Anything to do if it is null?
     try {
       renamedNote->load_foreign_note_xml(newCompleteContent, OTHER_DATA_CHANGED);
diff --git a/src/synchronization/syncmanager.cpp b/src/synchronization/syncmanager.cpp
index 5ee0f2e..14b490e 100644
--- a/src/synchronization/syncmanager.cpp
+++ b/src/synchronization/syncmanager.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -206,11 +206,11 @@ namespace sync {
       for(std::map<std::string, NoteUpdate>::iterator iter = noteUpdates.begin();
           iter != noteUpdates.end(); ++iter) {
         if(!find_note_by_uuid(iter->second.m_uuid) != 0) {
-          Note::Ptr existingNote = note_mgr().find(iter->second.m_title);
-          if(existingNote != 0 && !iter->second.basically_equal_to(existingNote)) {
+          NoteBase::Ptr existingNote = note_mgr().find(iter->second.m_title);
+          if(existingNote != 0 && !iter->second.basically_equal_to(static_pointer_cast<Note>(existingNote))) 
{
             DBG_OUT("Sync: Early conflict detection for '%s'", iter->second.m_title.c_str());
             if(m_sync_ui != 0) {
-              m_sync_ui->note_conflict_detected(note_mgr(), existingNote, iter->second, noteUpdateTitles);
+              m_sync_ui->note_conflict_detected(note_mgr(), static_pointer_cast<Note>(existingNote), 
iter->second, noteUpdateTitles);
             }
           }
         }
@@ -224,7 +224,7 @@ namespace sync {
       // Process updates from the server; the bread and butter of sync!
       for(std::map<std::string, NoteUpdate>::iterator iter = noteUpdates.begin();
           iter != noteUpdates.end(); ++iter) {
-        Note::Ptr existingNote = find_note_by_uuid(iter->second.m_uuid);
+        NoteBase::Ptr existingNote = find_note_by_uuid(iter->second.m_uuid);
 
         if(existingNote == 0) {
           // Actually, it's possible to have a conflict here
@@ -235,21 +235,21 @@ namespace sync {
           existingNote = note_mgr().find(iter->second.m_title);
           if(existingNote != 0) {
             DBG_OUT("SyncManager: Deleting auto-generated note: %s", iter->second.m_title.c_str());
-            delete_note_in_main_thread(existingNote);
+            delete_note_in_main_thread(static_pointer_cast<Note>(existingNote));
           }
           create_note_in_main_thread(iter->second);
         }
         else if(existingNote->metadata_change_date() <= m_client->last_sync_date()
-                || iter->second.basically_equal_to(existingNote)) {
+                || iter->second.basically_equal_to(static_pointer_cast<Note>(existingNote))) {
           // Existing note hasn't been modified since last sync; simply update it from server
-          update_note_in_main_thread(existingNote, iter->second);
+          update_note_in_main_thread(static_pointer_cast<Note>(existingNote), iter->second);
         }
         else {
           // Logger.Debug ("Sync: Late conflict detection for '{0}'", noteUpdate.Title);
           DBG_OUT("SyncManager: Content conflict in note update for note '%s'", 
iter->second.m_title.c_str());
           // Note already exists locally, but has been modified since last sync; prompt user
           if(m_sync_ui != 0) {
-            m_sync_ui->note_conflict_detected(note_mgr(), existingNote, iter->second, noteUpdateTitles);
+            m_sync_ui->note_conflict_detected(note_mgr(), static_pointer_cast<Note>(existingNote), 
iter->second, noteUpdateTitles);
           }
 
           // Note has been deleted or okay'd for overwrite
@@ -257,7 +257,7 @@ namespace sync {
           if(existingNote == 0)
             create_note_in_main_thread(iter->second);
           else
-            update_note_in_main_thread(existingNote, iter->second);
+            update_note_in_main_thread(static_pointer_cast<Note>(existingNote), iter->second);
         }
       }
 
@@ -274,23 +274,23 @@ namespace sync {
       // Look through all the notes modified on the client
       // and upload new or modified ones to the server
       std::list<Note::Ptr> newOrModifiedNotes;
-      std::list<Note::Ptr> notes = note_mgr().get_notes();
-      for(std::list<Note::Ptr>::iterator iter = notes.begin(); iter != notes.end(); ++iter) {
-        if(m_client->get_revision(*iter) == -1) {
+      FOREACH(const NoteBase::Ptr & iter, note_mgr().get_notes()) {
+        Note::Ptr note = static_pointer_cast<Note>(iter);
+        if(m_client->get_revision(note) == -1) {
           // This is a new note that has never been synchronized to the server
           // TODO: *OR* this is a note that we lost revision info for!!!
           // TODO: Do the above NOW!!! (don't commit this dummy)
-          note_save(*iter);
-          newOrModifiedNotes.push_back(*iter);
+          note_save(note);
+          newOrModifiedNotes.push_back(note);
           if(m_sync_ui != 0)
-            m_sync_ui->note_synchronized_th((*iter)->get_title(), UPLOAD_NEW);
+            m_sync_ui->note_synchronized_th(note->get_title(), UPLOAD_NEW);
         }
-        else if(m_client->get_revision(*iter) <= m_client->last_synchronized_revision()
-                && (*iter)->metadata_change_date() > m_client->last_sync_date()) {
-          note_save(*iter);
-          newOrModifiedNotes.push_back(*iter);
+        else if(m_client->get_revision(note) <= m_client->last_synchronized_revision()
+                && note->metadata_change_date() > m_client->last_sync_date()) {
+          note_save(note);
+          newOrModifiedNotes.push_back(note);
           if(m_sync_ui != 0) {
-            m_sync_ui->note_synchronized_th((*iter)->get_title(), UPLOAD_MODIFIED);
+            m_sync_ui->note_synchronized_th(note->get_title(), UPLOAD_MODIFIED);
           }
         }
       }
@@ -377,7 +377,7 @@ namespace sync {
   }
 
 
-  void SyncManager::handle_note_buffer_changed(const Note::Ptr &)
+  void SyncManager::handle_note_buffer_changed(const NoteBase::Ptr &)
   {
     // Note changed, iff a sync is coming up we kill the
     // timer to avoid interupting the user (we want to
@@ -421,7 +421,7 @@ namespace sync {
   }
 
 
-  void SyncManager::handle_note_saved_or_deleted(const Note::Ptr &)
+  void SyncManager::handle_note_saved_or_deleted(const NoteBase::Ptr &)
   {
     if(m_sync_thread == NULL && m_autosync_timeout_pref_minutes > 0) {
       sharp::TimeSpan time_since_last_check(sharp::DateTime::now() - m_last_background_check);
@@ -469,9 +469,9 @@ namespace sync {
       bool server_has_updates = false;
       bool client_has_updates = m_client->deleted_note_titles().size() > 0;
       if(!client_has_updates) {
-        std::list<Note::Ptr> notes = note_mgr().get_notes();
-        for(std::list<Note::Ptr>::iterator iter = notes.begin(); iter != notes.end(); ++iter) {
-          if(m_client->get_revision(*iter) == -1 || (*iter)->metadata_change_date() > 
m_client->last_sync_date()) {
+        FOREACH(const NoteBase::Ptr & iter, note_mgr().get_notes()) {
+          Note::Ptr note = static_pointer_cast<Note>(iter);
+          if(m_client->get_revision(note) == -1 || note->metadata_change_date() > 
m_client->last_sync_date()) {
             client_has_updates = true;
             break;
           }
@@ -582,7 +582,7 @@ namespace sync {
   }
 
 
-  void SyncManager::update_local_note(const Note::Ptr & localNote, const NoteUpdate & serverNote, 
NoteSyncType syncType)
+  void SyncManager::update_local_note(const NoteBase::Ptr & localNote, const NoteUpdate & serverNote, 
NoteSyncType syncType)
   {
     // In each case, update existingNote's content and revision
     try {
@@ -590,7 +590,7 @@ namespace sync {
     }
     catch(...)
     {} // TODO: Handle exception in case that serverNote.XmlContent is invalid XML
-    m_client->set_revision(localNote, serverNote.m_latest_revision);
+    m_client->set_revision(static_pointer_cast<Note>(localNote), serverNote.m_latest_revision);
 
     // Update dialog's sync status
     if(m_sync_ui != 0) {
@@ -599,7 +599,7 @@ namespace sync {
   }
 
 
-  Note::Ptr SyncManager::find_note_by_uuid(const std::string & uuid)
+  NoteBase::Ptr SyncManager::find_note_by_uuid(const std::string & uuid)
   {
     return note_mgr().find_by_uri("note://gnote/" + uuid);
   }
@@ -661,19 +661,20 @@ namespace sync {
   {
     try {
       // Make list of all local notes
-      std::list<Note::Ptr> localNotes = note_mgr().get_notes();
+      std::list<NoteBase::Ptr> localNotes = note_mgr().get_notes();
 
       // Get all notes currently on server
       std::list<std::string> serverNotes = server->get_all_note_uuids();
 
       // Delete notes locally that have been deleted on the server
-      for(std::list<Note::Ptr>::iterator iter = localNotes.begin(); iter != localNotes.end(); ++iter) {
-       if(SyncManager::_obj().m_client->get_revision(*iter) != -1
-          && std::find(serverNotes.begin(), serverNotes.end(), (*iter)->id()) == serverNotes.end()) {
+      FOREACH(const NoteBase::Ptr & iter, localNotes) {
+        Note::Ptr note = static_pointer_cast<Note>(iter);
+       if(SyncManager::_obj().m_client->get_revision(note) != -1
+          && std::find(serverNotes.begin(), serverNotes.end(), note->id()) == serverNotes.end()) {
          if(m_sync_ui != 0) {
-           m_sync_ui->note_synchronized((*iter)->get_title(), DELETE_FROM_CLIENT);
+           m_sync_ui->note_synchronized(note->get_title(), DELETE_FROM_CLIENT);
          }
-         note_mgr().delete_note(*iter);
+         note_mgr().delete_note(note);
        }
       }
     }
@@ -689,7 +690,7 @@ namespace sync {
   void SyncManager::create_note(const NoteUpdate & noteUpdate)
   {
     try {
-      Note::Ptr existingNote = note_mgr().create_with_guid(noteUpdate.m_title, noteUpdate.m_uuid);
+      NoteBase::Ptr existingNote = note_mgr().create_with_guid(noteUpdate.m_title, noteUpdate.m_uuid);
       update_local_note(existingNote, noteUpdate, DOWNLOAD_NEW);
     }
     catch(std::exception & e) {
diff --git a/src/synchronization/syncmanager.hpp b/src/synchronization/syncmanager.hpp
index 91a4992..e7ea829 100644
--- a/src/synchronization/syncmanager.hpp
+++ b/src/synchronization/syncmanager.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -57,8 +57,8 @@ namespace sync {
         return static_cast<SyncManager&>(obj());
       }
     void _init(NoteManager &);
-    void handle_note_saved_or_deleted(const Note::Ptr & note);
-    void handle_note_buffer_changed(const Note::Ptr & note);
+    void handle_note_saved_or_deleted(const NoteBase::Ptr & note);
+    void handle_note_buffer_changed(const NoteBase::Ptr & note);
     void preferences_setting_changed(const Glib::ustring & key);
     void update_sync_action();
     void background_sync_checker();
@@ -68,8 +68,8 @@ namespace sync {
     void create_note_in_main_thread(const NoteUpdate & noteUpdate);
     void update_note_in_main_thread(const Note::Ptr & existingNote, const NoteUpdate & noteUpdate);
     void delete_note_in_main_thread(const Note::Ptr & existingNote);
-    void update_local_note(const Note::Ptr & localNote, const NoteUpdate & serverNote, NoteSyncType 
syncType);
-    Note::Ptr find_note_by_uuid(const std::string & uuid);
+    void update_local_note(const NoteBase::Ptr & localNote, const NoteUpdate & serverNote, NoteSyncType 
syncType);
+    NoteBase::Ptr find_note_by_uuid(const std::string & uuid);
     NoteManager & note_mgr();
     void get_synchronized_xml_bits(const std::string & noteXml, std::string & title, std::string & tags, 
std::string & content);
     void delete_notes(const SyncServer::Ptr & server);
diff --git a/src/synchronization/syncutils.cpp b/src/synchronization/syncutils.cpp
index b6ee871..65c5ded 100644
--- a/src/synchronization/syncutils.cpp
+++ b/src/synchronization/syncutils.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013 Aurimas Cernius
+ * Copyright (C) 2012-2014 Aurimas Cernius
  *
  * 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
@@ -66,7 +66,9 @@ namespace sync {
     //       was not just a container for a big XML string
     sharp::XmlReader xml;
     xml.load_buffer(m_xml_content);
-    std::auto_ptr<NoteData> update_data(NoteArchiver::obj().read(xml, m_uuid));
+    NoteData *data = new NoteData(m_uuid);
+    NoteArchiver::obj().read(xml, *data);
+    std::auto_ptr<NoteData> update_data(data);
     xml.close();
 
     // NOTE: Mostly a hack to ignore missing version attributes
diff --git a/src/tag.cpp b/src/tag.cpp
index 46e6a4d..2559461 100644
--- a/src/tag.cpp
+++ b/src/tag.cpp
@@ -41,7 +41,7 @@ namespace gnote {
     set_name(_name);
   }
 
-  void Tag::add_note(Note & note)
+  void Tag::add_note(NoteBase & note)
   {
     if(m_notes.find(note.uri()) == m_notes.end()) {
       m_notes[note.uri()] = &note;
@@ -49,7 +49,7 @@ namespace gnote {
   }
 
 
-  void Tag::remove_note(const Note & note)
+  void Tag::remove_note(const NoteBase & note)
   {
     NoteMap::iterator iter = m_notes.find(note.uri());
     if(iter != m_notes.end()) {
@@ -76,7 +76,7 @@ namespace gnote {
   }
 
 
-  void Tag::get_notes(std::list<Note *> & l) const
+  void Tag::get_notes(std::list<NoteBase*> & l) const
   {
     sharp::map_get_values(m_notes, l);
   }
diff --git a/src/tag.hpp b/src/tag.hpp
index 98b7ba7..ad036c9 100644
--- a/src/tag.hpp
+++ b/src/tag.hpp
@@ -32,7 +32,14 @@
 
 namespace gnote {
 
-  class Note;
+  enum ChangeType {
+    NO_CHANGE,
+    CONTENT_CHANGED,
+    OTHER_DATA_CHANGED
+  };
+
+
+  class NoteBase;
 
   class Tag 
   {
@@ -45,11 +52,11 @@ namespace gnote {
     // <summary>
     // Associates the specified note with this tag.
     // </summary>
-    void add_note(Note & );
+    void add_note(NoteBase & );
     // <summary>
     // Unassociates the specified note with this tag.
     // </summary>
-    void remove_note(const Note & );
+    void remove_note(const NoteBase & );
     // <summary>
     // The name of the tag.  This is what the user types in as the tag and
     // what's used to show the tag to the user. This includes any 'system:' prefixes
@@ -84,7 +91,7 @@ namespace gnote {
     // Returns a list of all the notes that this tag is associated with.
     // These pointer are not meant to be freed. They are OWNED.
     // </summary>
-    void get_notes(std::list<Note *> &) const;
+    void get_notes(std::list<NoteBase*> &) const;
     // <summary>
     // Returns the number of notes this is currently tagging.
     // </summary>
@@ -100,7 +107,7 @@ namespace gnote {
     // Used to track which notes are currently tagged by this tag.  The
     // dictionary key is the Note.Uri.
     // </summary>
-    typedef std::map<std::string, Note*> NoteMap;
+    typedef std::map<std::string, NoteBase*> NoteMap;
     NoteMap m_notes;
   };
 
diff --git a/src/tagmanager.cpp b/src/tagmanager.cpp
index 0f8b6dd..2ffcb56 100644
--- a/src/tagmanager.cpp
+++ b/src/tagmanager.cpp
@@ -212,11 +212,10 @@ namespace gnote {
         DBG_OUT("Removed TreeIter from tag_map: %s", tag->normalized_name().c_str());
         tag_removed = true;
 
-        std::list<Note*> notes;
+        std::list<NoteBase*> notes;
         tag->get_notes(notes);
-        for(std::list<Note*>::const_iterator note_iter = notes.begin();
-            note_iter != notes.end(); ++note_iter) {
-          (*note_iter)->remove_tag(tag);
+        FOREACH(NoteBase *note_iter, notes) {
+          note_iter->remove_tag(tag);
         }
       }
     }
diff --git a/src/tray.cpp b/src/tray.cpp
index ed373fa..559c38f 100644
--- a/src/tray.cpp
+++ b/src/tray.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2010-2013 Aurimas Cernius
+ * Copyright (C) 2010-2014 Aurimas Cernius
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -289,11 +289,8 @@ namespace gnote {
 
     // List the most recently changed notes, any currently
     // opened notes, and any pinned notes...
-    const Note::List & notes(m_manager.get_notes());
-    for(Note::List::const_iterator iter = notes.begin();
-        iter != notes.end(); ++iter) {
-
-      const Note::Ptr & note(*iter);
+    FOREACH(const NoteBase::Ptr & iter, m_manager.get_notes()) {
+      Note::Ptr note(static_pointer_cast<Note>(iter));
       
       if (note->is_special()) {
         DBG_OUT("skipping special note '%s'", note->get_title().c_str());
@@ -328,9 +325,9 @@ namespace gnote {
       }
     }
 
-    Note::Ptr start = m_manager.find_by_uri(m_manager.start_note_uri());
+    NoteBase::Ptr start = m_manager.find_by_uri(m_manager.start_note_uri());
     if (start) {
-      item = Gtk::manage(new NoteMenuItem(start, false));
+      item = Gtk::manage(new NoteMenuItem(static_pointer_cast<Note>(start), false));
       m_tray_menu->insert(*item, -1);
       list_size++;
 
diff --git a/src/watchers.cpp b/src/watchers.cpp
index 0da2d72..04fa44b 100644
--- a/src/watchers.cpp
+++ b/src/watchers.cpp
@@ -210,7 +210,7 @@ namespace gnote {
   {
     std::string title = get_window()->get_name();
 
-    Note::Ptr existing = manager().find (title);
+    NoteBase::Ptr existing = manager().find (title);
     if (existing && (existing != get_note())) {
       show_name_clash_error (title, only_warn);
       return false;
@@ -784,7 +784,7 @@ namespace gnote {
   }
 
 
-  void NoteLinkWatcher::on_note_added(const Note::Ptr & added)
+  void NoteLinkWatcher::on_note_added(const NoteBase::Ptr & added)
   {
     if (added == get_note()) {
       return;
@@ -798,7 +798,7 @@ namespace gnote {
     highlight_in_block (get_buffer()->begin(), get_buffer()->end());
   }
 
-  void NoteLinkWatcher::on_note_deleted(const Note::Ptr & deleted)
+  void NoteLinkWatcher::on_note_deleted(const NoteBase::Ptr & deleted)
   {
     if (deleted == get_note()) {
       return;
@@ -823,7 +823,7 @@ namespace gnote {
   }
 
 
-  void NoteLinkWatcher::on_note_renamed(const Note::Ptr& renamed, const std::string& /*old_title*/)
+  void NoteLinkWatcher::on_note_renamed(const NoteBase::Ptr& renamed, const Glib::ustring& /*old_title*/)
   {
     if (renamed == get_note()) {
       return;
@@ -831,12 +831,12 @@ namespace gnote {
 
     // Highlight previously unlinked text
     if (contains_text (renamed->get_title())) {
-      highlight_note_in_block (renamed, get_buffer()->begin(), get_buffer()->end());
+      highlight_note_in_block(static_pointer_cast<Note>(renamed), get_buffer()->begin(), 
get_buffer()->end());
     }
   }
 
   
-  void NoteLinkWatcher::do_highlight(const TrieHit<Note::WeakPtr> & hit,
+  void NoteLinkWatcher::do_highlight(const TrieHit<NoteBase::WeakPtr> & hit,
                                      const Gtk::TextIter & start,
                                      const Gtk::TextIter &)
   {
@@ -853,7 +853,7 @@ namespace gnote {
       return;
     }
       
-    Note::Ptr hit_note(hit.value());
+    NoteBase::Ptr hit_note(hit.value());
 
     if (hit.key().lowercase() != hit_note->get_title().lowercase()) { // == 0 if same string
       DBG_OUT ("DoHighlight: '%s' links wrongly to note '%s'." ,
@@ -900,7 +900,7 @@ namespace gnote {
     }
   }
 
-  void NoteLinkWatcher::highlight_note_in_block (const Note::Ptr & find_note, 
+  void NoteLinkWatcher::highlight_note_in_block (const NoteBase::Ptr & find_note,
                                                  const Gtk::TextIter & start,
                                                  const Gtk::TextIter & end)
   {
@@ -913,7 +913,7 @@ namespace gnote {
       if (idx < 0)
         break;
 
-      TrieHit<Note::WeakPtr> hit(idx, idx + find_title_lower.length(),
+      TrieHit<NoteBase::WeakPtr> hit(idx, idx + find_title_lower.length(),
                              find_title_lower, find_note);
       do_highlight (hit, start, end);
 
@@ -926,8 +926,8 @@ namespace gnote {
   void NoteLinkWatcher::highlight_in_block(const Gtk::TextIter & start,
                                            const Gtk::TextIter & end)
   {
-    TrieHit<Note::WeakPtr>::ListPtr hits = manager().find_trie_matches (start.get_slice (end));
-    for(TrieHit<Note::WeakPtr>::List::const_iterator iter = hits->begin();
+    TrieHit<NoteBase::WeakPtr>::ListPtr hits = manager().find_trie_matches (start.get_slice (end));
+    for(TrieHit<NoteBase::WeakPtr>::List::const_iterator iter = hits->begin();
         iter != hits->end(); ++iter) {
       do_highlight (**iter, start, end);
     }
@@ -978,7 +978,7 @@ namespace gnote {
     if (tag->property_name() != get_note()->get_tag_table()->get_link_tag()->property_name())
       return;
     std::string link_name = start.get_text (end);
-    Note::Ptr link = manager().find (link_name);
+    NoteBase::Ptr link = manager().find(link_name);
     if(!link)
         unhighlight_in_block(start, end);
   }
@@ -989,7 +989,7 @@ namespace gnote {
                                             const Gtk::TextIter & end)
   {
     std::string link_name = start.get_text (end);
-    Note::Ptr link = manager().find (link_name);
+    NoteBase::Ptr link = manager().find(link_name);
 
     if (!link) {
       DBG_OUT("Creating note '%s'...", link_name.c_str());
@@ -1016,7 +1016,7 @@ namespace gnote {
     // also works around the bug.
     if (link) {
       DBG_OUT ("Opening note '%s' on click...", link_name.c_str());
-      MainWindow::present_default(link);
+      MainWindow::present_default(static_pointer_cast<Note>(link));
       return true;
     }
 
@@ -1299,12 +1299,12 @@ namespace gnote {
   void NoteTagsWatcher::initialize ()
   {
 #ifdef DEBUG
-    m_on_tag_added_cid = get_note()->signal_tag_added().connect(
+    m_on_tag_added_cid = get_note()->signal_tag_added.connect(
       sigc::mem_fun(*this, &NoteTagsWatcher::on_tag_added));
-    m_on_tag_removing_cid = get_note()->signal_tag_removing().connect(
+    m_on_tag_removing_cid = get_note()->signal_tag_removing.connect(
       sigc::mem_fun(*this, &NoteTagsWatcher::on_tag_removing));
 #endif
-    m_on_tag_removed_cid = get_note()->signal_tag_removed().connect(
+    m_on_tag_removed_cid = get_note()->signal_tag_removed.connect(
       sigc::mem_fun(*this, &NoteTagsWatcher::on_tag_removed));      
   }
 
@@ -1327,20 +1327,20 @@ namespace gnote {
   }
 
 #ifdef DEBUG
-  void NoteTagsWatcher::on_tag_added(const Note& DBG(note), const Tag::Ptr& DBG(tag))
+  void NoteTagsWatcher::on_tag_added(const NoteBase& DBG(note), const Tag::Ptr& DBG(tag))
   {
     DBG_OUT ("Tag added to %s: %s", note.get_title().c_str(), tag->name().c_str());
   }
 
 
-  void NoteTagsWatcher::on_tag_removing(const Note& note, const Tag & tag)
+  void NoteTagsWatcher::on_tag_removing(const NoteBase& note, const Tag & tag)
   {
     DBG_OUT ("Removing tag from %s: %s", note.get_title().c_str(), tag.name().c_str());
   }
 #endif
 
 
-  void NoteTagsWatcher::on_tag_removed(const Note::Ptr&, const std::string& tag_name)
+  void NoteTagsWatcher::on_tag_removed(const NoteBase::Ptr&, const std::string& tag_name)
   {
     Tag::Ptr tag = ITagManager::obj().get_tag(tag_name);
     DBG_OUT ("Watchers.OnTagRemoved popularity count: %d", tag ? tag->popularity() : 0);
diff --git a/src/watchers.hpp b/src/watchers.hpp
index 487c644..5da2c45 100644
--- a/src/watchers.hpp
+++ b/src/watchers.hpp
@@ -183,11 +183,11 @@ namespace gnote {
 
   private:
     bool contains_text(const Glib::ustring & text);
-    void on_note_added(const Note::Ptr &);
-    void on_note_deleted(const Note::Ptr &);
-    void on_note_renamed(const Note::Ptr&, const std::string&);
-    void do_highlight(const TrieHit<Note::WeakPtr> & , const Gtk::TextIter &,const Gtk::TextIter &);
-    void highlight_note_in_block (const Note::Ptr &, const Gtk::TextIter &,
+    void on_note_added(const NoteBase::Ptr &);
+    void on_note_deleted(const NoteBase::Ptr &);
+    void on_note_renamed(const NoteBase::Ptr&, const Glib::ustring&);
+    void do_highlight(const TrieHit<NoteBase::WeakPtr> & , const Gtk::TextIter &,const Gtk::TextIter &);
+    void highlight_note_in_block (const NoteBase::Ptr &, const Gtk::TextIter &,
                                   const Gtk::TextIter &);
     void highlight_in_block(const Gtk::TextIter &,const Gtk::TextIter &);
     void unhighlight_in_block(const Gtk::TextIter &,const Gtk::TextIter &);
@@ -276,9 +276,9 @@ namespace gnote {
     virtual void on_note_opened() override;
 
   private:
-    void on_tag_added(const Note&, const Tag::Ptr&);
-    void on_tag_removing(const Note&, const Tag &);
-    void on_tag_removed(const Note::Ptr&, const std::string&);
+    void on_tag_added(const NoteBase&, const Tag::Ptr&);
+    void on_tag_removing(const NoteBase&, const Tag &);
+    void on_tag_removed(const NoteBase::Ptr&, const std::string&);
 
     sigc::connection m_on_tag_added_cid;
     sigc::connection m_on_tag_removing_cid;


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