diff --git a/data/ArmarXGui/GuiDefaultConfigs/Statecharts.armarxgui b/data/ArmarXGui/GuiDefaultConfigs/Statecharts.armarxgui
index 69de95b384e7463e6c0cb6f4d4c75c31f3d63fc4..d0c7d986d99845e8188471a9ee1edb847aef3cf5 100644
--- a/data/ArmarXGui/GuiDefaultConfigs/Statecharts.armarxgui
+++ b/data/ArmarXGui/GuiDefaultConfigs/Statecharts.armarxgui
@@ -1,7 +1,7 @@
 [General]
 ConfigTitle="Statechart Programming"
 ConfigDescription="GUI layout for programming statecharts"
-IconPath=":statechart-editor/states.svg"
+IconPath="Statecharts.StatechartEditor.png"
 MainWindowGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\x18\0\0\0\x34\0\0\af\0\0\x4y\0\0\0\"\0\0\0U\0\0\a\\\0\0\x4o\0\0\0\0\0\0)
 DockWidgetsState="@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x1\0\0\0\x1\0\0\a;\0\0\x3\xc2\xfc\x2\0\0\0\x2\xfc\0\0\0\x43\0\0\x3\xc2\0\0\0\0\0\xff\xff\xff\xfc\x1\0\0\0\x2\xfc\0\0\0\0\0\0\x3\x32\0\0\0\0\0\xff\xff\xff\xfc\x2\0\0\0\x2\xfc\0\0\0\x43\0\0\x2%\0\0\0\0\0\xff\xff\xff\xfa\0\0\0\0\x2\0\0\0\x2\xfb\0\0\0$\0\x44\0o\0\x63\0k\0M\0\x65\0t\0\x61\0.\0L\0o\0g\0V\0i\0\x65\0w\0\x65\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\xfb\0\0\0(\0\x44\0o\0\x63\0k\0K\0i\0n\0\x65\0m\0\x61\0t\0i\0\x63\0U\0n\0i\0t\0G\0U\0I\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\xfb\0\0\0&\0\x44\0o\0\x63\0k\0P\0l\0\x61\0t\0\x66\0o\0r\0m\0U\0n\0i\0t\0G\0U\0I\x1\0\0\x2n\0\0\x1\x97\0\0\0\0\0\0\0\0\xfc\0\0\x3\x38\0\0\x4\x3\0\0\0\0\0\xff\xff\xff\xfa\0\0\0\0\x2\0\0\0\x2\xfb\0\0\0\x16\0\x44\0o\0\x63\0k\0R\0o\0\x62\0o\0t\0I\0K\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\xfb\0\0\0\x36\0\x44\0o\0\x63\0k\0V\0i\0s\0u\0\x61\0l\0i\0z\0\x61\0t\0i\0o\0n\0.\0\x33\0\x44\0 \0V\0i\0\x65\0w\0\x65\0r\x1\0\0\0\x43\0\0\x3[\0\0\0\0\0\0\0\0\xfc\0\0\0\x43\0\0\x3\xc2\0\0\0\x8c\x1\0\0\x1d\xfa\0\0\0\0\x2\0\0\0\x4\xfb\0\0\0(\0\x44\0o\0\x63\0k\0S\0t\0\x61\0t\0\x65\0\x63\0h\0\x61\0r\0t\0\x45\0\x64\0i\0t\0o\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\x62\0\xff\xff\xff\xfb\0\0\0(\0\x44\0o\0\x63\0k\0S\0t\0\x61\0t\0\x65\0\x63\0h\0\x61\0r\0t\0V\0i\0\x65\0w\0\x65\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0n\0\xff\xff\xff\xfb\0\0\0\x1a\0\x44\0o\0\x63\0k\0L\0o\0g\0V\0i\0\x65\0w\0\x65\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0n\0\xff\xff\xff\xfb\0\0\0\x34\0\x44\0o\0\x63\0k\0O\0\x62\0s\0\x65\0r\0v\0\x65\0r\0s\0.\0O\0\x62\0s\0\x65\0r\0v\0\x65\0r\0V\0i\0\x65\0w\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\x62\0\xff\xff\xff\0\0\0\0\0\0\x3\xc2\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\x2\0\0\0\x1\0\0\0\xe\0t\0o\0o\0l\0\x42\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)"
 WidgetCustomNames=LogViewer, Observers.ObserverView, StatechartEditor, StatechartViewer
diff --git a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp
index a62d6d90ef1ee987b144ca6725c49818ca51b3ed..7bcb6bf27ccd8ed8cd5d6486bfe194843a0f4385 100644
--- a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp
+++ b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp
@@ -105,18 +105,21 @@ using namespace armarx;
 
 ArmarXMainWindow::ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfacePtr& registry, const std::vector<string>& packages, const QString& configToLoad) :
     QMainWindow(NULL),
+    pluginCache(ArmarXManagerPtr::dynamicCast(registry)),
     defaultPackageNames(packages),
     mainSettings(QSettings::UserScope, ARMARX_ORGANIZATION, ARMARX_GUI_APPLICATION_NAME)
 {
+    mainWidgets = QStringList() << "Meta.LogViewer" << "Statecharts.StatechartEditor" << "Meta.SystemStateMonitor" << "Meta.ScenarioManager" << "MemoryX.WorkingMemoryGui";
+
     splashscreenPrefix =  "v" + QString::fromStdString(Application::GetVersion()) + " - ";
     QPixmap pm(QString("://icons/ArmarX-Splashscreen.png"));
     splashSceen = new QSplashScreen(pm);
-    splashSceen->show();
+    //    splashSceen->show();
 
     ui = new ::Ui::ArmarXMainWindow();
     mutex3d.reset(new boost::recursive_mutex);
     ArmarXWidgetInfoPtr viewerWidgetInfo(new ArmarXWidgetInfo(ArmarXWidgetController::createInstance<Viewer3DWidget>, Viewer3DWidget().getWidgetIcon(), QIcon()));
-    availableWidgets[ARMARX_VIEWER_NAME] = viewerWidgetInfo;
+    pluginCache.cacheWidget(ARMARX_VIEWER_NAME, viewerWidgetInfo);
 
     guiWindowBaseName = ARMARX_GUI_APPLICATION_NAME;
     setWindowTitle(guiWindowBaseName);
@@ -149,7 +152,8 @@ ArmarXMainWindow::ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfa
         pluginDirs.insert(getLibraryPathFromPackage(packageName.c_str()));
     }
     loadPlugins(pluginDirs, false);
-    instantiatePlugins();
+    pluginCache.preloadAsync(getFavoriteWidgets());
+    //    instantiatePlugins();
 
     updateRecentlyOpenedFileList();
 
@@ -159,13 +163,18 @@ ArmarXMainWindow::ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfa
     connectionStatusTimer->start(300);
     //changeLayout(2);
     QStringList recentlyFiles = mainSettings.value("RecentlyFiles").toStringList();
-    splashSceen->finish(this);
+    //    splashSceen->finish(this);
+
 
     guiUseCaseSelector = new GuiUseCaseSelector(this, mainSettings.value("DoNotShowUseCaseDialog").toBool(), this);
 
 
 
