diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0aa4faa27f71a7fa9b1be8663560afadc4ecdced..5a90c41aff7b96451378dd3f3b7673eb5903feea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,6 +58,11 @@ configure_file(
     IMMEDIATE @ONLY
 )
 
+# Early configure these files as we need them later on
+configure_file( CalamaresUse.cmake.in "${PROJECT_BINARY_DIR}/CalamaresUse.cmake" @ONLY )
+file( COPY CalamaresAddPlugin.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
+file( COPY CalamaresAddLibrary.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
+
 set( CALAMARES_LIBRARIES calamareslib )
 
 add_subdirectory( src )
diff --git a/CalamaresAddLibrary.cmake b/CalamaresAddLibrary.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..a7666b8eb26f2a3efebe36b4eb2b2cb711a49fee
--- /dev/null
+++ b/CalamaresAddLibrary.cmake
@@ -0,0 +1,112 @@
+include( CMakeParseArguments )
+
+function(calamares_add_library)
+    # parse arguments (name needs to be saved before passing ARGN into the macro)
+    set(NAME ${ARGV0})
+    set(options NO_INSTALL NO_VERSION)
+    set(oneValueArgs NAME TYPE EXPORT_MACRO TARGET TARGET_TYPE EXPORT VERSION SOVERSION INSTALL_BINDIR)
+    set(multiValueArgs SOURCES UI LINK_LIBRARIES LINK_PRIVATE_LIBRARIES COMPILE_DEFINITIONS QT5_MODULES)
+    cmake_parse_arguments(LIBRARY "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    set(LIBRARY_NAME ${NAME})
+
+
+#     message("*** Arguments for ${LIBRARY_NAME}")
+#     message("Sources: ${LIBRARY_SOURCES}")
+#     message("Link libraries: ${LIBRARY_LINK_LIBRARIES}")
+#     message("UI: ${LIBRARY_UI}")
+#     message("TARGET_TYPE: ${LIBRARY_TARGET_TYPE}")
+#     message("EXPORT_MACRO: ${LIBRARY_EXPORT_MACRO}")
+#     message("NO_INSTALL: ${LIBRARY_NO_INSTALL}")
+
+    set(target ${LIBRARY_NAME})
+
+    # qt stuff
+    include_directories(${CMAKE_CURRENT_LIST_DIR})
+    include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+    if(LIBRARY_UI)
+        qt_wrap_ui(LIBRARY_UI_SOURCES ${LIBRARY_UI})
+        list(APPEND LIBRARY_SOURCES ${LIBRARY_UI_SOURCES})
+    endif()
+
+    # add resources from current dir
+    if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/resources.qrc")
+        qt_add_resources(LIBRARY_RC_SOURCES "resources.qrc")
+        list(APPEND LIBRARY_SOURCES ${LIBRARY_RC_SOURCES})
+        unset(LIBRARY_RC_SOURCES)
+    endif()
+
+    # add target
+    if(LIBRARY_TARGET_TYPE STREQUAL "STATIC")
+        add_library(${target} STATIC ${LIBRARY_SOURCES})
+    elseif(LIBRARY_TARGET_TYPE STREQUAL "MODULE")
+        add_library(${target} MODULE ${LIBRARY_SOURCES})
+    else() # default
+        add_library(${target} SHARED ${LIBRARY_SOURCES})
+    endif()
+
+    # HACK: add qt modules - every lib should define its own set of modules
+    qt5_use_modules(${target} Core Gui Widgets ${LIBRARY_QT5_MODULES})
+
+    # definitions - can this be moved into set_target_properties below?
+    add_definitions(${QT_DEFINITIONS})
+    set_target_properties(${target} PROPERTIES AUTOMOC TRUE)
+
+    if(LIBRARY_EXPORT_MACRO)
+        set_target_properties(${target} PROPERTIES COMPILE_DEFINITIONS ${LIBRARY_EXPORT_MACRO})
+    endif()
+
+    if(LIBRARY_COMPILE_DEFINITIONS)
+        # Dear CMake, i hate you! Sincerely, domme
+        # At least in CMake 2.8.8, you CANNOT set more than one COMPILE_DEFINITIONS value
+        # only takes the first one if called multiple times or bails out with wrong number of arguments
+        # when passing in a list, thus i redefine the export macro here in hope it won't mess up other targets
+        add_definitions( "-D${LIBRARY_EXPORT_MACRO}" )
+
+        set_target_properties(${target} PROPERTIES COMPILE_DEFINITIONS ${LIBRARY_COMPILE_DEFINITIONS})
+    endif()
+
+    # add link targets
+    target_link_libraries(${target} ${CALAMARES_LIBRARIES})
+    if(LIBRARY_LINK_LIBRARIES)
+        target_link_libraries(${target} ${LIBRARY_LINK_LIBRARIES})
+    endif()
+    if(LIBRARY_LINK_PRIVATE_LIBRARIES)
+        target_link_libraries(${target} LINK_PRIVATE ${LIBRARY_LINK_PRIVATE_LIBRARIES})
+    endif()
+
+    # add soversion
+    if(NOT LIBRARY_NO_VERSION)
+        set_target_properties(${target} PROPERTIES VERSION ${LIBRARY_VERSION})
+
+        if(NOT LIBRARY_SOVERSION)
+            set(LIBRARY_SOVERSION ${LIBRARY_VERSION})
+        endif()
+
+        set_target_properties(${target} PROPERTIES SOVERSION ${LIBRARY_SOVERSION})
+    endif()
+
+
+    if(NOT LIBRARY_INSTALL_BINDIR)
+        set(LIBRARY_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}")
+    endif()
+
+    # make installation optional, maybe useful for dummy plugins one day
+    if(NOT LIBRARY_NO_INSTALL)
+        include(GNUInstallDirs)
+        if(NOT LIBRARY_EXPORT)
+            install( TARGETS ${target}
+                RUNTIME DESTINATION ${LIBRARY_INSTALL_BINDIR}
+                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            )
+        else()
+            install( TARGETS ${target}
+                EXPORT ${LIBRARY_EXPORT}
+                RUNTIME DESTINATION ${LIBRARY_INSTALL_BINDIR}
+                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            )
+        endif()
+    endif()
+endfunction()
diff --git a/CalamaresAddPlugin.cmake b/CalamaresAddPlugin.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fac053d1e20b5f1a54d34278c2da43fc1fdf18a3
--- /dev/null
+++ b/CalamaresAddPlugin.cmake
@@ -0,0 +1,55 @@
+include( CMakeParseArguments )
+include( ${CALAMARES_CMAKE_DIR}/CalamaresAddLibrary.cmake )
+
+function(calamares_add_plugin)
+    # parse arguments (name needs to be saved before passing ARGN into the macro)
+    set(NAME ${ARGV0})
+    set(options NO_INSTALL SHARED_LIB)
+    set(oneValueArgs NAME TYPE EXPORT_MACRO)
+    set(multiValueArgs SOURCES UI LINK_LIBRARIES COMPILE_DEFINITIONS)
+    cmake_parse_arguments(PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    set(PLUGIN_NAME ${NAME})
+
+#     message("*** Arguments for ${PLUGIN_NAME}")
+#     message("Sources: ${PLUGIN_SOURCES}")
+#     message("Link libraries: ${PLUGIN_LINK_LIBRARIES}")
+#     message("UI: ${PLUGIN_UI}")
+#     message("TYPE: ${PLUGIN_TYPE}")
+#     message("EXPORT_MACRO: ${PLUGIN_EXPORT_MACRO}")
+#     message("NO_INSTALL: ${PLUGIN_NO_INSTALL}")
+
+    # create target name once for convenience
+    set(target "calamares_${PLUGIN_TYPE}_${PLUGIN_NAME}")
+
+    # determine target type
+    if(NOT ${PLUGIN_SHARED_LIB})
+        set(target_type "MODULE")
+    else()
+        set(target_type "SHARED")
+    endif()
+
+    list(APPEND calamares_add_library_args
+      "${target}"
+      "EXPORT_MACRO" "${PLUGIN_EXPORT_MACRO}"
+      "TARGET_TYPE" "${target_type}"
+      "SOURCES" "${PLUGIN_SOURCES}"
+    )
+
+    if(PLUGIN_UI)
+        list(APPEND calamares_add_library_args "UI" "${PLUGIN_UI}")
+    endif()
+
+    if(PLUGIN_LINK_LIBRARIES)
+        list(APPEND calamares_add_library_args "LINK_LIBRARIES" "${PLUGIN_LINK_LIBRARIES}")
+    endif()
+
+    if(PLUGIN_COMPILE_DEFINITIONS)
+        list(APPEND calamares_add_library_args "COMPILE_DEFINITIONS" ${PLUGIN_COMPILE_DEFINITIONS})
+    endif()
+
+    list(APPEND calamares_add_library_args "NO_VERSION")
+
+    list(APPEND calamares_add_library_args "INSTALL_BINDIR" "${CMAKE_INSTALL_LIBDIR}")
+
+    calamares_add_library(${calamares_add_library_args})
+endfunction()
diff --git a/CalamaresConfig.cmake.in b/CalamaresConfig.cmake.in
index ccba1cbbf7b01b5bba1b29d02ff63b8c4af0a7ff..d725969280d5b0a7bc949aa170fbe6658440b5cf 100644
--- a/CalamaresConfig.cmake.in
+++ b/CalamaresConfig.cmake.in
@@ -18,4 +18,4 @@ include("${CALAMARES_CMAKE_DIR}/CalamaresLibraryDepends.cmake")
 
 # These are IMPORTED targets created by CalamaresLibraryDepends.cmake
 set(CALAMARES_LIBRARIES calamareslib)
-#set(CALAMARES_USE_FILE "${CALAMARES_CMAKE_DIR}/CalamaresUse.cmake")
+set(CALAMARES_USE_FILE "${CALAMARES_CMAKE_DIR}/CalamaresUse.cmake")
diff --git a/CalamaresUse.cmake.in b/CalamaresUse.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..b534b4707b77e9cb4dc0e3e239cea5e56491416e
--- /dev/null
+++ b/CalamaresUse.cmake.in
@@ -0,0 +1,10 @@
+#FIXME: this duplicates top level cmakelists: how can we reduce code duplication?
+
+find_package( Qt5 5.3.0 CONFIG REQUIRED Core Gui Widgets LinguistTools )
+
+if(NOT CALAMARES_CMAKE_DIR)
+    set(CALAMARES_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR})
+endif()
+
+include( "${CALAMARES_CMAKE_DIR}/CalamaresAddLibrary.cmake" )
+include( "${CALAMARES_CMAKE_DIR}/CalamaresAddPlugin.cmake" )
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 96b5c6dbbebd7413d626cabc84861ecf1ec361ed..3158ae1c2be494eec47994be3f8f360c8a421419 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,3 +1,5 @@
+include( ${PROJECT_BINARY_DIR}/CalamaresUse.cmake )
+
 include_directories( ${CMAKE_CURRENT_BINARY_DIR}/libcalamares )
 include_directories( ${CMAKE_CURRENT_LIST_DIR}/libcalamares )
 
@@ -9,3 +11,9 @@ add_subdirectory( libcalamares )
 
 # application
 add_subdirectory( calamares )
+
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/calamares )
+include_directories( ${CMAKE_CURRENT_LIST_DIR}/calamares )
+
+# plugins
+add_subdirectory( modules )
diff --git a/src/calamares/CMakeLists.txt b/src/calamares/CMakeLists.txt
index 4af1b170f4a1a09132bfe45a34af2332b4752d5d..b2555bce1d820b77f6a4c44e52b23a066e53c33a 100644
--- a/src/calamares/CMakeLists.txt
+++ b/src/calamares/CMakeLists.txt
@@ -8,6 +8,11 @@ set( calamaresSources
     main.cpp
     CalamaresApplication.cpp
     CalamaresWindow.cpp
+    ViewManager.cpp
+    Settings.cpp
+
+    viewpages/PagePlugin.cpp
+    viewpages/AbstractPage.cpp
 )
 
 set( calamaresUi
diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp
index ec410d28ebc855c2a9a0b2b4123a2561baab0f28..8c47f26a8c96ae92750867f25dd376dad78b51f5 100644
--- a/src/calamares/CalamaresWindow.cpp
+++ b/src/calamares/CalamaresWindow.cpp
@@ -18,8 +18,18 @@
 
 #include "CalamaresWindow.h"
 
+#include "ViewManager.h"
+
+#include "QBoxLayout"
+
 CalamaresWindow::CalamaresWindow( QWidget* parent )
     : QWidget( parent )
 {
     setupUi( this );
+
+    //This should create a PageManager or ViewManager or whatever, which
+    //should control the sidebar, next/back buttons and QSW.
+    Calamares::ViewManager* vm = new Calamares::ViewManager( this );
+
+    layout()->addWidget( vm->widget() );
 }
diff --git a/src/calamares/CalamaresWindow.ui b/src/calamares/CalamaresWindow.ui
index 8b36b7bf3fde002d59ac281213c6a2974ee0f8c6..7fdcbd8e3a048a23ca52696d89d2381e9d5fd5f4 100644
--- a/src/calamares/CalamaresWindow.ui
+++ b/src/calamares/CalamaresWindow.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>800</width>
-    <height>500</height>
+    <height>592</height>
    </rect>
   </property>
   <property name="maximumSize">
@@ -22,8 +22,8 @@
   <property name="styleSheet">
    <string notr="true"/>
   </property>
-  <layout class="QGridLayout" name="gridLayout_6">
-   <item row="0" column="0">
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
     <widget class="QFrame" name="leftSidebar">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@@ -98,7 +98,7 @@
            <string/>
           </property>
           <property name="pixmap">
-           <pixmap resource="../github/installer/ui/installer.qrc">:/Images/images/install.png</pixmap>
+           <pixmap>:/Images/images/install.png</pixmap>
           </property>
           <property name="scaledContents">
            <bool>true</bool>
@@ -540,133 +540,8 @@ p, li { white-space: pre-wrap; }
      </layout>
     </widget>
    </item>
-   <item row="0" column="1">
-    <layout class="QVBoxLayout" name="verticalLayout_3">
-     <property name="leftMargin">
-      <number>10</number>
-     </property>
-     <property name="topMargin">
-      <number>10</number>
-     </property>
-     <property name="rightMargin">
-      <number>10</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QStackedWidget" name="stackedWidget">
-       <property name="enabled">
-        <bool>true</bool>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>578</width>
-         <height>420</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>16777215</width>
-         <height>16777215</height>
-        </size>
-       </property>
-       <widget class="QWidget" name="page_2"/>
-      </widget>
-     </item>
-     <item>
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <property name="bottomMargin">
-        <number>8</number>
-       </property>
-       <item>
-        <widget class="QPushButton" name="abortButton">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>180</width>
-           <height>48</height>
-          </size>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="text">
-          <string>Abort installation</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer_3">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-       <item>
-        <widget class="QPushButton" name="previousButton">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>150</width>
-           <height>48</height>
-          </size>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="text">
-          <string comment="Previous Page">Previous</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="nextButton">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>150</width>
-           <height>48</height>
-          </size>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="text">
-          <string comment="Next Page">Next</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </item>
-    </layout>
-   </item>
   </layout>
  </widget>
- <resources>
-  <include location="../github/installer/ui/installer.qrc"/>
-  <include location="../github/installer/ui/installer.qrc"/>
- </resources>
+ <resources/>
  <connections/>
 </ui>
diff --git a/src/calamares/DllMacro.h b/src/calamares/DllMacro.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f487be4f0c972b8b2dec042032ed6e532ce7f86
--- /dev/null
+++ b/src/calamares/DllMacro.h
@@ -0,0 +1,32 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UIDLLMACRO_H
+#define UIDLLMACRO_H
+
+#include <QtCore/qglobal.h>
+
+#ifndef UIDLLEXPORT
+# if defined (UIDLLEXPORT_PRO)
+#  define UIDLLEXPORT Q_DECL_EXPORT
+# else
+#  define UIDLLEXPORT Q_DECL_IMPORT
+# endif
+#endif
+
+#endif
diff --git a/src/calamares/Settings.cpp b/src/calamares/Settings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6a8d1a97a324a14ab23982a23012406932e39fd7
--- /dev/null
+++ b/src/calamares/Settings.cpp
@@ -0,0 +1,24 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Settings.h"
+
+Settings::Settings( QObject* parent )
+    : QObject( parent )
+{
+}
diff --git a/src/calamares/Settings.h b/src/calamares/Settings.h
new file mode 100644
index 0000000000000000000000000000000000000000..5943b34c98435441c03444562acd9b12e5e7f41d
--- /dev/null
+++ b/src/calamares/Settings.h
@@ -0,0 +1,39 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <QObject>
+
+
+// Settings::instance() ?
+
+class Settings : public QObject
+{
+    Q_OBJECT
+public:
+    explicit Settings( QObject *parent = 0 );
+    //TODO: load from JSON then emit ready
+signals:
+
+public slots:
+
+};
+
+#endif // SETTINGS_H
diff --git a/src/calamares/ViewManager.cpp b/src/calamares/ViewManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1edaf7617890b9dbe55cdbc58dd7eacee7ffb0e
--- /dev/null
+++ b/src/calamares/ViewManager.cpp
@@ -0,0 +1,82 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ViewManager.h"
+
+#include <QBoxLayout>
+
+namespace Calamares
+{
+
+ViewManager* ViewManager::s_instance = 0;
+
+ViewManager*
+ViewManager::instance()
+{
+    return s_instance;
+}
+
+ViewManager::ViewManager( QObject* parent )
+    : QObject( parent )
+    , m_widget( new QWidget() )
+{
+    s_instance = this;
+    QBoxLayout* mainLayout = new QVBoxLayout;
+    m_widget->setLayout( mainLayout );
+
+    m_stack = new QStackedWidget( m_widget );
+    mainLayout->addWidget( m_stack );
+
+    m_back = new QPushButton( tr( "&Back" ), m_widget );
+    m_next = new QPushButton( tr( "&Next" ), m_widget );
+
+    QBoxLayout* bottomLayout = new QHBoxLayout;
+    mainLayout->addLayout( bottomLayout );
+    bottomLayout->addStretch();
+    bottomLayout->addWidget( m_back );
+    bottomLayout->addWidget( m_next );
+}
+
+
+ViewManager::~ViewManager()
+{
+    m_widget->deleteLater();
+}
+
+
+QWidget*
+ViewManager::widget()
+{
+    return m_widget;
+}
+
+
+void
+ViewManager::next()
+{
+    Q_ASSERT( 0 );
+}
+
+
+void
+ViewManager::back()
+{
+    Q_ASSERT( 0 );
+}
+
+}
diff --git a/src/calamares/ViewManager.h b/src/calamares/ViewManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8757d4f7ac6cede239e67ed52362ed6d5e63ad7
--- /dev/null
+++ b/src/calamares/ViewManager.h
@@ -0,0 +1,63 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef VIEWMANAGER_H
+#define VIEWMANAGER_H
+
+#include "DllMacro.h"
+#include "viewpages/PagePlugin.h"
+
+#include <QPushButton>
+#include <QStackedWidget>
+
+namespace Calamares
+{
+
+class UIDLLEXPORT ViewManager : public QObject
+{
+    Q_OBJECT
+public:
+    static ViewManager* instance();
+
+    explicit ViewManager( QObject* parent = 0 );
+    virtual ~ViewManager();
+
+    QWidget* widget();
+
+    void addPagePlugin( PagePlugin* plugin );
+
+    void insertPage( AbstractPage* page );
+    void setNext( AbstractPage* page );
+    void removePage( AbstractPage* page );
+
+public slots:
+    void next();
+    void back();
+
+private:
+    static ViewManager* s_instance;
+
+    QWidget* m_widget;
+    QStackedWidget* m_stack;
+    QPushButton* m_back;
+    QPushButton* m_next;
+};
+
+}
+
+#endif // VIEWMANAGER_H
diff --git a/src/calamares/viewpages/AbstractPage.cpp b/src/calamares/viewpages/AbstractPage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..19e5412c0364dc3a613bf32788f93eb9f7713254
--- /dev/null
+++ b/src/calamares/viewpages/AbstractPage.cpp
@@ -0,0 +1,29 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AbstractPage.h"
+
+namespace Calamares
+{
+
+AbstractPage::AbstractPage( QWidget* parent )
+    : QWidget( parent )
+{
+}
+
+}
diff --git a/src/calamares/viewpages/AbstractPage.h b/src/calamares/viewpages/AbstractPage.h
new file mode 100644
index 0000000000000000000000000000000000000000..6dd04af7cbf647c06b0c302323738034e2453246
--- /dev/null
+++ b/src/calamares/viewpages/AbstractPage.h
@@ -0,0 +1,43 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ABSTRACTPAGE_H
+#define ABSTRACTPAGE_H
+
+#include <QWidget>
+
+#include "../DllMacro.h"
+
+namespace Calamares
+{
+
+class UIDLLEXPORT AbstractPage : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit AbstractPage(QWidget *parent = 0);
+
+signals:
+
+public slots:
+
+};
+
+}
+
+#endif // ABSTRACTPAGE_H
diff --git a/src/calamares/viewpages/PagePlugin.cpp b/src/calamares/viewpages/PagePlugin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..95bcef2960835383f536dd383208e098b4d68d59
--- /dev/null
+++ b/src/calamares/viewpages/PagePlugin.cpp
@@ -0,0 +1,29 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PagePlugin.h"
+
+namespace Calamares
+{
+
+PagePlugin::PagePlugin( QObject* parent )
+    : QObject( parent )
+{
+}
+
+}
diff --git a/src/calamares/viewpages/PagePlugin.h b/src/calamares/viewpages/PagePlugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..58ba31cd81142b05a519fd338a5248a2d7560aba
--- /dev/null
+++ b/src/calamares/viewpages/PagePlugin.h
@@ -0,0 +1,46 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGEPLUGIN_H
+#define PAGEPLUGIN_H
+
+#include <QObject>
+
+#include "../DllMacro.h"
+
+namespace Calamares
+{
+
+class AbstractPage;
+
+class UIDLLEXPORT PagePlugin : public QObject
+{
+    Q_OBJECT
+public:
+    explicit PagePlugin( QObject *parent = 0 );
+
+signals:
+    void done();
+
+};
+
+}
+
+Q_DECLARE_INTERFACE( Calamares::PagePlugin, "calamares.PagePlugin/1.0" )
+
+#endif // PAGEPLUGIN_H
diff --git a/src/libcalamares/PluginDllMacro.h b/src/libcalamares/PluginDllMacro.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea73935f608cc0408afa05c9a5ddd7518732d4f9
--- /dev/null
+++ b/src/libcalamares/PluginDllMacro.h
@@ -0,0 +1,32 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PLUGINDLLMACRO_H
+#define PLUGINDLLMACRO_H
+
+#include <QtCore/qglobal.h>
+
+#ifndef PLUGINDLLEXPORT
+# if defined (PLUGINDLLEXPORT_PRO)
+#  define PLUGINDLLEXPORT Q_DECL_EXPORT
+# else
+#  define PLUGINDLLEXPORT Q_DECL_IMPORT
+# endif
+#endif
+
+#endif
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f418511f27b76aae7f36f6b012bbbcba1ba409be
--- /dev/null
+++ b/src/modules/CMakeLists.txt
@@ -0,0 +1,6 @@
+file(GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
+foreach(SUBDIRECTORY ${SUBDIRECTORIES})
+    if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/CMakeLists.txt")
+        add_subdirectory(${SUBDIRECTORY})
+    endif()
+endforeach()
diff --git a/src/modules/README.md b/src/modules/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ab1d6437d4d6b01fd04b0ec3c5a87c8fe13417ff
--- /dev/null
+++ b/src/modules/README.md
@@ -0,0 +1,5 @@
+Calamares modules directory
+===
+
+Calamares modules are plugins that implement the Calamares module API and can provide features like installer pages, batch jobs, etc.
+To add a module, put it in a subdirectory and make sure it has a CMakeLists.txt, it should be picked up automatically by our CMake magic.
diff --git a/src/modules/greeting/CMakeLists.txt b/src/modules/greeting/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c4eb762dade152c39e8bbd7c44d7d6f73c661e66
--- /dev/null
+++ b/src/modules/greeting/CMakeLists.txt
@@ -0,0 +1,12 @@
+include_directories( ${PROJECT_BINARY_DIR}/src/calamares )
+calamares_add_plugin( greeting
+    TYPE pageplugin
+    EXPORT_MACRO PLUGINDLLEXPORT_PRO
+    SOURCES
+        GreetingPagePlugin.cpp
+        GreetingPage.cpp
+    UI
+    LINK_LIBRARIES
+        ${CALAMARES_LIBRARIES}
+    SHARED_LIB
+)
diff --git a/src/modules/greeting/GreetingPage.cpp b/src/modules/greeting/GreetingPage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a215895c09f650da30d749816f4b2f7fa2d0d001
--- /dev/null
+++ b/src/modules/greeting/GreetingPage.cpp
@@ -0,0 +1,25 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GreetingPage.h"
+
+
+GreetingPage::GreetingPage( QWidget* parent )
+    : AbstractPage( parent )
+{
+}
diff --git a/src/modules/greeting/GreetingPage.h b/src/modules/greeting/GreetingPage.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb5d6c5ec50e133b9b1c6bbc309c20974d65d86f
--- /dev/null
+++ b/src/modules/greeting/GreetingPage.h
@@ -0,0 +1,36 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GREETINGPAGE_H
+#define GREETINGPAGE_H
+
+#include "viewpages/AbstractPage.h"
+
+class GreetingPage : public Calamares::AbstractPage
+{
+    Q_OBJECT
+public:
+    explicit GreetingPage( QWidget* parent = 0 );
+
+signals:
+
+public slots:
+
+};
+
+#endif // GREETINGPAGE_H
diff --git a/src/modules/greeting/GreetingPagePlugin.cpp b/src/modules/greeting/GreetingPagePlugin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2aa33f0189f7faf4085aaeef6fc3262dae82c92f
--- /dev/null
+++ b/src/modules/greeting/GreetingPagePlugin.cpp
@@ -0,0 +1,24 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GreetingPagePlugin.h"
+
+GreetingPagePlugin::GreetingPagePlugin( QObject *parent )
+    : PagePlugin( parent )
+{
+}
diff --git a/src/modules/greeting/GreetingPagePlugin.h b/src/modules/greeting/GreetingPagePlugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..61e6d729f19c128a8bfaf25d7c84a9a7106d50f9
--- /dev/null
+++ b/src/modules/greeting/GreetingPagePlugin.h
@@ -0,0 +1,39 @@
+/* === This file is part of Calamares - <http://github.com/calamares> ===
+ *
+ *   Copyright 2014, Teo Mrnjavac <teo@kde.org>
+ *
+ *   Calamares 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.
+ *
+ *   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GREETINGPAGEPLUGIN_H
+#define GREETINGPAGEPLUGIN_H
+
+#include <QObject>
+
+#include "viewpages/PagePlugin.h"
+#include "PluginDllMacro.h"
+
+class PLUGINDLLEXPORT GreetingPagePlugin : public Calamares::PagePlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA( IID "calamares.PagePlugin/1.0" )
+                       //FILE "module.json" )
+    Q_INTERFACES( Calamares::PagePlugin )
+public:
+    explicit GreetingPagePlugin(QObject *parent = 0);
+
+
+};
+
+#endif // GREETINGPAGEPLUGIN_H