-    if (!mainSettings.value("DoNotShowUseCaseDialog").toBool() && guiUseCaseSelector->exec() == QDialog::Accepted)
+    if (!configToLoad.isEmpty())
+    {
+        loadGuiConfig(configToLoad);
+    }
+    else if (!mainSettings.value("DoNotShowUseCaseDialog").toBool() && guiUseCaseSelector->exec() == QDialog::Accepted)
     {
         QString path = guiUseCaseSelector->getSelectedConfigFilePath();
         ARMARX_INFO << VAROUT(path);
@@ -174,10 +183,6 @@ ArmarXMainWindow::ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfa
             loadGuiConfig(path, false);
         }
     }
-    else if (!configToLoad.isEmpty())
-    {
-        loadGuiConfig(configToLoad);
-    }
     else if (recentlyFiles.size() > 0 && mainSettings.value(CONFIG_LOAD_LAST_CONFIG).toBool())
     {
         //set to false in case a plugin crashes the gui
@@ -280,6 +285,14 @@ void ArmarXMainWindow::loadPlugins(const QStringList& fileNames)
         guiFiles.push_back(fileName);
     }
 
+    for (int i = 0; i < guiFiles.size(); i++)
+    {
+        QString fileName = guiFiles.at(i);
+        pluginCache.cachePlugin(fileName);
+    }
+    updateAvailableWidgetList();
+    return;
+
     omp_lock_t writelock;
     omp_init_lock(&writelock);
 
@@ -323,6 +336,42 @@ QString ArmarXMainWindow::getLibraryPathFromPackage(const QString& packageName)
     return dir;
 }
 
+QStringList ArmarXMainWindow::getFavoriteWidgets()
+{
+    auto widgetUsageHistory = mainSettings.value("WidgetUsageHistory").toList();
+    std::map<QString, int> widgetUsage;
+    for (auto & widgetName : widgetUsageHistory)
+    {
+        if (widgetUsage.count(widgetName.toString()) == 0)
+        {
+            widgetUsage[widgetName.toString()] = 1;
+        }
+        else
+        {
+            widgetUsage[widgetName.toString()] += 1;
+        }
+    }
+    std::multimap<int, QString> ranking;
+    for (auto it = widgetUsage.begin(); it != widgetUsage.end(); it++)
+    {
+        ranking.insert(std::make_pair(it->second, it->first));
+    }
+    int i = 0;
+    int favCount = mainSettings.value("FavoriteWidgetCount", 6).toInt();
+    QStringList favoriteWidgetNames;
+    mainSettings.setValue("FavoriteWidgetCount", favCount);
+    for (auto it = ranking.rbegin(); it != ranking.rend() && i < favCount ; it++)
+    {
+        auto& widgetName = it->second;
+        if (!mainWidgets.contains(widgetName))
+        {
+            favoriteWidgetNames << widgetName;
+            i++;
+        }
+    }
+    return favoriteWidgetNames;
+}
+
 void ArmarXMainWindow::loadPluginsFromPackage(const QString& packageName)
 {
     QSet<QString> pluginDirs;
@@ -491,7 +540,7 @@ void ArmarXMainWindow::instantiatePlugin(QPluginLoader& loader)
             statusBar()->showMessage(QString::fromStdString(str.str()), 10000);
             splashSceen->showMessage(splashscreenPrefix + QString::fromStdString(str.str()), Qt::AlignJustify | Qt::AlignBottom);
             ARMARX_INFO << str.str();
-            availableWidgets.insert(newWidgets.begin(), newWidgets.end());
+            //            availableWidgets.insert(newWidgets.begin(), newWidgets.end());
             updateAvailableWidgetList();
             ArmarXManagerPtr manager = ArmarXManagerPtr::dynamicCast(registry);
 
@@ -510,27 +559,27 @@ void ArmarXMainWindow::instantiatePlugin(QPluginLoader& loader)
 
 bool ArmarXMainWindow::existsWidget(const QString& widgetName)
 {
-    WidgetCreatorMap::iterator it = availableWidgets.find(widgetName);
-
-    return (it != availableWidgets.end());
+    auto list = pluginCache.getAvailableWidgetNames();
+    return list.contains(widgetName);
 }
 
 void ArmarXMainWindow::loadPlugin(QString filePath)
 {
     QFileInfo pathInfo(filePath);
     QString fileName(pathInfo.fileName());
+    pluginCache.cachePlugin(filePath);
     ARMARX_INFO << "Plugin Path: " << pathInfo.absoluteFilePath().toStdString() << armarx::flush;
 
-    if (!loadedPluginFilepaths.contains(pathInfo.absoluteFilePath()))
-    {
-        QPluginLoader loader(filePath);
-        //        ARMARX_INFO << "loader created" << armarx::flush;
-        instantiatePlugin(loader);
-    }
-    else
-    {
-        ARMARX_INFO << "Plugin already loaded" << armarx::flush;
-    }
+    //    if (!loadedPluginFilepaths.contains(pathInfo.absoluteFilePath()))
+    //    {
+    //        QPluginLoader loader(filePath);
+    //        //        ARMARX_INFO << "loader created" << armarx::flush;
+    //        instantiatePlugin(loader);
+    //    }
+    //    else
+    //    {
+    //        ARMARX_INFO << "Plugin already loaded" << armarx::flush;
+    //    }
 }
 
 
@@ -864,9 +913,9 @@ ArmarXWidgetControllerPtr ArmarXMainWindow::createArmarXWidget(QString widgetNam
         return NULL;
     }
 
-    WidgetCreatorMap::iterator it = availableWidgets.find(widgetName);
+    auto creator = pluginCache.getWidgetCreator(widgetName);
 
-    if (it == availableWidgets.end())
+    if (!creator)
     {
         ArmarXWidgetController::showMessageBox("Could not find widget with Name: " + widgetName);
         return NULL;
@@ -878,7 +927,7 @@ ArmarXWidgetControllerPtr ArmarXMainWindow::createArmarXWidget(QString widgetNam
         widgetUsage.pop_front();
     }
     mainSettings.setValue("WidgetUsageHistory", widgetUsage);
-    ArmarXWidgetControllerPtr w = it->second->createInstance();
+    ArmarXWidgetControllerPtr w = creator->createInstance();
     w->setMainWindow(this);
     w->setInstanceName(customInstanceName);
     w->setTipDialog(tipDialog);
@@ -1171,26 +1220,46 @@ void ArmarXMainWindow::updateAvailableWidgetList()
     ui->toolBar->clear();
 
 
-    QStringList mainWidgets = QStringList() << "Meta.LogViewer" << "Statecharts.StatechartEditor" << "Meta.SystemStateMonitor" << "Meta.ScenarioManager" << "MemoryX.WorkingMemoryGui";
+
 
     QMap<QString, QAction*> actionList;
 
-    for (std::pair<QString, ArmarXWidgetInfoPtr> pair : availableWidgets)
+    for (std::pair<QString, ArmarXWidgetInfoPtr> pair : pluginCache.getAvailableWidgets())
     {
-        if (!pair.second)
-        {
-            continue;
-        }
+
         QString fullWidgetName = pair.first;
         QString widgetName = pair.first;
         widgetName = widgetName.remove(0, widgetName.lastIndexOf(".") + 1);
         widgetNameList << pair.first;
-        QIcon widgetIcon = pair.second->getIcon();
-        QIcon categoryIcon = pair.second->getCategoryIcon();
+        QIcon categoryIcon;
+        if (pair.second)
+        {
+            categoryIcon = pair.second->getCategoryIcon();
+        }
+        else
+        {
+            if (QFile::exists(PluginCache::GetCategoryIconPath(pair.first)))
+            {
+                categoryIcon = QIcon(PluginCache::GetCategoryIconPath(pair.first));
+            }
+        }
         auto menu = getCategoryMenu(pair.first.toStdString(), ui->menuAdd_Widget, categoryIcon);
         AddArmarXWidgetAction* action = new AddArmarXWidgetAction(widgetName, menu, this);
+        QIcon widgetIcon;
+        if (pair.second)
+        {
+            widgetIcon = pair.second->getIcon();
+        }
+        else
+        {
+            if (QFile::exists(PluginCache::GetIconPath(pair.first)))
+            {
+                widgetIcon = QIcon(PluginCache::GetIconPath(pair.first));
+            }
+        }
         action->setIcon(widgetIcon);
         action->setIconVisibleInMenu(true);
+
         action->setData(pair.first);
         menu->addAction(action);
 
@@ -1217,44 +1286,24 @@ void ArmarXMainWindow::updateAvailableWidgetList()
     ui->toolBar->addSeparator();
     ui->toolBar->addWidget(searchField);
 
-    auto widgetUsageHistory = mainSettings.value("WidgetUsageHistory").toList();
-    if (widgetUsageHistory.size() > 0)
+    auto favoriteWidgetNames = getFavoriteWidgets();
+
+    if (favoriteWidgetNames.size() > 0)
     {
         ui->toolBar->addSeparator();
         auto label = new QLabel("Favorites:");
         label->setToolTip("The favorites are generated from the usage frequency over the last X widget creations.");
         ui->toolBar->addWidget(label);
     }
-    std::map<QString, int> widgetUsage;
-    for (auto & widgetName : widgetUsageHistory)
-    {
-        if (widgetUsage.count(widgetName.toString()) == 0)
-        {
-            widgetUsage[widgetName.toString()] = 1;
-        }
-        else
-        {
-            widgetUsage[widgetName.toString()] += 1;
-        }
-    }
-    std::multimap<int, QString> ranking;
-    for (auto it = widgetUsage.begin(); it != widgetUsage.end(); it++)
-    {
-        ranking.insert(std::make_pair(it->second, it->first));
-    }
-    int i = 0;
-    int favCount = mainSettings.value("FavoriteWidgetCount", 6).toInt();
-    mainSettings.setValue("FavoriteWidgetCount", favCount);
-    for (auto it = ranking.rbegin(); it != ranking.rend() && i < favCount ; it++)
+
+
+    for (auto widgetName : favoriteWidgetNames)
     {
-        auto& widgetName = it->second;
-        if (actionList.contains(widgetName) && !mainWidgets.contains(widgetName))
+        if (actionList.contains(widgetName))
         {
-            ui->toolBar->addAction(actionList[it->second]);
-            i++;
+            ui->toolBar->addAction(actionList[widgetName]);
         }
     }
-
 }
 
 void ArmarXMainWindow::updateOpenWidgetList()
diff --git a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.h b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.h
index 402bd113ec96cb63fc62543fc39ebe01a041c190..dfbf71038ecce9c7b5c837c9edbfcc90eebf4980 100644
--- a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.h
+++ b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.h
@@ -25,6 +25,7 @@
 #define ARMARXMAINWINDOW_H
 
 #include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
+#include <ArmarXGui/libraries/ArmarXGuiBase/PluginCache.h>
 
 // Qt
 #include <QMainWindow>
@@ -116,6 +117,8 @@ namespace armarx
         bool existsWidget(const QString& widgetName);
         QString getLibraryPathFromPackage(const QString& packageName);
 
+        QStringList getFavoriteWidgets();
+
     public slots:
         void loadPluginsFromPackage(const QString& packageName);
         void loadGuiConfig(QString configFilepath = "", bool showAsOpenGuiConfig = true);
@@ -183,6 +186,7 @@ namespace armarx
 
         void instantiatePlugins();
 
+        PluginCache pluginCache;
         QDir pluginsDir;
         QStringList loadedPackages;
         std::vector<QPluginLoader*> pluginsToLoad;
@@ -196,7 +200,7 @@ namespace armarx
         QStringList loadedPluginFilepaths;
 
         QList<QWidget*> widgetsList;
-        WidgetCreatorMap availableWidgets;
+        //        WidgetCreatorMap availableWidgets;
 
         QMap<QString, SoNode*> viewer3DMap;
 
@@ -223,6 +227,7 @@ namespace armarx
         QSplashScreen* splashSceen;
         QString splashscreenPrefix;
         GuiUseCaseSelector* guiUseCaseSelector;
+        QStringList mainWidgets;
 
         boost::shared_ptr<boost::recursive_mutex> mutex3d;
 
diff --git a/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.cpp b/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.cpp
index c804b290ac2e266c0b39139e8f138ef95196649e..0724ec7598b603f64bb72b3b40088c93ab627fe0 100644
--- a/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.cpp
+++ b/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.cpp
@@ -25,10 +25,12 @@
 #include <ArmarXGui/applications/ArmarXGui/ui_UseCaseSelectorItem.h>
 #include <boost/filesystem/path.hpp>
 #include <ArmarXCore/core/logging/Logging.h>
+#include <QFile>
+#include <ArmarXGui/libraries/ArmarXGuiBase/PluginCache.h>
 namespace armarx
 {
 
-    UseCaseSelectorItem::UseCaseSelectorItem(const QString& title, const QString& description, const QString& configFilePath,  const QString& packageName, const QString& iconPath, QWidget* parent) :
+    UseCaseSelectorItem::UseCaseSelectorItem(const QString& title, const QString& description, const QString& configFilePath,  const QString& packageName, QString iconPath, QWidget* parent) :
         QWidget(parent),
         ui(new Ui::UseCaseSelectorItem),
         configFilePath(configFilePath)
@@ -40,16 +42,29 @@ namespace armarx
         boost::filesystem::path p(configFilePath.toStdString());
         p.filename().stem();
         ui->filenameLabel->setText(QString(p.filename().string().c_str()) + " in " + packageName + " ");
+        QString finalPath = iconPath;
         if (!iconPath.isEmpty())
         {
-            QPixmap pixmap(iconPath);
-            if (!pixmap.isNull())
+            if (!QFile::exists(iconPath))
             {
-                ui->iconLabel->setPixmap(pixmap.scaled(pixmapSize, pixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+                auto copy = iconPath;
+                finalPath = PluginCache::GetIconCachePath() + "resources/" + copy.remove(0, 1);
             }
-            else
+            if (!QFile::exists(finalPath))
             {
-                ARMARX_INFO_S << "Cannot find image: " << iconPath.toStdString();
+                finalPath = PluginCache::GetIconCachePath() + iconPath;
+            }
+            if (QFile::exists(finalPath))
+            {
+                QPixmap pixmap(finalPath);
+                if (!pixmap.isNull())
+                {
+                    ui->iconLabel->setPixmap(pixmap.scaled(pixmapSize, pixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+                }
+                else
+                {
+                    ARMARX_INFO_S << "Cannot find image: " << iconPath.toStdString();
+                }
             }
         }
     }
diff --git a/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.h b/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.h
index 0beea8fa16d1fa239f91dd28e6bb3b29fbc5fde5..82bd69cbbad9e71eeb9fbbfe5e471820c22673a7 100644
--- a/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.h
+++ b/source/ArmarXGui/applications/ArmarXGui/Widgets/UseCaseSelectorItem.h
@@ -39,7 +39,7 @@ namespace armarx
         Q_OBJECT
 
     public:
-        explicit UseCaseSelectorItem(const QString& title, const QString& description, const QString& configFilePath, const QString& packageName, const QString& iconPath, QWidget* parent = 0);
+        explicit UseCaseSelectorItem(const QString& title, const QString& description, const QString& configFilePath, const QString& packageName, QString iconPath, QWidget* parent = 0);
         ~UseCaseSelectorItem();
         QString getConfigFilePath() const;
         bool isHighlighted() const;
diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/controller/SettingsController.cpp b/source/ArmarXGui/gui-plugins/ScenarioManager/controller/SettingsController.cpp
index 1cf7c22437ff40621f64d1422b210bb005b296f3..610e6bbe2c2d6ca90304a5c706bea43d8a0ddb48 100644
--- a/source/ArmarXGui/gui-plugins/ScenarioManager/controller/SettingsController.cpp
+++ b/source/ArmarXGui/gui-plugins/ScenarioManager/controller/SettingsController.cpp
@@ -30,6 +30,7 @@
 #include <ArmarXCore/util/ScenarioManagerCommon/parser/PidManager.h>
 #include <ArmarXCore/core/logging/Logging.h>
 #include <QStringList>
+#include <QMessageBox>
 #include <QList>
 #include <QVariant>
 #include <QSettings>
@@ -126,6 +127,18 @@ void SettingsController::showPackageAdderView()
 
 void SettingsController::addPackage(std::string name)
 {
+    for (auto package : *packages)
+    {
+        if (package->getName().compare(name) == 0)
+        {
+            QMessageBox box;
+            QString message(QString::fromStdString("Package " + name + " is already open"));
+            box.setText(message);
+            box.exec();
+            return;
+        }
+    }
+
     QSettings settings("KIT", "ScenarioManager");
     QStringList packages = settings.value("packages").toStringList();
 
diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/detailedapplicationview.cpp b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/detailedapplicationview.cpp
index 9988584f8031384665d0ae61d96139e128fec219..41b4db891be660db76b2bcea20f50b2c69915123 100644
--- a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/detailedapplicationview.cpp
+++ b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/detailedapplicationview.cpp
@@ -522,9 +522,13 @@ void DetailedApplicationView::itemChanged(QtProperty* property, const QVariant&
             else if (property->propertyName().compare("Instance Name") && properties->getProperty(property->propertyName().toStdString()).compare(value.toString().toStdString()))
             {
                 lastAppInstance->modifyProperty(property->propertyName().toStdString(), property->valueText().toStdString());
-                lastAppInstance->setDefaultPropertyEnabled(property->propertyName().toStdString(), true);
-                variantManager->setAttribute(property, QLatin1String("enabled"), true);
-
+                if (value.toString().compare("<set value!>")
+                    && value.toString().compare("::NOT_DEFINED::")
+                    && value.toString().compare("::_NOT_SET_::"))
+                {
+                    lastAppInstance->setDefaultPropertyEnabled(property->propertyName().toStdString(), true);
+                    variantManager->setAttribute(property, QLatin1String("enabled"), true);
+                }
                 updateTimer.start(UPDATE_TIMER_INTERVAL);
             }
             //showApplicationInstance(lastAppInstance);
@@ -572,8 +576,8 @@ void DetailedApplicationView::itemAttributeChanged(QtProperty* property, const Q
 
                 if (definition.isRequired())
                 {
-                    properties->getProperties()->setProperty(property->propertyName().toStdString(), "");
-                    internalManager->setValue(property, "");
+                    properties->getProperties()->setProperty(property->propertyName().toStdString(), "::_NOT_SET_::");
+                    internalManager->setValue(property, "::_NOT_SET_::");
                 }
                 else
                 {
diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/scenarioitem.cpp b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/scenarioitem.cpp
index a4204bcf8b2ddd6b9d20d44e133ff95525a2edb5..765cf926faf76873542fbe0ad54b4c0f3c54dc40 100644
--- a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/scenarioitem.cpp
+++ b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/scenarioitem.cpp
@@ -75,27 +75,48 @@ void ScenarioItem::update()
     if (scenario.get() != nullptr)
     {
         m_itemData[0] = scenario->getName().c_str();
-        std::string status = scenario->getStatus();
-        if (status.compare("Running") == 0)
-        {
-            m_itemData[4] = "Running";
-        }
-        else if (status.compare("Stopped") == 0)
-        {
-            m_itemData[4] = "Stopped";
-        }
-        else if (status.compare("") == 0)
-        {
-            m_itemData[4] = "Unknown";
-        }
-        else
-        {
-            m_itemData[4] = "Mixed";
-        }
+        m_itemData[4] = QString::fromStdString(scenario->getStatus());
     }
     else if (!packageName.empty() && applications->size() > 0)
     {
         m_itemData[0] = QString::fromStdString(packageName);
+
+        std::string status = "";
+        for (auto app : *applications)
+        {
+            if (status.compare("") == 0 && app->getStatus().compare("Running") == 0)
+            {
+                status = "Running";
+            }
+            else if (status.compare("") == 0 && app->getStatus().compare("Stopped") == 0)
+            {
+                status = "Stopped";
+            }
+            else if (status.compare("Running") == 0 && app->getStatus().compare("Running") == 0)
+            {
+                status = "Running";
+            }
+            else if (status.compare("Stopped") == 0 && app->getStatus().compare("Stopped") == 0)
+            {
+                status = "Stopped";
+            }
+            else if (status.compare("Running") == 0 && app->getStatus().compare("Stopped") == 0)
+            {
+                status = "Mixed";
+                break;
+            }
+            else if (status.compare("Stopped") == 0 && app->getStatus().compare("Running") == 0)
+            {
+                status = "Mixed";
+                break;
+            }
+            else
+            {
+                status = "Mixed";
+                break;
+            }
+        }
+        m_itemData[4] = QString::fromStdString(status);
     }
     else
     {
@@ -125,7 +146,6 @@ void ScenarioItem::update()
         {
             m_itemData[4] = "Unknown";
         }
-
     }
 }
 
diff --git a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.cpp b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.cpp
index da5fc414517b1e2d44f2bf068cb48b1ccd5acac8..a7f26e8403b4ec6aa583f5932147eacc1e086bb0 100644
--- a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.cpp
+++ b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.cpp
@@ -20,6 +20,7 @@
 *             GNU General Public License
 */
 
+#include <ArmarXCore/core/ArmarXManager.h>
 #include <ArmarXCore/observers/exceptions/user/UnknownTypeException.h>
 #include <ArmarXCore/util/json/JSONObject.h>
 #include "../../StatechartViewerPlugin/model/stateinstance/RegularState.h"
@@ -34,8 +35,9 @@ using namespace armarx::exceptions::local;
 using namespace armarx::statechartio;
 using namespace armarx::statechartmodel;
 
-XmlReader::XmlReader(Ice::CommunicatorPtr iceCommunicator) :
-    iceCommunicator(iceCommunicator) {}
+XmlReader::XmlReader(Ice::CommunicatorPtr iceCommunicator, VariantInfoPtr info) :
+    iceCommunicator(iceCommunicator),
+    info(info) {}
 
 void XmlReader::parseXml(const QString& xmlString)
 {
@@ -200,13 +202,36 @@ armarx::statechartmodel::StateParameterMap XmlReader::readParameterList(rapidxml
 
         if (!stateParameter->getDefaultValueJson().isEmpty())
         {
-            try
+            std::function<bool(std::string, std::string)> loadVar;
+            loadVar = [&](std::string curType, std::string prevType)
             {
-                JSONObjectPtr jsonObject = new JSONObject(iceCommunicator);
-                jsonObject->fromString(stateParameter->getDefaultValueJson().toUtf8().data());
+                if (curType == prevType)
+                {
+                    return false;
+                }
+                try
+                {
+
+                    JSONObjectPtr jsonObject = new JSONObject(iceCommunicator);
+                    jsonObject->fromString(stateParameter->getDefaultValueJson().toUtf8().data());
+
+                    stateParameter->profileDefaultValues[QString::fromUtf8(StatechartProfiles::GetRootName().c_str())] =
+                    {VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject()), stateParameter->getDefaultValueJson()};
+
+                }
+                catch (Ice::NoObjectFactoryException& e)
+                {
+                    ARMARX_INFO_S << "Variant missing - trying to load variant " << e.type << " now";
+                    info->loadLibraryOfVariant(e.type);
+                    ArmarXManager::RegisterKnownObjectFactoriesWithIce(iceCommunicator);
+                    return loadVar(e.type, curType);
+                }
+                return true;
+            };
 
-                stateParameter->profileDefaultValues[QString::fromUtf8(StatechartProfiles::GetRootName().c_str())] =
-                {VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject()), stateParameter->getDefaultValueJson()};
+            try
+            {
+                loadVar("", "-");
             }
             catch (exceptions::user::UnknownTypeException& e)
             {
@@ -234,13 +259,34 @@ armarx::statechartmodel::StateParameterMap XmlReader::readParameterList(rapidxml
 
             QString valueJson = readAttribute(defaultValueCurNode, "value", true);
             VariantContainerBasePtr valueVariant;
+            std::function<bool(std::string, std::string)> loadVar;
+            loadVar = [&](std::string curType, std::string prevType)
+            {
+                if (curType == prevType)
+                {
+                    return false;
+                }
+                try
+                {
+
+                    JSONObjectPtr jsonObject = new JSONObject(iceCommunicator);
+                    jsonObject->fromString(valueJson.toUtf8().data());
+
+                    valueVariant = VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject());
+                }
+                catch (Ice::NoObjectFactoryException& e)
+                {
+                    ARMARX_INFO_S << "Variant missing - trying to load variant " << e.type << " now";
+                    info->loadLibraryOfVariant(e.type);
+                    ArmarXManager::RegisterKnownObjectFactoriesWithIce(iceCommunicator);
+                    return loadVar(e.type, curType);
+                }
+                return true;
+            };
 
             try
             {
-                JSONObjectPtr jsonObject = new JSONObject(iceCommunicator);
-                jsonObject->fromString(valueJson.toUtf8().data());
-
-                valueVariant = VariantContainerBasePtr::dynamicCast(jsonObject->deserializeIceObject());
+                loadVar("", "-");
             }
             catch (exceptions::user::UnknownTypeException& e)
             {
diff --git a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.h b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.h
index 314f572aff8081e22579a12f78378ed8e403010d..ce38e0884e9fd2d741e7af758d675c99edc99773 100644
--- a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.h
+++ b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/io/XmlReader.h
@@ -28,6 +28,7 @@
 #include <ArmarXCore/core/IceManager.h>
 #include <ArmarXCore/core/exceptions/Exception.h>
 #include <ArmarXCore/core/rapidxml/rapidxml.hpp>
+#include <ArmarXCore/observers/variant/VariantInfo.h>
 
 
 namespace armarx
@@ -45,7 +46,7 @@ namespace armarx
              * Creates a new XmlReader. The ICE communicator is required for deserialization of parameter default values from JSON.
              * @param iceCommunicator Ice communicator.
              */
-            XmlReader(Ice::CommunicatorPtr iceCommunicator);
+            XmlReader(Ice::CommunicatorPtr iceCommunicator, VariantInfoPtr info);
 
             /**
              * Parses the given XML document and builds a State object (that can be retrieved using getRootState()).
@@ -77,6 +78,7 @@ namespace armarx
             QString readAttribute(rapidxml::xml_node<>* node, const QString& attributeName, bool required = true) const;
 
             Ice::CommunicatorPtr iceCommunicator;
+            VariantInfoPtr info;
             armarx::statechartmodel::StatePtr loadedState;
             bool hasSubstateByInstanceName(const QString& name) const;
         };
diff --git a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/model/StateTreeModel.cpp b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/model/StateTreeModel.cpp
index e5c83ce3c826fee44b491887cf4f462a1527fb54..91fa0bfc62429ed69dd49126527c3cb675c90d77 100644
--- a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/model/StateTreeModel.cpp
+++ b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/model/StateTreeModel.cpp
@@ -15,9 +15,9 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
- * @package    
- * @author     
- * @date       
+ * @package
+ * @author
+ * @date
  * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
  *             GNU General Public License
  */
@@ -123,7 +123,7 @@ void StateTreeModel::loadNode(StateTreeNodePtr node, boost::filesystem::path par
         try
         {
             QString xml = GuiStatechartGroupXmlReader::ReadFileContents(QString::fromUtf8(nodePath.string().c_str()));
-            boost::shared_ptr<XmlReader> reader(new XmlReader(iceCommunicator));
+            boost::shared_ptr<XmlReader> reader(new XmlReader(iceCommunicator, variantInfo));
             reader->parseXml(xml);
             statechartmodel::StatePtr state = reader->getLoadedState();
             state->setEditable(node->getGroup()->getWriteAccess() == StatechartGroup::eWritable);
diff --git a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/test/XmlReaderTest.cpp b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/test/XmlReaderTest.cpp
index 211796ccc10babaef584d92dc1429fd14032fdf7..8b246c6fa2c85e36e91c72bc147e46b6e736d00f 100644
--- a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/test/XmlReaderTest.cpp
+++ b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/test/XmlReaderTest.cpp
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(testParseXml)
     QString xmlInput = armarx::RapidXmlReader::ReadFileContents("ArmarXGui/Teststate.xml").c_str();
 
 
-    XmlReader xmlReader(ic);
+    XmlReader xmlReader(ic, armarx::VariantInfoPtr());
     xmlReader.parseXml(xmlInput);
 
     StatePtr state = xmlReader.getLoadedState();
@@ -234,10 +234,10 @@ BOOST_AUTO_TEST_CASE(testAddReferences)
                            "</Substates></State>";
     QString subStateXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"RootStateName\" uuid=\"CF3662A8-9234-46BD-82C1-856344108823\" width=\"123\" height=\"456\"/>";
 
-    XmlReader xmlReaderRootState(ic);
+    XmlReader xmlReaderRootState(ic, armarx::VariantInfoPtr());
     xmlReaderRootState.parseXml(rootStateXml);
 
-    XmlReader xmlReaderSubState(ic);
+    XmlReader xmlReaderSubState(ic, armarx::VariantInfoPtr());
     xmlReaderSubState.parseXml(subStateXml);
 
     StatePtr rootState = xmlReaderRootState.getLoadedState();
@@ -268,52 +268,52 @@ BOOST_AUTO_TEST_CASE(testInvalidXml)  // Of course, we cannot test all possible
     armarx::ArmarXManager::RegisterKnownObjectFactoriesWithIce(ic);
 
     // Completely malformed
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("This is not XML!"), XmlReaderException);
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("This is not XML!"), XmlReaderException);
 
     // Wrong version number
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"0.1\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\"/>"), XmlReaderException);
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"0.1\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\"/>"), XmlReaderException);
 
     // Missing attribute (here: name)
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\"/>"), XmlReaderException);
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\"/>"), XmlReaderException);
 
     // Invalid value for parameter default
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<InputParameters><Parameter name=\"ParameterName\" type=\"string\" default=\"no JSON\" optional=\"no\"/></InputParameters>"
                       "</State>"), XmlReaderException);
 
     // Invalid value for optional attribute of parameter
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<InputParameters><Parameter name=\"ParameterName\" type=\"string\" optional=\"maybe\"/></InputParameters>"
                       "</State>"), XmlReaderException);
 
     // Duplicate parameter name
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<InputParameters><Parameter name=\"ParameterName\" type=\"string\" optional=\"yes\"/><Parameter name=\"ParameterName\" type=\"string\" optional=\"no\"/></InputParameters>"
                       "</State>"), XmlReaderException);
 
     // Invalid substate type
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Substates><BogusState name=\"SubstateName\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                       "</State>"), XmlReaderException);
 
     // Duplicate substate name
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Substates><EndState name=\"SubstateName\" event=\"foo\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/><EndState name=\"SubstateName\" event=\"bar\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                       "</State>"), XmlReaderException);
 
     // Duplicate event name
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Events><Event name=\"EventName\"/><Event name=\"EventName\"/></Events>"
                       "</State>"), XmlReaderException);
 
     // Invalid start state name
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Substates><LocalState name=\"LocalSubstateName\" refuuid=\"CF3662A8-9234-46BD-82C1-856344108823\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                       "<StartState substateName=\"NotExistingSubstateName\"/>"
                       "</State>"), XmlReaderException);
 
     // Invalid from state name for transition
-    XmlReader xmlReaderForInvalidFromState(ic);
+    XmlReader xmlReaderForInvalidFromState(ic, armarx::VariantInfoPtr());
     xmlReaderForInvalidFromState.parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                                           "<Substates><LocalState name=\"LocalSubstateName\" refuuid=\"CF3662A8-9234-46BD-82C1-856344108823\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/><RemoteState name=\"RemoteSubstateName\" refuuid=\"148C7D1D-1DB4-4A67-893F-D22D36A88823\" proxyName=\"RemoteSubstateProxyName\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                                           "<Transitions><Transition from=\"NotExistingSubstateName\" to=\"RemoteSubstateName\" eventName=\"Transition1EventName\"/></Transitions>"
@@ -321,13 +321,13 @@ BOOST_AUTO_TEST_CASE(testInvalidXml)  // Of course, we cannot test all possible
     BOOST_CHECK_EQUAL(xmlReaderForInvalidFromState.getLoadedState()->getTransitions().size(), 0);
 
     // Invalid to state name for transition
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Substates><LocalState name=\"LocalSubstateName\" refuuid=\"CF3662A8-9234-46BD-82C1-856344108823\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/><RemoteState name=\"RemoteSubstateName\" refuuid=\"148C7D1D-1DB4-4A67-893F-D22D36A88823\" proxyName=\"RemoteSubstateProxyName\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                       "<Transitions><Transition from=\"LocalSubstateName\" to=\"NotExistingSubstateName\" eventName=\"Transition1EventName\"/></Transitions>"
                       "</State>"), XmlReaderException);
 
     // Invalid sourceType name for parameter mapping
-    BOOST_CHECK_THROW(XmlReader(ic).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
+    BOOST_CHECK_THROW(XmlReader(ic, armarx::VariantInfoPtr()).parseXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><State version=\"1.0\" name=\"Name\" uuid=\"09F54A1A-3A29-4560-B20C-299069288823\" width=\"0\" height=\"0\">"
                       "<Substates><LocalState name=\"LocalSubstateName\" refuuid=\"CF3662A8-9234-46BD-82C1-856344108823\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/><RemoteState name=\"RemoteSubstateName\" refuuid=\"148C7D1D-1DB4-4A67-893F-D22D36A88823\" proxyName=\"RemoteSubstateProxyName\" left=\"0\" top=\"0\" boundingSquareSize=\"0\"/></Substates>"
                       "<Transitions><Transition from=\"LocalSubstateName\" to=\"RemoteSubstateName\" eventName=\"Transition1EventName\"><ParameterMappings><ParameterMapping sourceType=\"invalidSourceType\" from=\"Transition1ParameterMappingSourceKey\" to=\"Transition1ParameterMappingDestinationKey\"/></ParameterMappings></Transition></Transitions>"
                       "</State>"), XmlReaderException);
diff --git a/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/StateWatcher.cpp b/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/StateWatcher.cpp
index 1a6fd83e579abe105753a87527ddc3313b8ada61..2d3283bd25885d278f544aef87663ab6edd91d34 100644
--- a/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/StateWatcher.cpp
+++ b/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/StateWatcher.cpp
@@ -289,7 +289,7 @@ namespace armarx
                         }
                         else
                         {
-                            ARMARX_WARNING << "could not find state " << activeSubstateName;
+                            ARMARX_INFO << "could not find state " << activeSubstateName;
                         }
                     }
                     else
diff --git a/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/layout/LayoutController.cpp b/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/layout/LayoutController.cpp
index 0ddf2faeb1adbefaf87514a75284928686744ed3..15f882c28621a67ce411d498b4fb05e2ad10d957 100644
--- a/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/layout/LayoutController.cpp
+++ b/source/ArmarXGui/gui-plugins/StatechartViewerPlugin/layout/LayoutController.cpp
@@ -15,9 +15,9 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
- * @package    
- * @author     
- * @date       
+ * @package
+ * @author
+ * @date
  * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
  *             GNU General Public License
  */
@@ -36,6 +36,7 @@ armarx::LayoutController::LayoutController(armarx::statechartmodel::StatePtr top
       idCounter(0),
       layoutingDisabled(!startEnabled)
 {
+    qRegisterMetaType<size_t>("size_t");
     timer.setInterval(100);
     connect(&timer, SIGNAL(timeout()), this, SLOT(startNextLayouting()), Qt::QueuedConnection);
 
diff --git a/source/ArmarXGui/libraries/ArmarXGuiBase/CMakeLists.txt b/source/ArmarXGui/libraries/ArmarXGuiBase/CMakeLists.txt
index 7ee147a75de93c98bf9d5b050770e7a3e2cdae32..15bd2d4dad22736c3a8157e26a50bf015f343d6e 100644
--- a/source/ArmarXGui/libraries/ArmarXGuiBase/CMakeLists.txt
+++ b/source/ArmarXGui/libraries/ArmarXGuiBase/CMakeLists.txt
@@ -26,6 +26,7 @@ set(LIBS ArmarXCoreJsonObject
 
 set(LIB_FILES   ArmarXWidgetController.cpp
                 ArmarXComponentWidgetController.cpp
+				PluginCache.cpp
                 widgets/CoinViewer.cpp
                 widgets/editorfileopener.cpp
                 widgets/IceProxyFinder.cpp
@@ -43,6 +44,7 @@ set(LIB_FILES   ArmarXWidgetController.cpp
 set(LIB_HEADERS ArmarXGuiInterface.h
                 ArmarXGuiPlugin.h
                 ArmarXWidgetController.h
+				PluginCache.h
                 widgets/CoinViewer.h
                 ArmarXComponentWidgetController.h
                 widgets/editorfileopener.h
diff --git a/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57f673dc5680ea14392374da3f10da6f94e132f5
--- /dev/null
+++ b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp
@@ -0,0 +1,351 @@
+#include "PluginCache.h"
+
+#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiInterface.h>
+
+#include <ArmarXCore/core/system/ArmarXDataPath.h>
+#include <ArmarXCore/core/ArmarXManager.h>
+
+#include <QDateTime>
+#include <QDirIterator>
+#include <QFile>
+#include <QResource>
+#include <QCryptographicHash>
+
+namespace armarx
+{
+
+    PluginCache::PluginCache(ArmarXManagerPtr manager) :
+        cachePath(GetIconCachePath()),
+        manager(manager)
+    {
+        QDir dir(cachePath);
+        if (!dir.exists())
+        {
+            dir.mkpath(".");
+        }
+
+        QSettings s(settingsOrganization, settingsApplicationName);
+        auto map = s.value("widgets").toMap();
+        for (QString key : map.keys())
+        {
+            QStringList w = map[key].toString().split(":");
+            QStringList keyparts = key.split(":");
+            if (w.size() == 3)
+            {
+                pluginData[key].pluginPath = keyparts[0];
+                pluginData[key].lastModified = QDateTime::fromMSecsSinceEpoch(w[0].toLongLong());
+                pluginData[key].hash = w[1].toAscii();
+                ARMARX_INFO_S << "Widget: " << w[2];
+                pluginData[key].widgets[w[2]] = ArmarXWidgetInfoPtr();
+            }
+        }
+    }
+
+    PluginCache::~PluginCache()
+    {
+        shutdown = true;
+        if (preloadFuture.valid())
+        {
+            preloadFuture.wait();
+        }
+    }
+
+    bool PluginCache::cachePlugin(const QString& pluginPath)
+    {
+        if (pluginPath.isEmpty())
+        {
+            return false;
+        }
+        bool found = false;
+        QFileInfo info(pluginPath) ;
+        ScopedRecursiveLock lock(cacheMutex);
+        for (auto & elem : pluginData)
+        {
+            //            ARMARX_INFO_S << info.lastModified().toString() << elem.pluginPath;
+            if (elem.pluginPath == pluginPath)
+            {
+                if (info.lastModified() == elem.lastModified)
+                {
+                    ARMARX_DEBUG_S << "Same timestamp";
+                    found = true;
+                }
+                else if (getHash(pluginPath) == elem.hash)
+                {
+                    ARMARX_DEBUG_S << "Same hash";
+                    found = true;
+                }
+                else
+                {
+                    ARMARX_VERBOSE_S << "Plugin filestamp is different - loading plugin again.";
+                }
+                break;
+            }
+        }
+        if (!found)
+        {
+            writeToCache(pluginPath);
+            return false;
+        }
+        ARMARX_INFO_S << "Found plugin " << pluginPath << " in cache";
+        return true;
+    }
+
+    bool PluginCache::cacheWidget(QString widgetName, ArmarXWidgetInfoPtr widgetCreator)
+    {
+        ScopedRecursiveLock lock(cacheMutex);
+        pluginData[""].widgets[widgetName] = widgetCreator;
+        return true;
+    }
+
+    ArmarXWidgetInfoPtr PluginCache::getWidgetCreator(const QString& widgetName)
+    {
+        ScopedRecursiveLock lock(cacheMutex);
+        for (const PluginData & data : pluginData)
+        {
+            WidgetCreatorMap::const_iterator it = data.widgets.find(widgetName);
+            if (it != data.widgets.end())
+            {
+                if (it->second)
+                {
+                    return it->second;
+                }
+            }
+        }
+        PluginData data = loadFromCache(widgetName);
+        pluginData[data.pluginPath] = data;
+        WidgetCreatorMap::const_iterator it = data.widgets.find(widgetName);
+        if (it != data.widgets.end())
+        {
+            return it->second;
+        }
+        return ArmarXWidgetInfoPtr();
+    }
+
+    QStringList PluginCache::getAvailableWidgetNames() const
+    {
+        ScopedRecursiveLock lock(cacheMutex);
+        QStringList result;
+        for (const PluginData & data : pluginData)
+        {
+            for (const auto & elem : data.widgets)
+            {
+                result << elem.first;
+            }
+        }
+        return result;
+
+    }
+
+    WidgetCreatorMap PluginCache::getAvailableWidgets() const
+    {
+        ScopedRecursiveLock lock(cacheMutex);
+        WidgetCreatorMap result;
+        for (const PluginData & data : pluginData)
+        {
+            result.insert(data.widgets.begin(), data.widgets.end());
+        }
+        return result;
+    }
+
+    void PluginCache::copyResourcesToCache()
+    {
+        QDirIterator it(":", QDirIterator::Subdirectories);
+        while (it.hasNext())
+        {
+            QString path = it.next().remove(0, 1);
+            auto newPath = cachePath + "/resources/" + path;
+            QDir dir(newPath);
+            if (!dir.exists())
+            {
+                dir.mkpath(".");
+            }
+            if (!path.isEmpty() && !QFile::exists(newPath))
+            {
+                QFile::copy(it.next(), newPath);
+            }
+        }
+    }
+
+    QString PluginCache::GetIconCachePath()
+    {
+        return QString(armarx::ArmarXDataPath::GetCachePath().c_str()) + "/icons/";
+    }
+
+    QString PluginCache::GetIconPath(const QString& widgetName)
+    {
+        return GetIconCachePath() + widgetName + ".png";
+    }
+
+    QString PluginCache::GetCategoryIconPath(const QString& widgetName)
+    {
+        return GetIconCachePath() + widgetName + "-category.png";
+    }
+
+    void PluginCache::preloadAsync(QStringList widgetNames, int delayMS)
+    {
+        widgetNames.removeDuplicates();
+        auto preload = [this](QStringList widgetNames, int delayMS)
+        {
+            usleep(delayMS * 1000);
+            for (QString widgetName : widgetNames)
+            {
+                {
+                    ScopedRecursiveLock lock(cacheMutex);
+                    QString pluginPath;
+                    for (PluginData & data : pluginData)
+                    {
+                        for (auto & elem : data.widgets)
+                        {
+                            if (shutdown)
+                            {
+                                return;
+                            }
+                            if (widgetName ==  elem.first)
+                            {
+                                pluginPath = data.pluginPath;
+                                if (!data.pluginLoader && !pluginPath.isEmpty())
+                                {
+                                    auto pluginLoader = QSharedPointer<QPluginLoader>(new QPluginLoader(pluginPath));
+                                    ARMARX_INFO_S << "Loading plugin " << pluginPath;
+                                    pluginLoader->load();
+                                    //                                data.pluginLoader->load();
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                usleep(1000); // give others chance to get mutex
+            }
+        };
+        preloadFuture = std::async(std::launch::async, preload, widgetNames, delayMS);
+    }
+
+    void PluginCache::clearCacheFile()
+    {
+        QSettings s(settingsOrganization, settingsApplicationName);
+        s.clear();
+    }
+
+    QByteArray PluginCache::getHash(const QString& pluginPath)
+    {
+        QFile file(pluginPath);
+        QByteArray hashData;
+        if (file.open(QIODevice::ReadOnly))
+        {
+            QByteArray fileData = file.readAll();
+            hashData = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
+        }
+        return hashData.toHex();
+    }
+
+    void PluginCache::writeToCache(const QString& pluginPath)
+    {
+        auto start = IceUtil::Time::now();
+        QByteArray hashData = getHash(pluginPath);
+        ARMARX_DEBUG_S << "Hashing took " << (IceUtil::Time::now() - start).toMicroSecondsDouble();
+        QSharedPointer<QPluginLoader> loader(new QPluginLoader(pluginPath));
+        auto widgets = loadPlugin(loader);
+        QSettings s(settingsOrganization, settingsApplicationName);
+        ARMARX_INFO_S << "Writing plugin " << pluginPath << " to cache";
+        QMap<QString, QVariant> widgetMap = s.value("widgets").toMap();
+        QDateTime time = QFileInfo(pluginPath).lastModified();
+        for (auto & elem : widgets)
+        {
+            ARMARX_INFO_S << pluginPath << ": " << (QString::number(time.toMSecsSinceEpoch()) + ":" + hashData + ":" + elem.first);
+            widgetMap[pluginPath + ":" + elem.first] = QString::number(time.toMSecsSinceEpoch()) + ":" + hashData + ":" + elem.first;
+        }
+
+        s.setValue("widgets", widgetMap);
+
+        copyResourcesToCache();
+        ScopedRecursiveLock lock(cacheMutex);
+        pluginData[pluginPath] = {loader, pluginPath, hashData, time, widgets};
+
+    }
+
+    PluginData PluginCache::loadFromCache(const QString& widgetName)
+    {
+        ARMARX_INFO_S << "Loading widget " << widgetName << " from cache ";
+        QSettings s(settingsOrganization, settingsApplicationName);
+        QString pluginPath;
+        QSharedPointer<QPluginLoader> loader;
+        WidgetCreatorMap widgets;
+        QDateTime time;
+        QByteArray hash;
+        auto map = s.value("widgets").toMap();
+        for (auto key : map.keys())
+        {
+            QStringList w = map[key].toString().split(":");
+            QStringList keyparts = key.split(":");
+            if (w.size() == 3)
+            {
+                if (w[2] == widgetName)
+                {
+                    pluginPath = keyparts[0];
+                    if (QFile::exists(pluginPath))
+                    {
+                        hash = w[1].toAscii();
+                        loader = QSharedPointer<QPluginLoader>(new QPluginLoader(pluginPath));
+                        widgets = loadPlugin(loader);
+                        time = QDateTime::fromMSecsSinceEpoch(w[0].toLongLong());
+                        break;
+                    }
+                    else
+                    {
+                        ARMARX_INFO_S << pluginPath << " does not exist";
+                    }
+
+                }
+            }
+
+        }
+        if (!loader)
+        {
+            ARMARX_WARNING_S << "Could not find " << widgetName << " in cache";
+        }
+        if (manager)
+        {
+            manager->registerKnownObjectFactoriesWithIce();
+        }
+        return PluginData {loader, pluginPath, hash, time, widgets};
+    }
+
+    WidgetCreatorMap PluginCache::loadPlugin(QSharedPointer<QPluginLoader> loader)
+    {
+        WidgetCreatorMap result;
+        ARMARX_INFO_S << "Loading plugin " << loader->fileName();
+        loader->load();
+        QObject* plugin = loader->instance();
+        if (plugin)
+        {
+            ArmarXGuiInterface* newPlugin = qobject_cast<ArmarXGuiInterface*>(plugin);
+            if (newPlugin)
+            {
+                //ARMARX_INFO << "cast successful" << armarx::flush;
+                WidgetCreatorMap newWidgets = newPlugin->getProvidedWidgets();
+                for (auto elem : newWidgets)
+                {
+                    ArmarXWidgetInfoPtr info = elem.second;
+                    QIcon icon = info->getIcon();
+                    if (!icon.isNull())
+                    {
+                        icon.pixmap(64).save(GetIconPath(elem.first));
+                    }
+                    icon = info->getCategoryIcon();
+                    if (!icon.isNull())
+                    {
+                        icon.pixmap(64).save(GetCategoryIconPath(elem.first));
+                    }
+                }
+                result.insert(newWidgets.begin(), newWidgets.end());
+            }
+        }
+        else
+        {
+            ARMARX_WARNING_S << "Instantiating plugin failed: " << loader->fileName();
+        }
+        return result;
+    }
+
+} // namespace armarx
diff --git a/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.h b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.h
new file mode 100644
index 0000000000000000000000000000000000000000..864ee7b0faa311b956d3408f3b5d5387ab5aedc8
--- /dev/null
+++ b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.h
@@ -0,0 +1,68 @@
+#ifndef _ARMARX_PLUGINCACHE_H
+#define _ARMARX_PLUGINCACHE_H
+
+#include <boost/shared_ptr.hpp>
+#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXWidgetController.h>
+#include <QDateTime>
+#include <QPluginLoader>
+#include <QSet>
+#include <future>
+
+
+class QProgressDialog;
+
+class ArmarXWidgetInfo;
+typedef boost::shared_ptr<ArmarXWidgetInfo> ArmarXWidgetInfoPtr;
+
+typedef armarx::ArmarXWidgetControllerPtr(*WidgetCreatorFunction)();
+typedef std::map<QString, ArmarXWidgetInfoPtr > WidgetCreatorMap;
+
+namespace armarx
+{
+
+    struct PluginData
+    {
+        QSharedPointer<QPluginLoader> pluginLoader;
+        QString pluginPath;
+        QByteArray hash;
+        QDateTime lastModified;
+        WidgetCreatorMap widgets;
+    };
+
+    class PluginCache
+    {
+    public:
+        PluginCache(ArmarXManagerPtr manager);
+        ~PluginCache();
+        bool cachePlugin(const QString& pluginPath);
+        bool cacheWidget(QString widgetName, ArmarXWidgetInfoPtr widgetCreator);
+        ArmarXWidgetInfoPtr getWidgetCreator(const QString& widgetName);
+        QStringList getAvailableWidgetNames() const;
+        WidgetCreatorMap getAvailableWidgets() const;
+        const QString settingsOrganization = "KIT";
+        const QString settingsApplicationName = "PluginCache";
+        void copyResourcesToCache();
+        static QString GetIconCachePath();
+        static QString GetIconPath(const QString& widgetName);
+        static QString GetCategoryIconPath(const QString& widgetName);
+        void preloadAsync(QStringList widgetNames, int delayMS = 1000);
+        void clearCacheFile();
+        QByteArray getHash(const QString& pluginPath);
+
+    protected:
+        void writeToCache(const QString& pluginPath);
+        PluginData loadFromCache(const QString& pluginPath);
+        WidgetCreatorMap loadPlugin(QSharedPointer<QPluginLoader> loader);
+        const QString cachePath;
+        QMap<QString, PluginData> pluginData;
+        ArmarXManagerPtr manager;
+        mutable RecursiveMutex cacheMutex;
+        std::future<void> preloadFuture;
+        bool shutdown = false;
+
+    };
+    typedef boost::shared_ptr<PluginCache> PluginCachePtr;
+
+} // namespace armarx
+
+#endif // ARMARX_PLUGINCACHE_H