diff --git a/PlayWall/.classpath b/PlayWall/.classpath
index a8ad48e81f02fb008bf288df3ca4de61c39311b2..d2cd0493fcde2baf421f34395e597c63978e8ebe 100644
--- a/PlayWall/.classpath
+++ b/PlayWall/.classpath
@@ -15,5 +15,6 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JLayer"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Updater"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties
index cae2209260275be3c7b92c311c6080f0156b0ed4..841951b5c15168623334cfc51993f7acaa11f9a7 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties
+++ b/PlayWall/assets/de/tobias/playpad/assets/lang/_de.properties
@@ -50,7 +50,7 @@ UI.Layout.Classic.Theme.LIGHT=Hell
 # UI - Window - Main
 UI.Window.Main.CloseRequest=Es wird gerade noch Musik abgespielt. M�chten Sie PlayWall trotzdem beenden?
 UI.Window.Main.SaveRequest=M�chten Sie die �nderungen speichern?
-UI.Window.Main.PageButton = Seite {}
+UI.Window.Main.PageButton=Seite {}
 
 # UI - Dialog - Launch
 UI.Dialog.Launch.Info={} - {}
@@ -117,7 +117,7 @@ Info.Settings.ResetWarning=Die Einstellungen wurden zur
 Info.Settings.CacheDelete={} Datei(en) wurden gel�scht.
 
 # Info - Print
-Info.Print.Header={} - Seite {}
+Info.Print.Header={} - {}
 
 # Error - Standard
 Error.Standard.Gen=Es ist ein Fehler aufgetreten. Bitte versuchen Sie es sp�ter erneut. ({})
@@ -147,6 +147,7 @@ Error.Project.Rename=Das Projekt konnte nicht umbenannt werden. ({})
 Error.Project.Delete=Das Projekt konnte nicht gel�scht werden. ({})
 Error.Project.Export=Das Projekt {} konnte nicht exportiert werden. ({})
 Error.Project.MediaPath=Der neue Ordner darf kein Unterodner des alten Medienordners sein.
+Error.Project.PageCount=Sie k�nnen nicht mehr als 8 Seiten erstellen.
 
 # Error - Pad - Enum
 Error.Pad.FILE_NOT_FOUND=Die Datei {} konnte nicht gefunden werden.
@@ -169,6 +170,7 @@ Error.Midi.Send=Der Midi Befehl konnte nicht gesendet werden. ({})
 # Error - Plugins
 Error.Plugins.Download=Die Erweiterung {} konnte nicht geladen werden.
 Error.Plugins.Avaiable=Es sind keine Erweiterungen f�r diesen Update-Kanal verf�gbar.
+Error.Plugins.Missing=Es wurden im Projekt Erweiterungen verwendet, welche momentan nicht installiert sind. Sie k�nnen das Projekt dennoch �ffnen, es kann aber zu Fehlern dabei kommen, wenn Sie folgende Erweiterungen nicht installiert haben.
 
 #Mapper
 Mapper.Keyboard.Name=Tastatur
@@ -223,8 +225,8 @@ UI.Dialog.Save.Header=Speichern
 UI.Dialog.Save.Content=M�chten Sie das Projekt speichern?
 UI.Dialog.Save.Title=Speichern
 UI.Dialog.Save.Checkbox=Immer automatisch speichern und diesen Dialog nicht mehr anzeigen.
-UI.Dialog.Save.Button.Yes=Speichern
-UI.Dialog.Save.Button.No=Nicht Speichern
+UI.Dialog.Save.Button.Yes=Ja
+UI.Dialog.Save.Button.No=Nein
 UI.Dialog.Save.Button.Cancel=Abbrechen
 
 # Update Channel - BaseName
@@ -257,6 +259,7 @@ TriggerPoint.EOF_STOP=Ende/Stop
 
 # Drag and Drop Mode
 DnDMode.Replace=Ersetzen
+DnDMode.Duplicate=Duplizieren
 DnDMode.Move=Tauschen
 
 # Main Layout
@@ -266,4 +269,28 @@ MainLayout.Touch=Touchmodus
 # Suche
 Search.Button=Suchen
 Search.Placeholder=Suche
-Search.Alert.NoMatches=Keine Treffer gefunden.
\ No newline at end of file
+Search.Alert.NoMatches=Keine Treffer gefunden.
+
+# UI - Dialog - Page - Delete
+UI.Dialog.Page.Delete.Header=Seite l�schen
+UI.Dialog.Page.Delete.Content=M�chten Sie die Seite unwiederbringlich l�schen?
+
+# UI - Dialog - Name - Delete
+UI.Dialog.Page.Name.Header=Seite umbenennen
+UI.Dialog.Page.Name.Content=Geben Sie einen Namen f�r die Seite ein.
+
+# Tooltips
+Tooltip.PlayButton=Wiedergabe
+Tooltip.DragButton=Kacheln verschieben
+Tooltip.PageButton=Seiten bearbeiten
+Tooltip.ColorButton=Kacheln einf�rben
+
+Tooltip.Page.LeftMove=Nach links verschieben
+Tooltip.Page.RightMove=Nach rechts verschieben
+Tooltip.Page.Rename=Umbenennen
+Tooltip.Page.Clone=Duplizieren
+Tooltip.Page.Delete=L�schen
+
+# Audio Features
+EQUALIZER=Equalizer:
+SOUNDCARD=Soundkarte:
\ No newline at end of file
diff --git a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties
index 9438e06b62639682604ff2e1351a3afefbc41a97..afe3290c008ceef5b34304c88e1c03c526ae906d 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties
+++ b/PlayWall/assets/de/tobias/playpad/assets/lang/ui_de.properties
@@ -15,9 +15,13 @@ main.menuitem.recentFiles=Zuletzt verwendete Projekte
 main.menuitem.profile=Profile verwalten...
 main.menuitem.print=Drucken...
 main.menuitem.onTop=Fenster im Vordergrund
-main.menuitem.plugins=Erweiterungen...
-main.menuitem.dnd=Bearbeitungsmodus
+main.menu.editmode=Modus
+main.menuitem.play=Wiedergabe
+main.menuitem.drag=Kacheln verschieben
+main.menuitem.page=Seiten bearbeiten
+main.menuitem.color=Kacheln einf�rben
 main.menuitem.errors=Fehlerbericht anzeigen...
+main.menuitem.plugins=Erweiterungen...
 main.menuitem.projectSettings=Projekteinstellungen...
 main.menuitem.profileSettings=Profileinstellungen...
 main.menuitem.globalSettings=Globale Einstellungen...
@@ -32,7 +36,6 @@ main.menuitem.searchPad=Kachel suchen...
 main.label.live=Live
 
 settings.gen.label.view=Ansicht:
-settings.gen.label.pages=Anzahl der Seiten:
 settings.gen.label.columns=Anzahl der Spalten:
 settings.gen.label.rows=Anzahl der Reihen:
 settings.gen.label.liveMode=Live Modus:
@@ -41,9 +44,9 @@ settings.gen.label.liveMode.settings=Einstellungen 
 settings.gen.label.liveMode.media=Mediadateien �ndern:
 settings.gen.label.liveMode.dragPads=Kacheln verschieben:
 settings.gen.label.liveMode.pageChange=Seite wechseln:
-settings.gen.radio.liveMode.enable=Deaktivieren
+settings.gen.radio.liveMode.enable=Verbieten
 settings.gen.radio.liveMode.disable=Erlauben
-settings.gen.label.liveModeInfo=Der Live Modus verhindet ungewollte Aktionen w�hrend der Wiedergabe einer Kachel.
+settings.gen.label.liveModeInfo=Der Live Modus verhindert ausgew�hlte Aktionen w�hrend der Wiedergabe.
 settings.gen.warning.button.reset=Hinweismeldungen zur�cksetzen
 settings.gen.cache.label=Cachespeicher:
 settings.gen.cache.button.choose=W�hlen
@@ -216,7 +219,6 @@ mappingPreset.button.delete=L
 mappingPreset.button.finish=Fertig
 mappingPreset.label.mapping=Mapping:
 mappingPreset.label.name=Name:
-#da war noch ein Fehler drin, habe ich korrigiert (urspr�nglich: mappingPreset.label.name: Name:)
 
 errorSummary.label.headline=Fehlerzusammenfassung:
 errorSummary.column.cart=Kachel
@@ -231,6 +233,8 @@ triggertime.label.time=Zeit vom Trigger: (Sek)
 carttrigger.label.action=Aktion f�r Kacheln:
 carttrigger.label.carts=Kacheln:
 carttrigger.checkbox.all=Alle anderen Kacheln
+carttrigger.label.add.placeholder=Hinzuf�gen (Name der Kachel)
+carttrigger.button.add=Hinzuf�gen
 
 volumetrigger.label.volume=Lautst�rke:
 volumetrigger.label.duration=�berblenddauer:
\ No newline at end of file
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml
index dec8adcf9d311f4a8d8c9ab7b27f9fe00a685994..3bc628651c3be6d86bd71a62dc915fa7b1d6f0fd 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/audio/tinySoundSettings.fxml
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<?import javafx.scene.control.*?>
 <?import java.lang.*?>
+<?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 
-
 <HBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
-      <Label alignment="CENTER_RIGHT" layoutX="14.0" layoutY="19.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%tinysound.label.soundcard" />
       <ComboBox fx:id="soundCardComboBox" layoutX="118.0" layoutY="14.0" prefHeight="26.0" prefWidth="241.0" />
       <Button fx:id="testButton" layoutX="372.0" layoutY="14.0" mnemonicParsing="false" onAction="#testButtonHandler" />
    </children>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/main/desktop/header.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/main/desktop/header.fxml
index dd7c7d2aa525e7b2093debec88e177d3f3cdc92f..d80d50eb1cb08fc1ca50320c4ec9d8af4d072b84 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/view/main/desktop/header.fxml
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/main/desktop/header.fxml
@@ -39,11 +39,31 @@
       </Menu>
       <Menu mnemonicParsing="false" text="%main.menu.option">
          <items>
-            <CheckMenuItem fx:id="dndModeMenuItem" mnemonicParsing="false" onAction="#dndModeHandler" text="%main.menuitem.dnd">
-               <accelerator>
-                  <KeyCodeCombination alt="UP" code="M" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
-               </accelerator>
-            </CheckMenuItem>
+                  <Menu mnemonicParsing="false" text="%main.menu.editmode">
+                     <items>
+                        <MenuItem fx:id="playMenu" mnemonicParsing="false" onAction="#playMenuHandler" text="%main.menuitem.play">
+                           <accelerator>
+                              <KeyCodeCombination alt="UP" code="H" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+                           </accelerator>
+                        </MenuItem>
+                        <MenuItem fx:id="dragMenu" mnemonicParsing="false" onAction="#dragMenuHandler" text="%main.menuitem.drag">
+                           <accelerator>
+                              <KeyCodeCombination alt="UP" code="J" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+                           </accelerator>
+                        </MenuItem>
+                        <MenuItem fx:id="pageMenu" mnemonicParsing="false" onAction="#pageMenuHandler" text="%main.menuitem.page">
+                           <accelerator>
+                              <KeyCodeCombination alt="UP" code="K" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+                           </accelerator>
+                        </MenuItem>
+                        <MenuItem fx:id="colorMenu" mnemonicParsing="false" onAction="#colorMenuHandler" text="%main.menuitem.color">
+                           <accelerator>
+                              <KeyCodeCombination alt="UP" code="L" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
+                           </accelerator>
+                        </MenuItem>
+                     </items>
+                  </Menu>
+                  <SeparatorMenuItem mnemonicParsing="false" />
             <MenuItem fx:id="errorMenu" mnemonicParsing="false" onAction="#errorMenuHandler" text="%main.menuitem.errors">
                <accelerator>
                   <KeyCodeCombination alt="UP" code="E" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml
index 3aee2f7dda47d7fcd51ad973ddb0a0a4a4ea055b..2043f7d953b159897da9d9bb6f0fa0780c79504a 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/pad/trigger/cartTrigger.fxml
@@ -18,7 +18,13 @@
             <VBox spacing="14.0">
                <children>
                   <CheckBox fx:id="allCartsCheckbox" mnemonicParsing="false" text="%carttrigger.checkbox.all" />
-                  <TextField fx:id="cartTextField" prefWidth="150.0" promptText="1, 3-5" />
+                  <HBox spacing="14.0">
+                     <children>
+                        <TextField fx:id="cartTextField" prefWidth="150.0" promptText="%carttrigger.label.add.placeholder" />
+                        <Button fx:id="addButton" mnemonicParsing="false" onAction="#addHandler" text="%carttrigger.button.add" />
+                     </children>
+                  </HBox>
+                  <ListView fx:id="addedCarts" prefHeight="200.0" prefWidth="200.0" />
                </children>
             </VBox>
          </children>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/profile/audioTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/profile/audioTab.fxml
index 86cb23c1f4f1362e39a0d79c5b87ea3147c51acd..4bd1254fc09e075952d7c577831c15a24d046fe2 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/view/option/profile/audioTab.fxml
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/profile/audioTab.fxml
@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
+<?import javafx.geometry.*?>
 <?import java.lang.*?>
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 
-<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+<VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
       <HBox layoutX="14.0" layoutY="14.0" spacing="14.0">
          <children>
@@ -12,6 +13,9 @@
             <ComboBox fx:id="audioTypeComboBox" layoutX="156.0" layoutY="14.0" prefHeight="26.0" prefWidth="226.0" />
          </children>
       </HBox>
-      <AnchorPane fx:id="audioUserInfoSettings" layoutX="14.0" layoutY="53.0" prefHeight="312.0" prefWidth="617.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="53.0" />
+      <VBox fx:id="options" prefHeight="200.0" prefWidth="100.0" spacing="14.0" />
    </children>
-</AnchorPane>
+   <padding>
+      <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+   </padding>
+</VBox>
diff --git a/PlayWall/assets/de/tobias/playpad/assets/view/option/project/generalTab.fxml b/PlayWall/assets/de/tobias/playpad/assets/view/option/project/generalTab.fxml
index 846711017bc96d87dc8447291d4c5d1bcec0184a..6bd490e9c7252f868b06f88972db4af325d03272 100644
--- a/PlayWall/assets/de/tobias/playpad/assets/view/option/project/generalTab.fxml
+++ b/PlayWall/assets/de/tobias/playpad/assets/view/option/project/generalTab.fxml
@@ -5,16 +5,9 @@
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 
-
 <VBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
       <Label text="%settings.gen.label.view" underline="true" />
-      <HBox spacing="14.0">
-         <children>
-            <Label alignment="BASELINE_RIGHT" layoutX="21.0" layoutY="40.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.pages" />
-            <TextField fx:id="pageCountTextField" prefWidth="50.0" />
-         </children>
-      </HBox>
       <HBox spacing="14.0">
          <children>
             <Label alignment="BASELINE_RIGHT" layoutX="20.0" layoutY="68.0" maxHeight="1.7976931348623157E308" prefWidth="150.0" text="%settings.gen.label.columns" />
diff --git a/PlayWall/build.xml b/PlayWall/build.xml
index 9f70f6dacf655436463692f25d7a9ae460cf5199..cdbc4d9bb97cd35b3f952e3c275e451225d46164 100644
--- a/PlayWall/build.xml
+++ b/PlayWall/build.xml
@@ -15,7 +15,7 @@
 
 	<target name="buildApp">
 		<bundleapp outputdirectory="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/dist" name="Play Wall" displayname="Play Wall" identifier="de.tobias.playwall" mainclassname="de.tobias.playpad.PlayPadMain" icon="/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWall/src/icon.icns">
-			<runtime dir="/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home" />
+			<runtime dir="/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home" />
 			<classpath file="/Users/tobias/Documents/Programmieren/Java/eclipse/PlayWall/build/PlayWall.jar" />
 		</bundleapp>
 
diff --git a/PlayWall/src/application.yml b/PlayWall/src/application.yml
index 4ed0bd37d618f8b78403b3a82be171e26e437731..613c4dfbce1d868b81c116072eddc870d657586a 100644
--- a/PlayWall/src/application.yml
+++ b/PlayWall/src/application.yml
@@ -1,7 +1,7 @@
 name: PlayWall
-version: 5.1.0
-build: 35
-identifier: de.tobias.playpad
+version: 6.0.1
+build: 37
+identifier: de.tobias.playpad.v6
 main: de.tobias.playpad.PlayPadMain
 author: Tobias Ullerich
 backup: false
diff --git a/PlayWall/src/de/tobias/playpad/PlayPadImpl.java b/PlayWall/src/de/tobias/playpad/PlayPadImpl.java
index 83b0ae9f158a67dd7b75e20541b165c2d9be331b..fd2981104a375d373fd739f34e58e8b1633c1901 100644
--- a/PlayWall/src/de/tobias/playpad/PlayPadImpl.java
+++ b/PlayWall/src/de/tobias/playpad/PlayPadImpl.java
@@ -9,6 +9,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -22,6 +23,9 @@ import de.tobias.playpad.audio.JavaFXAudioHandler;
 import de.tobias.playpad.design.modern.ModernGlobalDesign;
 import de.tobias.playpad.midi.device.DeviceRegistry;
 import de.tobias.playpad.midi.device.PD12;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.plugin.AdvancedPlugin;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.PadListener;
 import de.tobias.playpad.plugin.SettingsListener;
 import de.tobias.playpad.plugin.WindowListener;
@@ -33,14 +37,21 @@ import de.tobias.playpad.viewcontroller.IPadSettingsViewController;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.main.MainViewController;
 import de.tobias.playpad.viewcontroller.option.IProfileSettingsViewController;
+import de.tobias.playpad.volume.GlobalVolume;
+import de.tobias.playpad.volume.PadVolume;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateRegistery;
+import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.util.FileUtils;
 import de.tobias.utils.util.SystemUtils;
 import de.tobias.utils.util.Worker;
 import javafx.scene.image.Image;
+import net.xeoh.plugins.base.Plugin;
 import net.xeoh.plugins.base.PluginManager;
 import net.xeoh.plugins.base.impl.PluginManagerFactory;
+import net.xeoh.plugins.base.util.PluginManagerUtil;
 
 public class PlayPadImpl implements PlayPad {
 
@@ -57,13 +68,23 @@ public class PlayPadImpl implements PlayPad {
 
 	private MainViewController mainViewController;
 	private Project currentProject;
+	private static Module module;
+
 	protected GlobalSettings globalSettings;
 
+	private Set<Module> modules;
+
 	public PlayPadImpl(GlobalSettings globalSettings) {
+		App app = ApplicationUtils.getApplication();
+		module = new Module(app.getInfo().getName(), app.getInfo().getIdentifier());
+
 		pluginManager = PluginManagerFactory.createPluginManager();
 		deletedPlugins = new HashSet<>();
+		modules = new HashSet<>();
 
 		this.globalSettings = globalSettings;
+
+		getModules().add(module); // Add Main Module
 	}
 
 	@Override
@@ -188,13 +209,28 @@ public class PlayPadImpl implements PlayPad {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		
+
 		pluginManager.shutdown();
 		Worker.shutdown();
 	}
 
+	@Override
 	public void loadPlugin(URI uri) {
 		pluginManager.addPluginsFrom(uri);
+
+		// Registriert Funktionen aus Plugin (Module und Update, ...)
+		PluginManagerUtil util = new PluginManagerUtil(pluginManager);
+		Collection<Plugin> plugins = util.getPlugins();
+		for (Plugin plugin : plugins) {
+			if (plugin instanceof AdvancedPlugin) {
+				AdvancedPlugin advancedPlugin = (AdvancedPlugin) plugin;
+				Module module = advancedPlugin.getModule();
+				Updatable updatable = advancedPlugin.getUpdatable();
+
+				modules.add(module);
+				UpdateRegistery.registerUpdateable(updatable);
+			}
+		}
 	}
 
 	@Override
@@ -213,11 +249,11 @@ public class PlayPadImpl implements PlayPad {
 	public Project getCurrentProject() {
 		return currentProject;
 	}
-	
+
 	public void startup(ResourceBundle resourceBundle) {
 		registerComponents(resourceBundle);
 	}
-	
+
 	private void registerComponents(ResourceBundle resourceBundle) {
 		// Midi
 		DeviceRegistry.getFactoryInstance().registerDevice(PD12.NAME, PD12.class);
@@ -226,14 +262,14 @@ public class PlayPadImpl implements PlayPad {
 			// Load Components
 			RegistryCollection registryCollection = PlayPadPlugin.getRegistryCollection();
 
-			registryCollection.getActions().loadComponentsFromFile("de/tobias/playpad/components/Actions.xml");
-			registryCollection.getAudioHandlers().loadComponentsFromFile("de/tobias/playpad/components/AudioHandler.xml");
-			registryCollection.getDragModes().loadComponentsFromFile("de/tobias/playpad/components/DragMode.xml");
-			registryCollection.getDesigns().loadComponentsFromFile("de/tobias/playpad/components/Design.xml");
-			registryCollection.getMappers().loadComponentsFromFile("de/tobias/playpad/components/Mapper.xml");
-			registryCollection.getPadContents().loadComponentsFromFile("de/tobias/playpad/components/PadContent.xml");
-			registryCollection.getTriggerItems().loadComponentsFromFile("de/tobias/playpad/components/Trigger.xml");
-			registryCollection.getMainLayouts().loadComponentsFromFile("de/tobias/playpad/components/Layout.xml");
+			registryCollection.getActions().loadComponentsFromFile("de/tobias/playpad/components/Actions.xml", module);
+			registryCollection.getAudioHandlers().loadComponentsFromFile("de/tobias/playpad/components/AudioHandler.xml", module);
+			registryCollection.getDragModes().loadComponentsFromFile("de/tobias/playpad/components/DragMode.xml", module);
+			registryCollection.getDesigns().loadComponentsFromFile("de/tobias/playpad/components/Design.xml", module);
+			registryCollection.getMappers().loadComponentsFromFile("de/tobias/playpad/components/Mapper.xml", module);
+			registryCollection.getPadContents().loadComponentsFromFile("de/tobias/playpad/components/PadContent.xml", module);
+			registryCollection.getTriggerItems().loadComponentsFromFile("de/tobias/playpad/components/Trigger.xml", module);
+			registryCollection.getMainLayouts().loadComponentsFromFile("de/tobias/playpad/components/Layout.xml", module);
 
 			// Set Default
 			registryCollection.getAudioHandlers().setDefaultID(JavaFXAudioHandler.TYPE);
@@ -243,11 +279,17 @@ public class PlayPadImpl implements PlayPad {
 			e.printStackTrace();
 		}
 
-		// Key Bindings
-		GlobalSettings globalSettings = PlayPadPlugin.getImplementation().getGlobalSettings();
-		globalSettings.getKeyCollection().loadDefaultFromFile("de/tobias/playpad/components/Keys.xml", resourceBundle);
+		// Volume Management
+		Pad.getVolumeManager().addFilter(new GlobalVolume());
+		Pad.getVolumeManager().addFilter(new PadVolume());
 
 		// Mapper
 		MapperRegistry.setOverviewViewController(new MapperOverviewViewController());
+
+	}
+
+	@Override
+	public Set<Module> getModules() {
+		return modules;
 	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/de/tobias/playpad/PlayPadMain.java
index 924c2c8f4c3b513b8d8673ee4fc378bb77a9bfae..9a472114c8ddba0cc6d5b0595f2f3f529f5f289d 100644
--- a/PlayWall/src/de/tobias/playpad/PlayPadMain.java
+++ b/PlayWall/src/de/tobias/playpad/PlayPadMain.java
@@ -9,16 +9,16 @@ import java.util.Optional;
 import java.util.ResourceBundle;
 import java.util.UUID;
 
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.project.Project;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.settings.GlobalSettings;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.playpad.update.PlayPadUpdater;
-import de.tobias.playpad.update.UpdateRegistery;
 import de.tobias.playpad.update.Updates;
 import de.tobias.playpad.viewcontroller.LaunchDialog;
 import de.tobias.playpad.viewcontroller.dialog.AutoUpdateDialog;
 import de.tobias.playpad.viewcontroller.dialog.ChangelogDialog;
+import de.tobias.updater.client.UpdateRegistery;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
@@ -31,7 +31,7 @@ import de.tobias.utils.util.OS.OSType;
 import de.tobias.utils.util.Worker;
 import javafx.application.Application;
 import javafx.application.Platform;
-import javafx.scene.control.ButtonType;
+import javafx.scene.control.ButtonBar.ButtonData;
 import javafx.scene.image.Image;
 import javafx.stage.Stage;
 import javafx.stage.Window;
@@ -60,7 +60,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 
 	private static PlayPadImpl impl;
 	private static PlayPadUpdater updater;
-	
+
 	public static ResourceBundle getUiResourceBundle() {
 		return uiResourceBundle;
 	}
@@ -84,16 +84,19 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 	public void init() throws Exception {
 		App app = ApplicationUtils.getApplication();
 
-		Path globalSettingsPath = app.getPath(PathType.CONFIGURATION, "GlobalSettings.yml");
+		// Localization
+		setupLocalization();
+
+		// Setup Global Settings
+		Path globalSettingsPath = app.getPath(PathType.CONFIGURATION, "GlobalSettings.xml");
 		GlobalSettings globalSettings = GlobalSettings.load(globalSettingsPath);
+		globalSettings.getKeyCollection().loadDefaultFromFile("de/tobias/playpad/components/Keys.xml", uiResourceBundle);
+		globalSettings.getKeyCollection().load(globalSettingsPath);
 
 		impl = new PlayPadImpl(globalSettings);
 		PlayPadPlugin.setImplementation(impl);
 		PlayPadPlugin.setRegistryCollection(new RegistryCollectionImpl());
 
-		// Localization
-		setupLocalization();
-
 		// Console
 		if (!app.isDebug()) {
 			System.setOut(ConsoleUtils.streamToFile(app.getPath(PathType.LOG, "out.log")));
@@ -121,17 +124,21 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 			// Load Plugin Path
 			Path pluginFolder;
 			if (getParameters().getNamed().containsKey("plugin")) {
-				pluginFolder = Paths.get(getParameters().getNamed().get("plugin"));
+				String pluginParam = getParameters().getNamed().get("plugin");
+				for (String part : pluginParam.split(":")) {
+					pluginFolder = Paths.get(part);
+					setupPlugins(pluginFolder);
+				}
 			} else {
 				pluginFolder = ApplicationUtils.getApplication().getPath(PathType.LIBRARY);
+				setupPlugins(pluginFolder);
 			}
-			setupPlugins(pluginFolder);
 
 			/*
 			 * Load Data
 			 */
-			ProfileReference.loadProfiles();
-			ProjectReference.loadProjects();
+			ProfileReferences.loadProfiles();
+			ProjectReferences.loadProjects();
 
 			// Changelog nach Update anzeigen
 			ViewController.create(ChangelogDialog.class);
@@ -140,7 +147,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 			if (getParameters().getRaw().size() > 0) {
 				if (getParameters().getNamed().containsKey("project")) {
 					UUID uuid = UUID.fromString(getParameters().getNamed().get("project"));
-					impl.openProject(Project.load(ProjectReference.getProject(uuid), true, null));
+					impl.openProject(Project.load(ProjectReferences.getProject(uuid), true, null));
 					return;
 				}
 			}
@@ -165,7 +172,7 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 					Platform.runLater(() ->
 					{
 						AutoUpdateDialog autoUpdateDialog = new AutoUpdateDialog(owner);
-						autoUpdateDialog.showAndWait().filter(item -> item == ButtonType.APPLY).ifPresent(result ->
+						autoUpdateDialog.showAndWait().filter(item -> item.getButtonData() == ButtonData.APPLY).ifPresent(result ->
 						{
 							try {
 								Updates.startUpdate();
@@ -185,8 +192,8 @@ public class PlayPadMain extends Application implements LocalizationDelegate {
 	@Override
 	public void stop() throws Exception {
 		try {
-			ProfileReference.saveProfiles();
-			ProjectReference.saveProjects();
+			ProfileReferences.saveProfiles();
+			ProjectReferences.saveProjects();
 			impl.getGlobalSettings().save();
 		} catch (Exception e) {
 			e.printStackTrace(); // Speichern Fehler
diff --git a/PlayWall/src/de/tobias/playpad/RegistryCollectionImpl.java b/PlayWall/src/de/tobias/playpad/RegistryCollectionImpl.java
index 12d4b0fe594f1c12be839fa66fd6f129c1424acc..8e9b2bf1773efe28ae50e2bea3f3490bead6e7be 100644
--- a/PlayWall/src/de/tobias/playpad/RegistryCollectionImpl.java
+++ b/PlayWall/src/de/tobias/playpad/RegistryCollectionImpl.java
@@ -4,7 +4,7 @@ import de.tobias.playpad.action.ActionConnect;
 import de.tobias.playpad.action.mapper.MapperConnect;
 import de.tobias.playpad.audio.AudioRegistry;
 import de.tobias.playpad.design.DesignConnect;
-import de.tobias.playpad.pad.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.pad.drag.PadDragMode;
 import de.tobias.playpad.registry.ComponentRegistry;
 import de.tobias.playpad.registry.DefaultComponentRegistry;
diff --git a/PlayWall/src/de/tobias/playpad/Strings.java b/PlayWall/src/de/tobias/playpad/Strings.java
index ecd9bf62c80aef675ee7fd54034d9ed29e3282c5..7a24acf3963219898bdddc974049ce50e19f0853 100644
--- a/PlayWall/src/de/tobias/playpad/Strings.java
+++ b/PlayWall/src/de/tobias/playpad/Strings.java
@@ -46,8 +46,6 @@ public class Strings {
 
 	// UI - Window - Main
 	public static final String UI_Window_Main_CloseRequest = "UI.Window.Main.CloseRequest";
-	@Deprecated
-	public static final String UI_Window_Main_SaveRequest = "UI.Window.Main.SaveRequest";
 	public static final String UI_Window_Main_PageButton = "UI.Window.Main.PageButton";
 
 	// UI - Dialog - Launch
@@ -145,6 +143,7 @@ public class Strings {
 	public static final String Error_Project_Delete = "Error.Project.Delete";
 	public static final String Error_Project_Export = "Error.Project.Export";
 	public static final String Error_Project_MediaPath = "Error.Project.MediaPath";
+	public static final String Error_Project_PageCount = "Error.Project.PageCount";
 
 	// Error - Pad
 	public static final String Error_Pad_BaseName = "Error.Pad.";
@@ -161,8 +160,8 @@ public class Strings {
 	public static final String Error_Midi_Send = "Error.Midi.Send";
 
 	// Error - Plugins
-	@Deprecated public static final String Error_Plugins_Download = "Error.Plugins.Download";
 	public static final String Error_Plugins_Available = "Error.Plugins.Available";
+	public static final String Error_Plugins_Missing = "Error.Plugins.Missing";
 
 	// Mapper
 	public static final String Mapper_Keyboard_Name = "Mapper.Keyboard.Name";
@@ -229,9 +228,6 @@ public class Strings {
 	public static final String UI_Dialog_Update_Info = "UI.Dialog.Update.Info";
 	public static final String UI_Window_Settings_Updates_CurrentVersion = "UI.Window.Settings.Updates.CurrentVersion";
 
-	// Error - Update - Downlaod
-	@Deprecated public static final String Error_Update_Download = "Error.Update.Download";
-
 	// Layout
 	public static final String Layout_Modern_Name = "Layout.Modern.Name";
 	public static final String Layout_Classic_Name = "Layout.Classic.Name";
@@ -246,6 +242,7 @@ public class Strings {
 
 	// Drag and Drop Mode
 	public static final String DnDMode_Move = "DnDMode.Move";
+	public static final String DnDMode_Duplicate = "DnDMode.Duplicate";
 	public static final String DnDMode_Replace = "DnDMode.Replace";
 
 	// Main Layout
@@ -256,4 +253,24 @@ public class Strings {
 	public static final String Search_Button = "Search.Button";
 	public static final String Search_Placeholder = "Search.Placeholder";
 	public static final String Search_Alert_NoMatches = "Search.Alert.NoMatches";
+
+	// UI - Dialog - Page - Delete
+	public static final String UI_Dialog_Page_Delete_Header = "UI.Dialog.Page.Delete.Header";
+	public static final String UI_Dialog_Page_Delete_Content = "UI.Dialog.Page.Delete.Content";
+
+	// UI - Dialog - Page - Name
+	public static final String UI_Dialog_Page_Name_Header = "UI.Dialog.Page.Name.Header";
+	public static final String UI_Dialog_Page_Name_Content = "UI.Dialog.Page.Name.Content";
+
+	// Tooltip
+	public static final String Tooltip_PlayButton = "Tooltip.PlayButton";
+	public static final String Tooltip_DragButton = "Tooltip.DragButton";
+	public static final String Tooltip_PageButton = "Tooltip.PageButton";
+	public static final String Tooltip_ColorButton = "Tooltip.ColorButton";
+
+	public static final String Tooltip_Page_LeftMove = "Tooltip.Page.LeftMove";
+	public static final String Tooltip_Page_RightMove = "Tooltip.Page.RightMove";
+	public static final String Tooltip_Page_Rename = "Tooltip.Page.Rename";
+	public static final String Tooltip_Page_Clone = "Tooltip.Page.Clone";
+	public static final String Tooltip_Page_Delete = "Tooltip.Page.Delete";
 }
diff --git a/PlayWall/src/de/tobias/playpad/VersionUpdater.java b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
index 7cc6280d1f22f6614e5207f330a1a37afc2f2e0e..9e821f39112798518bd3ec31955658e82ab2e1ee 100644
--- a/PlayWall/src/de/tobias/playpad/VersionUpdater.java
+++ b/PlayWall/src/de/tobias/playpad/VersionUpdater.java
@@ -1,76 +1,13 @@
 package de.tobias.playpad;
 
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.UUID;
-
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.dom4j.io.OutputFormat;
-import org.dom4j.io.SAXReader;
-import org.dom4j.io.XMLWriter;
-
-import de.tobias.playpad.project.ProjectSettings;
 import de.tobias.utils.application.App;
-import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.application.update.UpdateService;
 
 public class VersionUpdater implements UpdateService {
 
 	@Override
 	public void update(App app, long oldVersion, long newVersion) {
-		try {
-			if (newVersion >= 33 && oldVersion < 33)
-				update33(app);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void update33(App app) throws DocumentException, IOException {
-		SAXReader reader = new SAXReader();
-
-		Document projectsDocument = reader.read(Files.newInputStream(app.getPath(PathType.CONFIGURATION, "Projects.xml")));
-		for (Object obj : projectsDocument.getRootElement().elements("Project")) {
-			if (obj instanceof Element) {
-				Element element = (Element) obj;
-
-				UUID profile = UUID.fromString(element.attributeValue("profile"));
-				UUID project = UUID.fromString(element.attributeValue("uuid"));
-
-				updateProject(profile, project, app);
-			}
-		}
-	}
-
-	private void updateProject(UUID profile, UUID project, App app) throws DocumentException, IOException {
-		Path profileSettings = app.getPath(PathType.CONFIGURATION, profile.toString(), "ProfileSettings.xml");
-		SAXReader reader = new SAXReader();
-
-		Document document = reader.read(Files.newInputStream(profileSettings));
-		Element rootElement = document.getRootElement();
-
-		int pages = Integer.valueOf(rootElement.element("PageCount").getStringValue());
-		int rows = Integer.valueOf(rootElement.element("Rows").getStringValue());
-		int columns = Integer.valueOf(rootElement.element("Columns").getStringValue());
-
-		Path projectSettings = app.getPath(PathType.DOCUMENTS, project.toString() + ".xml");
-		Document projectDocument = reader.read(Files.newInputStream(projectSettings));
-		Element rootProjectElement = projectDocument.getRootElement();
-		Element settingsElement = rootProjectElement.addElement("Settings");
-
-		ProjectSettings projectSettings2 = new ProjectSettings();
-		projectSettings2.setColumns(columns);
-		projectSettings2.setRows(rows);
-		projectSettings2.setPageCount(pages);
-
-		projectSettings2.save(settingsElement);
 
-		XMLWriter writer = new XMLWriter(Files.newOutputStream(projectSettings), OutputFormat.createPrettyPrint());
-		writer.write(projectDocument);
-		writer.close();
 	}
 
 }
diff --git a/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java b/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java
index b4c9e005d4ad67297301d689e39bef045c7d9ab6..e8df71b43fc387729ec9e6eec1be816a75e47ecd 100644
--- a/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java
+++ b/PlayWall/src/de/tobias/playpad/action/actions/NavigateAction.java
@@ -21,6 +21,7 @@ public class NavigateAction extends Action {
 		PREVIOUS,
 		NEXT;
 
+		@Override
 		public String toString() {
 			return Localization.getString(Strings.NavigationType_BaseName + name());
 		};
diff --git a/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java b/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java
index 6cc149eb532554103b8b7f3b1badf41ab10b11f3..cd564863f87794440c4ba5052e095d7e179698a7 100644
--- a/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java
+++ b/PlayWall/src/de/tobias/playpad/action/actions/PageAction.java
@@ -98,6 +98,7 @@ public class PageAction extends Action {
 		return new SimpleStringProperty(toString());
 	}
 
+	@Override
 	public Action cloneAction() throws CloneNotSupportedException {
 		PageAction action = (PageAction) super.clone();
 
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java
index b6cc56cdb510a9ee0cca3e9a6798661221e92150..15796b6fc3052711b3690481fb6c1f4b6cb1d666 100644
--- a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java
@@ -22,9 +22,7 @@ import javafx.beans.property.StringProperty;
 public class CartAction extends Action implements ColorAdjustable {
 
 	public enum ControlMode {
-		PLAY_PAUSE,
-		PLAY_STOP,
-		PLAY_HOLD;
+		PLAY_PAUSE, PLAY_STOP, PLAY_HOLD;
 	}
 
 	private int x;
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java
index 7bd14fdcdc4b151f2a70ab7869209333f9b224e7..c9e3afdfee365576aebdcf81a0da981f39701484 100644
--- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadPositionWarningListener.java
@@ -4,7 +4,6 @@ import de.tobias.playpad.action.feedback.FeedbackMessage;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadSettings;
 import de.tobias.playpad.pad.conntent.play.Durationable;
-import de.tobias.playpad.settings.Warning;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.util.Duration;
@@ -35,13 +34,13 @@ public class PadPositionWarningListener implements ChangeListener<Duration> {
 				// Warning nur wenn kein Loop
 				if (!padSettings.isLoop()) {
 					// Warning
-					Warning warning = padSettings.getWarning();
+					Duration warning = padSettings.getWarning();
 					Duration totalDuration = durationable.getDuration();
 					if (totalDuration != null) {
 						Duration rest = totalDuration.subtract(newValue);
 						double seconds = rest.toSeconds();
 
-						if (warning.getTime().toSeconds() > seconds && !send) {
+						if (warning.toSeconds() > seconds && !send) {
 							action.handleFeedback(FeedbackMessage.WARNING);
 							send = true;
 						}
diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java
index dfafdc97e589aaf83718dd8d2f0e707cfc6bdc12..992dec67bc5dd786c9b14e0cfafc0625159832ea 100644
--- a/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java
+++ b/PlayWall/src/de/tobias/playpad/action/cartaction/PadStatusFeedbackListener.java
@@ -5,7 +5,6 @@ import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadSettings;
 import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.pad.conntent.play.Durationable;
-import de.tobias.playpad.settings.Warning;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.util.Duration;
@@ -41,11 +40,11 @@ public class PadStatusFeedbackListener implements ChangeListener<PadStatus> {
 							PadSettings padSettings = pad.getPadSettings();
 
 							if (!padSettings.isLoop()) {
-								Warning warning = padSettings.getWarning();
+								Duration warning = padSettings.getWarning();
 								Duration rest = durationable.getDuration().subtract(durationable.getPosition());
 								double seconds = rest.toSeconds();
 
-								if (warning.getTime().toSeconds() > seconds) {
+								if (warning.toSeconds() > seconds) {
 									action.handleFeedback(FeedbackMessage.WARNING);
 								}
 							}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java
index f6f60e3937638419efae957f1133e34df713eee7..f4073ed53acb60792b896faff8737c8aa3d4dfa8 100644
--- a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapper.java
@@ -104,9 +104,9 @@ public class MidiMapper extends Mapper implements ColorAssociator, MapperFeedbac
 	}
 
 	@Override
-	public void setColor(FeedbackMessage feedbackMessage, int value) {
+	public void setColor(FeedbackMessage feedbackMessage, DisplayableFeedbackColor color) {
 		if (feedbackMessage == FeedbackMessage.STANDARD || feedbackMessage == FeedbackMessage.EVENT) {
-			feedback.setFeedback(feedbackMessage, value);
+			feedback.setFeedback(feedbackMessage, color.mapperFeedbackValue());
 		} else {
 			throw new IllegalArgumentException("Unexpected Message Type.");
 		}
diff --git a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java
index f9f169dd42791b3c686c9656ad5056ca0c6098fe..e70c964c141cca12ef407f30e7c0a79e9cc604fb 100644
--- a/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java
+++ b/PlayWall/src/de/tobias/playpad/action/mapper/MidiMapperConnect.java
@@ -20,7 +20,7 @@ public class MidiMapperConnect extends MapperConnect implements MapperConnectFee
 
 	@Override
 	public void initFeedbackType() {
-		Midi.getInstance().getMidiDevice().ifPresent(device -> device.initFeedback());
+		Midi.getInstance().getMidiDevice().ifPresent(device -> device.initDevice());
 	}
 
 	@Override
diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java
index 235b0455c069d0ebd61505bf9995b1edbea28b51..d80cae8b7c5065780df897b9490f41598050657d 100644
--- a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java
+++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java
@@ -85,9 +85,7 @@ public class ClipAudioHandler extends AudioHandler {
 					}
 
 					Thread.sleep(SLEEP_TIME_POSITION);
-				} catch (InterruptedException e) {
-				} catch (ConcurrentModificationException e) {
-				} catch (Exception e) {
+				} catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) {
 					e.printStackTrace();
 				}
 			}
@@ -166,18 +164,14 @@ public class ClipAudioHandler extends AudioHandler {
 		return durationProperty;
 	}
 
-	@Override
-	public void setVolume(double volume, double masterVolume, double customVolume) {
-		setVolume(masterVolume * volume * customVolume);
-	}
-
 	/**
 	 * Lineaer to dB
 	 * 
 	 * @param volume
 	 *            [0, 1]
 	 */
-	private void setVolume(double volume) {
+	@Override
+	public void setVolume(double volume) {
 		if (volumeControl != null) {
 			if (volume == 1.0) {
 				volumeControl.setValue(0);
diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java
index bb004a440ff00caa12fc400a3ab4fb9f44cdb2eb..24e5ee44d90437d47c5a133b015ace6cb4f23757 100644
--- a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java
+++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandlerConnect.java
@@ -23,7 +23,20 @@ public class ClipAudioHandlerConnect extends AudioHandlerConnect implements Auto
 
 	@Override
 	public void close() throws Exception {
-		TinyAudioHandler.shutdown();
+		ClipAudioHandler.shutdown();
 	}
 
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		for (Class<?> clazz : ClipAudioHandler.class.getInterfaces()) {
+			if (clazz.equals(audioCapability.getAudioFeature()))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		return null;
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java
index f9c5a4651d921efb605128d8810b0c5558da32e6..a5a4a39fd0d2fd0e84298b9ad8578a9ab59bcf4d 100644
--- a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java
+++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java
@@ -79,9 +79,10 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable {
 	}
 
 	@Override
-	public void setVolume(double volume, double masterVolume, double customVolume) {
-		if (player != null)
-			player.setVolume(volume * masterVolume * customVolume);
+	public void setVolume(double volume) {
+		if (player != null) {
+			player.setVolume(volume);
+		}
 	}
 
 	@Override
@@ -91,7 +92,8 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable {
 
 	@Override
 	public void loadMedia(Path[] paths) {
-		Platform.runLater(() -> {
+		Platform.runLater(() ->
+		{
 			if (getContent().getPad().isPadVisible()) {
 				getContent().getPad().getController().getView().showBusyView(true);
 			}
@@ -107,28 +109,33 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable {
 		player = new MediaPlayer(media);
 
 		// Player Listener
-		player.setOnReady(() -> {
+		player.setOnReady(() ->
+		{
 			durationProperty.set(player.getTotalDuration());
 			getContent().getPad().setStatus(PadStatus.READY);
 			loadedProperty.set(true);
 
-			Platform.runLater(() -> {
+			Platform.runLater(() ->
+			{
 				if (getContent().getPad().isPadVisible()) {
 					getContent().getPad().getController().getView().showBusyView(false);
 				}
 			});
 		});
 
-		player.setOnError(() -> {
-			Platform.runLater(() -> {
+		player.setOnError(() ->
+		{
+			Platform.runLater(() ->
+			{
 				if (getContent().getPad().isPadVisible()) {
 					getContent().getPad().getController().getView().showBusyView(false);
 				}
 			});
 			loadedProperty.set(false);
-			getContent().getPad().throwException(path, player.getError());
+			// getContent().getPad().throwException(path, player.getError()); TODO Error Handling User
 		});
-		player.setOnEndOfMedia(() -> {
+		player.setOnEndOfMedia(() ->
+		{
 			if (!getContent().getPad().getPadSettings().isLoop()) {
 				getContent().getPad().setEof(true);
 				getContent().getPad().setStatus(PadStatus.STOP);
diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java
index baca001b6e97120e49f96f5bde06800138aded15..fb63c182d18ddb891dc3b55d9892f46954c49aa0 100644
--- a/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java
+++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXHandlerConnect.java
@@ -19,4 +19,18 @@ public class JavaFXHandlerConnect extends AudioHandlerConnect {
 	public String getType() {
 		return JavaFXAudioHandler.TYPE;
 	}
+	
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		for (Class<?> clazz : JavaFXAudioHandler.class.getInterfaces()) {
+			if (clazz.equals(audioCapability.getAudioFeature()))
+				return true;
+		}
+		return false;
+	}
+	
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		return null;
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java
index c25c2f83d9a86a357330e34afb167610f5a0e733..8e8e8d163388f59d0c83e044316b52fddb7eb3d6 100644
--- a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java
+++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java
@@ -38,7 +38,7 @@ import javazoom.jl.decoder.JavaLayerException;
 import kuusisto.tinysound.Music;
 import kuusisto.tinysound.TinySound;
 
-public class TinyAudioHandler extends AudioHandler {
+public class TinyAudioHandler extends AudioHandler implements Soundcardable {
 
 	public static final String SOUND_CARD = "SoundCard";
 
@@ -98,9 +98,7 @@ public class TinyAudioHandler extends AudioHandler {
 					}
 
 					Thread.sleep(SLEEP_TIME_POSITION);
-				} catch (InterruptedException e) {
-				} catch (ConcurrentModificationException e) {
-				} catch (Exception e) {
+				} catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) {
 					e.printStackTrace();
 				}
 			}
@@ -201,9 +199,9 @@ public class TinyAudioHandler extends AudioHandler {
 	}
 
 	@Override
-	public void setVolume(double volume, double masterVolume, double customVolume) {
+	public void setVolume(double volume) {
 		if (music != null) {
-			music.setVolume(volume * masterVolume * customVolume);
+			music.setVolume(volume);
 		}
 	}
 
@@ -214,7 +212,8 @@ public class TinyAudioHandler extends AudioHandler {
 
 	@Override
 	public void loadMedia(Path[] paths) {
-		initTinySound();
+		String audioCardName = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(SOUND_CARD);
+		initTinySound(audioCardName);
 
 		unloadMedia();
 		Platform.runLater(() ->
@@ -248,7 +247,7 @@ public class TinyAudioHandler extends AudioHandler {
 				});
 			} catch (Exception e) {
 				loadedProperty.set(false);
-				getContent().getPad().throwException(path, e);
+				// getContent().getPad().throwException(path, e); TODO Error Handling User
 				e.printStackTrace();
 			} finally {
 				Platform.runLater(() ->
@@ -263,7 +262,7 @@ public class TinyAudioHandler extends AudioHandler {
 
 	private void calcDuration(URL url) throws UnsupportedAudioFileException, IOException {
 		AudioInputStream iStr = AudioSystem.getAudioInputStream(url);
-		double max = 1000.0 * (double) iStr.getFrameLength() / (double) iStr.getFormat().getFrameRate();
+		double max = 1000.0 * iStr.getFrameLength() / iStr.getFormat().getFrameRate();
 		Duration duration = Duration.millis(max);
 		Platform.runLater(() -> this.duration.set(duration));
 		iStr.close();
@@ -298,9 +297,7 @@ public class TinyAudioHandler extends AudioHandler {
 
 	private static String audioCardName;
 
-	private void initTinySound() {
-		String audioCardName = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(SOUND_CARD);
-
+	private void initTinySound(String audioCardName) {
 		if (TinyAudioHandler.audioCardName != null) {
 			if (!TinyAudioHandler.audioCardName.equals(audioCardName)) {
 				TinySound.shutdown();
@@ -334,4 +331,9 @@ public class TinyAudioHandler extends AudioHandler {
 		executorService.shutdown();
 		positionThread.interrupt();
 	}
+
+	@Override
+	public void setOutputDevice(String name) {
+		initTinySound(name);
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java
index cf8388f1f83557cf8c9ab87b7a84c2faca1de8ee..af7bc01e9e2ffdd0281f2649c737d44fc323033f 100644
--- a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java
+++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandlerConnect.java
@@ -25,4 +25,21 @@ public class TinyAudioHandlerConnect extends AudioHandlerConnect implements Auto
 	public void close() throws Exception {
 		TinyAudioHandler.shutdown();
 	}
+
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		for (Class<?> clazz : TinyAudioHandler.class.getInterfaces()) {
+			if (clazz.equals(audioCapability.getAudioFeature()))
+				return true;
+		}
+		return false;
+	}
+	
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		if (audioCapablility == AudioCapability.SOUNDCARD) {
+			return new TinySoundSettingsViewController();
+		}
+		return null;
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/components/AudioHandler.xml b/PlayWall/src/de/tobias/playpad/components/AudioHandler.xml
index f217977524027c6ea86e2d752a2bcc54852390a3..4eb786b33b8fda7019303f173383fccc60afdaca 100644
--- a/PlayWall/src/de/tobias/playpad/components/AudioHandler.xml
+++ b/PlayWall/src/de/tobias/playpad/components/AudioHandler.xml
@@ -1,5 +1,4 @@
 <Actions>
 	<Component id="JavaFx">de.tobias.playpad.audio.JavaFXHandlerConnect</Component>
 	<Component id="TinyAudio">de.tobias.playpad.audio.TinyAudioHandlerConnect</Component>
-	<Component id="clip">de.tobias.playpad.audio.ClipAudioHandlerConnect</Component>
 </Actions>
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/components/DragMode.xml b/PlayWall/src/de/tobias/playpad/components/DragMode.xml
index 11359ce78858ad76de75fe09e03e4c74ff9c78af..3d2b2e610574982028042d5f8a3de259d4c69ac6 100644
--- a/PlayWall/src/de/tobias/playpad/components/DragMode.xml
+++ b/PlayWall/src/de/tobias/playpad/components/DragMode.xml
@@ -1,4 +1,5 @@
 <Actions>
 	<Component id="move">de.tobias.playpad.pad.drag.MoveDragMode</Component>
+	<Component id="duplicate">de.tobias.playpad.pad.drag.DuplicateDragMode</Component>
 	<Component id="replace">de.tobias.playpad.pad.drag.ReplaceDragMode</Component>
 </Actions>
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/components/Keys.xml b/PlayWall/src/de/tobias/playpad/components/Keys.xml
index d5f0239e01f66870f30a2311003816151f3532af..11254b52b39b1b179f0b5477e73cb1f5bc0587fd 100644
--- a/PlayWall/src/de/tobias/playpad/components/Keys.xml
+++ b/PlayWall/src/de/tobias/playpad/components/Keys.xml
@@ -6,8 +6,13 @@
 		<Key id="save_proj" name="main.menuitem.save" key="S" ctrl="true" alt="false" meta="false" shift="false"/>
 		<Key id="print_proj" name="main.menuitem.print" key="P" ctrl="true" alt="false" meta="false" shift="false"/>
 		
-		<Key id="dnd" name="main.menuitem.dnd" key="M" ctrl="true" alt="false" meta="false" shift="false"/>
+		<Key id="play" name="main.menuitem.play" key="H" ctrl="true" alt="false" meta="false" shift="false"/>
+		<Key id="drag" name="main.menuitem.drag" key="J" ctrl="true" alt="false" meta="false" shift="false"/>
+		<Key id="page" name="main.menuitem.page" key="K" ctrl="true" alt="false" meta="false" shift="false"/>
+		<Key id="color" name="main.menuitem.color" key="L" ctrl="true" alt="false" meta="false" shift="false"/>
+
 		<Key id="errors" name="main.menuitem.errors" key="E" ctrl="true" alt="false" meta="false" shift="false"/>
+		
 		<Key id="plugins" name="main.menuitem.plugins"/>
 		<Key id="project_settings" name="main.menuitem.projectSettings" key="Comma" ctrl="true" alt="true" meta="false" shift="false"/>
 		<Key id="profile_settings" name="main.menuitem.profileSettings" key="Comma" ctrl="true" alt="false" meta="false" shift="false"/>
@@ -23,8 +28,13 @@
 		<Key id="save_proj" name="main.menuitem.save" key="S" ctrl="false" alt="false" meta="true" shift="false"/>
 		<Key id="print_proj" name="main.menuitem.print" key="P" ctrl="false" alt="false" meta="true" shift="false"/>
 		
-		<Key id="dnd" name="main.menuitem.dnd" key="M" ctrl="false" alt="false" meta="true" shift="false"/>
+		<Key id="play" name="main.menuitem.play" key="H" ctrl="false" alt="false" meta="true" shift="false"/>
+		<Key id="drag" name="main.menuitem.drag" key="J" ctrl="false" alt="false" meta="true" shift="false"/>
+		<Key id="page" name="main.menuitem.page" key="K" ctrl="false" alt="false" meta="true" shift="false"/>
+		<Key id="color" name="main.menuitem.color" key="L" ctrl="false" alt="false" meta="true" shift="false"/>
+		
 		<Key id="errors" name="main.menuitem.errors" key="E" ctrl="false" alt="false" meta="true" shift="false"/>
+		
 		<Key id="plugins" name="main.menuitem.plugins"/>
 		<Key id="project_settings" name="main.menuitem.projectSettings" key="Comma" ctrl="false" alt="true" meta="true" shift="false"/>
 		<Key id="profile_settings" name="main.menuitem.profileSettings" key="Comma" ctrl="false" alt="false" meta="true" shift="false"/>
diff --git a/PlayWall/src/de/tobias/playpad/design/classic/ClassicCartDesign.java b/PlayWall/src/de/tobias/playpad/design/classic/ClassicCartDesign.java
index af5a1e1ff864e345625432827a6911c7b0c3a7bd..01f9b4da5cf0abcefa2e75de59261f24c26c8808 100644
--- a/PlayWall/src/de/tobias/playpad/design/classic/ClassicCartDesign.java
+++ b/PlayWall/src/de/tobias/playpad/design/classic/ClassicCartDesign.java
@@ -17,10 +17,10 @@ import de.tobias.playpad.design.Design;
 import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.utils.util.ColorXMLUtils;
 import javafx.application.Platform;
 import javafx.scene.paint.Color;
+import javafx.util.Duration;
 
 public class ClassicCartDesign extends Design implements CartDesign {
 
@@ -91,6 +91,7 @@ public class ClassicCartDesign extends Design implements CartDesign {
 		this.accentColor = accentColor;
 	}
 
+	@Override
 	public void reset() {
 		backgroundColor = Color.TRANSPARENT;
 		playbackColor = Color.web("#ffb48bbb");
@@ -102,6 +103,7 @@ public class ClassicCartDesign extends Design implements CartDesign {
 		titleLabelColor = Color.BLACK;
 	}
 
+	@Override
 	public void load(Element rootElement) {
 		setBackgroundColor(ColorXMLUtils.load(rootElement.element("BackgroundColor")));
 		setPlaybackColor(ColorXMLUtils.load(rootElement.element("PlaybackColor")));
@@ -120,6 +122,7 @@ public class ClassicCartDesign extends Design implements CartDesign {
 		}
 	}
 
+	@Override
 	public void save(Element element) {
 		ColorXMLUtils.save(element.addElement("BackgroundColor"), backgroundColor);
 		ColorXMLUtils.save(element.addElement("PlaybackColor"), playbackColor);
@@ -162,6 +165,7 @@ public class ClassicCartDesign extends Design implements CartDesign {
 		return layout;
 	}
 
+	@Override
 	public String convertToCss(String classSufix, boolean fullCss) {
 		StringBuilder builder = new StringBuilder();
 
@@ -210,7 +214,7 @@ public class ClassicCartDesign extends Design implements CartDesign {
 	}
 
 	@Override
-	public void handleWarning(IPadViewController controller, Warning warning, GlobalDesign layout) {
+	public void handleWarning(IPadViewController controller, Duration warning, GlobalDesign layout) {
 		final IPadView view = controller.getView();
 
 		try {
diff --git a/PlayWall/src/de/tobias/playpad/design/classic/ClassicDesignConnect.java b/PlayWall/src/de/tobias/playpad/design/classic/ClassicDesignConnect.java
index d4c0a91cbe2b3566b71d04389a68ad13a0daef45..d551c8a3bf703aaf6657fd60253954cb13765109 100644
--- a/PlayWall/src/de/tobias/playpad/design/classic/ClassicDesignConnect.java
+++ b/PlayWall/src/de/tobias/playpad/design/classic/ClassicDesignConnect.java
@@ -2,8 +2,8 @@ package de.tobias.playpad.design.classic;
 
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.design.CartDesign;
-import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.DesignConnect;
+import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.viewcontroller.CartDesignViewController;
 import de.tobias.playpad.viewcontroller.GlobalDesignViewController;
 import de.tobias.playpad.viewcontroller.design.ClassicCartDesignViewController;
diff --git a/PlayWall/src/de/tobias/playpad/design/classic/ClassicGlobalDesign.java b/PlayWall/src/de/tobias/playpad/design/classic/ClassicGlobalDesign.java
index e317fc50cd6c4398292a962305ef26245ed71344..093b7bfc6a5806792442aa6a7e8f3531021136fc 100644
--- a/PlayWall/src/de/tobias/playpad/design/classic/ClassicGlobalDesign.java
+++ b/PlayWall/src/de/tobias/playpad/design/classic/ClassicGlobalDesign.java
@@ -15,7 +15,6 @@ import de.tobias.playpad.pad.PadSettings;
 import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.project.Project;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
@@ -25,6 +24,7 @@ import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
+import javafx.util.Duration;
 
 public class ClassicGlobalDesign extends Design implements GlobalDesign {
 
@@ -161,6 +161,7 @@ public class ClassicGlobalDesign extends Design implements GlobalDesign {
 		return minWidth;
 	}
 
+	@Override
 	public void reset() {
 		themeProperty = new SimpleObjectProperty<>(Theme.LIGHT);
 		customLayout = false;
@@ -324,12 +325,12 @@ public class ClassicGlobalDesign extends Design implements GlobalDesign {
 		String css = convertToCSS("", isCustomLayout());
 
 		// Pad Spezelles Layout immer
-		for (Pad pad : project.getPads().values()) {
+		for (Pad pad : project.getPads()) {
 			PadSettings padSettings = pad.getPadSettings();
 
 			if (padSettings.isCustomLayout()) {
-				CartDesign layoutOpt = padSettings.getLayout();
-				css += "\n" + layoutOpt.convertToCss(String.valueOf(pad.getIndex()), true);
+				CartDesign layoutOpt = padSettings.getDesign();
+				css += "\n" + layoutOpt.convertToCss(pad.getPadIndex().toString(), true);
 			}
 		}
 
@@ -345,7 +346,7 @@ public class ClassicGlobalDesign extends Design implements GlobalDesign {
 	}
 
 	@Override
-	public void handleWarning(IPadViewController controller, Warning warning) {
+	public void handleWarning(IPadViewController controller, Duration warning) {
 		final IPadView view = controller.getView();
 
 		try {
diff --git a/PlayWall/src/de/tobias/playpad/design/modern/ModernCartDesign.java b/PlayWall/src/de/tobias/playpad/design/modern/ModernCartDesign.java
index 86fde0806c5beead2460a7394eddb8a40ccc9d97..baa4871b6acf78ca50710ae721270965b8c5f5f5 100644
--- a/PlayWall/src/de/tobias/playpad/design/modern/ModernCartDesign.java
+++ b/PlayWall/src/de/tobias/playpad/design/modern/ModernCartDesign.java
@@ -11,11 +11,10 @@ import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
-import de.tobias.playpad.settings.Warning;
 import javafx.scene.paint.Color;
 import javafx.util.Duration;
 
-public class ModernCartDesign extends Design implements CartDesign, DesignColorAssociator {
+public class ModernCartDesign extends Design implements CartDesign, DesignColorAssociator, Cloneable {
 
 	public static final String TYPE = "modern";
 
@@ -41,6 +40,7 @@ public class ModernCartDesign extends Design implements CartDesign, DesignColorA
 		this.playColor = playColor;
 	}
 
+	@Override
 	public void reset() {
 		backgroundColor = ModernColor.GRAY1;
 		playColor = ModernColor.RED1;
@@ -75,7 +75,7 @@ public class ModernCartDesign extends Design implements CartDesign, DesignColorA
 
 	// Warn Handler -> Animation oder Blinken
 	@Override
-	public void handleWarning(IPadViewController controller, Warning warning, GlobalDesign layout) {
+	public void handleWarning(IPadViewController controller, Duration warning, GlobalDesign layout) {
 		if (layout instanceof ModernGlobalDesign && ((ModernGlobalDesign) layout).isWarnAnimation()) {
 			warnAnimation(controller, warning);
 		} else {
@@ -88,21 +88,20 @@ public class ModernCartDesign extends Design implements CartDesign, DesignColorA
 		ModernDesignAnimator.stopAnimation(controller);
 	}
 
-	private void warnAnimation(IPadViewController controller, Warning warning) {
+	private void warnAnimation(IPadViewController controller, Duration warning) {
 		FadeableColor stopColor = new FadeableColor(this.backgroundColor.getColorHi(), this.backgroundColor.getColorLow());
 		FadeableColor playColor = new FadeableColor(this.playColor.getColorHi(), this.playColor.getColorLow());
 
-		Duration warnDuration = warning.getTime();
 		Pad pad = controller.getPad();
 
 		if (pad.getContent() instanceof Durationable) {
 			Duration padDuration = ((Durationable) pad.getContent()).getDuration();
-			if (warnDuration.greaterThan(padDuration)) {
-				warnDuration = padDuration;
+			if (warning.greaterThan(padDuration)) {
+				warning = padDuration;
 			}
 		}
 
-		ModernDesignAnimator.animateWarn(controller, playColor, stopColor, warnDuration);
+		ModernDesignAnimator.animateWarn(controller, playColor, stopColor, warning);
 	}
 
 	// Cart Layout
@@ -166,6 +165,15 @@ public class ModernCartDesign extends Design implements CartDesign, DesignColorA
 		endStyleClass(builder);
 	}
 
+	@Override
+	public void copyGlobalLayout(GlobalDesign globalLayout) {
+		if (globalLayout instanceof ModernGlobalDesign) {
+			ModernGlobalDesign modernLayoutGlobal = (ModernGlobalDesign) globalLayout;
+			backgroundColor = modernLayoutGlobal.getBackgroundColor();
+			playColor = modernLayoutGlobal.getPlayColor();
+		}
+	}
+
 	// Color Associator
 	@Override
 	public Color getAssociatedEventColor() {
@@ -178,11 +186,11 @@ public class ModernCartDesign extends Design implements CartDesign, DesignColorA
 	}
 
 	@Override
-	public void copyGlobalLayout(GlobalDesign globalLayout) {
-		if (globalLayout instanceof ModernGlobalDesign) {
-			ModernGlobalDesign modernLayoutGlobal = (ModernGlobalDesign) globalLayout;
-			backgroundColor = modernLayoutGlobal.getBackgroundColor();
-			playColor = modernLayoutGlobal.getPlayColor();
-		}
+	public Object clone() throws CloneNotSupportedException {
+		ModernCartDesign clone = (ModernCartDesign) super.clone();
+		clone.backgroundColor = backgroundColor;
+		clone.playColor = playColor;
+		return clone;
 	}
+
 }
diff --git a/PlayWall/src/de/tobias/playpad/design/modern/ModernDesignConnect.java b/PlayWall/src/de/tobias/playpad/design/modern/ModernDesignConnect.java
index 4658e1a66596a0a05648a6817a84190f544861fd..f39235706560e340277ec0128e14fdad1a500103 100644
--- a/PlayWall/src/de/tobias/playpad/design/modern/ModernDesignConnect.java
+++ b/PlayWall/src/de/tobias/playpad/design/modern/ModernDesignConnect.java
@@ -2,8 +2,8 @@ package de.tobias.playpad.design.modern;
 
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.design.CartDesign;
-import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.DesignConnect;
+import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.viewcontroller.CartDesignViewController;
 import de.tobias.playpad.viewcontroller.GlobalDesignViewController;
 import de.tobias.playpad.viewcontroller.design.ModernCartDesignViewController;
diff --git a/PlayWall/src/de/tobias/playpad/design/modern/ModernGlobalDesign.java b/PlayWall/src/de/tobias/playpad/design/modern/ModernGlobalDesign.java
index 8a1903ab15afc82900c77eb0bca03a8d6c57f9b3..37ff76e8f621881c49b2d9f28bc06f412ac83e2c 100644
--- a/PlayWall/src/de/tobias/playpad/design/modern/ModernGlobalDesign.java
+++ b/PlayWall/src/de/tobias/playpad/design/modern/ModernGlobalDesign.java
@@ -3,11 +3,14 @@ package de.tobias.playpad.design.modern;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.function.Consumer;
 
 import org.dom4j.Element;
 
+import de.tobias.playpad.DisplayableColor;
 import de.tobias.playpad.PseudoClasses;
 import de.tobias.playpad.design.CartDesign;
+import de.tobias.playpad.design.ColorModeHandler;
 import de.tobias.playpad.design.Design;
 import de.tobias.playpad.design.DesignColorAssociator;
 import de.tobias.playpad.design.FadeableColor;
@@ -18,15 +21,16 @@ import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.Warning;
+import de.tobias.playpad.view.ColorPickerView;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
+import javafx.scene.Node;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
 import javafx.util.Duration;
 
-public class ModernGlobalDesign extends Design implements GlobalDesign, DesignColorAssociator {
+public class ModernGlobalDesign extends Design implements GlobalDesign, DesignColorAssociator, ColorModeHandler {
 
 	public static final String TYPE = "modern";
 
@@ -101,6 +105,7 @@ public class ModernGlobalDesign extends Design implements GlobalDesign, DesignCo
 		return minWidth;
 	}
 
+	@Override
 	public void reset() {
 		backgroundColor = ModernColor.GRAY1;
 		playColor = ModernColor.RED1;
@@ -195,12 +200,12 @@ public class ModernGlobalDesign extends Design implements GlobalDesign, DesignCo
 		String css = convertToCSS();
 
 		// Pad Spezelles Layout immer
-		for (Pad pad : project.getPads().values()) {
+		for (Pad pad : project.getPads()) {
 			PadSettings padSettings = pad.getPadSettings();
 
 			if (padSettings.isCustomLayout()) {
 				CartDesign layoutOpt = padSettings.getLayout(Profile.currentProfile().getProfileSettings().getLayoutType());
-				css += "\n" + layoutOpt.convertToCss(String.valueOf(pad.getIndex()), true);
+				css += "\n" + layoutOpt.convertToCss(pad.getPadIndex().toString(), true);
 			}
 		}
 
@@ -274,7 +279,7 @@ public class ModernGlobalDesign extends Design implements GlobalDesign, DesignCo
 
 	// Warn Handler -> Animation oder Blinken
 	@Override
-	public void handleWarning(IPadViewController controller, Warning warning) {
+	public void handleWarning(IPadViewController controller, Duration warning) {
 		if (isWarnAnimation) {
 			warnAnimation(controller, warning);
 		} else {
@@ -287,20 +292,19 @@ public class ModernGlobalDesign extends Design implements GlobalDesign, DesignCo
 		ModernDesignAnimator.stopAnimation(controller);
 	}
 
-	private void warnAnimation(IPadViewController controller, Warning warning) {
+	private void warnAnimation(IPadViewController controller, Duration warning) {
 		FadeableColor stopColor = new FadeableColor(this.backgroundColor.getColorHi(), this.backgroundColor.getColorLow());
 		FadeableColor playColor = new FadeableColor(this.playColor.getColorHi(), this.playColor.getColorLow());
 
-		Duration warnDuration = warning.getTime();
 		Pad pad = controller.getPad();
 
 		if (pad.getContent() instanceof Durationable) {
-			if (warnDuration.greaterThan(((Durationable) pad.getContent()).getDuration())) {
-				warnDuration = ((Durationable) pad.getContent()).getDuration();
+			if (warning.greaterThan(((Durationable) pad.getContent()).getDuration())) {
+				warning = ((Durationable) pad.getContent()).getDuration();
 			}
 		}
 
-		ModernDesignAnimator.animateWarn(controller, playColor, stopColor, warnDuration);
+		ModernDesignAnimator.animateWarn(controller, playColor, stopColor, warning);
 	}
 
 	// Color Associator
@@ -313,4 +317,17 @@ public class ModernGlobalDesign extends Design implements GlobalDesign, DesignCo
 	public Color getAssociatedStandardColor() {
 		return Color.web(backgroundColor.getColorHi());
 	}
+
+	// Color View
+	@Override
+	public Node getColorInterface(Consumer<DisplayableColor> onSelection) {
+		return new ColorPickerView(null, ModernColor.values(), onSelection);
+	}
+
+	@Override
+	public void setColor(CartDesign design, DisplayableColor color) {
+		if (design instanceof ModernCartDesign && color instanceof ModernColor) {
+			((ModernCartDesign) design).setBackgroundColor((ModernColor) color);
+		}
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2b57535204595628082269752c93692a238b7eb
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopColorPickerView.java
@@ -0,0 +1,80 @@
+package de.tobias.playpad.layout.desktop;
+
+import java.util.function.Consumer;
+
+import org.controlsfx.control.PopOver;
+import org.controlsfx.control.PopOver.ArrowLocation;
+
+import de.tobias.playpad.DisplayableColor;
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.design.CartDesign;
+import de.tobias.playpad.design.ColorModeHandler;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadSettings;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+
+public class DesktopColorPickerView implements Consumer<DisplayableColor>, EventHandler<MouseEvent> {
+
+	private ColorModeHandler colorModeHandler;
+	private DisplayableColor selectedColor;
+
+	private PopOver colorChooser;
+
+	public DesktopColorPickerView(ColorModeHandler colorModeHandler) {
+		this.colorModeHandler = colorModeHandler;
+
+		Node node = colorModeHandler.getColorInterface(this);
+		VBox root = new VBox(node);
+
+		// Init Stage
+		colorChooser = new PopOver();
+		colorChooser.setContentNode(root);
+		colorChooser.setDetachable(false);
+		colorChooser.setCornerRadius(5);
+		colorChooser.setArrowLocation(ArrowLocation.TOP_CENTER);
+	}
+
+	public void show(Node anchorNode) {
+		colorChooser.show(anchorNode);
+	}
+
+	public void hide() {
+		if (colorChooser != null) {
+			colorChooser.hide();
+		}
+	}
+
+	// Handle Selected Color from View.
+	@Override
+	public void accept(DisplayableColor t) {
+		selectedColor = t;
+		colorChooser.hide();
+	}
+
+	// Listener, wenn auf ein Pad Geclicked wurde, zum färben
+	@Override
+	public void handle(MouseEvent event) {
+		// TODO Rewrite this
+		if (event.getSource() instanceof StackPane) {
+			StackPane view = (StackPane) event.getSource();
+			if (view.getUserData() instanceof Pad) {
+				Pad pad = (Pad) view.getUserData();
+				PadSettings padSettings = pad.getPadSettings();
+
+				if (event.getButton() == MouseButton.PRIMARY) {
+					padSettings.setCustomLayout(true);
+					CartDesign design = padSettings.getDesign();
+					colorModeHandler.setColor(design, selectedColor);
+				} else if (event.getButton() == MouseButton.SECONDARY) {
+					padSettings.setCustomLayout(false);
+				}
+				PlayPadMain.getProgramInstance().getMainViewController().loadUserCss();
+			}
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopEditMode.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopEditMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..874ce0c5539b63dc4adab75d150e61e5bb101e19
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopEditMode.java
@@ -0,0 +1,6 @@
+package de.tobias.playpad.layout.desktop;
+
+public enum DesktopEditMode {
+
+	PLAY, DRAG, PAGE, COLOR;
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMainLayoutConnect.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMainLayoutConnect.java
index 9d9b3657b2436e236cf07934870d735adbc84ee4..9accf5d4df1d1b6da6de2812ecc72fa8b5b820c6 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMainLayoutConnect.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMainLayoutConnect.java
@@ -3,11 +3,15 @@ package de.tobias.playpad.layout.desktop;
 import java.util.Stack;
 
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.desktop.pad.DesktopPadView;
 import de.tobias.playpad.pad.view.IPadView;
+import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.view.main.MainLayoutConnect;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.main.MenuToolbarViewController;
 import de.tobias.utils.util.Localization;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
 
 /**
  * Desktop Implmentierung des Main Layouts.
@@ -21,6 +25,7 @@ public class DesktopMainLayoutConnect implements MainLayoutConnect {
 	private static final String TYPE = "Desktop";
 
 	private DesktopMenuToolbarViewController desktopMenuToolbarViewController;
+	private ObjectProperty<DesktopEditMode> editMode = new SimpleObjectProperty<>(DesktopEditMode.PLAY);
 
 	private Stack<IPadView> recyclingStack;
 
@@ -41,7 +46,7 @@ public class DesktopMainLayoutConnect implements MainLayoutConnect {
 	@Override
 	public MenuToolbarViewController createMenuToolbar(IMainViewController mainViewRef) {
 		if (desktopMenuToolbarViewController == null) {
-			desktopMenuToolbarViewController = new DesktopMenuToolbarViewController(mainViewRef);
+			desktopMenuToolbarViewController = new DesktopMenuToolbarViewController(mainViewRef, this);
 		}
 		return desktopMenuToolbarViewController;
 	}
@@ -51,7 +56,7 @@ public class DesktopMainLayoutConnect implements MainLayoutConnect {
 		if (!recyclingStack.isEmpty()) {
 			return recyclingStack.pop();
 		}
-		return new DesktopPadView();
+		return new DesktopPadView(this);
 	}
 
 	@Override
@@ -64,4 +69,18 @@ public class DesktopMainLayoutConnect implements MainLayoutConnect {
 		return null;
 	}
 
+	public DesktopEditMode getEditMode() {
+		return editMode.get();
+	}
+
+	public void setEditMode(DesktopEditMode editMode) {
+		if (editMode != DesktopEditMode.PLAY && Profile.currentProfile().getProfileSettings().isLocked()) {
+			return;
+		}
+		this.editMode.set(editMode);
+	}
+
+	public ObjectProperty<DesktopEditMode> editModeProperty() {
+		return editMode;
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMenuToolbarViewController.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMenuToolbarViewController.java
index 6fe5003cf5241fdb29778da90997145b657d2ab7..e33f2211b23a30989c405b797c0caf5d18942f24 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMenuToolbarViewController.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopMenuToolbarViewController.java
@@ -8,19 +8,24 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import org.controlsfx.control.SegmentedButton;
 import org.controlsfx.control.textfield.TextFields;
 
 import de.tobias.playpad.AppUserInfoStrings;
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.design.ColorModeHandler;
+import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.midi.Midi;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectNotFoundException;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.page.Page;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.registry.Registry;
 import de.tobias.playpad.settings.GlobalSettings;
 import de.tobias.playpad.settings.Profile;
@@ -42,17 +47,20 @@ import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.option.global.GlobalSettingsViewController;
 import de.tobias.playpad.viewcontroller.option.profile.ProfileSettingsViewController;
 import de.tobias.playpad.viewcontroller.option.project.ProjectSettingsViewController;
-import de.tobias.playpad.viewcontroller.pad.PadDragListener;
 import de.tobias.utils.application.ApplicationInfo;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.ui.Alertable;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
 import de.tobias.utils.ui.scene.NotificationPane;
 import de.tobias.utils.util.Localization;
 import de.tobias.utils.util.Worker;
 import de.tobias.utils.util.net.FileUpload;
 import javafx.application.Platform;
 import javafx.beans.binding.Bindings;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.fxml.FXML;
@@ -68,12 +76,18 @@ import javafx.scene.control.MenuBar;
 import javafx.scene.control.MenuItem;
 import javafx.scene.control.Slider;
 import javafx.scene.control.TextField;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.Tooltip;
 import javafx.scene.input.KeyCombination;
+import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.HBox;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 
-public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewController implements EventHandler<ActionEvent> {
+public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewController
+		implements EventHandler<ActionEvent>, ChangeListener<DesktopEditMode> {
+
+	// TODO Page Buttons gleicher Margin wie pads
 
 	// meuBar
 	@FXML protected MenuBar menuBar;
@@ -84,7 +98,11 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 	@FXML protected MenuItem profileMenu;
 	@FXML protected MenuItem printProjectMenuItem;
 
-	@FXML protected CheckMenuItem dndModeMenuItem;
+	@FXML protected MenuItem playMenu;
+	@FXML protected MenuItem dragMenu;
+	@FXML protected MenuItem pageMenu;
+	@FXML protected MenuItem colorMenu;
+
 	@FXML protected MenuItem errorMenu;
 	@FXML protected MenuItem pluginMenu;
 
@@ -104,15 +122,30 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@FXML protected Label liveLabel;
 
+	protected SegmentedButton editButtons;
+	protected ToggleButton playButton;
+	protected ToggleButton dragButton;
+	protected ToggleButton pageButton;
+	protected ToggleButton colorButton;
+	private Button addPageButton;
+
 	private IMainViewController mainViewController;
 
-	private ProjectSettingsViewController projectSettingsViewController;
-	private ProfileSettingsViewController profileSettingsViewController;
-	private GlobalSettingsViewController globalSettingsViewController;
+	private transient ProjectSettingsViewController projectSettingsViewController;
+	private transient ProfileSettingsViewController profileSettingsViewController;
+	private transient GlobalSettingsViewController globalSettingsViewController;
+	private transient DesktopColorPickerView colorPickerView;
 
-	public DesktopMenuToolbarViewController(IMainViewController controller) {
+	private DesktopMainLayoutConnect connect;
+
+	public DesktopMenuToolbarViewController(IMainViewController controller, DesktopMainLayoutConnect connect) {
 		super("header", "de/tobias/playpad/assets/view/main/desktop/", PlayPadMain.getUiResourceBundle());
 		this.mainViewController = controller;
+		this.connect = connect;
+		this.connect.editModeProperty().addListener(this);
+
+		// Ist Zustand herstellen, indem Listener mit dem Initialen Wert bekannt gemacht wird.
+		changed(connect.editModeProperty(), null, connect.getEditMode());
 
 		initLayoutMenu();
 	}
@@ -129,6 +162,112 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		// Help Menu --> HIDDEN TODO
 		helpMenu.setVisible(false);
 		helpMenu.getItems().add(new HelpMenuItem(helpMenu));
+
+		// Edit Mode Buttons
+		editButtons = new SegmentedButton();
+		playButton = new ToggleButton("", new FontIcon(FontAwesomeType.PLAY));
+		playButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_PlayButton)));
+		playButton.setFocusTraversable(false);
+		dragButton = new ToggleButton("", new FontIcon(FontAwesomeType.ARROWS));
+		dragButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_DragButton)));
+		dragButton.setFocusTraversable(false);
+		pageButton = new ToggleButton("", new FontIcon(FontAwesomeType.FILES_ALT));
+		pageButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_PageButton)));
+		pageButton.setFocusTraversable(false);
+		colorButton = new ToggleButton("", new FontIcon(FontAwesomeType.PENCIL));
+		colorButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_ColorButton)));
+		colorButton.setFocusTraversable(false);
+		// Zeigt die Farbauswahl
+		colorButton.setOnAction(e ->
+		{
+			GlobalDesign design = Profile.currentProfile().currentLayout();
+			if (design instanceof ColorModeHandler) {
+				if (colorPickerView == null) {
+					colorPickerView = new DesktopColorPickerView((ColorModeHandler) design);
+
+					// Add Listener for Pads
+					mainViewController.addListenerForPads(colorPickerView, MouseEvent.MOUSE_CLICKED);
+				}
+				colorPickerView.show(colorButton);
+			}
+		});
+		editButtons.getButtons().addAll(playButton, dragButton, pageButton, colorButton);
+		editButtons.getToggleGroup().selectedToggleProperty().addListener((a, b, c) ->
+		{
+			if (c == playButton) {
+				connect.setEditMode(DesktopEditMode.PLAY);
+			} else if (c == dragButton) {
+				connect.setEditMode(DesktopEditMode.DRAG);
+			} else if (c == pageButton) {
+				connect.setEditMode(DesktopEditMode.PAGE);
+			} else if (c == colorButton) {
+				connect.setEditMode(DesktopEditMode.COLOR);
+			} else if (c == null) {
+				// select Old Button, if new selecting is empty
+				editButtons.getToggleGroup().selectToggle(b);
+			}
+		});
+
+		// Add Page Button for Drag Mode (Page Edit Mode)
+		addPageButton = new Button("", new FontIcon(FontAwesomeType.PLUS));
+		addPageButton.setFocusTraversable(false);
+		addPageButton.setOnAction(e ->
+		{
+			if (openProject.addPage()) {
+				// seite konnte hinzugefügt werden
+				initPageButtons();
+				highlightPageButton(mainViewController.getPage());
+			} else {
+				showErrorMessage(Localization.getString(Strings.Error_Project_PageCount), PlayPadMain.stageIcon);
+			}
+		});
+
+		iconHbox.getChildren().add(editButtons);
+	}
+
+	// Desktop Edit Mode Change Listener --> Update Button
+	@Override
+	public void changed(ObservableValue<? extends DesktopEditMode> observable, DesktopEditMode oldValue, DesktopEditMode newValue) {
+		// handle old mode
+		if (oldValue == DesktopEditMode.DRAG) {
+			for (IPadView view : mainViewController.getPadViews()) {
+				view.enableDragAndDropDesignMode(false);
+			}
+		} else if (oldValue == DesktopEditMode.PAGE) {
+			highlightPageButton(currentSelectedPageButton);
+			iconHbox.getChildren().remove(addPageButton);
+		} else if (oldValue == DesktopEditMode.COLOR) {
+			if (colorPickerView != null) {
+				mainViewController.removeListenerForPads(colorPickerView, MouseEvent.MOUSE_CLICKED);
+				colorPickerView.hide();
+				colorPickerView = null;
+			}
+		}
+
+		// handle new mode
+		if (newValue == DesktopEditMode.PLAY) {
+			playButton.setSelected(true);
+		} else if (newValue == DesktopEditMode.DRAG) {
+			// Wenn Live Mode on, dann zum alten Wert zurück
+			GlobalSettings settings = PlayPadPlugin.getImplementation().getGlobalSettings();
+			if (settings.isLiveMode() && settings.isLiveModeDrag() && openProject.getActivePlayers() != 0) {
+				connect.setEditMode(oldValue);
+				return;
+			}
+			// Drag and Drop Aktivieren
+			dragButton.setSelected(true);
+			for (IPadView view : mainViewController.getPadViews()) {
+				view.enableDragAndDropDesignMode(true);
+			}
+		} else if (newValue == DesktopEditMode.PAGE) {
+			pageButton.setSelected(true);
+			iconHbox.getChildren().add(0, addPageButton);
+			highlightPageButton(currentSelectedPageButton);
+		} else if (newValue == DesktopEditMode.COLOR) {
+			colorButton.setSelected(true);
+		}
+
+		mainViewController.getPadViews().forEach(i -> i.getViewController().updateButtonDisable());
 	}
 
 	private void initLayoutMenu() {
@@ -171,14 +310,22 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@Override
 	public void initPageButtons() {
+		currentSelectedPageButton = -1;
 		pageHBox.getChildren().clear();
 
 		if (openProject == null) {
 			return;
 		}
 
-		for (int i = 0; i < openProject.getSettings().getPageCount(); i++) {
-			Button button = new Button(Localization.getString(Strings.UI_Window_Main_PageButton, (i + 1)));
+		for (int i = 0; i < openProject.getPages().size(); i++) {
+			Page page = openProject.getPage(i);
+
+			String name = page.getName();
+			if (name.isEmpty()) {
+				name = Localization.getString(Strings.UI_Window_Main_PageButton, (i + 1));
+			}
+
+			Button button = new Button(name);
 			button.setUserData(i);
 			button.setOnDragOver(new PageButtonDragHandler(mainViewController, i));
 			button.setFocusTraversable(false);
@@ -194,7 +341,11 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		setKeyBindingForMenu(saveProjectMenuItem, keys.getKey("save_proj"));
 		setKeyBindingForMenu(printProjectMenuItem, keys.getKey("print_proj"));
 
-		setKeyBindingForMenu(dndModeMenuItem, keys.getKey("dnd"));
+		setKeyBindingForMenu(playMenu, keys.getKey("play"));
+		setKeyBindingForMenu(dragMenu, keys.getKey("drag"));
+		setKeyBindingForMenu(pageMenu, keys.getKey("page"));
+		setKeyBindingForMenu(colorMenu, keys.getKey("color"));
+
 		setKeyBindingForMenu(errorMenu, keys.getKey("errors"));
 		setKeyBindingForMenu(pluginMenu, keys.getKey("plugins"));
 		setKeyBindingForMenu(projectSettingsMenuItem, keys.getKey("project_settings"));
@@ -210,7 +361,11 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		saveProjectMenuItem.setDisable(false);
 		printProjectMenuItem.setDisable(false);
 
-		dndModeMenuItem.setDisable(false);
+		playMenu.setDisable(false);
+		dragMenu.setDisable(false);
+		pageMenu.setDisable(false);
+		colorMenu.setDisable(false);
+
 		errorMenu.setDisable(false);
 		pluginMenu.setDisable(false);
 		projectSettingsMenuItem.setDisable(false);
@@ -224,7 +379,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@Override
 	public void setLocked(boolean looked) {
-		dndModeMenuItem.setDisable(looked);
+		connect.setEditMode(DesktopEditMode.PLAY);
 	}
 
 	@Override
@@ -267,7 +422,11 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		saveProjectMenuItem.setDisable(true);
 		printProjectMenuItem.setDisable(true);
 
-		dndModeMenuItem.setDisable(true);
+		playMenu.setDisable(true);
+		dragMenu.setDisable(true);
+		pageMenu.setDisable(true);
+		colorMenu.setDisable(true);
+
 		errorMenu.setDisable(true);
 		pluginMenu.setDisable(true);
 		projectSettingsMenuItem.setDisable(true);
@@ -278,13 +437,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		alwaysOnTopItem.setDisable(true);
 		searchPadMenuItem.setDisable(true);
 
-		// Disable Drag Mode wenn aktiv und diese Toolbar deaktiviert wird.
-		if (dndModeMenuItem.isSelected()) {
-			PadDragListener.setDndMode(false);
-			for (IPadView view : mainViewController.getPadViews()) {
-				view.enableDragAndDropDesignMode(false);
-			}
-		}
+		connect.setEditMode(DesktopEditMode.PLAY);
 	}
 
 	@Override
@@ -292,20 +445,30 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		return volumeSlider;
 	}
 
-	private int currentPage = 0;
+	private int currentSelectedPageButton = 0;
 
 	@Override
 	public void highlightPageButton(int index) {
 		if (index >= 0) {
-			if (pageHBox.getChildren().size() > currentPage) {
-				Node removeNode = pageHBox.getChildren().get(currentPage);
+			if (pageHBox.getChildren().size() > currentSelectedPageButton && currentSelectedPageButton >= 0) {
+				Node removeNode = pageHBox.getChildren().get(currentSelectedPageButton);
 				removeNode.getStyleClass().remove(CURRENT_PAGE_BUTTON);
+
+				if (removeNode instanceof Button) {
+					((Button) removeNode).setGraphic(null);
+				}
 			}
 
-			if (pageHBox.getChildren().size() > index) {
+			if (index < pageHBox.getChildren().size()) {
 				Node newNode = pageHBox.getChildren().get(index);
 				newNode.getStyleClass().add(CURRENT_PAGE_BUTTON);
-				currentPage = index;
+				currentSelectedPageButton = index;
+
+				if (newNode instanceof Button && connect.getEditMode() == DesktopEditMode.PAGE) { // Nur bei Drag And Drop mode
+					Button button = (Button) newNode;
+					DesktopPageEditButtonView editBox = new DesktopPageEditButtonView(this, openProject.getPage(index), button);
+					button.setGraphic(editBox);
+				}
 			}
 		}
 	}
@@ -330,9 +493,8 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		doAction(() ->
 		{
 			Stage stage = mainViewController.getStage();
-			Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
 
-			ProjectManagerDialog view = new ProjectManagerDialog(stage, currentProject);
+			ProjectManagerDialog view = new ProjectManagerDialog(stage, openProject);
 			Optional<ProjectReference> result = view.showAndWait();
 
 			if (result.isPresent()) {
@@ -367,10 +529,8 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@FXML
 	void saveMenuHandler(ActionEvent event) {
-		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-
 		try {
-			currentProject.save();
+			openProject.save();
 			mainViewController.notify(Localization.getString(Strings.Standard_File_Save), PlayPadMain.displayTimeMillis);
 		} catch (IOException e) {
 			mainViewController.showError(Localization.getString(Strings.Error_Project_Save));
@@ -382,9 +542,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 	void profileMenuHandler(ActionEvent event) {
 		doAction(() ->
 		{
-			Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-
-			ProfileViewController controller = new ProfileViewController(mainViewController.getStage(), currentProject);
+			ProfileViewController controller = new ProfileViewController(mainViewController.getStage(), openProject);
 			controller.getStage().showAndWait();
 			mainViewController.updateWindowTitle();
 		});
@@ -392,30 +550,28 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@FXML
 	void printMenuHandler(ActionEvent event) {
-		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-		PrintDialog dialog = new PrintDialog(currentProject, mainViewController.getStage());
+		PrintDialog dialog = new PrintDialog(openProject, mainViewController.getStage());
 		dialog.getStage().show();
 	}
 
 	@FXML
-	void dndModeHandler(ActionEvent event) {
-		if (dndModeMenuItem.isSelected()) {
-			GlobalSettings settings = PlayPadPlugin.getImplementation().getGlobalSettings();
-			Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
+	void playMenuHandler(ActionEvent event) {
+		connect.setEditMode(DesktopEditMode.PLAY);
+	}
 
-			if (settings.isLiveMode() && settings.isLiveModeDrag() && currentProject.getActivePlayers() == 0) {
-				PadDragListener.setDndMode(true);
-				for (IPadView view : mainViewController.getPadViews()) {
-					view.enableDragAndDropDesignMode(true);
-				}
-			}
-		} else {
-			PadDragListener.setDndMode(false);
-			for (IPadView view : mainViewController.getPadViews()) {
-				view.enableDragAndDropDesignMode(false);
-			}
-		}
+	@FXML
+	void dragMenuHandler(ActionEvent event) {
+		connect.setEditMode(DesktopEditMode.DRAG);
+	}
+
+	@FXML
+	void pageMenuHandler(ActionEvent event) {
+		connect.setEditMode(DesktopEditMode.PAGE);
+	}
 
+	@FXML
+	void colorMenuHandler(ActionEvent event) {
+		connect.setEditMode(DesktopEditMode.COLOR);
 	}
 
 	@FXML
@@ -434,19 +590,15 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 
 	@FXML
 	void projectSettingsHandler(ActionEvent event) {
-		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-
 		if (projectSettingsViewController == null) {
 			Stage mainStage = mainViewController.getStage();
 
 			Runnable onFinish = () ->
 			{
 				projectSettingsViewController = null;
-				mainStage.toFront();
 			};
 
-			projectSettingsViewController = new ProjectSettingsViewController(mainViewController.getScreen(), mainStage, currentProject,
-					onFinish);
+			projectSettingsViewController = new ProjectSettingsViewController(mainViewController.getScreen(), mainStage, openProject, onFinish);
 
 			projectSettingsViewController.getStage().show();
 		} else if (projectSettingsViewController.getStage().isShowing()) {
@@ -458,9 +610,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 	void profileSettingsHandler(ActionEvent event) {
 		Midi midi = Midi.getInstance();
 		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-
 		GlobalSettings settings = PlayPadPlugin.getImplementation().getGlobalSettings();
-
 		if (settings.isLiveMode() && settings.isLiveModeSettings() && currentProject.getActivePlayers() > 0) {
 			return;
 		}
@@ -476,7 +626,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 				mainStage.toFront();
 			};
 
-			profileSettingsViewController = new ProfileSettingsViewController(midi, mainViewController.getScreen(), mainStage, currentProject,
+			profileSettingsViewController = new ProfileSettingsViewController(midi, mainViewController.getScreen(), mainStage, openProject,
 					onFinish);
 
 			profileSettingsViewController.getStage().show();
@@ -522,7 +672,8 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		field.setPromptText(Localization.getString(Strings.Search_Placeholder));
 
 		Button button = new Button(Localization.getString(Strings.Search_Button));
-		button.setOnAction(new DesktopSearchController(field, this));
+		Project project = PlayPadMain.getProgramInstance().getCurrentProject();
+		button.setOnAction(new DesktopSearchController(project, field, mainViewController));
 
 		HBox box = new HBox(14, field, button);
 		box.setAlignment(Pos.CENTER_LEFT);
@@ -531,8 +682,7 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 		pane.show("", box);
 
 		// Auto Complete
-		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-		Set<String> names = currentProject.getPads().values().stream().filter(p -> p.getStatus() != PadStatus.EMPTY).map(Pad::getName)
+		Set<String> names = openProject.getPads().stream().filter(p -> p.getStatus() != PadStatus.EMPTY).map(Pad::getName)
 				.collect(Collectors.toSet());
 		TextFields.bindAutoCompletion(field, names);
 	}
@@ -585,9 +735,9 @@ public class DesktopMenuToolbarViewController extends BasicMenuToolbarViewContro
 	public void createRecentDocumentMenuItems() {
 		recentOpenMenu.getItems().clear();
 
-		String project = openProject.getRef().getName();
+		String project = openProject.getProjectReference().getName();
 
-		ProjectReference.getProjectsSorted().stream().filter(item -> !item.getName().equals(project)).limit(LAST_DOCUMENT_LIMIT).forEach(item ->
+		ProjectReferences.getProjectsSorted().stream().filter(item -> !item.getName().equals(project)).limit(LAST_DOCUMENT_LIMIT).forEach(item ->
 		{
 			MenuItem menuItem = new MenuItem(item.toString());
 			menuItem.setUserData(item);
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPageEditButtonView.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPageEditButtonView.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a161e2deac46215f00d77108cb223774be0b570
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPageEditButtonView.java
@@ -0,0 +1,169 @@
+package de.tobias.playpad.layout.desktop;
+
+import java.util.Optional;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.Page;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.playpad.viewcontroller.main.MenuToolbarViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.TextInputDialog;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.HBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+public class DesktopPageEditButtonView extends HBox implements EventHandler<ActionEvent> {
+
+	private Page page;
+	private Button leftMoveButton;
+	private Button rightMoveButton;
+	private Button editTextButton;
+	private Button cloneButton;
+	private Button deleteButton;
+
+	private transient Button pageButton;
+	private transient MenuToolbarViewController controller;
+
+	public DesktopPageEditButtonView(MenuToolbarViewController controller, Page page, Button pageButton) {
+		this.page = page;
+		this.pageButton = pageButton;
+		this.controller = controller;
+
+		leftMoveButton = new Button("", new FontIcon(FontAwesomeType.ARROW_LEFT));
+		leftMoveButton.setOnAction(this);
+		leftMoveButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_Page_LeftMove)));
+		leftMoveButton.setFocusTraversable(false);
+
+		rightMoveButton = new Button("", new FontIcon(FontAwesomeType.ARROW_RIGHT));
+		rightMoveButton.setOnAction(this);
+		rightMoveButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_Page_RightMove)));
+		rightMoveButton.setFocusTraversable(false);
+
+		editTextButton = new Button("", new FontIcon(FontAwesomeType.EDIT));
+		editTextButton.setOnAction(this);
+		editTextButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_Page_Rename)));
+		editTextButton.setFocusTraversable(false);
+
+		cloneButton = new Button("", new FontIcon(FontAwesomeType.COPY));
+		cloneButton.setOnAction(this);
+		cloneButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_Page_Clone)));
+		cloneButton.setFocusTraversable(false);
+
+		deleteButton = new Button("", new FontIcon(FontAwesomeType.TRASH));
+		deleteButton.setOnAction(this);
+		deleteButton.setTooltip(new Tooltip(Localization.getString(Strings.Tooltip_Page_Delete)));
+		deleteButton.setFocusTraversable(false);
+
+		getChildren().addAll(leftMoveButton, rightMoveButton, editTextButton, cloneButton, deleteButton);
+		setSpacing(7);
+	}
+
+	@Override
+	public void handle(ActionEvent event) {
+		if (event.getSource() == leftMoveButton) {
+			Project project = page.getProjectReference();
+			if (page.getId() > 0) {
+				Page leftPage = project.getPage(page.getId() - 1);
+
+				int leftIndex = leftPage.getId();
+				int rightIndex = page.getId();
+
+				project.setPage(rightIndex, leftPage);
+				project.setPage(leftIndex, page);
+
+				IMainViewController controller = PlayPadPlugin.getImplementation().getMainViewController();
+				if (controller.getMenuToolbarController() != null)
+					controller.getMenuToolbarController().initPageButtons();
+				controller.showPage(leftIndex);
+			}
+			event.consume();
+		} else if (event.getSource() == rightMoveButton) {
+			Project project = page.getProjectReference();
+			if (page.getId() < project.getPages().size()) {
+				Page rightPage = project.getPage(page.getId() + 1);
+
+				int rightIndex = rightPage.getId();
+				int leftIndex = page.getId();
+
+				project.setPage(leftIndex, rightPage);
+				project.setPage(rightIndex, page);
+
+				IMainViewController controller = PlayPadPlugin.getImplementation().getMainViewController();
+				if (controller.getMenuToolbarController() != null)
+					controller.getMenuToolbarController().initPageButtons();
+				controller.showPage(rightIndex);
+			}
+			event.consume();
+		} else if (event.getSource() == editTextButton) {
+			TextInputDialog dialog = new TextInputDialog();
+
+			dialog.setHeaderText(Localization.getString(Strings.UI_Dialog_Page_Name_Header));
+			dialog.setContentText(Localization.getString(Strings.UI_Dialog_Page_Name_Content));
+			dialog.initOwner(controller.getStage());
+			dialog.initModality(Modality.WINDOW_MODAL);
+			Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
+			PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+			Optional<String> result = dialog.showAndWait();
+
+			result.filter(name -> name != null && !name.isEmpty()).ifPresent(name ->
+			{
+				page.setName(name);
+			});
+
+			// Update Page Button in Toolbar
+			String name = page.getName();
+			if (name.isEmpty())
+				name = Localization.getString(Strings.UI_Window_Main_PageButton, (page.getId() + 1)); // Default Text
+			pageButton.setText(name);
+
+			event.consume();
+		} else if (event.getSource() == cloneButton) {
+			try {
+				Page clone = page.clone();
+				Project project = page.getProjectReference();
+				project.addPage(clone);
+
+				controller.initPageButtons();
+				controller.highlightPageButton(page.getId());
+				event.consume();
+			} catch (CloneNotSupportedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		} else if (event.getSource() == deleteButton) {
+			Alert alert = new Alert(AlertType.CONFIRMATION);
+
+			alert.setHeaderText(Localization.getString(Strings.UI_Dialog_Page_Delete_Header));
+			alert.setContentText(Localization.getString(Strings.UI_Dialog_Page_Delete_Content));
+			alert.initOwner(controller.getStage());
+			alert.initModality(Modality.WINDOW_MODAL);
+			Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
+			PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
+
+			Optional<ButtonType> result = alert.showAndWait();
+			result.filter(r -> r == ButtonType.OK).ifPresent(r ->
+			{
+				Project project = page.getProjectReference();
+				project.removePage(page);
+				PlayPadMain.getProgramInstance().getMainViewController().showPage(0);
+				controller.initPageButtons();
+				controller.highlightPageButton(0); // Show first page
+				event.consume();
+			});
+		}
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopSearchController.java b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopSearchController.java
index ddeb4138d48ceeb95bdbc745018e02049f0884c5..92acef47e403c4ec10f92c03afa0087a9bc3f2c1 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopSearchController.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopSearchController.java
@@ -1,53 +1,66 @@
 package de.tobias.playpad.layout.desktop;
 
+import java.util.List;
+
 import de.tobias.playpad.PlayPadMain;
-import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.project.Project;
-import de.tobias.utils.ui.Alertable;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.utils.util.Localization;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.scene.control.TextField;
 
+// TODO Search Pads
 public class DesktopSearchController implements EventHandler<ActionEvent> {
 
+	private static final int HIGHLIGHT_DURATION = 3;
+
+	private Project currentProject;
+
 	private TextField textField;
-	private Alertable alertable;
+	private IMainViewController mainView;
+
+	public DesktopSearchController(Project project, TextField textField, IMainViewController mainView) {
+		this.currentProject = project;
 
-	public DesktopSearchController(TextField textField, Alertable alertable) {
 		this.textField = textField;
-		this.alertable = alertable;
+		this.mainView = mainView;
 	}
 
+	// Current Search
+	private String lastSearchTerm;
 	private int currentIndex = 0;
+	private List<Pad> searchResult;
 
 	@Override
 	public void handle(ActionEvent event) {
-		if (textField.getText().isEmpty()) {
+		String currentSearchTerm = textField.getText();
+		if (currentSearchTerm.isEmpty()) {
 			return;
 		}
 
-		Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-		main: for (int i = currentIndex; i < currentProject.getPadCount(); i++) {
-			Pad pad = currentProject.getPad(i);
-			if (pad.getStatus() != PadStatus.EMPTY) {
-				if (pad.getName().startsWith(textField.getText())) {
-					while (pad.getController() == null) {
-						if (!PlayPadPlugin.getImplementation().getMainViewController()
-								.showPage(PlayPadPlugin.getImplementation().getMainViewController().getPage() + 1)) {
-							break main;
-						}
-					}
-					pad.getController().getView().highlightView(3);
-					currentIndex = i + 1;
-					return;
-				}
+		// New Search
+		if (!currentSearchTerm.equals(lastSearchTerm)) {
+			this.lastSearchTerm = currentSearchTerm;
+			searchResult = currentProject.findPads(currentSearchTerm);
+			currentIndex = 0;
+		}
+
+		if (searchResult.isEmpty()) {
+			mainView.showInfoMessage(Localization.getString(Strings.Search_Alert_NoMatches), PlayPadMain.stageIcon.orElse(null));
+		}
+
+		if (currentIndex < searchResult.size()) {
+			Pad result = searchResult.get(currentIndex++);
+			mainView.showPage(result.getPage());
+			if (result.getController() != null) {
+				result.getController().getView().highlightView(HIGHLIGHT_DURATION);
 			}
+		} else {
+			mainView.showInfoMessage(Localization.getString(Strings.Search_Alert_NoMatches), PlayPadMain.stageIcon.orElse(null));
+			currentIndex = 0;
 		}
-		alertable.showInfoMessage(Localization.getString(Strings.Search_Alert_NoMatches), PlayPadMain.stageIcon.orElse(null));
-		currentIndex = 0;
 	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/PageButtonDragHandler.java b/PlayWall/src/de/tobias/playpad/layout/desktop/PageButtonDragHandler.java
index 64b67e7204d8d147366d572b64b8d2b2954da50b..5d4e7d37e5e2f0ee01870aaff8cb22a10419a7c0 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/PageButtonDragHandler.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/PageButtonDragHandler.java
@@ -4,6 +4,13 @@ import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import javafx.event.EventHandler;
 import javafx.scene.input.DragEvent;
 
+/**
+ * Drag and Drop eines Pads auf ein Page Button (umschalten auf neue Page), wird im DesktopMenuToolbarController verwaltet.
+ * 
+ * @author tobias
+ * 
+ * @since 5.1.0
+ */
 public class PageButtonDragHandler implements EventHandler<DragEvent> {
 
 	private IMainViewController controller;
@@ -14,6 +21,7 @@ public class PageButtonDragHandler implements EventHandler<DragEvent> {
 		this.page = page;
 	}
 
+	@Override
 	public void handle(DragEvent event) {
 		if (event.getEventType() == DragEvent.DRAG_OVER) {
 			controller.showPage(page);
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadDragListener.java b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadDragListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d5ef535dc72721464a7cc66853ae51c8cfbfd69
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadDragListener.java
@@ -0,0 +1,250 @@
+package de.tobias.playpad.layout.desktop.pad;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.layout.desktop.DesktopEditMode;
+import de.tobias.playpad.layout.desktop.DesktopMainLayoutConnect;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
+import de.tobias.playpad.pad.drag.PadDragMode;
+import de.tobias.playpad.pad.view.IPadView;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
+import de.tobias.playpad.registry.NoSuchComponentException;
+import de.tobias.playpad.settings.GlobalSettings;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.view.FileDragOptionView;
+import de.tobias.playpad.view.PadDragOptionView;
+import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.utils.util.FileUtils;
+import javafx.event.EventHandler;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.image.WritableImage;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DataFormat;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+
+public class DesktopPadDragListener implements EventHandler<DragEvent> {
+
+	private static final String PADINDEX_DATATYPE = "de.tobias.playpad.padindex";
+	private static final DataFormat dataFormat = new DataFormat(PADINDEX_DATATYPE);
+
+	private Pad currentPad;
+	private final Pane padView; // Node der PadView
+
+	private DesktopMainLayoutConnect connect;
+	private static Project project;
+
+	private PadDragOptionView padHud;
+	private FileDragOptionView fileHud;
+
+	public DesktopPadDragListener(Pad currentPad, IPadView view, DesktopMainLayoutConnect connect) {
+		this.currentPad = currentPad;
+		this.connect = connect;
+
+		this.padView = view.getRootNode();
+	}
+
+	public void addListener() {
+		this.padView.setOnDragOver(event -> dragOver(event));
+		this.padView.setOnDragExited(event -> dragExited());
+		this.padView.setOnDragDropped(event -> dragDropped(event));
+		this.padView.setOnDragDetected(event -> dragDetacted(event));
+	}
+
+	public void removeListener() {
+		this.padView.setOnDragOver(null);
+		this.padView.setOnDragExited(null);
+		this.padView.setOnDragDropped(null);
+		this.padView.setOnDragDetected(null);
+	}
+
+	@Override
+	public void handle(DragEvent event) {
+		if (event.getEventType() == DragEvent.DRAG_OVER) {
+			dragOver(event);
+		} else if (event.getEventType() == DragEvent.DRAG_EXITED) {
+			dragExited();
+		} else if (event.getEventType() == DragEvent.DRAG_DROPPED) {
+			dragDropped(event);
+		}
+	}
+
+	private void dragOver(DragEvent event) {
+		if (Profile.currentProfile().getProfileSettings().isLocked()) {
+			return;
+		}
+
+		if (event.getGestureSource() != this && event.getDragboard().hasFiles()) {
+			File file = event.getDragboard().getFiles().get(0);
+			if (file.isFile()) {
+				// Check Live Mode
+				if (checkLiveMode()) {
+					return;
+				}
+
+				// Build In Filesupport
+				try {
+					PadContentRegistry registry = PlayPadPlugin.getRegistryCollection().getPadContents();
+					Set<PadContentConnect> connects = registry.getPadContentConnectsForFile(file.toPath());
+
+					if (!connects.isEmpty()) {
+						if (fileHud == null) {
+							fileHud = new FileDragOptionView(padView);
+						}
+						fileHud.showDropOptions(connects);
+
+						event.acceptTransferModes(TransferMode.LINK);
+						return;
+					}
+				} catch (NoSuchComponentException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		// Drag and Drop von Pads
+		if (event.getDragboard().hasContent(dataFormat)) {
+			PadIndex index = (PadIndex) event.getDragboard().getContent(dataFormat); // TODO Check cast
+			if (!currentPad.getPadIndex().equals(index)) {
+
+				Collection<PadDragMode> connects = PlayPadPlugin.getRegistryCollection().getDragModes().getComponents();
+
+				if (!connects.isEmpty()) {
+					if (padHud == null) {
+						padHud = new PadDragOptionView(padView);
+					}
+					padHud.showDropOptions(connects);
+
+					event.acceptTransferModes(TransferMode.MOVE);
+				}
+			}
+		}
+		event.consume();
+	}
+
+	private void dragExited() {
+		if (padHud != null) {
+			padHud.hide();
+		}
+		if (fileHud != null) {
+			fileHud.hide();
+		}
+	}
+
+	// Drag Content ist los gelassen am Ziel
+	private void dragDropped(DragEvent event) {
+		Dragboard db = event.getDragboard();
+		boolean success = false;
+
+		// File Handling
+		if (db.hasFiles()) {
+			success = true;
+			File file = db.getFiles().get(0);
+
+			PadContentConnect connect = fileHud.getSelectedConnect();
+			if (connect != null) {
+				PadContent content = currentPad.getContent();
+				if (currentPad.getContent() == null || !currentPad.getContent().getType().equals(connect.getType())) {
+					content = connect.newInstance(currentPad);
+				}
+
+				try {
+					content.handlePath(file.toPath());
+				} catch (NoSuchComponentException | IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				this.currentPad.setContent(content);
+				this.currentPad.setName(FileUtils.getFilenameWithoutExtention(file.toPath().getFileName()));
+
+				if (currentPad.getController() != null) {
+					IPadView padView = currentPad.getController().getView();
+					padView.setContentView(currentPad);
+					padView.addDefaultElements(currentPad);
+				}
+			}
+		}
+
+		// Pad DnD
+		if (db.hasContent(dataFormat)) {
+			Object data = db.getContent(dataFormat);
+			if (data instanceof PadIndex) {
+				PadIndex srcIndex = (PadIndex) data;
+				PadIndex newIndex = currentPad.getPadIndex(); // Lister ist auf Ziel Pad, daher ist der Index von currentPad
+
+				System.out.println(newIndex);
+
+				// Drag handle
+				PadDragMode mode = padHud.getSelectedPadDragMode();
+				success = mode.handle(srcIndex, newIndex, project);
+				padHud.hide();
+
+				// Update der Pad Views nach dem DnD
+				IMainViewController mainViewController = PlayPadPlugin.getImplementation().getMainViewController();
+				mainViewController.showPage(mainViewController.getPage());
+
+				// Event Completion
+				event.setDropCompleted(success);
+				event.consume();
+			}
+		}
+	}
+
+	private void dragDetacted(MouseEvent event) {
+		if (connect.getEditMode() == DesktopEditMode.DRAG) {
+			if (checkLiveMode()) {
+				return;
+			}
+
+			Dragboard dragboard = padView.startDragAndDrop(TransferMode.MOVE);
+
+			// Create Snapshot
+			SnapshotParameters parameters = new SnapshotParameters();
+			parameters.setFill(Color.TRANSPARENT);
+			WritableImage snapshot = padView.snapshot(parameters, null);
+			for (int x = 0; x < snapshot.getWidth(); x++) {
+				for (int y = 0; y < snapshot.getHeight(); y++) {
+					Color oldColor = snapshot.getPixelReader().getColor(x, y).darker().darker();
+					Color newColor = new Color(oldColor.getRed(), oldColor.getGreen(), oldColor.getBlue(), oldColor.getOpacity() * 0.5);
+					snapshot.getPixelWriter().setColor(x, y, newColor);
+				}
+			}
+
+			dragboard.setDragView(snapshot);
+
+			ClipboardContent content = new ClipboardContent();
+			content.put(dataFormat, currentPad.getPadIndex());
+			dragboard.setContent(content);
+
+			event.consume();
+		}
+	}
+
+	// Utils
+	private boolean checkLiveMode() {
+		GlobalSettings globalSettings = PlayPadPlugin.getImplementation().getGlobalSettings();
+		if (currentPad.getProject() != null) {
+			if (globalSettings.isLiveMode() && globalSettings.isLiveModeFile() && currentPad.getProject().getActivePlayers() > 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public static void setProject(Project project) {
+		DesktopPadDragListener.project = project;
+	}
+
+}
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadView.java b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java
similarity index 94%
rename from PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadView.java
rename to PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java
index 72d74d982d3b7465e7abe24e6b4c0a58774e56ea..567d497b129d854acc27d35780b9ba17446eeabd 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadView.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadView.java
@@ -1,15 +1,17 @@
-package de.tobias.playpad.layout.desktop;
+package de.tobias.playpad.layout.desktop.pad;
 
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.PseudoClasses;
+import de.tobias.playpad.layout.desktop.DesktopMainLayoutConnect;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadContentRegistry;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.pad.conntent.play.Pauseable;
 import de.tobias.playpad.pad.view.IPadContentView;
 import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.view.EmptyPadView;
 import de.tobias.utils.ui.icon.FontAwesomeType;
@@ -56,9 +58,9 @@ public class DesktopPadView implements IPadView {
 	private BusyView busyView;
 
 	private transient DesktopPadViewController controller; // Reference to its controller
-
-	public DesktopPadView() {
-		controller = new DesktopPadViewController(this);
+	
+	public DesktopPadView(DesktopMainLayoutConnect connect) {
+		controller = new DesktopPadViewController(this, connect);
 		setupView();
 	}
 
@@ -125,6 +127,8 @@ public class DesktopPadView implements IPadView {
 
 	@Override
 	public void setContentView(Pad pad) {
+		superRoot.setUserData(pad);
+		
 		if (previewContent != null) {
 			previewContent.deinit();
 		}
@@ -139,7 +143,7 @@ public class DesktopPadView implements IPadView {
 					previewContent = connect.getPadContentPreview(pad, preview);
 					Node node = previewContent.getNode();
 
-					node.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title");
+					node.getStyleClass().addAll("pad-title", "pad" + pad.getPadIndex() + "-title");
 
 					// Copy Pseudoclasses
 					for (PseudoClass pseudoClass : superRoot.getPseudoClassStates()) {
@@ -156,7 +160,7 @@ public class DesktopPadView implements IPadView {
 		}
 		EmptyPadView view = new EmptyPadView(preview);
 		if (pad != null) {
-			view.getStyleClass().addAll("pad-title", "pad" + pad.getIndex() + "-title");
+			view.getStyleClass().addAll("pad-title", "pad" + pad.getPadIndex() + "-title");
 		} else {
 			view.getStyleClass().addAll("pad-title");
 		}
@@ -269,7 +273,7 @@ public class DesktopPadView implements IPadView {
 	}
 
 	@Override
-	public void addDefaultElement(Pad pad) {
+	public void addDefaultElements(Pad pad) {
 		if (pad != null) {
 			if (pad.getContent() != null) {
 				if (pad.getContent() instanceof Pauseable) {
@@ -301,7 +305,7 @@ public class DesktopPadView implements IPadView {
 	}
 
 	@Override
-	public void applyStyleClasses(int index) {
+	public void applyStyleClasses(PadIndex index) {
 		superRoot.getStyleClass().addAll("pad", "pad" + index);
 
 		indexLabel.getStyleClass().addAll("pad-index", "pad" + index + "-index", "pad-info", "pad" + index + "-info");
@@ -333,7 +337,7 @@ public class DesktopPadView implements IPadView {
 	@Override
 	public void removeStyleClasses() {
 		Pad pad = getViewController().getPad();
-		int index = pad.getIndex();
+		PadIndex index = pad.getPadIndex();
 
 		superRoot.getStyleClass().removeAll("pad", "pad" + index);
 
@@ -383,15 +387,15 @@ public class DesktopPadView implements IPadView {
 		pulseTranslation.play();
 	}
 
-	public void clearIndex() {
+	public void clearIndexLabel() {
 		indexLabel.setText("");
 	}
 
-	public void clearTime() {
+	public void clearTimeLabel() {
 		timeLabel.setText("");
 	}
 
-	public void clearPreviewContent() {
+	public void clearPreviewContentView() {
 		if (previewContent != null) {
 			previewContent.deinit();
 		}
diff --git a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadViewController.java b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java
similarity index 85%
rename from PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadViewController.java
rename to PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java
index 0384a296e54b07d84224036dd1865e53d0717f57..b252d13b36915e32bbb9e4709bdf38fc69e777ce 100644
--- a/PlayWall/src/de/tobias/playpad/layout/desktop/DesktopPadViewController.java
+++ b/PlayWall/src/de/tobias/playpad/layout/desktop/pad/DesktopPadViewController.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.layout.desktop;
+package de.tobias.playpad.layout.desktop.pad;
 
 import java.io.File;
 import java.io.IOException;
@@ -7,12 +7,14 @@ import java.util.Set;
 
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.layout.desktop.DesktopEditMode;
+import de.tobias.playpad.layout.desktop.DesktopMainLayoutConnect;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadContentRegistry;
 import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.pad.TimeMode;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.listener.IPadPositionListener;
 import de.tobias.playpad.pad.listener.PadContentListener;
@@ -29,7 +31,6 @@ import de.tobias.playpad.settings.ProfileSettings;
 import de.tobias.playpad.view.FileDragOptionView;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.option.pad.PadSettingsViewController;
-import de.tobias.playpad.viewcontroller.pad.PadDragListener;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.util.FileUtils;
 import de.tobias.utils.util.Localization;
@@ -44,7 +45,6 @@ import javafx.util.Duration;
 
 public class DesktopPadViewController implements IPadViewController, EventHandler<ActionEvent> {
 
-	protected static final String CURRENT_PAGE_BUTTON = "current-page-button";
 	private static final String OPEN_FOLDER = "openFolder";
 	private static final String DURATION_FORMAT = "%d:%02d";
 
@@ -57,11 +57,16 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 	private PadDurationListener padDurationListener;
 	private IPadPositionListener padPositionListener;
 
-	private PadDragListener padDragListener;
+	private DesktopPadDragListener padDragListener;
 
-	public DesktopPadViewController(DesktopPadView padView) {
+	private static DesktopMainLayoutConnect connect;
+
+	public DesktopPadViewController(DesktopPadView padView, DesktopMainLayoutConnect connect) {
 		this.padView = padView;
 
+		if (DesktopPadViewController.connect != connect) // Set once
+			DesktopPadViewController.connect = connect;
+
 		padLockedListener = new PadLockedListener(this);
 		padStatusListener = new PadStatusListener(this);
 		padContentListener = new PadContentListener(this);
@@ -100,36 +105,36 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 			padContentListener.setPad(pad);
 			padPositionListener.setPad(pad);
 
-			// Pad Content Chnage
+			// Add Listener
 			pad.contentProperty().addListener(padContentListener);
-			// Pad Status Change
 			pad.statusProperty().addListener(padStatusListener);
 
-			// First Listener call with new data
+			// Inital Listener call with new data
 			padContentListener.changed(null, null, pad.getContent()); // Add Duration listener
 			padStatusListener.changed(null, null, pad.getStatus());
 
-			padDragListener = new PadDragListener(pad, padView);
+			// Add Drag and Drop Listener
+			padDragListener = new DesktopPadDragListener(pad, padView, connect);
+			padDragListener.addListener();
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 
-		padView.applyStyleClasses(pad.getIndex());
+		padView.applyStyleClasses(pad.getPadIndex());
 		padView.setContentView(pad);
 	}
 
 	@Override
 	public void removePad() {
 		if (padView != null && pad != null) {
-
-			padView.clearIndex();
-			padView.clearPreviewContent();
-			padView.clearTime();
-
+			// Clear VIew
+			padView.clearIndexLabel();
+			padView.clearPreviewContentView();
+			padView.clearTimeLabel();
 			padView.setTriggerLabelActive(false);
-
 			padView.loopLabelVisibleProperty().unbind();
 
+			// Remove Bindings & Listener
 			pad.contentProperty().removeListener(padContentListener);
 			pad.statusProperty().removeListener(padStatusListener);
 
@@ -139,6 +144,8 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 				durationable.positionProperty().removeListener(padPositionListener);
 			}
 			pad.setController(null);
+
+			padDragListener.removeListener();
 			padDragListener = null;
 
 			// GUI Cleaning
@@ -157,21 +164,23 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 
 	@Override
 	public void handle(ActionEvent event) {
-		if (event.getSource() == padView.getPlayButton()) {
-			onPlay();
-		} else if (event.getSource() == padView.getPauseButton()) {
-			onPause();
-		} else if (event.getSource() == padView.getStopButton()) {
-			onStop();
-		} else if (event.getSource() == padView.getNewButton()) {
-			try {
-				onNew(event);
-			} catch (NoSuchComponentException e) {
-				// TODO Error Handling
-				e.printStackTrace();
+		if (connect.getEditMode() == DesktopEditMode.PLAY) {
+			if (event.getSource() == padView.getPlayButton()) {
+				onPlay();
+			} else if (event.getSource() == padView.getPauseButton()) {
+				onPause();
+			} else if (event.getSource() == padView.getStopButton()) {
+				onStop();
+			} else if (event.getSource() == padView.getNewButton()) {
+				try {
+					onNew(event);
+				} catch (NoSuchComponentException e) {
+					// TODO Error Handling
+					e.printStackTrace();
+				}
+			} else if (event.getSource() == padView.getSettingsButton()) {
+				onSettings();
 			}
-		} else if (event.getSource() == padView.getSettingsButton()) {
-			onSettings();
 		}
 	}
 
@@ -269,7 +278,7 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 			}
 
 			Stage owner = mvc.getStage();
-			
+
 			PadSettingsViewController padSettingsViewController = new PadSettingsViewController(pad, owner);
 			padSettingsViewController.getStage().setOnHiding(ev ->
 			{
@@ -377,10 +386,20 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 			padView.getSettingsButton().setDisable(false);
 		}
 
+		// Disable Settings and New wenn Locked
 		if (Profile.currentProfile().getProfileSettings().isLocked()) {
 			padView.getNewButton().setDisable(true);
 			padView.getSettingsButton().setDisable(true);
 		}
+		
+		// Alles Desktivieren, wenn nicht Play Mode
+		if (connect.getEditMode() != DesktopEditMode.PLAY) {
+			padView.getPlayButton().setDisable(true);
+			padView.getPauseButton().setDisable(true);
+			padView.getStopButton().setDisable(true);
+			padView.getNewButton().setDisable(true);
+			padView.getSettingsButton().setDisable(true);
+		}
 	}
 
 	@Override
@@ -393,7 +412,7 @@ public class DesktopPadViewController implements IPadViewController, EventHandle
 		return padDurationListener;
 	}
 
-	public PadDragListener getPadDragListener() {
+	public DesktopPadDragListener getPadDragListener() {
 		return padDragListener;
 	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java b/PlayWall/src/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java
index 347361cd08b6c8ebde4b661e2259f438e71df8fe..1c239edc95aeb74d17ddf47cce72a9869293cb1c 100644
--- a/PlayWall/src/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java
+++ b/PlayWall/src/de/tobias/playpad/layout/touch/TouchMenuToolbarViewController.java
@@ -4,6 +4,7 @@ import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.Page;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.keys.KeyCollection;
 import de.tobias.playpad.view.main.MainLayoutConnect;
@@ -50,8 +51,14 @@ public class TouchMenuToolbarViewController extends BasicMenuToolbarViewControll
 			return;
 		}
 
-		for (int i = 0; i < openProject.getSettings().getPageCount(); i++) {
-			Button button = new Button(Localization.getString(Strings.UI_Window_Main_PageButton, (i + 1)));
+		for (int i = 0; i < openProject.getPages().size(); i++) {
+			Page page = openProject.getPage(i);
+			String name = page.getName(); 
+			if (name.isEmpty()) {
+				name = Localization.getString(Strings.UI_Window_Main_PageButton, (i + 1));
+			}
+			
+			Button button = new Button(name);
 			button.setUserData(i);
 			button.setFocusTraversable(false);
 			button.setOnAction(this);
diff --git a/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadView.java b/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadView.java
index 8d68d5e6a08f27cc473292cf326b645f3d36c1ef..02c20f1a2be7cc5543b867a0e599c5af88cdf074 100644
--- a/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadView.java
+++ b/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadView.java
@@ -1,6 +1,5 @@
 package de.tobias.playpad.layout.touch;
 
-import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.PseudoClasses;
 import de.tobias.playpad.pad.Pad;
@@ -9,6 +8,7 @@ import de.tobias.playpad.pad.conntent.PadContentConnect;
 import de.tobias.playpad.pad.view.IPadContentView;
 import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.view.EmptyPadView;
 import de.tobias.utils.ui.icon.FontAwesomeType;
@@ -220,7 +220,7 @@ public class TouchPadView implements IPadView {
 	}
 
 	@Override
-	public void addDefaultElement(Pad pad) {
+	public void addDefaultElements(Pad pad) {
 		infoBox.getChildren().setAll(indexLabel, loopLabel, triggerLabel, errorLabel, timeLabel);
 
 		// alle Labels in der InfoBox sollen die gleiche Höhe haben, damit die Icons auf gleicher höhe sind
@@ -232,7 +232,7 @@ public class TouchPadView implements IPadView {
 	}
 
 	@Override
-	public void applyStyleClasses(int index) {
+	public void applyStyleClasses(PadIndex index) {
 		superRoot.getStyleClass().addAll("pad", "pad" + index);
 
 		indexLabel.getStyleClass().addAll("pad-index", "pad" + index + "-index", "pad-info", "pad" + index + "-info");
@@ -251,7 +251,7 @@ public class TouchPadView implements IPadView {
 	@Override
 	public void removeStyleClasses() {
 		Pad pad = getViewController().getPad();
-		int index = pad.getIndex();
+		PadIndex index = pad.getPadIndex();
 
 		superRoot.getStyleClass().removeAll("pad", "pad" + index);
 
diff --git a/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadViewController.java b/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadViewController.java
index 11ef9044b35d086c2f6dbcce2d21a24b8714d7e4..eb3df64993ddcc97eb98238f148c6be79e08283e 100644
--- a/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadViewController.java
+++ b/PlayWall/src/de/tobias/playpad/layout/touch/TouchPadViewController.java
@@ -14,7 +14,6 @@ import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileSettings;
-import de.tobias.playpad.viewcontroller.pad.PadDragListener;
 import javafx.beans.value.ChangeListener;
 import javafx.event.Event;
 import javafx.event.EventHandler;
@@ -37,8 +36,6 @@ public class TouchPadViewController implements IPadViewController, EventHandler<
 	private PadDurationListener padDurationListener;
 	private IPadPositionListener padPositionListener;
 
-	private PadDragListener padDragListener;
-
 	public TouchPadViewController(TouchPadView padView) {
 		this.padView = padView;
 
@@ -87,17 +84,13 @@ public class TouchPadViewController implements IPadViewController, EventHandler<
 			pad.statusProperty().addListener(padStatusListener);
 
 			// First Listener call with new data
-			padContentListener.changed(null, null, pad.getContent()); // Add
-																		// Duration
-																		// listener
+			padContentListener.changed(null, null, pad.getContent()); // Add Duration listener
 			padStatusListener.changed(null, null, pad.getStatus());
-
-			padDragListener = new PadDragListener(pad, padView);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 
-		padView.applyStyleClasses(pad.getIndex());
+		padView.applyStyleClasses(pad.getPadIndex());
 		padView.setContentView(pad);
 	}
 
@@ -122,14 +115,12 @@ public class TouchPadViewController implements IPadViewController, EventHandler<
 				durationable.positionProperty().removeListener(padPositionListener);
 			}
 			pad.setController(null);
-			padDragListener = null;
 
 			// GUI Cleaning
 			padPositionListener.stopWaning();
 			padView.removeStyleClasses();
 		}
 
-		this.padDragListener = null;
 		this.pad = null;
 	}
 
@@ -232,8 +223,4 @@ public class TouchPadViewController implements IPadViewController, EventHandler<
 	public ChangeListener<Duration> getPadDurationListener() {
 		return padDurationListener;
 	}
-
-	public PadDragListener getPadDragListener() {
-		return padDragListener;
-	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/midi/device/PD12.java b/PlayWall/src/de/tobias/playpad/midi/device/PD12.java
index df4ceb01d9a4883b17752afdbab848abdae5c03d..40c050e4f26906dac9be42609b06c028bc418835 100644
--- a/PlayWall/src/de/tobias/playpad/midi/device/PD12.java
+++ b/PlayWall/src/de/tobias/playpad/midi/device/PD12.java
@@ -43,7 +43,7 @@ public class PD12 extends Device {
 	public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) {}
 
 	@Override
-	public void initFeedback() {}
+	public void initDevice() {}
 
 	@Override
 	public void clearFeedback() {}
diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java
index 2d9b220013ad986e4502722119ec04c91fe980fb..d7a07ac1327d20eafe34c6e920b3a07fe73bd053 100644
--- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java
+++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java
@@ -1,6 +1,5 @@
 package de.tobias.playpad.pad.content;
 
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -12,18 +11,18 @@ import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.audio.AudioHandler;
 import de.tobias.playpad.audio.AudioRegistry;
 import de.tobias.playpad.audio.Equalizable;
+import de.tobias.playpad.audio.fade.Fading;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadSettings;
 import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.path.SinglePathContent;
 import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.conntent.play.Fadeable;
+import de.tobias.playpad.pad.conntent.play.IVolume;
 import de.tobias.playpad.pad.conntent.play.Pauseable;
 import de.tobias.playpad.project.ProjectExporter;
 import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileSettings;
+import de.tobias.playpad.volume.VolumeManager;
 import de.tobias.utils.util.ZipFile;
 import javafx.animation.Transition;
 import javafx.application.Platform;
@@ -34,7 +33,7 @@ import javafx.beans.value.ChangeListener;
 import javafx.scene.media.AudioEqualizer;
 import javafx.util.Duration;
 
-public class AudioContent extends PadContent implements Pauseable, Durationable, Fadeable, Equalizable, SinglePathContent {
+public class AudioContent extends PadContent implements Pauseable, Durationable, Fadeable, Equalizable, SinglePathContent, IVolume {
 
 	private static final String TYPE = "audio";
 
@@ -45,22 +44,15 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 	private ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>();
 
 	private ChangeListener<Number> volumeListener;
-	private ChangeListener<Number> customVolumeListener;
+
+	private Fading fading;
 
 	private transient Transition transition;
 
 	public AudioContent(Pad pad) {
 		super(pad);
-		volumeListener = (a, b, c) ->
-		{
-			ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
-			audioHandler.setVolume(c.doubleValue(), profileSettings.getVolume(), pad.getCustomVolume());
-		};
-		customVolumeListener = (a, b, c) ->
-		{
-			ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
-			audioHandler.setVolume(pad.getPadSettings().getVolume(), profileSettings.getVolume(), c.doubleValue());
-		};
+		// Pad Volume Listener
+		volumeListener = (a, b, c) -> updateVolume();
 	}
 
 	@Override
@@ -80,10 +72,9 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 	}
 
 	@Override
-	public void setMasterVolume(double masterVolume) {
-		if (audioHandler != null) {
-			audioHandler.setVolume(getPad().getPadSettings().getVolume(), masterVolume, getPad().getCustomVolume());
-		}
+	public void updateVolume() {
+		double volume = Pad.getVolumeManager().computeVolume(getPad());
+		audioHandler.setVolume(volume);
 	}
 
 	@Override
@@ -93,7 +84,6 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 
 	@Override
 	public void play() {
-		getPad().setCustomVolume(1);
 		getPad().setEof(false);
 		audioHandler.play();
 	}
@@ -111,31 +101,10 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 
 	@Override
 	public void fadeIn() {
-		if (transition != null) {
-			transition.stop();
-		}
-
 		Pad pad = getPad();
 
 		if (pad.getPadSettings().getFade().getFadeIn().toMillis() > 0) {
-			double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
-			audioHandler.setVolume(0, masterVolume, pad.getCustomVolume());
-			transition = new Transition() {
-
-				{
-					setCycleDuration(pad.getPadSettings().getFade().getFadeIn());
-				}
-
-				@Override
-				protected void interpolate(double frac) {
-					audioHandler.setVolume(frac * pad.getPadSettings().getVolume(), masterVolume, pad.getCustomVolume());
-				}
-			};
-			transition.setOnFinished(e ->
-			{
-				transition = null;
-			});
-			transition.play();
+			fading.fadeIn(pad.getPadSettings().getFade().getFadeIn());
 		}
 	}
 
@@ -146,31 +115,11 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 		}
 
 		if (getPad().getPadSettings().getFade().getFadeOut().toMillis() > 0) {
-			transition = new Transition() {
-
-				{
-					setCycleDuration(getPad().getPadSettings().getFade().getFadeOut());
-				}
-
-				@Override
-				protected void interpolate(double frac) {
-					double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
-					PadSettings padSettings = getPad().getPadSettings();
-
-					audioHandler.setVolume(padSettings.getVolume() - frac * padSettings.getVolume(), masterVolume, getPad().getCustomVolume());
-				}
-			};
-			transition.setOnFinished(event ->
+			fading.fadeOut(getPad().getPadSettings().getFade().getFadeOut(), () ->
 			{
 				onFinish.run();
-
-				double masterVolume = Profile.currentProfile().getProfileSettings().getVolume();
-				PadSettings padSettings = getPad().getPadSettings();
-
-				audioHandler.setVolume(padSettings.getVolume(), masterVolume, getPad().getCustomVolume());
-				transition = null;
+				updateVolume();
 			});
-			transition.play();
 		} else {
 			onFinish.run();
 		}
@@ -184,6 +133,14 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 		return false;
 	}
 
+	@Override
+	public void setFadeLevel(double level) {
+		Pad pad = getPad();
+		VolumeManager manager = Pad.getVolumeManager();
+
+		audioHandler.setVolume(level * manager.computeVolume(pad));
+	}
+
 	@Override
 	public AudioEqualizer getAudioEqualizer() {
 		if (audioHandler instanceof Equalizable) {
@@ -223,6 +180,8 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 		AudioRegistry audioRegistry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
 		audioHandler = audioRegistry.getCurrentAudioHandler().createAudioHandler(this);
 
+		fading = new Fading(this);
+
 		if (Files.exists(path)) {
 			audioHandler.loadMedia(new Path[] { path });
 
@@ -230,24 +189,25 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 			positionProperty.bind(audioHandler.positionProperty());
 
 			getPad().getPadSettings().volumeProperty().addListener(volumeListener);
-			getPad().customVolumeProperty().addListener(customVolumeListener);
 		} else {
-			getPad().throwException(path, new FileNotFoundException());
+			// getPad().throwException(path, new FileNotFoundException()); TODO Error Handling User
 		}
 	}
 
 	@Override
 	public void unloadMedia() {
+		// First Stop the pad (if playing)
+		getPad().setStatus(PadStatus.STOP);
+
 		durationProperty.unbind();
 		positionProperty.unbind();
 
 		getPad().getPadSettings().volumeProperty().removeListener(volumeListener);
-		getPad().customVolumeProperty().removeListener(customVolumeListener);
 
 		if (audioHandler != null)
 			audioHandler.unloadMedia();
 
-		Platform.runLater(() ->
+		Platform.runLater(() -> // TODO Platform.runLater ?
 		{
 			if (getPad() != null) {
 				getPad().setStatus(PadStatus.EMPTY);
@@ -299,4 +259,18 @@ public class AudioContent extends PadContent implements Pauseable, Durationable,
 		}
 	}
 
+	@Override
+	public PadContent clone() throws CloneNotSupportedException {
+		AudioContent clone = (AudioContent) super.clone();
+		clone.path = Paths.get(path.toUri());
+
+		AudioRegistry audioRegistry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
+		clone.audioHandler = audioRegistry.getCurrentAudioHandler().createAudioHandler(this);
+
+		clone.durationProperty = new SimpleObjectProperty<>();
+		clone.positionProperty = new SimpleObjectProperty<>();
+
+		clone.loadMedia();
+		return clone;
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java
index 538d4d411600c0e4dc39c80441242c6ed4bb0b2c..f0eb579ddee579440e26edd3561596dc1cd2b48d 100644
--- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java
+++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java
@@ -70,7 +70,7 @@ public class AudioContentConnect extends PadContentConnect {
 		public AudioContentView(Pad pad, Pane parentNode) {
 			nameLabel = new Label();
 			nameLabel.textProperty().bind(pad.nameProperty());
-			
+
 			nameLabel.setWrapText(true);
 			nameLabel.setAlignment(Pos.CENTER);
 			nameLabel.setTextAlignment(TextAlignment.CENTER);
@@ -86,7 +86,7 @@ public class AudioContentConnect extends PadContentConnect {
 		}
 
 		@Override
-		public void unconnect() {
+		public void deinit() {
 			nameLabel.textProperty().unbind();
 		}
 	}
diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/DuplicateDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/DuplicateDragMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1101315aa0e6d187444a8fe6923f5aeb0887b55
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/pad/drag/DuplicateDragMode.java
@@ -0,0 +1,60 @@
+package de.tobias.playpad.pad.drag;
+
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.Localization;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.scene.Node;
+
+public class DuplicateDragMode extends PadDragMode {
+
+	private static final String TYPE = "duplicate";
+
+	private FontIcon icon;
+	private StringProperty displayProperty;
+
+	public DuplicateDragMode() {
+		icon = new FontIcon(FontAwesomeType.COPY);
+		icon.setSize(30);
+
+		displayProperty = new SimpleStringProperty(Localization.getString(Strings.DnDMode_Duplicate));
+	}
+
+	@Override
+	public StringProperty displayProperty() {
+		return displayProperty;
+	}
+
+	@Override
+	public Node getGraphics() {
+		return icon;
+	}
+
+	@Override
+	public String getType() {
+		return TYPE;
+	}
+
+	@Override
+	public boolean handle(PadIndex oldIndex, PadIndex newIndex, Project project) {
+		Pad oldPad = project.getPad(oldIndex);
+		try {
+			Pad copyPad = oldPad.clone();
+
+			// Alte Pads entfernen, damit keine Nebenabhängigkeiten entstehen in den verschiedenen Seiten
+			project.setPad(newIndex, null);
+
+			// Neue Pads in die Seiten einfügen
+			project.setPad(newIndex, copyPad);
+			return true;
+		} catch (CloneNotSupportedException e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java
index 16a3526c19e4f374654150a47327d6f7be972f9b..dfa1923a5e1d6c93f02c6f73553d1f1e46a95123 100644
--- a/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java
+++ b/PlayWall/src/de/tobias/playpad/pad/drag/MoveDragMode.java
@@ -3,6 +3,7 @@ package de.tobias.playpad.pad.drag;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
 import de.tobias.utils.util.Localization;
@@ -40,12 +41,18 @@ public class MoveDragMode extends PadDragMode {
 	}
 
 	@Override
-	public void handle(int oldIndex, int newIndex, Project project) {
+	public boolean handle(PadIndex oldIndex, PadIndex newIndex, Project project) {
 		Pad oldPad = project.getPad(oldIndex);
 		Pad newPad = project.getPad(newIndex);
 
-		project.setPad(newIndex, oldPad);
+		// Alte Pads entfernen, damit keine Nebenabhängigkeiten entstehen in den verschiedenen Seiten
+		project.setPad(oldIndex, null);
+		project.setPad(newIndex, null);
+
+		// Neue Pads in die Seiten einfügen
 		project.setPad(oldIndex, newPad);
+		project.setPad(newIndex, oldPad);
+		return true;
 	}
 
 }
diff --git a/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java
index 0e48d10e02295c9bc053efd83d7ec5bf19383967..e1c67a5dc91ac27fcbafdc08e7d06b3eb8ae6454 100644
--- a/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java
+++ b/PlayWall/src/de/tobias/playpad/pad/drag/ReplaceDragMode.java
@@ -3,6 +3,7 @@ package de.tobias.playpad.pad.drag;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
 import de.tobias.utils.util.Localization;
@@ -40,11 +41,15 @@ public class ReplaceDragMode extends PadDragMode {
 	}
 
 	@Override
-	public void handle(int oldPad, int newPad, Project project) {
+	public boolean handle(PadIndex oldPad, PadIndex newPad, Project project) {
 		Pad srcPad = project.getPad(oldPad);
 
+		// Alte Pads entfernen, damit keine Nebenabhängigkeiten entstehen in den verschiedenen Seiten
+		project.setPad(oldPad, null);
+		project.setPad(newPad, null);
+
 		project.setPad(newPad, srcPad);
-		project.setPad(oldPad, new Pad(project, oldPad));
+		return true;
 	}
 
 }
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java
index b27598ecfbac618ab3cce68b8a5172f19ac07f61..d974f109d6562289133c8a195079f7e378318d24 100644
--- a/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadContentListener.java
@@ -24,7 +24,7 @@ public class PadContentListener implements ChangeListener<PadContent> {
 	public void changed(ObservableValue<? extends PadContent> observable, PadContent oldValue, PadContent newValue) {
 		// wenn Content change, update preview & buttons
 		controller.getView().setContentView(pad);
-		controller.getView().addDefaultElement(pad);
+		controller.getView().addDefaultElements(pad);
 
 		controller.updateButtonDisable();
 		controller.updateTimeLabel();
diff --git a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java
index f1ddd7d222840089fb73f7f63bbf8a69f6e783e2..0bc0126ec95f77ab1cff8dd8c2800574ad1a3e59 100644
--- a/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java
+++ b/PlayWall/src/de/tobias/playpad/pad/listener/PadPositionListener.java
@@ -8,7 +8,6 @@ import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.conntent.play.Fadeable;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.Warning;
 import javafx.beans.value.ObservableValue;
 import javafx.util.Duration;
 
@@ -66,11 +65,11 @@ public class PadPositionListener implements Runnable, IPadPositionListener {
 		// wird
 		if (!pad.getPadSettings().isLoop() && pad.getStatus() == PadStatus.PLAY) {
 			// Warning
-			Warning warning = pad.getPadSettings().getWarning();
+			Duration warning = pad.getPadSettings().getWarning();
 			Duration rest = durationable.getDuration().subtract(newValue);
 			double seconds = rest.toSeconds();
 
-			if (warning.getTime().toSeconds() > seconds && !send) {
+			if (warning.toSeconds() > seconds && !send) {
 				startWarningThread();
 				send = true;
 			}
@@ -88,10 +87,10 @@ public class PadPositionListener implements Runnable, IPadPositionListener {
 	@Override
 	public void run() {
 		PadSettings padSettings = pad.getPadSettings();
-		Warning warning = padSettings.getWarning();
+		Duration warning = padSettings.getWarning();
 
 		if (padSettings.isCustomLayout()) {
-			padSettings.getLayout().handleWarning(controller, warning, Profile.currentProfile().currentLayout());
+			padSettings.getDesign().handleWarning(controller, warning, Profile.currentProfile().currentLayout());
 		} else {
 			Profile.currentProfile().currentLayout().handleWarning(controller, warning);
 		}
@@ -115,7 +114,7 @@ public class PadPositionListener implements Runnable, IPadPositionListener {
 		PadSettings padSettings = pad.getPadSettings();
 
 		if (padSettings.isCustomLayout()) {
-			padSettings.getLayout().stopWarning(controller);
+			padSettings.getDesign().stopWarning(controller);
 		} else {
 			Profile.currentProfile().currentLayout().stopWarning(controller);
 		}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java
index b7e056734a4a0985f231369a7ec3e77018f886b4..631f2e8f1aa5a5921c09ad4d646dd84460cc13d4 100644
--- a/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java
+++ b/PlayWall/src/de/tobias/playpad/trigger/CartTriggerItem.java
@@ -2,6 +2,7 @@ package de.tobias.playpad.trigger;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 
 import org.dom4j.Element;
 
@@ -14,19 +15,19 @@ import de.tobias.playpad.viewcontroller.main.IMainViewController;
 
 public class CartTriggerItem extends TriggerItem {
 
-	private List<Integer> carts;
+	private List<UUID> uuids;
 	private boolean allCarts;
 	private PadStatus newStatus; // Only Play, Pause, Stop
 
 	public CartTriggerItem() {
 		newStatus = PadStatus.PLAY;
 		allCarts = false;
-		carts = new ArrayList<Integer>() {
+		uuids = new ArrayList<UUID>() {
 
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			public boolean add(Integer e) {
+			public boolean add(UUID e) {
 				if (!contains(e))
 					return super.add(e);
 				else
@@ -35,8 +36,8 @@ public class CartTriggerItem extends TriggerItem {
 		};
 	}
 
-	public List<Integer> getCarts() {
-		return carts;
+	public List<UUID> getCarts() {
+		return uuids;
 	}
 
 	public boolean isAllCarts() {
@@ -62,16 +63,22 @@ public class CartTriggerItem extends TriggerItem {
 	}
 
 	@Override
-	public void performAction(Pad pad, Project project, IMainViewController controller, Profile profile) {
+	public void performAction(Pad source, Project project, IMainViewController controller, Profile profile) {
 		if (allCarts) {
-			for (Pad cart : project.getPads().values()) {
-				if (cart.getIndex() != pad.getIndex())
+			for (Pad cart : project.getPads()) {
+				if (cart.getUuid().equals(source.getUuid()))
 					cart.setStatus(newStatus);
 			}
 		} else {
-			for (int cart : carts) {
-				if (cart != pad.getIndex())
-					project.getPad(cart).setStatus(newStatus);
+			System.out.println(uuids);
+			// TODO Cart Trigger mit Pages und Index --> PadIndex
+			for (UUID uuid : uuids) {
+				if (!uuid.equals(source.getUuid())) {
+					Pad pad = project.getPad(uuid);
+					System.out.println(pad);
+					if (pad != null)
+						pad.setStatus(newStatus);
+				}
 			}
 		}
 	}
@@ -92,7 +99,7 @@ public class CartTriggerItem extends TriggerItem {
 		for (Object cartObj : element.elements(CART_ELEMENT)) {
 			if (cartObj instanceof Element) {
 				Element cartElement = (Element) cartObj;
-				carts.add(Integer.valueOf(cartElement.getStringValue()));
+				uuids.add(UUID.fromString(cartElement.getStringValue()));
 			}
 		}
 	}
@@ -104,64 +111,9 @@ public class CartTriggerItem extends TriggerItem {
 		element.addAttribute(STATUS_ATTR, newStatus.name());
 		element.addAttribute(ALLCARTS_ATTR, String.valueOf(allCarts));
 
-		for (int cart : carts) {
+		for (UUID cart : uuids) {
 			Element cartElement = element.addElement(CART_ELEMENT);
 			cartElement.addText(String.valueOf(cart));
 		}
 	}
-
-	public void setCartsString(String string) {
-		if (string != null) {
-			carts.clear();
-			string = string.replace(" ", "");
-			for (String part : string.split(",")) {
-				if (part.contains("-")) {
-					if (part.split("-").length == 2) {
-						int start = Integer.valueOf(part.split("-")[0]);
-						int end = Integer.valueOf(part.split("-")[1]);
-
-						for (int i = start; i <= end; i++) {
-							carts.add(i - 1);
-						}
-					}
-				} else {
-					int cart = Integer.valueOf(part);
-					carts.add(cart - 1);
-				}
-			}
-			carts.sort(Integer::compareTo);
-		}
-	}
-
-	public String getCartsString() {
-		String string = "";
-		int startValue = -1;
-
-		for (int i = 0; i < carts.size(); i++) {
-			if (i + 1 < carts.size()) {
-				if (carts.get(i) + 1 == carts.get(i + 1)) {
-					if (startValue == -1) {
-						startValue = carts.get(i);
-					}
-				} else {
-					if (startValue != -1)
-						string += (startValue + 1) + "-" + (carts.get(i) + 1) + ",";
-					else
-						string += (carts.get(i) + 1) + ",";
-					startValue = -1;
-
-				}
-			} else {
-				if (startValue == -1) {
-					string += (carts.get(i) + 1) + ",";
-				} else {
-					string += (startValue + 1) + "-" + (carts.get(i) + 1) + ",";
-				}
-			}
-		}
-		if (string.isEmpty()) {
-			return null;
-		}
-		return string.substring(0, string.length() - 1);
-	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java b/PlayWall/src/de/tobias/playpad/trigger/TriggerDisplayable.java
similarity index 91%
rename from PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java
rename to PlayWall/src/de/tobias/playpad/trigger/TriggerDisplayable.java
index edd8e29b8be0b2496e93d7e469be775993c4161c..f385b88833e9613e810363b10a3084faaec99c83 100644
--- a/PlayWall/src/de/tobias/playpad/trigger/TriggerUIWrapper.java
+++ b/PlayWall/src/de/tobias/playpad/trigger/TriggerDisplayable.java
@@ -8,11 +8,11 @@ import de.tobias.utils.util.Localization;
 import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
 
-public class TriggerUIWrapper implements Displayable {
+public class TriggerDisplayable implements Displayable {
 
 	private Trigger trigger;
 
-	public TriggerUIWrapper(Trigger trigger) {
+	public TriggerDisplayable(Trigger trigger) {
 		this.trigger = trigger;
 		updateString();
 	}
diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java
index c9a6ce6b351d09cb7ddc1160ecf40b8d3350768d..282bb4cedb75c979f4f2dbb166ec0f6b698e0048 100644
--- a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java
+++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java
@@ -54,13 +54,14 @@ public class VolumeTriggerItem extends TriggerItem {
 
 			@Override
 			protected void interpolate(double frac) {
-				for (Pad p : project.getPads().values()) {
+				for (Pad p : project.getPads()) {
 					if (p.getIndex() != pad.getIndex()) {
-						if (p.getCustomVolume() > volume) {
-							p.setCustomVolume(currentValue - frac * (currentValue - volume));
-						} else {
-							p.setCustomVolume(currentValue + frac * (volume - currentValue));
-						}
+						// TODO Volume Trigger Implemeitation
+						// if (p.getCustomVolume() > volume) {
+						// p.setCustomVolume(currentValue - frac * (currentValue - volume));
+						// } else {
+						// p.setCustomVolume(currentValue + frac * (volume - currentValue));
+						// }
 					}
 				}
 			}
diff --git a/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java b/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java
index f7d3c16f59e26a6e2b604215d50327333c54c2db..7ce8cc5f331161bee409c52ada6920d7a8056326 100644
--- a/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java
+++ b/PlayWall/src/de/tobias/playpad/update/PlayPadUpdater.java
@@ -8,8 +8,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.util.SystemUtils;
diff --git a/PlayWall/src/de/tobias/playpad/update/Updates.java b/PlayWall/src/de/tobias/playpad/update/Updates.java
index a507e8d4b28ca862fb5a59a0dbf9248366f4145e..76dbd21de4eed6736c525f89a7d20b070cb2cd2b 100644
--- a/PlayWall/src/de/tobias/playpad/update/Updates.java
+++ b/PlayWall/src/de/tobias/playpad/update/Updates.java
@@ -9,6 +9,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 
 import de.tobias.playpad.AppUserInfoStrings;
+import de.tobias.updater.client.UpdateRegistery;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.NativeLauncher;
diff --git a/PlayWall/src/de/tobias/playpad/view/ColorView.java b/PlayWall/src/de/tobias/playpad/view/ColorPickerView.java
similarity index 65%
rename from PlayWall/src/de/tobias/playpad/view/ColorView.java
rename to PlayWall/src/de/tobias/playpad/view/ColorPickerView.java
index ff09b68021852c4ebf68451ece4cb165c952fccf..06718f47d9dffbb984ced623dd16eb4391248cfc 100644
--- a/PlayWall/src/de/tobias/playpad/view/ColorView.java
+++ b/PlayWall/src/de/tobias/playpad/view/ColorPickerView.java
@@ -7,9 +7,11 @@ import javafx.geometry.Insets;
 import javafx.scene.layout.GridPane;
 import javafx.scene.shape.Rectangle;
 
-public class ColorView extends GridPane {
+public class ColorPickerView extends GridPane {
 
-	public ColorView(DisplayableColor startColor, DisplayableColor[] colors, Consumer<DisplayableColor> finish) {
+	private Rectangle currentSelected;
+	
+	public ColorPickerView(DisplayableColor startColor, DisplayableColor[] colors, Consumer<DisplayableColor> finish) {
 		double size = Math.sqrt(colors.length);
 		int iSize = (int) size;
 		if (size != iSize) {
@@ -39,7 +41,15 @@ public class ColorView extends GridPane {
 					}
 
 					// EventHandler
-					rectangle.setOnMouseReleased(event -> finish.accept(color));
+					rectangle.setOnMouseReleased(event ->
+					{
+						if (currentSelected != null) {
+							currentSelected.getStrokeDashArray().clear();
+						}
+						rectangle.getStrokeDashArray().addAll(3.0);
+						currentSelected = rectangle;
+						finish.accept(color);
+					});
 					add(rectangle, x, y);
 				}
 			}
diff --git a/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java b/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java
index 16a64687ce031eac36fb3ccd1d14adc61cf7488e..5f2fd9cbd8c94bc862402cb6da22f17a40eb9057 100644
--- a/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java
+++ b/PlayWall/src/de/tobias/playpad/view/PadDragOptionView.java
@@ -109,7 +109,12 @@ public class PadDragOptionView {
 			for (PadDragMode connect : options.stream().sorted().toArray(value -> new PadDragMode[value])) {
 				Label label = new Label();
 				label.getStyleClass().add("dnd-file-option");
-				label.textProperty().bind(connect.displayProperty());
+
+				// Text nur wenn 2 oder weniger Optionen sind, weil zu wenig Platz
+				if (options.size() >= 2) {
+					label.textProperty().bind(connect.displayProperty());
+				}
+
 				Node graphics = connect.getGraphics();
 				if (graphics != null) {
 					graphics.setStyle("-fx-text-fill: white;");
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java
index d659f482f881527f96cb000d17c10405ec4c776d..e3dc06be70db2a04b67f12b8175634873c40b736 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/LaunchDialog.java
@@ -14,16 +14,19 @@ import de.tobias.playpad.project.ProfileChooseable;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectImporter;
 import de.tobias.playpad.project.ProjectNotFoundException;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileNotFoundException;
 import de.tobias.playpad.viewcontroller.cell.ProjectCell;
 import de.tobias.playpad.viewcontroller.dialog.ImportDialog;
 import de.tobias.playpad.viewcontroller.dialog.NewProjectDialog;
+import de.tobias.playpad.viewcontroller.dialog.PluginViewController;
 import de.tobias.playpad.viewcontroller.dialog.ProfileChooseDialog;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.ui.ViewController;
+import de.tobias.utils.util.Localization;
 import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
 import javafx.scene.control.Alert;
@@ -56,7 +59,7 @@ public class LaunchDialog extends ViewController implements ProfileChooseable {
 
 	public LaunchDialog(Stage stage) {
 		super("launchDialog", "de/tobias/playpad/assets/dialog/", stage, null, PlayPadMain.getUiResourceBundle());
-		projectListView.getItems().addAll(ProjectReference.getProjectsSorted());
+		projectListView.getItems().addAll(ProjectReferences.getProjectsSorted());
 	}
 
 	@Override
@@ -106,9 +109,10 @@ public class LaunchDialog extends ViewController implements ProfileChooseable {
 
 		stage.setTitle(getString(Strings.UI_Dialog_Launch_Title));
 		PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
-		
+
 		stage.setResizable(false);
 		stage.setWidth(650);
+		stage.setHeight(400);
 		stage.show();
 	}
 
@@ -165,7 +169,7 @@ public class LaunchDialog extends ViewController implements ProfileChooseable {
 			alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item ->
 			{
 				try {
-					ProjectReference.removeDocument(ref);
+					ProjectReferences.removeDocument(ref);
 					projectListView.getItems().remove(ref); // VIEW
 				} catch (DocumentException | IOException e) {
 					showErrorMessage(getString(Strings.Error_Project_Delete, e.getLocalizedMessage()));
@@ -184,12 +188,19 @@ public class LaunchDialog extends ViewController implements ProfileChooseable {
 	}
 
 	/**
-	 * Launch a project and close this view.
+	 * Öffnet ein Project und zeigt es im MainView an. Zudem wird as entsprechende Profile geladen und geprüft ob Module (Plugins) fehlen.
 	 * 
 	 * @param ref
 	 *            Project to launch
 	 */
 	private void launchProject(ProjectReference ref) {
+		// Es fehlen Module
+		if (!ref.getMissedModules().isEmpty()) {
+			showInfoMessage(Localization.getString(Strings.Error_Plugins_Missing));
+			PluginViewController controller = new PluginViewController(getStage(), ref.getMissedModules());
+			controller.getStage().showAndWait();
+		}
+
 		try {
 			Project project = Project.load(ref, true, this);
 			PlayPadMain.getProgramInstance().openProject(project);
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java
index 6326b9c7015b56a4e6510a47bde8cd42676311bd..34edd58feec6ceb1c79a9aa86f32886e71f6262d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/actions/CartActionsViewController.java
@@ -63,7 +63,7 @@ public class CartActionsViewController extends ContentViewController {
 		gridPane.getChildren().clear();
 
 		gridPane.getColumnConstraints().clear();
-		double xPercentage = 1.0 / (double) settings.getColumns();
+		double xPercentage = 1.0 / settings.getColumns();
 		for (int i = 0; i < settings.getColumns(); i++) {
 			ColumnConstraints c = new ColumnConstraints();
 			c.setPercentWidth(xPercentage * 100);
@@ -71,7 +71,7 @@ public class CartActionsViewController extends ContentViewController {
 		}
 
 		gridPane.getRowConstraints().clear();
-		double yPercentage = 1.0 / (double) settings.getRows();
+		double yPercentage = 1.0 / settings.getRows();
 		for (int i = 0; i < settings.getRows(); i++) {
 			RowConstraints c = new RowConstraints();
 			c.setPercentHeight(yPercentage * 100);
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PageNameListCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PageNameListCell.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2b661dc4ed199bd4e4e008b2ba7c4abd2a2d8cf
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PageNameListCell.java
@@ -0,0 +1,25 @@
+package de.tobias.playpad.viewcontroller.cell;
+
+import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.Strings;
+import de.tobias.playpad.project.page.Page;
+import de.tobias.utils.util.Localization;
+import javafx.scene.control.ListCell;
+
+public final class PageNameListCell extends ListCell<Integer> {
+
+	@Override
+	protected void updateItem(Integer item, boolean empty) {
+		super.updateItem(item, empty);
+		if (!empty) {
+			Page page = PlayPadMain.getProgramInstance().getCurrentProject().getPage(item);
+			String name = page.getName();
+			if (name.isEmpty()) {
+				name = Localization.getString(Strings.UI_Window_Main_PageButton, (item));
+			}
+			setText(name);
+		} else {
+			setText("");
+		}
+	}
+}
\ No newline at end of file
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java
index 6deea2a19ee6d00415ee5d33d791fb75f90439ec..04a4b7619c5ea2e4e317884d0844276899e22793 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/PluginCell.java
@@ -1,18 +1,15 @@
 package de.tobias.playpad.viewcontroller.cell;
 
-import java.io.IOException;
-import java.net.URL;
-import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
 
 import de.tobias.playpad.PlayPadMain;
-import de.tobias.playpad.plugin.Plugin;
+import de.tobias.playpad.plugin.PluginDescription;
 import de.tobias.playpad.plugin.Plugins;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.geometry.Pos;
@@ -20,9 +17,9 @@ import javafx.scene.control.CheckBox;
 import javafx.scene.control.ListCell;
 import javafx.scene.layout.HBox;
 
-public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boolean> {
+public class PluginCell extends ListCell<PluginDescription> implements ChangeListener<Boolean> {
 
-	private Plugin plugin;
+	private PluginDescription plugin;
 	private HBox buttons;
 	private CheckBox checkBox;
 
@@ -36,7 +33,7 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole
 	}
 
 	@Override
-	protected void updateItem(Plugin item, boolean empty) {
+	protected void updateItem(PluginDescription item, boolean empty) {
 		super.updateItem(item, empty);
 		if (!empty) {
 			this.plugin = item;
@@ -58,51 +55,22 @@ public class PluginCell extends ListCell<Plugin> implements ChangeListener<Boole
 
 		Path path = app.getPath(PathType.LIBRARY, plugin.getFileName());
 		if (newValue) { // Wurde Aktiviert
-			downloadPlugin(plugin, path);
+			Worker.runLater(() ->
+			{
+				Plugins.downloadPlugin(plugin, path);
 
-			// Dependencies
-			loadDependencies(app);
+				// Dependencies
+				Plugins.loadDependencies(plugin);
 
-			// Add Plugin to classpath
-			PlayPadMain.getProgramInstance().loadPlugin(path.toUri());
+				// Add Plugin to classpath
+				Platform.runLater(() -> PlayPadMain.getProgramInstance().loadPlugin(path.toUri())); // FX Thread, damit Plugins GUI Zeug
+																									// gleich auf dem richtigen Thread
+																									// haben, sonst müssen sie den Worker
+																									// nutzen
+			});
 		} else {
 			// Deaktivieren
 			PlayPadMain.getProgramInstance().addDeletedPlugin(path);
 		}
 	}
-
-	private void loadDependencies(App app) {
-		List<Plugin> dependencies = findDependencies();
-		dependencies.forEach(p ->
-		{
-			Path decPath = app.getPath(PathType.LIBRARY, p.getFileName());
-			downloadPlugin(p, decPath);
-
-			// Add Plugin to classpath
-			PlayPadMain.getProgramInstance().loadPlugin(decPath.toUri());
-		});
-	}
-
-	private List<Plugin> findDependencies() {
-		List<Plugin> plugins = new ArrayList<>();
-		for (String dependencyName : plugin.getDependencies()) {
-			for (Plugin plugin : Plugins.getPlugins()) {
-				if (plugin.getName().equals(dependencyName)) {
-					plugins.add(plugin);
-				}
-			}
-		}
-		return plugins;
-	}
-
-	private void downloadPlugin(Plugin plugin, Path path) {
-		if (Files.notExists(path)) {
-			try {
-				Files.createDirectories(path.getParent());
-				Files.copy(new URL(plugin.getUrl()).openStream(), path);
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java
index 650064aac576b12399d42c650a4b3309f3de78ae..68b8729394997b82289d4534d706dfaf50990f20 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/ProjectCell.java
@@ -4,8 +4,8 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 
 import de.tobias.playpad.Displayable;
-import de.tobias.playpad.project.ProjectReference;
-import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.project.ref.ProjectReference;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
 import javafx.geometry.Pos;
@@ -60,7 +60,7 @@ public class ProjectCell extends ListCell<ProjectReference> {
 
 				// File not Exists
 				Path path = ref.getProjectPath();
-				if (Files.notExists(path)) {
+				if (Files.notExists(path) || !ref.getMissedModules().isEmpty()) {
 					FontIcon graphics = new FontIcon(FontAwesomeType.WARNING);
 					graphics.setColor(Color.RED);
 					rootBox.getChildren().add(graphics);
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java
index c33fffdfd7df206c1edeff9ee6a14c09e93a8b25..5ba3fce1254df6bb2cc80eee1e0e1528ec1e2e56 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/UpdateCell.java
@@ -2,7 +2,7 @@ package de.tobias.playpad.viewcontroller.cell;
 
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.update.PlayPadUpdater;
-import de.tobias.playpad.update.Updatable;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.util.Localization;
 import javafx.scene.control.ListCell;
 import javafx.scene.image.ImageView;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java
index 25a1cc9ceee850e0f0ecbb6ce98d61d49ce3301f..adc09ae77eb350f40b0e9226abf9be3ccc9dde0d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/ErrorCell.java
@@ -1,8 +1,8 @@
 package de.tobias.playpad.viewcontroller.cell.errordialog;
 
 import de.tobias.playpad.pad.PadException;
-import javafx.scene.control.Control;
 import javafx.scene.control.TableCell;
+import javafx.scene.layout.Region;
 import javafx.scene.text.Text;
 
 public class ErrorCell extends TableCell<PadException, String> {
@@ -11,7 +11,7 @@ public class ErrorCell extends TableCell<PadException, String> {
 		Text text = new Text();
 		text.getStyleClass().add("label");
 		setGraphic(text);
-		setPrefHeight(Control.USE_COMPUTED_SIZE);
+		setPrefHeight(Region.USE_COMPUTED_SIZE);
 		text.wrappingWidthProperty().bind(widthProperty());
 		text.textProperty().bind(itemProperty());
 	}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java
index 2e6e65f3117abbed7dff065272484dd5180b5fba..f183023a8b30443342387262f075fc8a552c50b1 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/FixCell.java
@@ -52,7 +52,7 @@ public class FixCell extends TableCell<PadException, PadException> {
 			deleteButton.setOnAction(a ->
 			{
 				deleteExButton.getHandler().handle(item.getPad(), stage);
-				item.getPad().getProject().removeException(item);
+				// item.getPad().getProject().removeException(item);TODO Error Handling User
 			});
 			vbox.getChildren().add(deleteButton);
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/IOExceptionButtonListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/IOExceptionButtonListener.java
index 94b61fe98861c4299b201c66436513213f2f1f4d..d0ff923ecac5c67c074a2a808096107638549d0d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/IOExceptionButtonListener.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/cell/errordialog/IOExceptionButtonListener.java
@@ -6,10 +6,10 @@ import java.nio.file.Path;
 
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadContentRegistry;
 import de.tobias.playpad.pad.PadException;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.view.ExceptionButton;
 import de.tobias.utils.util.FileUtils;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ClassicGlobalDesignViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ClassicGlobalDesignViewController.java
index d27b88dd43431697726f1251c642dfdc00de6ebf..491005c05eccdbcfa7eb0ed3d89cff53f3bdfd0b 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ClassicGlobalDesignViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ClassicGlobalDesignViewController.java
@@ -2,8 +2,8 @@ package de.tobias.playpad.viewcontroller.design;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PseudoClasses;
-import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.DesignConnect;
+import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.classic.ClassicGlobalDesign;
 import de.tobias.playpad.design.classic.Theme;
 import de.tobias.playpad.viewcontroller.GlobalDesignViewController;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java
index fbda591aa744faa54b000b0b47622d76fbd5de94..99644a917a096a1badef9824f179e1d6c77fe9ab 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernCartDesignViewController.java
@@ -10,7 +10,7 @@ import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.design.CartDesign;
 import de.tobias.playpad.design.modern.ModernCartDesign;
 import de.tobias.playpad.design.modern.ModernColor;
-import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.view.ColorPickerView;
 import de.tobias.playpad.viewcontroller.CartDesignViewController;
 import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
@@ -65,7 +65,7 @@ public class ModernCartDesignViewController extends CartDesignViewController {
 	}
 
 	private void colorChooser(Button anchorNode, ModernColor startColor, Consumer<ModernColor> onFinish) {
-		ColorView view = new ColorView(startColor, ModernColor.values(), (DisplayableColor t) ->
+		ColorPickerView view = new ColorPickerView(startColor, ModernColor.values(), (DisplayableColor t) ->
 		{
 			colorChooser.hide();
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernGlobalDesignViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernGlobalDesignViewController.java
index 19811e5ca8d27854d38315930f809f245f152bb3..d90331f55d16e2b23717cbfa8517dfee0c81a460 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernGlobalDesignViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/design/ModernGlobalDesignViewController.java
@@ -10,7 +10,7 @@ import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.modern.ModernColor;
 import de.tobias.playpad.design.modern.ModernGlobalDesign;
-import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.view.ColorPickerView;
 import de.tobias.playpad.viewcontroller.GlobalDesignViewController;
 import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
@@ -94,7 +94,7 @@ public class ModernGlobalDesignViewController extends GlobalDesignViewController
 	}
 
 	private void colorChooser(Button anchorNode, ModernColor startColor, Consumer<ModernColor> onFinish) {
-		ColorView view = new ColorView(startColor, ModernColor.values(), (DisplayableColor t) ->
+		ColorPickerView view = new ColorPickerView(startColor, ModernColor.values(), (DisplayableColor t) ->
 		{
 			colorChooser.hide();
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/AutoUpdateDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/AutoUpdateDialog.java
index f3d0fb89824c60c308730e1c0a365442544023d0..c8fb0d37cfe613c92dba330cc96c09af40bb4321 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/AutoUpdateDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/AutoUpdateDialog.java
@@ -1,11 +1,11 @@
 package de.tobias.playpad.viewcontroller.dialog;
 
-import java.util.List;
+import java.util.Set;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateRegistery;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateRegistery;
 import de.tobias.utils.ui.AdvancedDialog;
 import de.tobias.utils.util.Localization;
 import javafx.scene.control.ButtonBar.ButtonData;
@@ -16,7 +16,7 @@ public class AutoUpdateDialog extends AdvancedDialog {
 
 	public AutoUpdateDialog(Window owner) {
 		super(owner);
-		List<Updatable> updates = UpdateRegistery.getAvailableUpdates();
+		Set<Updatable> updates = UpdateRegistery.getAvailableUpdates();
 
 		StringBuilder builder = new StringBuilder();
 		for (Updatable update : updates) {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java
index 8556d72177365c43b1a3e563c2e2f976ffd8e2ee..da7c833673ea20a8b697a1aeb8d74eb26577a823 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProfileDialog.java
@@ -4,8 +4,9 @@ import java.util.Optional;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
 import javafx.scene.control.Button;
@@ -27,7 +28,7 @@ public class DuplicateProfileDialog extends TextInputDialog {
 		Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);
 		getEditor().textProperty().addListener((a, b, c) ->
 		{
-			if (ProfileReference.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
+			if (ProfileReferences.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
 				button.setDisable(true);
 			} else {
 				button.setDisable(false);
@@ -38,13 +39,13 @@ public class DuplicateProfileDialog extends TextInputDialog {
 		showAndWait().filter(name -> !name.isEmpty()).ifPresent(name ->
 		{
 			try {
-				if (ProfileReference.getProfiles().contains(name)) {
+				if (ProfileReferences.getProfiles().contains(name)) {
 					controller.showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
 					return;
 				}
 
 				newRef = new ProfileReference(name);
-				ProfileReference.duplicate(cloneableProfile, newRef);
+				ProfileReferences.duplicate(cloneableProfile, newRef);
 
 			} catch (Exception e) {
 				e.printStackTrace();
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java
index 180f5230e0b9fde768b3a71c8e065bf3a65d3b50..8b14194ea86e8cf78064ea06accefeb29ca3cbb4 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/DuplicateProjectDialog.java
@@ -4,9 +4,10 @@ import java.util.Optional;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.project.Project;
-import de.tobias.playpad.project.ProjectReference;
-import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
 import javafx.scene.control.Button;
@@ -40,7 +41,7 @@ public class DuplicateProjectDialog extends TextInputDialog {
 		Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);
 		getEditor().textProperty().addListener((a, b, c) ->
 		{
-			if (ProjectReference.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) {
+			if (ProjectReferences.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) {
 				button.setDisable(true);
 			} else {
 				button.setDisable(false);
@@ -51,12 +52,12 @@ public class DuplicateProjectDialog extends TextInputDialog {
 		showAndWait().filter(name -> !name.isEmpty()).ifPresent(name ->
 		{
 			try {
-				if (ProfileReference.getProfiles().contains(name)) {
+				if (ProfileReferences.getProfiles().contains(name)) {
 					controller.showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
 					return;
 				}
 
-				ref = ProjectReference.duplicate(cloneableProject, name);
+				ref = ProjectReferences.duplicate(cloneableProject, name);
 			} catch (Exception e) {
 				e.printStackTrace();
 				controller.showErrorMessage(Localization.getString(Strings.Error_Project_Save, name, e.getMessage()));
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java
index 7e83853ccb61db8e51b022cdde2bb5b7347b557e..5a5b64dfd8e618c6444058c6697477f8bf72991d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ErrorSummaryDialog.java
@@ -72,7 +72,8 @@ public class ErrorSummaryDialog extends ViewController {
 					string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(),
 							padException.getPad().getIndexReadable());
 				else
-					string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(), padException.getPath().toString());
+					string = Localization.getString(Strings.Error_Pad_BaseName + padException.getType().name(),
+							padException.getPath().toString());
 			} catch (Exception e) {
 				e.printStackTrace();
 			}
@@ -94,7 +95,7 @@ public class ErrorSummaryDialog extends ViewController {
 	}
 
 	public void setProject(Project project) {
-		errorTable.setItems(project.getExceptions());
+		// errorTable.setItems(project.getExceptions()); TODO Error Handling User
 		errorTable.getItems().addListener(new ListChangeListener<PadException>() {
 
 			@Override
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java
index b59e10fc3ea267ae949d7f7d8ac8fb89186dc1b4..cafa9abe59255bcaee8469b32dc3e7d3ac3d9592 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/MappingListViewController.java
@@ -117,7 +117,7 @@ public class MappingListViewController extends ViewController {
 
 	@FXML
 	private void addButtonHandler(ActionEvent event) {
-		Mapping preset = new Mapping(true, Profile.currentProfile());
+		Mapping preset = new Mapping(true);
 
 		mappingList.add(preset);
 		presetsListView.getItems().add(preset);
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java
index 294c7f99b43d034d9eeba22752ee2f7200d82654..292a169445017fc7fbc24a19886f6f6e157b7438 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProfileDialog.java
@@ -1,12 +1,15 @@
 package de.tobias.playpad.viewcontroller.dialog;
 
+import java.util.List;
+
 import javax.sound.midi.MidiDevice.Info;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.midi.Midi;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
 import de.tobias.utils.util.Worker;
@@ -86,7 +89,7 @@ public class NewProfileDialog extends ViewController {
 			if (c.isEmpty()) {
 				finishButton.setDisable(true);
 			} else {
-				if (ProfileReference.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
+				if (ProfileReferences.getProfiles().contains(c) || !c.matches(Profile.profileNameEx)) {
 					finishButton.setDisable(true);
 					return;
 				}
@@ -125,12 +128,14 @@ public class NewProfileDialog extends ViewController {
 	private void finishButtonHandler(ActionEvent event) {
 		String name = nameTextField.getText();
 		try {
-			if (ProfileReference.getProfiles().contains(name) || !name.matches(Profile.profileNameEx)) {
+			List<ProfileReference> profiles = ProfileReferences.getProfiles();
+
+			if (profiles.contains(name) || !name.matches(Profile.profileNameEx)) {
 				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, name));
 				return;
 			}
 
-			profile = ProfileReference.newProfile(name);
+			profile = ProfileReferences.newProfile(name);
 
 			profile.getProfileSettings().setMidiActive(activeCheckBox.isSelected());
 			profile.getProfileSettings().setMidiDeviceName(midiDeviceComboBox.getSelectionModel().getSelectedItem());
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java
index 47352aa2fb1383ef5cc6ab84be004c91033714d5..9f12a82e215d1517f76db27b96f322a5452ca17d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/NewProjectDialog.java
@@ -9,11 +9,13 @@ import org.dom4j.DocumentException;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.project.Project;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileNotFoundException;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
 import javafx.event.ActionEvent;
@@ -57,7 +59,7 @@ public class NewProjectDialog extends ViewController {
 		getStage().initOwner(owner);
 		getStage().initModality(Modality.WINDOW_MODAL);
 
-		profileComboBox.getItems().addAll(ProfileReference.getProfiles());
+		profileComboBox.getItems().addAll(ProfileReferences.getProfiles());
 		profileComboBox.getSelectionModel().selectFirst();
 	}
 
@@ -68,7 +70,7 @@ public class NewProjectDialog extends ViewController {
 			if (c.isEmpty()) {
 				finishButton.setDisable(true);
 			} else {
-				if (ProjectReference.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) {
+				if (ProjectReferences.getProjects().contains(c) || !c.matches(Project.PROJECT_NAME_PATTERN)) {
 					finishButton.setDisable(true);
 					return;
 				}
@@ -138,7 +140,7 @@ public class NewProjectDialog extends ViewController {
 			project.getSettings().setMediaPath(newMediaPath);
 			project.save();
 
-			ProjectReference.addProject(projectReference);
+			ProjectReferences.addProject(projectReference);
 
 			getStage().close();
 		} catch (IOException | DocumentException | ProfileNotFoundException e) {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java
index 42341a2c4ebd3b53e96a89c1f079945e4337f675..cf25ad254df4a91b277777fe4364e8ce279f28da 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PluginViewController.java
@@ -3,6 +3,7 @@ package de.tobias.playpad.viewcontroller.dialog;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import org.bukkit.configuration.MemorySection;
 
@@ -10,12 +11,13 @@ import de.tobias.playpad.AppUserInfoStrings;
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
-import de.tobias.playpad.plugin.Plugin;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.playpad.plugin.PluginDescription;
 import de.tobias.playpad.plugin.Plugins;
 import de.tobias.playpad.settings.GlobalSettings;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.update.UpdateChannel;
 import de.tobias.playpad.viewcontroller.cell.PluginCell;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
@@ -32,10 +34,14 @@ import javafx.stage.Window;
 
 public class PluginViewController extends ViewController {
 
-	@FXML private ListView<Plugin> pluginListView;
+	@FXML private ListView<PluginDescription> pluginListView;
 	@FXML private Button finishButton;
 
 	public PluginViewController(Window owner) {
+		this(owner, null);
+	}
+
+	public PluginViewController(Window owner, Set<Module> modules) {
 		super("pluginView", "de/tobias/playpad/assets/dialog/", null, PlayPadMain.getUiResourceBundle());
 
 		getStage().initOwner(owner);
@@ -60,18 +66,31 @@ public class PluginViewController extends ViewController {
 					return;
 				}
 
-				List<Plugin> plugins = Plugins.load(pluginInfoURL, true);
+				List<PluginDescription> plugins = Plugins.loadDescriptionFromServer(pluginInfoURL, true);
 
 				Collections.sort(plugins);
 				Platform.runLater(() ->
 				{
-					pluginListView.getItems().setAll(plugins);
+					// Nur bestimmte Plugins zur Liste (die, die Fehlen)
+					if (modules != null) {
+						for (PluginDescription plugin : plugins) {
+							for (Module module : modules) {
+								if (module.identifier.equals(plugin.getId())) {
+									pluginListView.getItems().add(plugin);
+								}
+							}
+						}
+					} else {
+						// Alle Plugins zur Liste
+						pluginListView.getItems().setAll(plugins);
+					}
 				});
 			} catch (IOException e) {
 				e.printStackTrace();
 				showErrorMessage(Localization.getString(Strings.Error_Standard_Gen), PlayPadMain.stageIcon);
 			}
 		});
+
 	}
 
 	@Override
@@ -92,7 +111,8 @@ public class PluginViewController extends ViewController {
 
 		stage.setTitle(Localization.getString(Strings.UI_Dialog_Plugins_Title));
 
-		Profile.currentProfile().currentLayout().applyCss(getStage());
+		if (Profile.currentProfile() != null)
+			Profile.currentProfile().currentLayout().applyCss(getStage());
 	}
 
 	@FXML
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java
index 71d6ca6354fbd3c34fddb557ed30c3f5d97e9f77..d4fe619c978fdd49f7db89f930b981b0fb9c81f9 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/PrintDialog.java
@@ -13,7 +13,10 @@ import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectSettings;
+import de.tobias.playpad.project.page.PadIndex;
+import de.tobias.playpad.project.page.Page;
 import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.cell.PageNameListCell;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
@@ -45,11 +48,13 @@ public class PrintDialog extends ViewController {
 		super("printDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle());
 		this.project = project;
 
-		int pages = project.getSettings().getPageCount();
+		int pages = project.getPages().size();
 		for (int i = 0; i < pages; i++) {
-			pageComboBox.getItems().add(i + 1);
+			pageComboBox.getItems().add(i);
 		}
 		pageComboBox.getSelectionModel().selectFirst();
+		pageComboBox.setCellFactory(param -> new PageNameListCell());
+		pageComboBox.setButtonCell(new PageNameListCell());
 
 		getStage().initOwner(owner);
 	}
@@ -58,7 +63,7 @@ public class PrintDialog extends ViewController {
 	public void init() {
 		pageComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
 		{
-			createPreview(c - 1);
+			createPreview(c);
 		});
 
 		addCloseKeyShortcut(() -> getStage().close());
@@ -75,7 +80,7 @@ public class PrintDialog extends ViewController {
 		Profile.currentProfile().currentLayout().applyCss(getStage());
 	}
 
-	private void createPreview(int page) {
+	private void createPreview(int pageIndex) {
 		Html html = new Html();
 		Body body = new Body();
 		body.setStyle("max-width: 1000px; font-family: sans-serif;");
@@ -83,7 +88,13 @@ public class PrintDialog extends ViewController {
 
 		H1 header = new H1();
 
-		String headerString = Localization.getString(Strings.Info_Print_Header, project.getRef().getName(), page + 1);
+		Page page = project.getPage(pageIndex);
+		String pageName = page.getName();
+		if (pageName.isEmpty()) {
+			pageName = Localization.getString(Strings.UI_Window_Main_PageButton, (pageIndex + 1));
+		}
+
+		String headerString = Localization.getString(Strings.Info_Print_Header, project.getProjectReference().getName(), pageName);
 		header.appendText(headerString);
 		header.setStyle("text-align: center;");
 		body.appendChild(header);
@@ -92,7 +103,7 @@ public class PrintDialog extends ViewController {
 		table.setStyle("border:1px solid black;border-collapse:collapse;");
 
 		ProjectSettings settings = project.getSettings();
-		int i = page * settings.getRows() * settings.getColumns();
+		int padIndex = 0;
 
 		for (int y = 0; y < settings.getRows(); y++) {
 			Tr tr = new Tr();
@@ -103,14 +114,14 @@ public class PrintDialog extends ViewController {
 						+ "px; padding: 5px; vertical-align: center; text-align: center; min-height: 30px; min-width: 100px;");
 				Div div = new Div();
 				div.setStyle("word-break: break-all; white-space: normal;");
-				Pad pad = this.project.getPad(i);
+				Pad pad = this.project.getPad(new PadIndex(padIndex, pageIndex));
 
 				if (pad.getContent() != null && pad.getContent().isPadLoaded())
 					div.appendText(pad.getName());
 				else
 					div.appendText("-");
 				td.appendChild(div);
-				i++;
+				padIndex++;
 				tr.appendChild(td);
 			}
 		}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java
index 16362ff2cae9c234455fbbab6f86d343eafeafaa..d516fcd3d631672ef212daaf66f3f202c1a9ab31 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileChooseDialog.java
@@ -6,9 +6,10 @@ import org.dom4j.DocumentException;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileNotFoundException;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
 import javafx.event.ActionEvent;
@@ -35,7 +36,7 @@ public class ProfileChooseDialog extends ViewController {
 		getStage().initOwner(owner);
 		getStage().initModality(Modality.WINDOW_MODAL);
 
-		profileComboBox.getItems().addAll(ProfileReference.getProfiles());
+		profileComboBox.getItems().addAll(ProfileReferences.getProfiles());
 		profileComboBox.getSelectionModel().selectFirst();
 	}
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java
index afd7641c48aaffa3b3709727e00337758fe041ce..293390b3c2021cc76ae1b1e6e8c609fd43d80431 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProfileViewController.java
@@ -7,10 +7,11 @@ import org.dom4j.DocumentException;
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PseudoClasses;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileNotFoundException;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.playpad.viewcontroller.cell.DisplayableCell;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
@@ -50,7 +51,7 @@ public class ProfileViewController extends ViewController implements ChangeListe
 		getStage().initOwner(owner);
 		getStage().initModality(Modality.WINDOW_MODAL);
 
-		if (ProfileReference.getProfiles().size() == 1
+		if (ProfileReferences.getProfiles().size() == 1
 				|| profileList.getSelectionModel().getSelectedItem().equals(Profile.currentProfile().getRef())) {
 			deleteButton.setDisable(true);
 		}
@@ -58,14 +59,14 @@ public class ProfileViewController extends ViewController implements ChangeListe
 
 	@Override
 	public void init() {
-		profileList.getItems().setAll(ProfileReference.getProfiles());
+		profileList.getItems().setAll(ProfileReferences.getProfiles());
 		profileList.setCellFactory(list -> new DisplayableCell<>());
 
 		nameTextField.textProperty().addListener((a, b, c) ->
 		{
 			if (c != null) {
 				try {
-					if ((ProfileReference.getProfiles().contains(c) && !profileList.getSelectionModel().getSelectedItem().equals(c))
+					if ((ProfileReferences.getProfiles().contains(c) && !profileList.getSelectionModel().getSelectedItem().equals(c))
 							&& !c.equals(profileList.getSelectionModel().getSelectedItem().getName())) {
 						nameTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true);
 					} else {
@@ -98,7 +99,7 @@ public class ProfileViewController extends ViewController implements ChangeListe
 	@FXML
 	private void chooseButtonHandler(ActionEvent event) {
 		ProfileReference ref = profileList.getSelectionModel().getSelectedItem();
-		project.getRef().setProfileReference(ref);
+		project.getProjectReference().setProfileReference(ref);
 
 		try {
 			Profile.load(ref);
@@ -150,7 +151,7 @@ public class ProfileViewController extends ViewController implements ChangeListe
 		alert.showAndWait().filter(button -> button == ButtonType.OK).ifPresent(button ->
 		{
 			try {
-				ProfileReference.removeProfile(ref);
+				ProfileReferences.removeProfile(ref);
 				profileList.getItems().remove(ref);
 			} catch (Exception e) {
 				e.printStackTrace();
@@ -164,7 +165,7 @@ public class ProfileViewController extends ViewController implements ChangeListe
 		ProfileReference ref = profileList.getSelectionModel().getSelectedItem();
 		try {
 			String newProfileName = nameTextField.getText();
-			if (ProfileReference.getProfiles().contains(newProfileName) || !newProfileName.matches(Profile.profileNameEx)) {
+			if (ProfileReferences.getProfiles().contains(newProfileName) || !newProfileName.matches(Profile.profileNameEx)) {
 				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, newProfileName));
 				return;
 			}
@@ -190,7 +191,7 @@ public class ProfileViewController extends ViewController implements ChangeListe
 		chooseButton.setDisable(newValue == null);
 		duplicateButton.setDisable(newValue == null);
 
-		if (ProfileReference.getProfiles().size() == 1 || profileList.getSelectionModel().getSelectedItem() == null
+		if (ProfileReferences.getProfiles().size() == 1 || profileList.getSelectionModel().getSelectedItem() == null
 				|| profileList.getSelectionModel().getSelectedItem().equals(Profile.currentProfile().getRef())) {
 			deleteButton.setDisable(true);
 		} else {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java
index 134b544ce3667fbfe00eb68a4c376a0356897031..e730c2d2635343b48322d45fd80ac73055b3b9eb 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectExportDialog.java
@@ -8,7 +8,7 @@ import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.project.ProjectExporter;
 import de.tobias.playpad.project.ProjectExporter.ExportView;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReference;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.utils.ui.NotificationHandler;
 import de.tobias.utils.ui.ViewController;
@@ -90,7 +90,7 @@ public class ProjectExportDialog extends ViewController implements ExportView {
 					boolean includeProject = profileCheckBox.isSelected();
 					boolean includeMedia = mediaCheckBox.isSelected();
 
-					ProjectExporter.exportProject(projectRef, path, includeProject, includeMedia, (ExportView) this);
+					ProjectExporter.exportProject(projectRef, path, includeProject, includeMedia, this);
 
 					Platform.runLater(() ->
 					{
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java
index 83bf7d61f216e0d82d8b821a6256251620df9590..13f99b0344427a5198b28c70e7e62749c71723fd 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/dialog/ProjectManagerDialog.java
@@ -9,11 +9,12 @@ import org.dom4j.DocumentException;
 
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.profile.ref.ProfileReference;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectImporter;
-import de.tobias.playpad.project.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.playpad.viewcontroller.cell.ProjectCell;
 import de.tobias.utils.ui.NotificationHandler;
 import de.tobias.utils.ui.ViewController;
@@ -69,7 +70,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		super("openDialog", "de/tobias/playpad/assets/dialog/project/", null, PlayPadMain.getUiResourceBundle());
 		this.currentProject = currentProject;
 
-		projectList.getItems().setAll(ProjectReference.getProjectsSorted());
+		projectList.getItems().setAll(ProjectReferences.getProjectsSorted());
 
 		getStage().initOwner(owner);
 		getStage().initModality(Modality.WINDOW_MODAL);
@@ -79,7 +80,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 	public void init() {
 		// Notification Handler
 		notificationPane = new NotificationPane(rootNode);
-		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+		notificationPane.getStyleClass().add(org.controlsfx.control.NotificationPane.STYLE_CLASS_DARK);
 
 		setAnchor(notificationPane, 0, 0, 0, 0);
 		((AnchorPane) getParent()).getChildren().add(notificationPane);
@@ -118,7 +119,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 					e.printStackTrace();
 				}
 
-				if (currentProject.getRef().equals(c)) {
+				if (currentProject.getProjectReference().equals(c)) {
 					deleteButton.setDisable(true);
 				} else {
 					deleteButton.setDisable(false);
@@ -176,7 +177,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		alert.showAndWait().filter(item -> item == ButtonType.OK).ifPresent(item ->
 		{
 			try {
-				ProjectReference.removeDocument(ref);
+				ProjectReferences.removeDocument(ref);
 				projectList.getItems().remove(ref); // VIEW
 			} catch (Exception e) {
 				showErrorMessage(Localization.getString(Strings.Error_Project_Delete, e.getLocalizedMessage()));
@@ -201,14 +202,14 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		String oldName = projectReference.toString();
 
 		try {
-			String newProjectName = (String) nameTextField.getText();
-			if (ProjectReference.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.PROJECT_NAME_PATTERN)) {
+			String newProjectName = nameTextField.getText();
+			if (ProjectReferences.getProjects().contains(newProjectName) || !nameTextField.getText().matches(Project.PROJECT_NAME_PATTERN)) {
 				showErrorMessage(Localization.getString(Strings.Error_Standard_NameInUse, nameTextField.getText()));
 				return;
 			}
 
 			projectReference.setName(newProjectName);
-			projectList.getItems().setAll(ProjectReference.getProjectsSorted());
+			projectList.getItems().setAll(ProjectReferences.getProjectsSorted());
 
 			selectProject(projectReference);
 		} catch (Exception e) {
@@ -223,7 +224,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		dialog.getStage().showAndWait();
 
 		Project project = dialog.getProject();
-		projectList.getItems().add(project.getRef());
+		projectList.getItems().add(project.getProjectReference());
 	}
 
 	@FXML
@@ -267,10 +268,11 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		ProjectReference selectedProject = getSelectedProject();
 
 		// Speicher das Aktuelle Projekt erst, damit es in der Exportmethode seperat neu geladen werden kann
-		if (currentProject.getRef().equals(selectedProject)) {
+		if (currentProject.getProjectReference().equals(selectedProject)) {
 			try {
 				currentProject.save();
 			} catch (IOException e) {
+				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
 		}
@@ -283,7 +285,7 @@ public class ProjectManagerDialog extends ViewController implements Notification
 		getStage().showAndWait();
 		if (!cancel) {
 			if (getSelecteItem() != null) {
-				if (currentProject.getRef() != getSelecteItem()) {
+				if (currentProject.getProjectReference() != getSelecteItem()) {
 					return Optional.of(getSelecteItem());
 				}
 			}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java
index c9a0df0fa17fd21bdb493a49d92f84ab90d0b264..a25c1b9c63eaf9656c83d2f0e22b27cee3e9b599 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewController.java
@@ -15,6 +15,7 @@ import de.tobias.playpad.action.mapper.listener.KeyboardHandler;
 import de.tobias.playpad.action.mapper.listener.MidiHandler;
 import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.layout.desktop.DesktopMainLayoutConnect;
+import de.tobias.playpad.layout.desktop.pad.DesktopPadDragListener;
 import de.tobias.playpad.midi.Midi;
 import de.tobias.playpad.midi.MidiListener;
 import de.tobias.playpad.pad.Pad;
@@ -22,6 +23,7 @@ import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.plugin.WindowListener;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectSettings;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.settings.GlobalSettings;
@@ -33,9 +35,7 @@ import de.tobias.playpad.view.main.MainLayoutConnect;
 import de.tobias.playpad.view.main.MainLayoutHandler;
 import de.tobias.playpad.viewcontroller.dialog.ErrorSummaryDialog;
 import de.tobias.playpad.viewcontroller.dialog.SaveDialog;
-import de.tobias.playpad.viewcontroller.pad.PadDragListener;
 import de.tobias.utils.ui.BasicControllerSettings;
-import de.tobias.utils.ui.NotificationHandler;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.ui.scene.NotificationPane;
 import de.tobias.utils.util.Localization;
@@ -44,6 +44,7 @@ import de.tobias.utils.util.OS.OSType;
 import de.tobias.utils.util.Worker;
 import javafx.application.Platform;
 import javafx.beans.property.DoubleProperty;
+import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.event.EventType;
 import javafx.fxml.FXML;
@@ -52,6 +53,7 @@ import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.control.Alert;
 import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.ButtonBar.ButtonData;
 import javafx.scene.control.ButtonType;
 import javafx.scene.input.KeyCombination;
 import javafx.scene.input.KeyEvent;
@@ -66,7 +68,7 @@ import javafx.stage.Modality;
 import javafx.stage.Screen;
 import javafx.stage.Stage;
 
-public class MainViewController extends ViewController implements IMainViewController, NotificationHandler, ProfileListener {
+public class MainViewController extends ViewController implements IMainViewController, ProfileListener {
 
 	private static final int FIRST_PAGE = 0;
 
@@ -81,7 +83,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 	private MenuToolbarViewController menuToolbarViewController;
 
 	private Project openProject;
-	private int currentPageShowing = -1;
+	private int currentPageShowing = 0;
 
 	// Mapper
 	private Midi midi;
@@ -111,7 +113,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 		layoutActions = new ArrayList<>();
 
 		// Init Listener
-		volumeChangeListener = new VolumeChangeListener(this);
+		volumeChangeListener = new VolumeChangeListener(openProject);
 		lockedListener = new LockedListener(this);
 		layoutChangedListener = new LayoutChangedListener();
 		initMapper(openProject);
@@ -178,7 +180,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 		padGridPane.getStyleClass().add("pad-grid");
 
 		notificationPane = new NotificationPane(padGridPane);
-		notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK);
+		notificationPane.getStyleClass().add(org.controlsfx.control.NotificationPane.STYLE_CLASS_DARK);
 
 		gridContainer.getChildren().add(notificationPane);
 		setAnchor(notificationPane, 0, 0, 0, 0);
@@ -189,6 +191,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 		return mainLayout;
 	}
 
+	@Override
 	public void setMainLayout(MainLayoutConnect mainLayoutConnect) {
 		removePadsFromView();
 		removePadViews();
@@ -308,10 +311,10 @@ public class MainViewController extends ViewController implements IMainViewContr
 				if (result.isPresent()) {
 					globalSettings.setIgnoreSaveDialog(alert.isSelected());
 					ButtonType buttonType = result.get();
-					if (buttonType == ButtonType.YES) {
+					if (buttonType.getButtonData() == ButtonData.YES) {
 						// Projekt Speichern
 						saveProject();
-					} else if (buttonType == ButtonType.CANCEL) {
+					} else if (buttonType.getButtonData() == ButtonData.CANCEL_CLOSE) {
 						return false;
 					}
 				}
@@ -354,7 +357,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 
 	private void saveProject() {
 		try {
-			if (openProject.getRef() != null) {
+			if (openProject.getProjectReference() != null) {
 				openProject.save();
 				System.out.println("Saved Project: " + openProject);
 			}
@@ -374,17 +377,19 @@ public class MainViewController extends ViewController implements IMainViewContr
 	public void openProject(Project project) {
 		removePadsFromView();
 
-		if (project != null)
+		if (openProject != null)
 			removePadsFromView();
 
 		openProject = project;
 
+		volumeChangeListener.setOpenProject(openProject);
 		midiHandler.setProject(project);
 		keyboardHandler.setProject(project);
+		Profile.currentProfile().getMappings().getActiveMapping().showFeedback(openProject);
 
 		midiHandler.setProject(project);
 		keyboardHandler.setProject(project);
-		PadDragListener.setProject(project);
+		DesktopPadDragListener.setProject(project);
 		ErrorSummaryDialog.getInstance().setProject(openProject);
 
 		menuToolbarViewController.setOpenProject(openProject);
@@ -405,7 +410,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 
 		// Table
 		padGridPane.getColumnConstraints().clear();
-		double xPercentage = 1.0 / (double) projectSettings.getColumns();
+		double xPercentage = 1.0 / projectSettings.getColumns();
 		for (int i = 0; i < projectSettings.getColumns(); i++) {
 			ColumnConstraints c = new ColumnConstraints();
 			c.setPercentWidth(xPercentage * 100);
@@ -413,7 +418,7 @@ public class MainViewController extends ViewController implements IMainViewContr
 		}
 
 		padGridPane.getRowConstraints().clear();
-		double yPercentage = 1.0 / (double) projectSettings.getRows();
+		double yPercentage = 1.0 / projectSettings.getRows();
 		for (int i = 0; i < projectSettings.getRows(); i++) {
 			RowConstraints c = new RowConstraints();
 			c.setPercentHeight(yPercentage * 100);
@@ -463,15 +468,13 @@ public class MainViewController extends ViewController implements IMainViewContr
 	private void addPadsToView() {
 		ProjectSettings settings = openProject.getSettings();
 
-		int index = currentPageShowing * settings.getRows() * settings.getColumns();
 		for (int i = 0; i < settings.getRows() * settings.getColumns(); i++) {
 			if (padViews.size() > i) {
 				IPadView view = padViews.get(i);
-				Pad pad = openProject.getPad(index);
+				Pad pad = openProject.getPad(new PadIndex(i, currentPageShowing));
 
 				view.getViewController().setupPad(pad);
 			}
-			index++;
 		}
 	}
 
@@ -490,9 +493,8 @@ public class MainViewController extends ViewController implements IMainViewContr
 		if (openProject == null) {
 			return false;
 		}
-		ProjectSettings projectSettings = openProject.getSettings();
 
-		if (page < 0 || page >= projectSettings.getPageCount()) {
+		if (page < 0 || page >= openProject.getPages().size()) {
 			return false;
 		}
 
@@ -504,6 +506,8 @@ public class MainViewController extends ViewController implements IMainViewContr
 		if (menuToolbarViewController != null) {
 			menuToolbarViewController.highlightPageButton(page);
 		}
+		loadUserCss();
+		
 		return true;
 	}
 
@@ -512,16 +516,6 @@ public class MainViewController extends ViewController implements IMainViewContr
 		return currentPageShowing;
 	}
 
-	@Override
-	public void setGlobalVolume(double volume) {
-		if (openProject != null) {
-			for (Pad pad : openProject.getPads().values()) {
-				if (pad != null)
-					pad.setMasterVolume(volume);
-			}
-		}
-	}
-
 	// Settings
 	@Override
 	public void reloadSettings(Profile old, Profile currentProfile) {
@@ -557,14 +551,16 @@ public class MainViewController extends ViewController implements IMainViewContr
 			Worker.runLater(() ->
 			{
 				loadMidiDevice(profileSettings.getMidiDevice());
-				Profile.currentProfile().getMappings().getActiveMapping().adjustPadColorToMapper(openProject);
-
+				
 				Platform.runLater(() ->
 				{
 					// Handle Mapper
-					if (Profile.currentProfile() != null) {
+					if (currentProfile != null) {
 						activeMapping.initFeedback();
-						activeMapping.showFeedback(openProject);
+						if (openProject != null) {
+							activeMapping.showFeedback(openProject);
+							currentProfile.getMappings().getActiveMapping().adjustPadColorToMapper();
+						}
 					}
 				});
 			});
@@ -654,6 +650,20 @@ public class MainViewController extends ViewController implements IMainViewContr
 		getParent().getScene().addEventHandler(eventType, listener);
 	}
 
+	@Override
+	public <T extends Event> void addListenerForPads(EventHandler<? super T> handler, EventType<T> eventType) {
+		for (IPadView view : padViews) {
+			view.getRootNode().addEventFilter(eventType, handler);
+		}
+	}
+	
+	@Override
+	public <T extends Event> void removeListenerForPads(EventHandler<? super T> handler, EventType<T> eventType) {
+		for (IPadView view : padViews) {
+			view.getRootNode().removeEventFilter(eventType, handler);
+		}
+	}
+
 	@Override
 	public void loadUserCss() {
 		Scene scene = getStage().getScene();
@@ -668,10 +678,13 @@ public class MainViewController extends ViewController implements IMainViewContr
 
 		// design spezific css
 		if (openProject != null) {
-			Profile.currentProfile().currentLayout().applyCssMainView(this, getStage(), openProject);
+			Profile currentProfile = Profile.currentProfile();
+			currentProfile.currentLayout().applyCssMainView(this, getStage(), openProject);
+			
+			Mapping activeMapping = currentProfile.getMappings().getActiveMapping();
+			activeMapping.adjustPadColorToMapper();
+			activeMapping.showFeedback(openProject);
 		}
-
-		Profile.currentProfile().getMappings().getActiveMapping().adjustPadColorToMapper(openProject);
 	}
 
 	/**
@@ -695,9 +708,10 @@ public class MainViewController extends ViewController implements IMainViewContr
 		}
 	}
 
+	@Override
 	public void updateWindowTitle() {
 		if (openProject != null && Profile.currentProfile() != null) {
-			getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title, openProject.getRef().getName(),
+			getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title, openProject.getProjectReference().getName(),
 					Profile.currentProfile().getRef().getName()));
 		} else {
 			getStage().setTitle(Localization.getString(Strings.UI_Window_Main_Title));
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java
index 2d017c45054c6cc0a50273085ea55886c5765d3d..382803a4290b5c1611ed74a4731c4502c1bf5a66 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java
@@ -1,18 +1,30 @@
 package de.tobias.playpad.viewcontroller.main;
 
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.project.Project;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 
 public class VolumeChangeListener implements ChangeListener<Number> {
 
-	private IMainViewController mainViewController;
+	private Project openProject;
 
-	public VolumeChangeListener(IMainViewController mainViewController) {
-		this.mainViewController = mainViewController;
+	public VolumeChangeListener(Project openProject) {
+		this.openProject = openProject;
+	}
+
+	public void setOpenProject(Project openProject) {
+		this.openProject = openProject;
 	}
 
 	@Override
 	public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
-		mainViewController.setGlobalVolume(newValue.doubleValue());
+		if (openProject != null) {
+			for (Pad pad : openProject.getPads()) {
+				if (pad != null && pad.getStatus() != PadStatus.EMPTY)
+					pad.getContent().updateVolume();
+			}
+		}
 	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java
index 81b5e1992d378e5a8c151cdcf0896b5ee17d0104..8a9fbce01763b5933bb0c16ae160f6e45e039f1d 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/DoubleFeedbackViewController.java
@@ -11,7 +11,7 @@ import de.tobias.playpad.action.feedback.FeedbackMessage;
 import de.tobias.playpad.action.mapper.feedback.DoubleMidiFeedback;
 import de.tobias.playpad.action.mididevice.Device;
 import de.tobias.playpad.midi.Midi;
-import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.view.ColorPickerView;
 import de.tobias.utils.ui.ContentViewController;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
@@ -84,7 +84,7 @@ public class DoubleFeedbackViewController extends ContentViewController {
 					color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.EVENT));
 				}
 				
-				ColorView colorView = new ColorView(color, device.getColors(), item ->
+				ColorPickerView colorView = new ColorPickerView(color, device.getColors(), item ->
 				{
 					colorChooser.hide();
 					if (item instanceof DisplayableFeedbackColor) {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java
index 94cfd8b3228a1e354861e70e34948b09e345036b..b29ff5718a8d4d2e294b3f9d272588bbd686bdf4 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/feedback/SingleFeedbackViewController.java
@@ -11,7 +11,7 @@ import de.tobias.playpad.action.feedback.FeedbackMessage;
 import de.tobias.playpad.action.mapper.feedback.SingleMidiFeedback;
 import de.tobias.playpad.action.mididevice.Device;
 import de.tobias.playpad.midi.Midi;
-import de.tobias.playpad.view.ColorView;
+import de.tobias.playpad.view.ColorPickerView;
 import de.tobias.utils.ui.ContentViewController;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
@@ -65,7 +65,7 @@ public class SingleFeedbackViewController extends ContentViewController {
 			{
 				DisplayableFeedbackColor color = device.getColor(feedback.getValueForFeedbackMessage(FeedbackMessage.STANDARD));
 
-				ColorView colorView = new ColorView(color, device.getColors(), item ->
+				ColorPickerView colorView = new ColorPickerView(color, device.getColors(), item ->
 				{
 					colorChooser.hide();
 					if (item instanceof DisplayableFeedbackColor) {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/GlobalSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/GlobalSettingsViewController.java
index e7551ff2c858cff00df4d0e07478cc898948bfec..71db68f789744e5f92362aad7331b817ccd9b169 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/GlobalSettingsViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/GlobalSettingsViewController.java
@@ -103,6 +103,7 @@ public class GlobalSettingsViewController extends ViewController implements IGlo
 		}
 	}
 
+	@Override
 	public boolean closeRequest() {
 		return onFinish();
 	}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/UpdateTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/UpdateTabViewController.java
index bc7aeddd7ec4750cb9aae7cd1b5ec6614a03a483..805b15feba95781de7a272f13aff4e475a19f363 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/UpdateTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/global/UpdateTabViewController.java
@@ -7,14 +7,14 @@ import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.settings.GlobalSettings;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
-import de.tobias.playpad.update.UpdateRegistery;
 import de.tobias.playpad.update.Updates;
 import de.tobias.playpad.viewcontroller.cell.EnumCell;
 import de.tobias.playpad.viewcontroller.cell.UpdateCell;
 import de.tobias.playpad.viewcontroller.dialog.UpdaterDialog;
 import de.tobias.playpad.viewcontroller.option.GlobalSettingsTabViewController;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
+import de.tobias.updater.client.UpdateRegistery;
 import de.tobias.utils.application.ApplicationInfo;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.util.Localization;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java
index 468c689d0beae454669725b3c0e072e37c87c4a1..111ad6285b739667f3ffb71d3013f3c03c34b50e 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PadSettingsViewController.java
@@ -8,10 +8,10 @@ import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadContentRegistry;
 import de.tobias.playpad.pad.PadStatus;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.pad.conntent.path.MultiPathContent;
 import de.tobias.playpad.pad.conntent.path.SinglePathContent;
 import de.tobias.playpad.registry.NoSuchComponentException;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PathLookupListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PathLookupListener.java
index c397e4e397e471a2bd578e654599b4d6f901cdd0..ef255025e7b51c7511dd1ff459bda7d9d373111f 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PathLookupListener.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PathLookupListener.java
@@ -21,6 +21,7 @@ public class PathLookupListener implements EventHandler<ActionEvent> {
 		this.alertable = alertable;
 	}
 
+	@Override
 	public void handle(ActionEvent event) {
 		Object source = event.getSource();
 		if (source instanceof Button) {
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java
index 8757543768ae05b1b536979e26c6cdc1d0960322..3bb69488e0b907a031b3c9643884a89e51f2daba 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/PlayerPadTabViewController.java
@@ -5,7 +5,6 @@ import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadSettings;
 import de.tobias.playpad.settings.Fade;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
 import de.tobias.playpad.viewcontroller.settings.FadeViewController;
 import de.tobias.playpad.viewcontroller.settings.WarningFeedbackViewController;
@@ -13,6 +12,7 @@ import de.tobias.utils.util.Localization;
 import javafx.fxml.FXML;
 import javafx.scene.control.CheckBox;
 import javafx.scene.layout.VBox;
+import javafx.util.Duration;
 
 public class PlayerPadTabViewController extends PadSettingsTabViewController {
 
@@ -60,7 +60,7 @@ public class PlayerPadTabViewController extends PadSettingsTabViewController {
 			PadSettings padSettings = pad.getPadSettings();
 
 			if (c && !padSettings.isCustomWarning())
-				padSettings.setWarning(new Warning());
+				padSettings.setWarning(Duration.seconds(5));
 			else if (!c && padSettings.isCustomWarning())
 				padSettings.setWarning(null);
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java
index 49df6c486600731271687aaf3075bfdea243f686..818e56c64718846bd39a995c08bab1e70191b481 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/TriggerPadTabViewController.java
@@ -7,7 +7,7 @@ import de.tobias.playpad.Strings;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.tigger.Trigger;
 import de.tobias.playpad.tigger.TriggerPoint;
-import de.tobias.playpad.trigger.TriggerUIWrapper;
+import de.tobias.playpad.trigger.TriggerDisplayable;
 import de.tobias.playpad.viewcontroller.PadSettingsTabViewController;
 import de.tobias.playpad.viewcontroller.cell.DisplayableTreeCell;
 import de.tobias.playpad.viewcontroller.option.pad.trigger.TriggerPointViewController;
@@ -20,9 +20,9 @@ import javafx.scene.control.TreeView;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.VBox;
 
-public class TriggerPadTabViewController extends PadSettingsTabViewController implements ChangeListener<TreeItem<TriggerUIWrapper>> {
+public class TriggerPadTabViewController extends PadSettingsTabViewController implements ChangeListener<TreeItem<TriggerDisplayable>> {
 
-	@FXML private TreeView<TriggerUIWrapper> treeView;
+	@FXML private TreeView<TriggerDisplayable> treeView;
 	@FXML private VBox contentView;
 
 	private Pad pad;
@@ -40,25 +40,26 @@ public class TriggerPadTabViewController extends PadSettingsTabViewController im
 
 	private void createTreeView() {
 		HashMap<TriggerPoint, Trigger> triggers = pad.getPadSettings().getTriggers();
-		TreeItem<TriggerUIWrapper> rootItem = new TreeItem<>();
+		TreeItem<TriggerDisplayable> rootItem = new TreeItem<>();
 
 		// Sort the tpyes for the treeview
 		for (TriggerPoint point : TriggerPoint.values()) {
 			Trigger trigger = triggers.get(point);
 
-			TreeItem<TriggerUIWrapper> triggerItem = new TreeItem<>(new TriggerUIWrapper(trigger));
+			TreeItem<TriggerDisplayable> triggerItem = new TreeItem<>(new TriggerDisplayable(trigger));
 			rootItem.getChildren().add(triggerItem);
 		}
 
 		treeView.setRoot(rootItem);
 	}
 
-	public void changed(ObservableValue<? extends TreeItem<TriggerUIWrapper>> observable, TreeItem<TriggerUIWrapper> oldValue,
-			TreeItem<TriggerUIWrapper> newValue) {
+	@Override
+	public void changed(ObservableValue<? extends TreeItem<TriggerDisplayable>> observable, TreeItem<TriggerDisplayable> oldValue,
+			TreeItem<TriggerDisplayable> newValue) {
 		contentView.getChildren().clear();
 
 		if (newValue != null) {
-			TriggerUIWrapper triggerWrapper = newValue.getValue();
+			TriggerDisplayable triggerWrapper = newValue.getValue();
 			TriggerPointViewController controller = new TriggerPointViewController(triggerWrapper);
 			contentView.getChildren().setAll(controller.getParent());
 			VBox.setVgrow(controller.getParent(), Priority.ALWAYS);
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java
index 5e5f457bb24a08f10381e3c0053fe3ffb2b73482..69e604402909e4f4c2f497af0a8c3842b6c3eb64 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/CartTriggerViewController.java
@@ -1,20 +1,37 @@
 package de.tobias.playpad.viewcontroller.option.pad.trigger;
 
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import org.controlsfx.control.textfield.TextFields;
+
 import de.tobias.playpad.PlayPadMain;
+import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.project.Project;
 import de.tobias.playpad.trigger.CartTriggerItem;
 import de.tobias.utils.ui.ContentViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
+import javafx.scene.control.Button;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.ComboBox;
+import javafx.scene.control.ContentDisplay;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
 import javafx.scene.control.TextField;
-
+import javafx.util.Callback;
 
 public class CartTriggerViewController extends ContentViewController {
 
 	@FXML private ComboBox<PadStatus> statusComboBox;
 	@FXML private CheckBox allCartsCheckbox;
 	@FXML private TextField cartTextField;
+	@FXML private ListView<UUID> addedCarts;
+	@FXML private Button addButton;
 
 	private CartTriggerItem item;
 
@@ -24,7 +41,7 @@ public class CartTriggerViewController extends ContentViewController {
 
 		statusComboBox.setValue(item.getNewStatus());
 		allCartsCheckbox.setSelected(item.isAllCarts());
-		cartTextField.setText(item.getCartsString());
+		addedCarts.getItems().setAll(item.getCarts());
 	}
 
 	@Override
@@ -34,13 +51,46 @@ public class CartTriggerViewController extends ContentViewController {
 
 		allCartsCheckbox.selectedProperty().addListener((a, b, c) ->
 		{
-			cartTextField.setDisable(c);
 			item.setAllCarts(c);
 		});
-		cartTextField.textProperty().addListener((a, b, c) ->
-		{
-			if (c != null && !c.isEmpty())
-				item.setCartsString(c);
+
+		// Auto Complete
+		Project project = PlayPadMain.getProgramInstance().getCurrentProject();
+		Set<String> names = project.getPads().stream().filter(p -> p.getStatus() != PadStatus.EMPTY).map(Pad::getName)
+				.collect(Collectors.toSet());
+		TextFields.bindAutoCompletion(cartTextField, names);
+
+		addedCarts.setCellFactory(new Callback<ListView<UUID>, ListCell<UUID>>() {
+
+			@Override
+			public ListCell<UUID> call(ListView<UUID> param) {
+				ListCell<UUID> cell = new ListCell<UUID>() {
+					@Override
+					protected void updateItem(UUID item, boolean empty) {
+						super.updateItem(item, empty);
+						if (!empty) {
+							setGraphic(new Button("", new FontIcon(FontAwesomeType.TRASH)));
+							setContentDisplay(ContentDisplay.RIGHT);
+							Project project = PlayPadMain.getProgramInstance().getCurrentProject();
+							setText(project.getPad(item).getName());
+						}
+					}
+				};
+				return cell;
+			}
 		});
 	}
+
+	@FXML
+	private void addHandler(ActionEvent event) {
+		Project project = PlayPadMain.getProgramInstance().getCurrentProject();
+		for (Pad pad : project.getPads()) {
+			if (pad.getStatus() != PadStatus.EMPTY) {
+				if (pad.getName().equals(cartTextField.getText())) {
+					item.getCarts().add(pad.getUuid());
+					addedCarts.getItems().add(pad.getUuid());
+				}
+			}
+		}
+	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java
index 04a53006c8bda7d22cb25f7b958cbc8336f0d917..19421ded87abb3bdaeff6515896d94d9c0a9c8af 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/pad/trigger/TriggerPointViewController.java
@@ -7,7 +7,7 @@ import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.tigger.TriggerItem;
 import de.tobias.playpad.tigger.TriggerItemConnect;
-import de.tobias.playpad.trigger.TriggerUIWrapper;
+import de.tobias.playpad.trigger.TriggerDisplayable;
 import de.tobias.utils.ui.ContentViewController;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
@@ -23,9 +23,9 @@ public class TriggerPointViewController extends ContentViewController {
 	@FXML private VBox itemView;
 	@FXML private HBox buttonBox;
 
-	private TriggerUIWrapper triggerWrapper;
+	private TriggerDisplayable triggerWrapper;
 
-	public TriggerPointViewController(TriggerUIWrapper triggerWrapper) {
+	public TriggerPointViewController(TriggerDisplayable triggerWrapper) {
 		super("triggerPoint", "de/tobias/playpad/assets/view/option/pad/trigger/", PlayPadMain.getUiResourceBundle());
 		this.triggerWrapper = triggerWrapper;
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/AudioTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/AudioTabViewController.java
index e83f9a002ea0c3e33e757e3d006526d0b062a5b4..d577a3a3313f4ecf2c82e5cddd2fb56fb7543e9b 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/AudioTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/AudioTabViewController.java
@@ -1,8 +1,13 @@
 package de.tobias.playpad.viewcontroller.option.profile;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
+import de.tobias.playpad.audio.AudioCapability;
+import de.tobias.playpad.audio.AudioHandlerConnect;
 import de.tobias.playpad.audio.AudioRegistry;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.registry.NoSuchComponentException;
@@ -12,18 +17,25 @@ import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.option.IProfileReloadTask;
 import de.tobias.playpad.viewcontroller.option.ProfileSettingsTabViewController;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
 import de.tobias.utils.util.Localization;
 import javafx.concurrent.Task;
 import javafx.fxml.FXML;
+import javafx.geometry.Pos;
+import javafx.scene.Parent;
 import javafx.scene.control.ComboBox;
-import javafx.scene.layout.AnchorPane;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
 
 public class AudioTabViewController extends ProfileSettingsTabViewController implements IProfileReloadTask {
 
 	// Audio
 	@FXML private ComboBox<String> audioTypeComboBox;
-	@FXML private AnchorPane audioUserInfoSettings;
-	private AudioHandlerViewController audioViewController;
+	@FXML private VBox options;
+
+	private List<AudioHandlerViewController> audioViewController;
 	private boolean changeAudioSettings;
 
 	public AudioTabViewController(boolean playerActive) {
@@ -31,12 +43,14 @@ public class AudioTabViewController extends ProfileSettingsTabViewController imp
 
 		if (playerActive) {
 			audioTypeComboBox.setDisable(true);
-			audioUserInfoSettings.setDisable(true);
+			options.setDisable(true);
 		}
 	}
 
 	@Override
 	public void init() {
+		audioViewController = new ArrayList<>();
+
 		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
 
 		// Audio Classes
@@ -44,8 +58,7 @@ public class AudioTabViewController extends ProfileSettingsTabViewController imp
 		audioTypeComboBox.getItems().addAll(audioHandlerRegistry.getTypes());
 
 		// Listener for selection
-		audioTypeComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) ->
-		{
+		audioTypeComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) -> {
 			if (b != null && c != null)
 				changeAudioSettings = true;
 			showAudioSettings(c);
@@ -55,26 +68,55 @@ public class AudioTabViewController extends ProfileSettingsTabViewController imp
 
 	private void showAudioSettings(String classID) {
 		if (audioViewController != null) {
-			if (audioViewController.isChanged()) {
+			// Es gibt ein Settings View Controller der isChanged true ist
+			if (audioViewController.stream().filter(c -> c.isChanged()).count() > 0) {
 				changeAudioSettings = true;
 			}
 		}
 
-		audioUserInfoSettings.getChildren().clear();
+		options.getChildren().clear();
 
+		AudioRegistry audioHandlerRegistry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
 		try {
-			AudioRegistry audioHandlerRegistry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
-			audioViewController = audioHandlerRegistry.getComponent(classID).getAudioHandlerSettingsViewController();
+			AudioHandlerConnect audio = audioHandlerRegistry.getComponent(classID);
 
-			if (audioViewController != null) {
-				audioUserInfoSettings.getChildren().add(audioViewController.getParent());
+			for (AudioCapability audioCapability : AudioCapability.getFeatures()) {
+				options.getChildren().add(createCapabilityView(audio, audioCapability));
 			}
 		} catch (NoSuchComponentException e) {
 			e.printStackTrace();
-			// TODO Errorhandling
 		}
 	}
 
+	private Parent createCapabilityView(AudioHandlerConnect audio, AudioCapability audioCapability) {
+		HBox masterView = new HBox(14);
+		VBox detailView = new VBox(14);
+
+		Label nameLabel = new Label(Localization.getString(audioCapability.getName()));
+		nameLabel.setAlignment(Pos.CENTER_RIGHT);
+		nameLabel.setMinWidth(150);
+
+		AudioHandlerViewController settingsViewController = null;
+
+		Label availableLabel;
+		if (audio.isFeatureAvaiable(audioCapability)) {
+			availableLabel = new FontIcon(FontAwesomeType.CHECK);
+
+			settingsViewController = audio.getAudioFeatureSettings(audioCapability);
+		} else {
+			availableLabel = new FontIcon(FontAwesomeType.TIMES);
+		}
+
+		detailView.getChildren().add(availableLabel);
+		if (settingsViewController != null) {
+			detailView.getChildren().add(settingsViewController.getParent());
+			audioViewController.add(settingsViewController);
+		}
+
+		masterView.getChildren().addAll(nameLabel, detailView);
+		return masterView;
+	}
+
 	@Override
 	public void loadSettings(Profile profile) {
 		ProfileSettings profileSettings = profile.getProfileSettings();
@@ -93,10 +135,8 @@ public class AudioTabViewController extends ProfileSettingsTabViewController imp
 
 	@Override
 	public boolean needReload() {
-		if (audioViewController != null) {
-			if (audioViewController.isChanged()) {
-				changeAudioSettings = true;
-			}
+		if (audioViewController.stream().filter(c -> c.isChanged()).count() > 0) {
+			changeAudioSettings = true;
 		}
 		return changeAudioSettings;
 	}
@@ -104,6 +144,7 @@ public class AudioTabViewController extends ProfileSettingsTabViewController imp
 	@Override
 	public Task<Void> getTask(ProfileSettings settings, Project project, IMainViewController controller) {
 		return new Task<Void>() {
+
 			@Override
 			protected Void call() throws Exception {
 				updateTitle(name());
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/DesignTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/DesignTabViewController.java
index d0585f047370d9990842adf8841c03fa03fe450e..bd24b753b9a6ad7d9ee6cc4e1f2cc16d8d8e8cb4 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/DesignTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/DesignTabViewController.java
@@ -3,8 +3,8 @@ package de.tobias.playpad.viewcontroller.option.profile;
 import de.tobias.playpad.PlayPadMain;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.Strings;
-import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.design.DesignConnect;
+import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.settings.Profile;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/MappingTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/MappingTabViewController.java
index f1fe20a9a9946fd2a2b116faa07548bcbdde439a..688b4b0f5e3b80b2b4ca0eb46bf95d4ba14b7685 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/MappingTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/MappingTabViewController.java
@@ -172,8 +172,7 @@ public class MappingTabViewController extends ProfileSettingsTabViewController i
 				updateTitle(name());
 				updateProgress(-1, -1);
 				
-				Project currentProject = PlayPadMain.getProgramInstance().getCurrentProject();
-				Profile.currentProfile().getMappings().getActiveMapping().adjustPadColorToMapper(currentProject);
+				Profile.currentProfile().getMappings().getActiveMapping().adjustPadColorToMapper();
 
 				Mapping activeMapping = Profile.currentProfile().getMappings().getActiveMapping();
 
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/ProfileSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/ProfileSettingsViewController.java
index 5d37af62d3c566b6d4f338ed640dc0eb79ddcc04..ae657afc775973a86d806fe2563d07e3849fa8be 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/ProfileSettingsViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/profile/ProfileSettingsViewController.java
@@ -140,6 +140,7 @@ public class ProfileSettingsViewController extends ViewController implements IPr
 		}
 	}
 
+	@Override
 	public boolean closeRequest() {
 		return onFinish();
 	}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/GeneralTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/GeneralTabViewController.java
index 24fe811955fbb7b5e7e7d5d3d1bc00ec5b09bcfb..f1fb5142df4839f85760a0c8df77d9e7f1282fc8 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/GeneralTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/GeneralTabViewController.java
@@ -25,7 +25,6 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 	private Screen mainWindowScreen;
 	private Alertable parentController; // Für Benachrichtungen
 
-	@FXML private TextField pageCountTextField;
 	@FXML private TextField columnTextField;
 	@FXML private TextField rowTextField;
 
@@ -38,27 +37,12 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 		if (activePlayer) {
 			rowTextField.setDisable(true);
 			columnTextField.setDisable(true);
-			pageCountTextField.setDisable(true);
 		}
 
 	}
 
 	@Override
 	public void init() {
-		pageCountTextField.textProperty().addListener((a, b, c) ->
-		{
-			if (c.matches(DIGIT_POSITIV) && !c.isEmpty()) {
-				int number = Integer.valueOf(c);
-				if (number > ProjectSettings.MAX_PAGES) {
-					pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Zahl zu groß
-				} else {
-					pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, false); // Zahl ok
-				}
-			} else {
-				pageCountTextField.pseudoClassStateChanged(PseudoClasses.ERROR_CLASS, true); // Negativ oder leer
-			}
-		});
-
 		columnTextField.textProperty().addListener((a, b, c) ->
 		{
 			if (c.matches(DIGIT_POSITIV) && !c.isEmpty()) {
@@ -98,14 +82,12 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 
 			if (neededHeight <= height && neededWidth <= width)
 				return true;
-		} catch (NumberFormatException e) {
-		}
+		} catch (NumberFormatException e) {}
 		return false;
 	}
 
 	@Override
 	public void loadSettings(ProjectSettings settings) {
-		pageCountTextField.setText(String.valueOf(settings.getPageCount()));
 		columnTextField.setText(String.valueOf(settings.getColumns()));
 		rowTextField.setText(String.valueOf(settings.getRows()));
 
@@ -125,9 +107,8 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 	public void saveSettings(ProjectSettings settings) {
 		int columns = Integer.valueOf(columnTextField.getText());
 		int rows = Integer.valueOf(rowTextField.getText());
-		int pageCount = Integer.valueOf(pageCountTextField.getText());
 
-		if (settings.getColumns() != columns || settings.getRows() != rows || settings.getPageCount() != pageCount)
+		if (settings.getColumns() != columns || settings.getRows() != rows)
 			changeSettings = true;
 		else
 			changeSettings = false;
@@ -135,7 +116,6 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 		// Copy Settings
 		settings.setColumns(columns);
 		settings.setRows(rows);
-		settings.setPageCount(pageCount);
 	}
 
 	@Override
@@ -143,28 +123,6 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 		return changeSettings;
 	}
 
-	// @Override
-	// public void reload(ProjectSettings settings, Project project, IMainViewController controller) {
-	// Alert alert = new Alert(AlertType.INFORMATION);
-	// alert.setContentText(Localization.getString(Strings.UI_Window_Settings_Gen_Wait));
-	//
-	// alert.getButtonTypes().clear();
-	// alert.initOwner(controller.getStage());
-	// alert.initModality(Modality.WINDOW_MODAL);
-	// Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
-	// PlayPadMain.stageIcon.ifPresent(stage.getIcons()::add);
-	//
-	// alert.show();
-	//
-	// Worker.runLater(() ->
-	// {
-	// Platform.runLater(() ->
-	// {
-	//
-	// });
-	// });
-	// }
-
 	@Override
 	public boolean validSettings() {
 		if (screenValid()) {
@@ -191,6 +149,7 @@ public class GeneralTabViewController extends ProjectSettingsTabViewController i
 	@Override
 	public Task<Void> getTask(ProjectSettings settings, Project project, IMainViewController controller) {
 		return new Task<Void>() {
+
 			@Override
 			protected Void call() throws Exception {
 				updateTitle(name());
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/PathsTabViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/PathsTabViewController.java
index 551b2d4cba545afd719ada399446cf3d4b94edae..c5cc0bc29096bc194d8a97511f091eff7274a7b3 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/PathsTabViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/PathsTabViewController.java
@@ -122,7 +122,7 @@ public class PathsTabViewController extends ProjectSettingsTabViewController imp
 
 				project.closeFile();
 
-				for (Pad pad : project.getPads().values()) {
+				for (Pad pad : project.getPads()) {
 					try {
 						if (pad.getStatus() != PadStatus.EMPTY) {
 							PadContent content = pad.getContent();
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/ProjectSettingsViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/ProjectSettingsViewController.java
index 6d284bb6d5a013c3a4bdb4fac3ff82cc37c8de99..e5bcc71048895486d6dc71664977e6ca6bd89a3a 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/ProjectSettingsViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/option/project/ProjectSettingsViewController.java
@@ -11,8 +11,8 @@ import de.tobias.playpad.project.Project;
 import de.tobias.playpad.project.ProjectSettings;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
-import de.tobias.playpad.viewcontroller.option.IProjectSettingsViewController;
 import de.tobias.playpad.viewcontroller.option.IProjectReloadTask;
+import de.tobias.playpad.viewcontroller.option.IProjectSettingsViewController;
 import de.tobias.playpad.viewcontroller.option.ProjectSettingsTabViewController;
 import de.tobias.utils.ui.ViewController;
 import de.tobias.utils.util.Localization;
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java
deleted file mode 100644
index abbbf607050a5f6e31bef72c3a5fabdffb387c21..0000000000000000000000000000000000000000
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadDragListener.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package de.tobias.playpad.viewcontroller.pad;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Set;
-
-import de.tobias.playpad.PlayPadPlugin;
-import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadContentRegistry;
-import de.tobias.playpad.pad.conntent.PadContent;
-import de.tobias.playpad.pad.conntent.PadContentConnect;
-import de.tobias.playpad.pad.drag.PadDragMode;
-import de.tobias.playpad.pad.view.IPadView;
-import de.tobias.playpad.project.Project;
-import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.settings.GlobalSettings;
-import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.view.FileDragOptionView;
-import de.tobias.playpad.view.PadDragOptionView;
-import de.tobias.utils.util.FileUtils;
-import javafx.scene.SnapshotParameters;
-import javafx.scene.image.WritableImage;
-import javafx.scene.input.ClipboardContent;
-import javafx.scene.input.DragEvent;
-import javafx.scene.input.Dragboard;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.input.TransferMode;
-import javafx.scene.layout.Pane;
-import javafx.scene.paint.Color;
-
-public class PadDragListener {
-
-	private static final String REGEX = "[0-9]+";
-	private Pad sourcePad;
-	final private Pane view;
-
-	private static boolean dndMode;
-	private static Project project;
-
-	private PadDragOptionView padHud;
-	private FileDragOptionView fileHud;
-
-	public PadDragListener(Pad pad, IPadView view) {
-		this.sourcePad = pad;
-		this.view = view.getRootNode();
-
-		// Drag and Drop
-		this.view.setOnDragOver(event -> dragOver(event));
-		this.view.setOnDragExited(event -> dragExited());
-		this.view.setOnDragDropped(event -> dragDropped(event));
-		this.view.setOnDragDetected(event -> dragDetacted(event));
-	}
-
-	private void dragOver(DragEvent event) {
-		if (Profile.currentProfile().getProfileSettings().isLocked()) {
-			return;
-		}
-
-		if (event.getGestureSource() != this && event.getDragboard().hasFiles()) {
-			if (event.getDragboard().getFiles().get(0).isFile()) {
-
-				GlobalSettings globalSettings = PlayPadPlugin.getImplementation().getGlobalSettings();
-
-				if (sourcePad.getProject() != null) {
-					if (globalSettings.isLiveMode() && globalSettings.isLiveModeFile() && sourcePad.getProject().getActivePlayers() > 0) {
-						return;
-					}
-				}
-
-				File file = event.getDragboard().getFiles().get(0);
-
-				// Build In Filesupport
-				try {
-					PadContentRegistry registry = PlayPadPlugin.getRegistryCollection().getPadContents();
-					Set<PadContentConnect> connects = registry.getPadContentConnectsForFile(file.toPath());
-
-					if (!connects.isEmpty()) {
-						if (fileHud == null) {
-							fileHud = new FileDragOptionView(view);
-						}
-						fileHud.showDropOptions(connects);
-
-						event.acceptTransferModes(TransferMode.LINK);
-						return;
-					}
-				} catch (NoSuchComponentException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-
-		// Drag and Drop von Pads
-		if (event.getDragboard().hasString() && event.getDragboard().getString().trim().matches(REGEX)) {
-			int padID = Integer.valueOf(event.getDragboard().getString());
-			if (padID != sourcePad.getIndex()) {
-
-				Collection<PadDragMode> connects = PlayPadPlugin.getRegistryCollection().getDragModes().getComponents();
-
-				if (!connects.isEmpty()) {
-					if (padHud == null) {
-						padHud = new PadDragOptionView(view);
-					}
-					padHud.showDropOptions(connects);
-
-					event.acceptTransferModes(TransferMode.MOVE);
-				}
-			}
-		}
-		event.consume();
-	}
-
-	private void dragExited() {
-		if (padHud != null) {
-			padHud.hide();
-		}
-		if (fileHud != null) {
-			fileHud.hide();
-		}
-	}
-
-	private void dragDropped(DragEvent event) {
-		Dragboard db = event.getDragboard();
-		boolean success = false;
-		if (db.hasFiles()) {
-			success = true;
-			File file = db.getFiles().get(0);
-
-			PadContentConnect connect = fileHud.getSelectedConnect();
-			if (connect != null) {
-				PadContent content = sourcePad.getContent();
-				if (sourcePad.getContent() == null || !sourcePad.getContent().getType().equals(connect.getType())) {
-					content = connect.newInstance(sourcePad);
-				}
-
-				try {
-					content.handlePath(file.toPath());
-				} catch (NoSuchComponentException | IOException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-				this.sourcePad.setContent(content);
-				this.sourcePad.setName(FileUtils.getFilenameWithoutExtention(file.toPath().getFileName()));
-
-				if (sourcePad.getController() != null) {
-					IPadView padView = sourcePad.getController().getView();
-					padView.setContentView(sourcePad);
-					padView.addDefaultElement(sourcePad);
-				}
-			}
-		}
-
-		if (db.hasString() && db.getString().matches(REGEX)) {
-			int padID = Integer.valueOf(db.getString());
-
-			PadDragMode mode = padHud.getSelectedPadDragMode();
-			mode.handle(padID, sourcePad.getIndex(), project);
-			padHud.hide();
-
-			PlayPadPlugin.getImplementation().getMainViewController()
-					.showPage(PlayPadPlugin.getImplementation().getMainViewController().getPage());
-
-			event.setDropCompleted(success);
-			event.consume();
-		}
-	}
-
-	private void dragDetacted(MouseEvent event) {
-		if (dndMode) {
-			GlobalSettings globalSettings = PlayPadPlugin.getImplementation().getGlobalSettings();
-
-			if (sourcePad.getProject() != null) {
-				if (globalSettings.isLiveMode() && globalSettings.isLiveModeDrag() && sourcePad.getProject().getActivePlayers() > 0) {
-					return;
-				}
-			}
-
-			Dragboard dragboard = view.startDragAndDrop(TransferMode.MOVE);
-
-			SnapshotParameters parameters = new SnapshotParameters();
-			parameters.setFill(Color.TRANSPARENT);
-			WritableImage snapshot = view.snapshot(parameters, null);
-			for (int x = 0; x < snapshot.getWidth(); x++) {
-				for (int y = 0; y < snapshot.getHeight(); y++) {
-					Color oldColor = snapshot.getPixelReader().getColor(x, y).darker().darker();
-					snapshot.getPixelWriter().setColor(x, y,
-							new Color(oldColor.getRed(), oldColor.getGreen(), oldColor.getBlue(), oldColor.getOpacity() * 0.5));
-				}
-			}
-
-			dragboard.setDragView(snapshot);
-
-			ClipboardContent content = new ClipboardContent();
-			content.putString(String.valueOf(sourcePad.getIndex()));
-			dragboard.setContent(content);
-
-			event.consume();
-		}
-	}
-
-	/**
-	 * Aktiviert den Drag And Drop Modus für Kacheln. Diese Methode muss vom Menu / KeyShortcut aufgerufen werden.
-	 * 
-	 * @param dndMode
-	 *            <code>true</code> Aktiv
-	 */
-	public static void setDndMode(boolean dndMode) {
-		PadDragListener.dndMode = dndMode;
-	}
-
-	@Deprecated
-	public void setPad(Pad pad) {
-		this.sourcePad = pad;
-	}
-
-	public static void setProject(Project project) {
-		PadDragListener.project = project;
-	}
-
-}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java
deleted file mode 100644
index 47372327084c09e2b17c49f972f6956a1e89f1f6..0000000000000000000000000000000000000000
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/pad/PadViewController.java
+++ /dev/null
@@ -1,395 +0,0 @@
-package de.tobias.playpad.viewcontroller.pad;
-
-import java.io.File;
-import java.nio.file.Path;
-
-import de.tobias.playpad.PlayPadPlugin;
-import de.tobias.playpad.PseudoClasses;
-import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.pad.PadStatus;
-import de.tobias.playpad.pad.TimeMode;
-import de.tobias.playpad.pad.conntent.PadContent;
-import de.tobias.playpad.pad.conntent.PadContentConnect;
-import de.tobias.playpad.pad.conntent.play.Durationable;
-import de.tobias.playpad.pad.listener.IPadPositionListener;
-import de.tobias.playpad.pad.listener.PadContentListener;
-import de.tobias.playpad.pad.listener.PadDurationListener;
-import de.tobias.playpad.pad.listener.PadLockedListener;
-import de.tobias.playpad.pad.listener.PadPositionListener;
-import de.tobias.playpad.pad.listener.PadStatusListener;
-import de.tobias.playpad.pad.view.IPadViewController;
-import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileSettings;
-import de.tobias.playpad.view.PadView;
-import de.tobias.playpad.viewcontroller.IPadView;
-import de.tobias.playpad.viewcontroller.main.IMainViewController;
-import de.tobias.playpad.viewcontroller.option.pad.PadSettingsViewController;
-import de.tobias.utils.util.FileUtils;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.stage.Stage;
-import javafx.util.Duration;
-
-public class PadViewController implements EventHandler<ActionEvent>, IPadViewController {
-
-	private static final String DURATION_FORMAT = "%d:%02d";
-	private static final String OPEN_FOLDER = "openFolder";
-
-	private PadView view;
-	private Pad pad;
-
-	private PadLockedListener padLockedListener;
-	private PadStatusListener padStatusListener;
-	private PadContentListener padContentListener;
-	private PadDurationListener padDurationListener;
-	private PadPositionListener padPositionListener;
-
-	private PadDragListener padDragListener;
-	private transient PadSettingsViewController padSettingsViewController;
-
-	public PadViewController() {
-		view = new PadView(this);
-
-		// TODO Disable this
-		/*padLockedListener = new PadLockedListener(this);
-		padStatusListener = new PadStatusListener(this);
-		padContentListener = new PadContentListener(this);
-		padDurationListener = new PadDurationListener(this);
-		padPositionListener = new PadPositionListener(this);*/
-
-		// Listener muss nur einmal hier hinzugefügt werden, weil bei einem neuen Profile, werden neue PadViewController erzeugt
-		ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings();
-		profileSettings.lockedProperty().addListener(padLockedListener);
-	}
-
-	@Override
-	public IPadView getParent() {
-		return view;
-	}
-
-	@Override
-	public void handle(ActionEvent event) {
-		if (event.getSource() == view.getPlayButton()) {
-			onPlay();
-		} else if (event.getSource() == view.getPauseButton()) {
-			onPause();
-		} else if (event.getSource() == view.getStopButton()) {
-			onStop();
-		} else if (event.getSource() == view.getNewButton()) {
-			onNew(event);
-		} else if (event.getSource() == view.getSettingsButton()) {
-			onSettings();
-		}
-	}
-
-	private void onPlay() {
-		if (pad.getContent() != null) {
-			pad.setStatus(PadStatus.PLAY);
-		}
-	}
-
-	private void onPause() {
-		if (pad.getContent() != null) {
-			pad.setStatus(PadStatus.PAUSE);
-		}
-	}
-
-	private void onStop() {
-		if (pad.getContent() != null) {
-			pad.setStatus(PadStatus.STOP);
-		}
-	}
-
-	private void onNew(ActionEvent event) {
-//		ProfileSettings settings = Profile.currentProfile().getProfileSettings();
-//		if (pad.getProject() != null) {
-//			if (settings.isLiveMode() && settings.isLiveModeFile() && pad.getProject().getPlayedPlayers() > 0) {
-//				PlayPadPlugin.getImplementation().getMainViewController().showLiveInfo();
-//				return;
-//			}
-//		}
-//
-//		FileChooser chooser = new FileChooser();
-//
-//		// File Extension
-//		ExtensionFilter extensionFilter = new ExtensionFilter(Localization.getString(Strings.File_Filter_Media),
-//				PadContentRegistry.getSupportedFileTypes());
-//		chooser.getExtensionFilters().add(extensionFilter);
-//
-//		// Last Folder
-//		Object openFolder = ApplicationUtils.getApplication().getUserDefaults().getData(OPEN_FOLDER);
-//		if (openFolder != null) {
-//			File folder = new File(openFolder.toString());
-//			chooser.setInitialDirectory(folder);
-//		}
-//
-//		File file = chooser.showOpenDialog(((Node) event.getTarget()).getScene().getWindow());
-//		if (file != null) {
-//			Path path = file.toPath();
-//
-//			try {
-//				Set<PadContentConnect> connects = PadContentRegistry.getPadContentConnectsForFile(file.toPath());
-//				if (!connects.isEmpty()) {
-//					if (connects.size() > 1) {
-//						FileDragOptionView hud = new FileDragOptionView(view);
-//						hud.showDropOptions(connects, connect ->
-//						{
-//							if (connect != null) {
-//								setNewPadContent(file, path, connect);
-//								hud.hide();
-//							}
-//						});
-//					} else {
-//						PadContentConnect connect = connects.iterator().next();
-//						setNewPadContent(file, path, connect);
-//					}
-//				}
-//			} catch (UnkownPadContentException e) {
-//				e.printStackTrace();
-//			}
-//
-//			ApplicationUtils.getApplication().getUserDefaults().setData(OPEN_FOLDER, path.getParent().toString());
-//		}
-	}
-
-	private void setNewPadContent(File file, Path path, PadContentConnect connect) {
-		PadContent content = pad.getContent();
-		if (pad.getContent() == null || !pad.getContent().getType().equals(connect.getType())) {
-			content = connect.newInstance(pad);
-			this.pad.setContent(content);
-		}
-
-		try {
-			content.handlePath(file.toPath());
-		} catch (NoSuchComponentException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		this.pad.setName(FileUtils.getFilenameWithoutExtention(path.getFileName()));
-	}
-
-	private void onSettings() {
-		ProfileSettings settings = Profile.currentProfile().getProfileSettings();
-		IMainViewController mvc = PlayPadPlugin.getImplementation().getMainViewController();
-
-		if (mvc != null) {
-			if (pad.getProject() != null) {
-				if (settings.isLiveMode() && settings.isLiveModeSettings() && pad.getProject().getPlayedPlayers() > 0) {
-					mvc.showLiveInfo();
-					return;
-				}
-			}
-
-			Stage owner = mvc.getStage();
-			if (padSettingsViewController == null) {
-				padSettingsViewController = new PadSettingsViewController(pad, owner);
-				padSettingsViewController.getStage().setOnHiding(ev ->
-				{
-					if (view != null && pad != null)
-						view.setTriggerLabelActive(pad.hasTriggerItems());
-				});
-			}
-			padSettingsViewController.getStage().show();
-		}
-	}
-
-	@Override
-	public void unconnectPad() {
-		view.getIndexLabel().setText("");
-		view.clearPreviewContent();
-		view.getTimeLabel().setText("");
-
-		view.setTriggerLabelActive(false);
-
-		view.getLoopLabel().visibleProperty().unbind();
-
-		if (pad != null) {
-			pad.contentProperty().removeListener(padContentListener);
-			pad.statusProperty().removeListener(padStatusListener);
-
-			if (pad.getContent() instanceof Durationable) {
-				Durationable durationable = (Durationable) pad.getContent();
-				durationable.durationProperty().removeListener(padDurationListener);
-				durationable.positionProperty().removeListener(padPositionListener);
-			}
-			pad.setController(null);
-			padDragListener = null;
-
-			// GUI Cleaning
-			getPadPositionListener().stopWaning();
-			view.removeStyleClasses(pad);
-		}
-		this.pad = null;
-	}
-
-	@Override
-	public Pad getPad() {
-		return pad;
-	}
-
-	@Override
-	public void setPad(Pad pad) {
-		unconnectPad();
-
-		this.pad = pad;
-
-		view.setPreviewContent(pad);
-		view.addStyleClasses(pad);
-
-		connectPad();
-	}
-
-	@Override
-	public void connectPad() {
-//		pad.setController(this); TODO
-
-		try {
-			// Settings
-			view.getIndexLabel().setText(String.valueOf(pad.getIndexReadable()));
-			view.getLoopLabel().visibleProperty().bind(pad.loopProperty());
-
-			view.setTriggerLabelActive(pad.hasTriggerItems());
-
-			// Update Listener
-			padContentListener.setPad(pad);
-			padPositionListener.setPad(pad);
-
-			// Pad Content Chnage
-			pad.contentProperty().addListener(padContentListener);
-			// Pad Status Change
-			pad.statusProperty().addListener(padStatusListener);
-
-			// First Listener call with new data
-			padContentListener.changed(null, null, pad.getContent()); // Add Duration listener
-			padStatusListener.changed(null, null, pad.getStatus());
-
-//			padDragListener = new PadDragListener(pad, view); TODO
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void updateTimeLabel() {
-		if (pad.getContent() != null && pad.getStatus() != PadStatus.EMPTY && pad.getStatus() != PadStatus.ERROR) {
-			if (pad.getContent() instanceof Durationable) {
-				Durationable durationable = (Durationable) pad.getContent();
-
-				Duration duration = durationable.getDuration();
-				Duration position = durationable.getPosition();
-
-				if (duration != null) {
-					// Nur Gesamtzeit anzeigen
-					if (pad.getStatus() == PadStatus.READY || position == null) {
-						String time = durationToString(duration);
-						view.getTimeLabel().setText(time);
-						view.getPlayBar().setProgress(0);
-					} else {
-						// Play/Gesamtzeit anzeigen
-						TimeMode timeMode = pad.getTimeMode();
-
-						if (timeMode == TimeMode.REST) {
-							Duration leftTime = duration.subtract(position);
-
-							view.getTimeLabel().setText("- " + durationToString(leftTime));
-						} else if (timeMode == TimeMode.PLAYED) {
-							view.getTimeLabel().setText(durationToString(position));
-						} else if (timeMode == TimeMode.BOTH) {
-							String time = durationToString(position);
-							String totalTime = durationToString(duration);
-
-							view.getTimeLabel().setText(time + "/" + totalTime);
-						}
-					}
-				}
-				return;
-			}
-		}
-		view.getPlayBar().setProgress(0);
-		view.getTimeLabel().setText("");
-	}
-
-	public String durationToString(Duration value) {
-		if (value != null) {
-			int secounds = (int) ((value.toMillis() / 1000) % 60);
-			int minutes = (int) ((value.toMillis() / (1000 * 60)) % 60);
-			String time = String.format(DURATION_FORMAT, minutes, secounds);
-			return time;
-		} else {
-			return null;
-		}
-	}
-
-	public void updateButtonDisable() {
-		if (pad == null) {
-			return;
-		}
-		if (pad.getContent() != null) {
-			if (pad.getStatus() == PadStatus.PLAY) {
-				view.getPlayButton().setDisable(true);
-				view.getPauseButton().setDisable(false);
-				view.getStopButton().setDisable(false);
-				view.getNewButton().setDisable(true);
-				view.getSettingsButton().setDisable(false);
-			} else if (pad.getStatus() == PadStatus.PAUSE) {
-				view.getPlayButton().setDisable(false);
-				view.getPauseButton().setDisable(true);
-				view.getStopButton().setDisable(false);
-				view.getNewButton().setDisable(true);
-				view.getSettingsButton().setDisable(false);
-			} else if (pad.getStatus() == PadStatus.STOP) {
-				view.getPlayButton().setDisable(false);
-				view.getPauseButton().setDisable(true);
-				view.getStopButton().setDisable(true);
-				view.getNewButton().setDisable(true);
-				view.getSettingsButton().setDisable(false);
-			} else if (pad.getStatus() == PadStatus.READY) {
-				view.getPlayButton().setDisable(false);
-				view.getPauseButton().setDisable(true);
-				view.getStopButton().setDisable(true);
-				view.getNewButton().setDisable(false);
-				view.getSettingsButton().setDisable(false);
-			} else if (pad.getStatus() == PadStatus.ERROR) {
-				view.getPlayButton().setDisable(true);
-				view.getPauseButton().setDisable(true);
-				view.getStopButton().setDisable(true);
-				view.getNewButton().setDisable(false);
-				view.getSettingsButton().setDisable(false);
-			}
-		} else if (pad.getStatus() == PadStatus.EMPTY || pad.getStatus() == PadStatus.ERROR || pad.getContent() == null
-				|| !pad.getContent().isPadLoaded()) {
-			view.getPlayButton().setDisable(true);
-			view.getPauseButton().setDisable(true);
-			view.getStopButton().setDisable(true);
-			view.getNewButton().setDisable(false);
-			view.getSettingsButton().setDisable(false);
-		}
-
-		if (Profile.currentProfile().getProfileSettings().isLocked()) {
-			view.getNewButton().setDisable(true);
-			view.getSettingsButton().setDisable(true);
-		}
-	}
-
-	@Override
-	public void showDnDLayout(boolean b) {
-		view.pseudoClassState(PseudoClasses.DRAG_CLASS, b);
-	}
-
-	// getter for listener
-	public PadDurationListener getPadDurationListener() {
-		return padDurationListener;
-	}
-
-	public PadStatusListener getPadStatusListener() {
-		return padStatusListener;
-	}
-
-	public IPadPositionListener getPadPositionListener() {
-		return padPositionListener;
-	}
-
-	public PadDragListener getPadDragListener() {
-		return padDragListener;
-	}
-}
diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java
index ff0bb390135736ffb001579e52180aa04c562ab8..f2dca4d82a593bf8c1813d691b1a968d8d06faed 100644
--- a/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java
+++ b/PlayWall/src/de/tobias/playpad/viewcontroller/settings/WarningFeedbackViewController.java
@@ -21,12 +21,12 @@ public class WarningFeedbackViewController extends ContentViewController {
 		super("warningFeedbackSettingsView", "de/tobias/playpad/assets/settings/", PlayPadMain.getUiResourceBundle());
 		ProfileSettings profilSettings = Profile.currentProfile().getProfileSettings();
 
-		warningFeedbackTimeSlider.setValue(profilSettings.getWarningFeedback().getTime().toSeconds());
+		warningFeedbackTimeSlider.setValue(profilSettings.getWarningFeedback().toSeconds());
 		setTimeLabel();
 
 		warningFeedbackTimeSlider.valueProperty().addListener((a, b, c) ->
 		{
-			profilSettings.getWarningFeedback().setTime(Duration.seconds(c.doubleValue()));
+			profilSettings.setWarningTime(Duration.seconds(c.doubleValue()));
 		});
 	}
 
@@ -49,13 +49,13 @@ public class WarningFeedbackViewController extends ContentViewController {
 
 	public void setPadWarning(Pad pad) {
 		if (pad.getPadSettings().getWarning() != null) {
-			warningFeedbackTimeSlider.setValue(pad.getPadSettings().getWarning().getTime().toSeconds());
+			warningFeedbackTimeSlider.setValue(pad.getPadSettings().getWarning().toSeconds());
 			setTimeLabel();
 		}
 
 		warningFeedbackTimeSlider.valueProperty().addListener((a, b, c) ->
 		{
-			pad.getPadSettings().getWarning().setTime(Duration.seconds(c.doubleValue()));
+			pad.getPadSettings().setWarning(Duration.seconds(c.doubleValue()));
 		});
 	}
 }
diff --git a/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java b/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java
new file mode 100644
index 0000000000000000000000000000000000000000..d416c051002d05176f25dcc67f9c744a48440352
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java
@@ -0,0 +1,16 @@
+package de.tobias.playpad.volume;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.settings.Profile;
+
+public class GlobalVolume implements VolumeFilter {
+
+	@Override
+	public double getVolume(Pad pad) {
+		if (Profile.currentProfile() != null) {
+			return Profile.currentProfile().getProfileSettings().getVolume();
+		} else {
+			return 1.0;
+		}
+	}
+}
diff --git a/PlayWall/src/de/tobias/playpad/volume/PadVolume.java b/PlayWall/src/de/tobias/playpad/volume/PadVolume.java
new file mode 100644
index 0000000000000000000000000000000000000000..4781bd629b4256cef761054a66e063e1e289d244
--- /dev/null
+++ b/PlayWall/src/de/tobias/playpad/volume/PadVolume.java
@@ -0,0 +1,11 @@
+package de.tobias.playpad.volume;
+
+import de.tobias.playpad.pad.Pad;
+
+public class PadVolume implements VolumeFilter {
+
+	@Override
+	public double getVolume(Pad pad) {
+		return pad.getPadSettings().getVolume();
+	}
+}
diff --git a/PlayWallCore/.classpath b/PlayWallCore/.classpath
index a6fa9547a624843a634dba5d8d42da36ce69f661..5a6addb13d75837e0d5b1ea9f59ccce4810e8dc6 100644
--- a/PlayWallCore/.classpath
+++ b/PlayWallCore/.classpath
@@ -11,5 +11,6 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JLayer"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Json"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Updater"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/PlayWallCore/src/de/tobias/playpad/PlayPad.java b/PlayWallCore/src/de/tobias/playpad/PlayPad.java
index 7326cfbbde2f9e11be3ef46f1bb3670131f0eb8b..4f08b132929fe17e543caddde537f753800049f4 100644
--- a/PlayWallCore/src/de/tobias/playpad/PlayPad.java
+++ b/PlayWallCore/src/de/tobias/playpad/PlayPad.java
@@ -1,9 +1,11 @@
 package de.tobias.playpad;
 
 import java.net.URI;
+import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
 
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.PadListener;
 import de.tobias.playpad.plugin.SettingsListener;
 import de.tobias.playpad.plugin.WindowListener;
@@ -113,4 +115,11 @@ public interface PlayPad {
 	 * @return Global Settings
 	 */
 	public GlobalSettings getGlobalSettings();
+
+	/**
+	 * Gibt alle aktiven Module zurück.
+	 * 
+	 * @return Module
+	 */
+	public Collection<Module> getModules();
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/PlayPadPlugin.java b/PlayWallCore/src/de/tobias/playpad/PlayPadPlugin.java
index cdd076538f46abdcba1c2e01db8c252360a0723d..3be32345e43b267c3dab88f8e86a2dd4370e7d17 100644
--- a/PlayWallCore/src/de/tobias/playpad/PlayPadPlugin.java
+++ b/PlayWallCore/src/de/tobias/playpad/PlayPadPlugin.java
@@ -1,14 +1,10 @@
 package de.tobias.playpad;
 
-import de.tobias.playpad.project.Project;
-
 public final class PlayPadPlugin {
 
 	private static PlayPad implementation;
 	private static RegistryCollection registryCollection;
 
-	private Project currentProject;
-
 	public static PlayPad getImplementation() {
 		return implementation;
 	}
@@ -29,8 +25,4 @@ public final class PlayPadPlugin {
 	protected static void setRegistryCollection(RegistryCollection registryCollection) {
 		PlayPadPlugin.registryCollection = registryCollection;
 	}
-
-	public Project getCurrentproject() {
-		return currentProject;
-	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/RegistryCollection.java b/PlayWallCore/src/de/tobias/playpad/RegistryCollection.java
index c13e9df65df0fb3af5e87eb45c06d1a3b127ebbb..86f1372ca0fc0bb4aa47aaf6612b478fd68b99b4 100644
--- a/PlayWallCore/src/de/tobias/playpad/RegistryCollection.java
+++ b/PlayWallCore/src/de/tobias/playpad/RegistryCollection.java
@@ -4,7 +4,7 @@ import de.tobias.playpad.action.ActionConnect;
 import de.tobias.playpad.action.mapper.MapperConnect;
 import de.tobias.playpad.audio.AudioRegistry;
 import de.tobias.playpad.design.DesignConnect;
-import de.tobias.playpad.pad.PadContentRegistry;
+import de.tobias.playpad.pad.conntent.PadContentRegistry;
 import de.tobias.playpad.pad.drag.PadDragMode;
 import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.Registry;
diff --git a/PlayWallCore/src/de/tobias/playpad/Updatable.java b/PlayWallCore/src/de/tobias/playpad/Updatable.java
deleted file mode 100644
index 8d3b80e9f9bc64c26dd4b5d711ec78e30884304b..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/Updatable.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package de.tobias.playpad;
-
-import java.net.URL;
-import java.nio.file.Path;
-
-/**
- * Diese Schnittstelle wird dafür verwendet, damit das Programm für Plugins nach Updates suchen kann und diese auch
- * durchführen kann.
- * 
- * @author tobias
- *
- * @since 5.0.0
- */
-
-@Deprecated
-public interface Updatable {
-
-	/**
-	 * Gibt die aktuelle Build Nummer zurück
-	 * 
-	 * @return build number
-	 */
-	public int getCurrentBuild();
-
-	/**
-	 * Gibt die altuelle Programmversion (lesbar) für den Nutzer zurück.
-	 * 
-	 * @return version string
-	 */
-	public String getCurrentVersion();
-
-	/**
-	 * Gibt die neue Buildnummer zurück.
-	 * 
-	 * @return build number
-	 */
-	public int getNewBuild();
-
-	/**
-	 * Gibt die neue Versionsnummer (lesbar) zurück.
-	 * 
-	 * @return version string
-	 */
-	public String getNewVersion();
-
-	/**
-	 * Lädt alle Informationen für Updates vom Server, sodass die Methoden bescheid wissen.
-	 * 
-	 * @return <code>true</code> Erfolgreich.
-	 */
-	public boolean checkUpdate();
-
-	/**
-	 * Gibt den Downloadlink für das Update zurück.
-	 * 
-	 * @return server url
-	 */
-	public URL getDownloadPath();
-
-	/**
-	 * Gibt den Lokalen Pfad zur Datei.
-	 * 
-	 * @return local path
-	 */
-	public Path getLocalPath();
-
-	/**
-	 * Gibt den Display Namen zurück. (lesbar)
-	 * 
-	 * @return name
-	 */
-	public String name();
-
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
index ff4c629b9b32b37ce6c1625db046ae5eed342927..93e5df2219e338f567de94f832a0e6914c6578cd 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/ActionSerializer.java
@@ -7,10 +7,12 @@ import org.dom4j.Element;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.mapper.Mapper;
 import de.tobias.playpad.action.mapper.MapperSerializer;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLHandler;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLHandler;
+import de.tobias.utils.xml.XMLSerializer;
 
 public class ActionSerializer implements XMLSerializer<Action>, XMLDeserializer<Action> {
 
@@ -18,11 +20,25 @@ public class ActionSerializer implements XMLSerializer<Action>, XMLDeserializer<
 	private static final String MAPPER = "Mapper";
 
 	private Mapping mapping;
+	private Profile profile;
 
 	public ActionSerializer(Mapping mapping) {
 		this.mapping = mapping;
 	}
 
+	/**
+	 * Speichern.
+	 * 
+	 * @param mapping
+	 *            mapping
+	 * @param profile
+	 *            profile
+	 */
+	public ActionSerializer(Mapping mapping, Profile profile) {
+		this.mapping = mapping;
+		this.profile = profile;
+	}
+
 	@Override
 	public Action loadElement(Element element) {
 		String tpye = element.attributeValue(ACTION_TYPE);
@@ -49,6 +65,11 @@ public class ActionSerializer implements XMLSerializer<Action>, XMLDeserializer<
 
 	@Override
 	public void saveElement(Element newElement, Action data) {
+		Module module = PlayPadPlugin.getRegistryCollection().getActions().getModule(data.getType());
+		if (profile != null) {
+			profile.getRef().addRequestedModule(module);
+		}
+
 		newElement.addAttribute(ACTION_TYPE, data.getType());
 
 		data.save(newElement);
diff --git a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
index 434731682345ce9d284b5199e0a180e1f16e7385..5198bfea6be0241c01f87558970b3d58b2011e2e 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/Mapping.java
@@ -26,7 +26,7 @@ public class Mapping implements Cloneable, ActionDisplayable {
 	private UUID uuid;
 	private HashMap<Action, List<Mapper>> mapping;
 
-	public Mapping(boolean init, Profile profile) {
+	public Mapping(boolean init) {
 		mapping = new HashMap<>();
 		if (init) {
 			name = "Default";
@@ -161,8 +161,8 @@ public class Mapping implements Cloneable, ActionDisplayable {
 		getActions().forEach(action -> action.clearFeedback());
 	}
 
-	public void adjustPadColorToMapper(Project project) {
-		ColorAdjuster.applyColorsToMappers(project);
+	public void adjustPadColorToMapper() {
+		ColorAdjuster.applyColorsToMappers();
 	}
 
 	@Override
diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
index 103a680c903e400930e37f9d7610e6e7b4c5eea6..3951f1c53a969d86842398b62ddcf58dd76ad910 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/MappingList.java
@@ -2,6 +2,7 @@ package de.tobias.playpad.action;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.lang.ref.WeakReference;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -17,7 +18,7 @@ import org.dom4j.io.SAXReader;
 import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.utils.xml.XMLHandler;
 
 // COMMENT MappingList
 public class MappingList extends ArrayList<Mapping> {
@@ -25,9 +26,12 @@ public class MappingList extends ArrayList<Mapping> {
 	private static final long serialVersionUID = 1L;
 
 	private UUID activeMapping;
+	private WeakReference<Profile> profile;
 
 	public MappingList(Profile profile) {
-		add(new Mapping(true, profile));
+		add(new Mapping(true));
+
+		this.profile = new WeakReference<Profile>(profile);
 	}
 
 	public Mapping getActiveMapping() {
@@ -79,7 +83,7 @@ public class MappingList extends ArrayList<Mapping> {
 
 		// Init mappings, if non exists
 		if (mappings.size() == 0) {
-			mappings.add(new Mapping(true, profile));
+			mappings.add(new Mapping(true));
 		}
 
 		return mappings;
@@ -98,7 +102,7 @@ public class MappingList extends ArrayList<Mapping> {
 		}
 
 		XMLHandler<Mapping> handler = new XMLHandler<>(rootElement);
-		handler.saveElements(MAPPING, this, new MappingSerializer());
+		handler.saveElements(MAPPING, this, new MappingSerializer(profile.get()));
 
 		if (Files.notExists(path)) {
 			Files.createDirectories(path.getParent());
@@ -109,7 +113,7 @@ public class MappingList extends ArrayList<Mapping> {
 	}
 
 	public static Mapping importMappingPreset(Path path, Profile profile) throws DocumentException, IOException {
-		Mapping mapping = new Mapping(false, profile);
+		Mapping mapping = new Mapping(false);
 
 		SAXReader reader = new SAXReader();
 		Document document = reader.read(Files.newInputStream(path));
@@ -126,7 +130,7 @@ public class MappingList extends ArrayList<Mapping> {
 		Document docoment = DocumentHelper.createDocument();
 		Element rootElement = docoment.addElement(MAPPING);
 
-		MappingSerializer mappingSerializer = new MappingSerializer();
+		MappingSerializer mappingSerializer = new MappingSerializer(null);
 		mappingSerializer.saveElement(rootElement, preset);
 
 		XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
diff --git a/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java
index e1885680e2aed52d687d4cb6d4cdf0fb52a18382..c74dfad67f9b5ecc28d280c8728bc37a097e42e2 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/MappingSerializer.java
@@ -5,9 +5,9 @@ import java.util.UUID;
 import org.dom4j.Element;
 
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLHandler;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLHandler;
+import de.tobias.utils.xml.XMLSerializer;
 
 public class MappingSerializer implements XMLSerializer<Mapping>, XMLDeserializer<Mapping> {
 
@@ -17,17 +17,13 @@ public class MappingSerializer implements XMLSerializer<Mapping>, XMLDeserialize
 
 	private Profile profile;
 
-	public MappingSerializer() {
-
-	}
-
 	public MappingSerializer(Profile profile) {
 		this.profile = profile;
 	}
 
 	@Override
 	public Mapping loadElement(Element element) {
-		Mapping mapping = new Mapping(false, profile);
+		Mapping mapping = new Mapping(false);
 
 		mapping.setName(element.attributeValue(NAME));
 
@@ -50,6 +46,6 @@ public class MappingSerializer implements XMLSerializer<Mapping>, XMLDeserialize
 		newElement.addAttribute(UUID_NAME, data.getUuid().toString());
 
 		XMLHandler<Action> handler = new XMLHandler<>(newElement);
-		handler.saveElements(ACTION, data.getActions(), new ActionSerializer(data));
+		handler.saveElements(ACTION, data.getActions(), new ActionSerializer(data, profile));
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjustable.java b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjustable.java
index 01df8244bc74cce60d4a58507f1ba2f49bf119da..5e03b647873e27cf7e417b750eaedba1b6ee6e40 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjustable.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjustable.java
@@ -2,10 +2,27 @@ package de.tobias.playpad.action.feedback;
 
 import de.tobias.playpad.pad.Pad;
 
+/**
+ * Eine Action implementiert dieses Interface, falls die Feedbackfarbe automatisch an die Farbe der Kachel angepasst werden soll.
+ * 
+ * @author tobias
+ * @since 5.0.0
+ *
+ */
 public interface ColorAdjustable {
 
+	/**
+	 * Ist dieses Feature ative.
+	 * 
+	 * @return <code>true</code> Active
+	 */
 	public boolean isAutoFeedbackColors();
-	
+
+	/**
+	 * Kachel, die mit dieser Action verkünpft ist.
+	 * 
+	 * @return Pad
+	 */
 	public Pad getPad();
-	
+
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjuster.java b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjuster.java
index 8ca7614c0f368ead082b85c0be15a16c330e9379..44129b469e5e5bde06b1ff28a40b0ae3582c483d 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjuster.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAdjuster.java
@@ -9,7 +9,6 @@ import de.tobias.playpad.design.CartDesign;
 import de.tobias.playpad.design.DesignColorAssociator;
 import de.tobias.playpad.design.GlobalDesign;
 import de.tobias.playpad.pad.Pad;
-import de.tobias.playpad.project.Project;
 import de.tobias.playpad.settings.Profile;
 import javafx.scene.paint.Color;
 import javafx.scene.paint.Paint;
@@ -21,7 +20,8 @@ import javafx.scene.paint.Paint;
  * 
  * @since 5.1.0
  * 
- * @see ColorAdjustable Action muss dieses Interface dafür Implementieren, damit die Farbe Automatisch zum pad gemacht wird.
+ * @see ColorAdjustable Action muss dieses Interface dafür Implementieren, damit die Farbe Automatisch zum pad gemacht
+ *      wird.
  * @see ColorAssociator Mapper muss dieses Interface implemetieren, damit die entsprechenden Farbe gefunden werden kann
  *
  */
@@ -29,11 +29,8 @@ public class ColorAdjuster {
 
 	/**
 	 * Übernimmt die Farben des Pads und den verknüpften Aktionen zu einem Pad auf die Mapper.
-	 * 
-	 * @param project
-	 *            Aktuelles Projekt.
 	 */
-	public static void applyColorsToMappers(Project project) {
+	public static void applyColorsToMappers() {
 		// Apply Layout to Mapper
 		Set<Action> actions = Profile.currentProfile().getMappings().getActiveMapping().getActions();
 		for (Action action : actions) {
@@ -42,7 +39,7 @@ public class ColorAdjuster {
 				if (adjustable.isAutoFeedbackColors()) {
 					for (Mapper mapper : action.getMappers()) {
 						if (mapper instanceof MapperFeedbackable) {
-							mapColorForMapper(adjustable, mapper, project);
+							mapColorForMapper(adjustable, mapper);
 						}
 					}
 				}
@@ -52,7 +49,7 @@ public class ColorAdjuster {
 
 	// COMMENT ColorAdjuster
 
-	private static void mapColorForMapper(ColorAdjustable cartAction, Mapper mapper, Project project) {
+	private static void mapColorForMapper(ColorAdjustable cartAction, Mapper mapper) {
 		MapperFeedbackable feedbackable = (MapperFeedbackable) mapper;
 		if (feedbackable.supportFeedback() && mapper instanceof ColorAssociator) {
 			ColorAssociator colorAssociator = (ColorAssociator) mapper;
@@ -62,7 +59,7 @@ public class ColorAdjuster {
 			Color layoutEvColor = null;
 
 			if (pad.getPadSettings().isCustomLayout()) {
-				CartDesign layout = pad.getPadSettings().getLayout();
+				CartDesign layout = pad.getPadSettings().getDesign();
 				if (layout instanceof DesignColorAssociator) {
 					DesignColorAssociator associator = (DesignColorAssociator) layout;
 					layoutStdColor = associator.getAssociatedStandardColor();
@@ -78,13 +75,13 @@ public class ColorAdjuster {
 			}
 
 			if (layoutStdColor != null) {
-				DisplayableFeedbackColor associator = searchColor(colorAssociator, FeedbackMessage.STANDARD, layoutStdColor);
-				colorAssociator.setColor(FeedbackMessage.STANDARD, associator.mapperFeedbackValue());
+				DisplayableFeedbackColor matchedColor = searchColor(colorAssociator, FeedbackMessage.STANDARD, layoutStdColor);
+				colorAssociator.setColor(FeedbackMessage.STANDARD, matchedColor);
 			}
 
 			if (layoutEvColor != null) {
-				DisplayableFeedbackColor associator = searchColor(colorAssociator, FeedbackMessage.EVENT, layoutEvColor);
-				colorAssociator.setColor(FeedbackMessage.EVENT, associator.mapperFeedbackValue());
+				DisplayableFeedbackColor matchedColor = searchColor(colorAssociator, FeedbackMessage.EVENT, layoutEvColor);
+				colorAssociator.setColor(FeedbackMessage.EVENT, matchedColor);
 			}
 		}
 	}
diff --git a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java
index abdda9d2d12de6665cf8539801d2c57966df1b9f..339f72a96b19971bb2a388c3afc1b018ee13a42b 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/feedback/ColorAssociator.java
@@ -2,15 +2,51 @@ package de.tobias.playpad.action.feedback;
 
 import javafx.scene.paint.Color;
 
+/**
+ * Dieses Interface wird in einem Mapper implementiert. Dabei handelt er die Anfragen für das Mapping von Farben.
+ * 
+ * @author tobias
+ * @since 5.0.0
+ */
 public interface ColorAssociator {
 
+	/**
+	 * Gibt die Gerätefarben zurück. Dabei enthalten diese ein Int Value und ein Paint.
+	 * 
+	 * @return Liste an Farben
+	 */
 	public DisplayableFeedbackColor[] getColors();
 
+	/**
+	 * Standardfarbe, falls nichts passendes gefunden wurde.
+	 * 
+	 * @return Standardfarbe
+	 */
 	public DisplayableFeedbackColor getDefaultStandardColor();
 
+	/**
+	 * Eventfarbe, falls nichts passendes gefunden wurde.
+	 * 
+	 * @return Eventfarbe
+	 */
 	public DisplayableFeedbackColor getDefaultEventColor();
 
-	public void setColor(FeedbackMessage feedbackMessage, int value);
+	/**
+	 * Setzt die Feedback Farbe für die Instanz des Mappers.
+	 * 
+	 * @param feedbackMessage
+	 *            Art der Feedbacknachricht
+	 * @param color
+	 *            Matched Color
+	 */
+	public void setColor(FeedbackMessage feedbackMessage, DisplayableFeedbackColor color);
 
+	/**
+	 * Sucht zu einer {@link Color} die passende FeedbackColor, falls vorhanden.
+	 * 
+	 * @param color
+	 *            Kachel Farbe
+	 * @return Feedback Farbe oder null.
+	 */
 	public DisplayableFeedbackColor map(Color color);
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/action/mapper/MapperSerializer.java b/PlayWallCore/src/de/tobias/playpad/action/mapper/MapperSerializer.java
index 604f33b3ddc14c39556638c315fc02d8d51d9cff..34f621600019be97a504fc0f3a92fea92cb2d82d 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/mapper/MapperSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/mapper/MapperSerializer.java
@@ -5,8 +5,8 @@ import org.dom4j.Element;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.Action;
 import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLSerializer;
 
 /**
  * Laden und Speichern von Mappern (Array von Mappern)
diff --git a/PlayWallCore/src/de/tobias/playpad/action/mididevice/Device.java b/PlayWallCore/src/de/tobias/playpad/action/mididevice/Device.java
index e8d46339804f3024b3d0726fa1e8e2981e17f522..8a55c904fdb5b4d32c5b0dc7c7bbd82f61fd3dcd 100644
--- a/PlayWallCore/src/de/tobias/playpad/action/mididevice/Device.java
+++ b/PlayWallCore/src/de/tobias/playpad/action/mididevice/Device.java
@@ -35,7 +35,7 @@ public abstract class Device extends EventDispatcher implements Listener {
 
 	public abstract DisplayableFeedbackColor getColor(int id);
 
-	public abstract void initFeedback();
+	public abstract void initDevice();
 
 	public abstract void handleFeedback(FeedbackMessage type, int key, Feedback feedback);
 
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioCapability.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioCapability.java
new file mode 100644
index 0000000000000000000000000000000000000000..125317608174802768a73a3565090b5027fffc16
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioCapability.java
@@ -0,0 +1,27 @@
+package de.tobias.playpad.audio;
+
+public class AudioCapability {
+
+	public static final AudioCapability EQUALIZER = new AudioCapability("EQUALIZER", Equalizable.class);
+	public static final AudioCapability SOUNDCARD = new AudioCapability("SOUNDCARD", Soundcardable.class);
+
+	private String name;
+	private Class<? extends AudioFeature> clazz;
+
+	private AudioCapability(String name, Class<? extends AudioFeature> clazz) {
+		this.name = name;
+		this.clazz = clazz;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Class<? extends AudioFeature> getAudioFeature() {
+		return clazz;
+	}
+
+	public static AudioCapability[] getFeatures() {
+		return new AudioCapability[] { EQUALIZER, SOUNDCARD };
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioFeature.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioFeature.java
new file mode 100644
index 0000000000000000000000000000000000000000..7805f9ffc202c94465606069b8aed99580ecc556
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioFeature.java
@@ -0,0 +1,11 @@
+package de.tobias.playpad.audio;
+
+/**
+ * Flag für Audiofeature
+ * 
+ * @author tobias
+ *
+ */
+public interface AudioFeature {
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java
index dee8a0e13d6a7268720ec5a9c093099a4c2e4ab9..202af60899bcbf573ad2a1347867829dd60c338f 100644
--- a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java
+++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java
@@ -34,7 +34,7 @@ public abstract class AudioHandler {
 
 	public abstract ReadOnlyObjectProperty<Duration> durationProperty();
 
-	public abstract void setVolume(double volume, double masterVolume, double customVolume);
+	public abstract void setVolume(double volume);
 
 	public abstract boolean isMediaLoaded();
 
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandlerConnect.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandlerConnect.java
index 0d280a36ffd3d4af4f52975cd8cf2f4c1c577c85..122976a4f70e57b0802c04646ec55a9e6c9a3eb3 100644
--- a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandlerConnect.java
+++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandlerConnect.java
@@ -4,8 +4,9 @@ import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
 
 /**
- * Audio Handler Interface zur Verwaltung einer AudioHandler Implementierung. Für Aktionen beim schließen des
- * Programmes, muss der AudioHandler AutoClosable implementieren.
+ * Audio Handler Interface zur Verwaltung einer AudioHandler Implementierung.
+ * Für Aktionen beim schließen des Programmes, muss der AudioHandler
+ * AutoClosable implementieren.
  * 
  * @author tobias
  *
@@ -35,4 +36,23 @@ public abstract class AudioHandlerConnect {
 	 * @return Type
 	 */
 	public abstract String getType();
+
+	/**
+	 * Prüft ob ein Feature verfügbar ist.
+	 * 
+	 * @param audioCapability
+	 *            Feature
+	 * @return <code>true</code> Verfügbar
+	 */
+	public abstract boolean isFeatureAvaiable(AudioCapability audioCapability);
+
+	/**
+	 * Gibt wenn vorhanden einen ViewController für die entsprechenden
+	 * Einstellungen zurück.
+	 * 
+	 * @param audioCapablility
+	 *            Audio Feature
+	 * @return ViewController
+	 */
+	public abstract AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility);
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/Equalizable.java b/PlayWallCore/src/de/tobias/playpad/audio/Equalizable.java
index a0982852b0e2c4766dc3c5a1782ef0e8451744c8..d00c9d6280301a9b8a24bafc90967d7ca236ffed 100644
--- a/PlayWallCore/src/de/tobias/playpad/audio/Equalizable.java
+++ b/PlayWallCore/src/de/tobias/playpad/audio/Equalizable.java
@@ -2,7 +2,7 @@ package de.tobias.playpad.audio;
 
 import javafx.scene.media.AudioEqualizer;
 
-public interface Equalizable {
+public interface Equalizable extends AudioFeature {
 
 	public AudioEqualizer getAudioEqualizer();
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java
new file mode 100644
index 0000000000000000000000000000000000000000..29f41ebc7f6ec0c0f2f756600773662934e7526d
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java
@@ -0,0 +1,16 @@
+package de.tobias.playpad.audio;
+
+import javafx.beans.property.DoubleProperty;
+
+public interface Peakable {
+
+	public enum Channel {
+
+		LEFT,
+		RIGHT;
+	}
+	
+	public DoubleProperty audioLevelProperty(Channel channel);
+	
+	public double getAudioLevel(Channel channel);
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/Soundcardable.java b/PlayWallCore/src/de/tobias/playpad/audio/Soundcardable.java
new file mode 100644
index 0000000000000000000000000000000000000000..023fbdac355ee3569521fbe7a87c347466935f1d
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/Soundcardable.java
@@ -0,0 +1,14 @@
+package de.tobias.playpad.audio;
+
+/**
+ * Setzt die Soundcard für die Audioimplementierung.
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ *
+ */
+public interface Soundcardable extends AudioFeature {
+
+	public void setOutputDevice(String name);
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/fade/Fadeable.java b/PlayWallCore/src/de/tobias/playpad/audio/fade/Fadeable.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f888187677aa19a144dc837997efabf7b837f42
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/fade/Fadeable.java
@@ -0,0 +1,13 @@
+package de.tobias.playpad.audio.fade;
+
+/**
+ * Schnittstelle, die für das Faden die Lautstärke in der Audio Implementierung setzt.
+ * 
+ * @author tobias
+ *
+ * @since 6.0.0
+ */
+public interface Fadeable {
+
+	public void setVolume(double vol);
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/audio/fade/Fading.java b/PlayWallCore/src/de/tobias/playpad/audio/fade/Fading.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fe281b641efba4fb06f3cfc05eced1515fa5029
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/fade/Fading.java
@@ -0,0 +1,95 @@
+package de.tobias.playpad.audio.fade;
+
+import de.tobias.playpad.pad.conntent.play.IVolume;
+import javafx.animation.Transition;
+import javafx.util.Duration;
+
+/**
+ * Fading utils.
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ */
+public class Fading {
+
+	private IVolume iVolume;
+	private Transition currentFadeTransition;
+
+	private double velocity = 1;
+
+	public Fading(IVolume iVolume) {
+		this.iVolume = iVolume;
+	}
+
+	public double getVelocity() {
+		return velocity;
+	}
+
+	public void setVelocity(double velocity) {
+		this.velocity = velocity;
+	}
+
+	public void fadeIn(Duration duration) {
+		fade(0, 1, duration, null);
+	}
+
+	public void fadeIn(Duration duration, Runnable onFinsih) {
+		fade(0, 1, duration, onFinsih);
+	}
+
+	public void fadeOut(Duration duration) {
+		fade(1, 0, duration, null);
+	}
+
+	public void fadeOut(Duration duration, Runnable onFinish) {
+		fade(1, 0, duration, onFinish);
+	}
+
+	public boolean isFading() {
+		return currentFadeTransition != null;
+	}
+
+	private void fade(double from, double to, Duration duration, Runnable onFinish) {
+		if (currentFadeTransition != null) {
+			currentFadeTransition.stop();
+		}
+
+		currentFadeTransition = new Transition() {
+
+			{
+				setCycleDuration(duration);
+			}
+
+			@Override
+			protected void interpolate(double frac) {
+				double diff = Math.abs(to - from);
+				if (from < to) { // Fade In
+					double fade = fadeInVolumeMultiplier(frac, velocity);
+					iVolume.setFadeLevel(from + fade * diff);
+				} else { // Fade Out
+					double fade = fadeOutVolumeMultiplier(frac, velocity);
+					double newValue = to + fade * diff;
+					iVolume.setFadeLevel(newValue);
+				}
+			}
+		};
+		currentFadeTransition.setOnFinished(e ->
+		{
+			currentFadeTransition = null;
+			if (onFinish != null) {
+				onFinish.run();
+			}
+		});
+		currentFadeTransition.play();
+	}
+
+	protected double fadeInVolumeMultiplier(double time, double velocity) {
+		return Math.pow(Math.E, velocity * (time - 1)) * time;
+	}
+
+	protected double fadeOutVolumeMultiplier(double time, double velocity) {
+		return Math.pow(Math.E, -velocity * time) * (1 - time);
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/design/CartDesign.java b/PlayWallCore/src/de/tobias/playpad/design/CartDesign.java
index 12d6f3a81c062d1bfc85fa226e8800cd59306396..bdb096a5ffab05ad5354be081cc3cef810301855 100644
--- a/PlayWallCore/src/de/tobias/playpad/design/CartDesign.java
+++ b/PlayWallCore/src/de/tobias/playpad/design/CartDesign.java
@@ -3,7 +3,7 @@ package de.tobias.playpad.design;
 import org.dom4j.Element;
 
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
-import de.tobias.playpad.settings.Warning;
+import javafx.util.Duration;
 
 public interface CartDesign {
 
@@ -22,11 +22,13 @@ public interface CartDesign {
 	/*
 	 * Wird in einem neuen Thread aufgerufen
 	 */
-	public abstract void handleWarning(IPadViewController controller, Warning warning, GlobalDesign animate);
+	public abstract void handleWarning(IPadViewController controller, Duration warning, GlobalDesign animate);
 
 	public default void stopWarning(IPadViewController controller) {}
 
 	public void reset();
 
 	public void copyGlobalLayout(GlobalDesign globalLayout);
+	
+	Object clone() throws CloneNotSupportedException;
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/design/ColorModeHandler.java b/PlayWallCore/src/de/tobias/playpad/design/ColorModeHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8ddf1a2874624b57c2f166da5e7baaad0fdae97
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/design/ColorModeHandler.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.design;
+
+import java.util.function.Consumer;
+
+import de.tobias.playpad.DisplayableColor;
+import javafx.scene.Node;
+
+/**
+ * Wenn vom Design unterstützt, wird hier die GUI für Farbeinstellungen erstellt.
+ * 
+ * @author tobias
+ *
+ */
+public interface ColorModeHandler {
+
+	public Node getColorInterface(Consumer<DisplayableColor> onSelection);
+
+	public void setColor(CartDesign design, DisplayableColor color);
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/design/DesignColorAssociator.java b/PlayWallCore/src/de/tobias/playpad/design/DesignColorAssociator.java
index 1fc348f64781d214661cfb62e72cef4f61563dec..958a5e3360d49b7339f8d0da70298f6d0aebd42e 100644
--- a/PlayWallCore/src/de/tobias/playpad/design/DesignColorAssociator.java
+++ b/PlayWallCore/src/de/tobias/playpad/design/DesignColorAssociator.java
@@ -2,10 +2,27 @@ package de.tobias.playpad.design;
 
 import javafx.scene.paint.Color;
 
+/**
+ * Methoden für die Verwaltung der Farben, die an einer Kachel eingestellt sind. Das ist wichtig, falls Kachel eine andere Farbverwaltung
+ * verwendet (beispiel Lineare Gradient).
+ * 
+ * @author tobias
+ * @since 5.0.0
+ */
 public interface DesignColorAssociator {
 
+	/**
+	 * Gibt die Standardfarbe (Kacheln ohne Aktion) zurück.
+	 * 
+	 * @return Farbe der Kachel
+	 */
 	public Color getAssociatedStandardColor();
 
+	/**
+	 * Gibt die Eventfarbe (Kacheln mit Aktion) zurück.
+	 * 
+	 * @return Farbe der Kachel
+	 */
 	public Color getAssociatedEventColor();
 
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/design/GlobalDesign.java b/PlayWallCore/src/de/tobias/playpad/design/GlobalDesign.java
index de0fe92c4eed206e06e9191ff8feb511f58a134e..b8795f49297e3f8982e74edb0509e821366b44cd 100644
--- a/PlayWallCore/src/de/tobias/playpad/design/GlobalDesign.java
+++ b/PlayWallCore/src/de/tobias/playpad/design/GlobalDesign.java
@@ -19,9 +19,9 @@ import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import javafx.stage.Stage;
+import javafx.util.Duration;
 
 public interface GlobalDesign {
 
@@ -50,7 +50,7 @@ public interface GlobalDesign {
 	/*
 	 * Wird in einem neuen Thread aufgerufen
 	 */
-	public void handleWarning(IPadViewController controller, Warning warning);
+	public void handleWarning(IPadViewController controller, Duration warning);
 
 	public default void stopWarning(IPadViewController controller) {}
 
diff --git a/PlayWallCore/src/de/tobias/playpad/midi/Midi.java b/PlayWallCore/src/de/tobias/playpad/midi/Midi.java
index 099dd02d17f479c02237bbe5ffe2ada30bf31904..34868d79a351c4fcf102c23bdb58f598e4a6b240 100644
--- a/PlayWallCore/src/de/tobias/playpad/midi/Midi.java
+++ b/PlayWallCore/src/de/tobias/playpad/midi/Midi.java
@@ -170,6 +170,7 @@ public class Midi {
 			}
 		}
 
+		@Override
 		public void close() {}
 	}
 
diff --git a/PlayWallCore/src/de/tobias/playpad/midi/device/DefaultDevice.java b/PlayWallCore/src/de/tobias/playpad/midi/device/DefaultDevice.java
index 5fa72cb64767217eec3e45ff676ef9694804ce61..af8a3460898abbd3c1238f6e1839dadcb9d3980a 100644
--- a/PlayWallCore/src/de/tobias/playpad/midi/device/DefaultDevice.java
+++ b/PlayWallCore/src/de/tobias/playpad/midi/device/DefaultDevice.java
@@ -21,7 +21,7 @@ public class DefaultDevice extends Device {
 	public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) {}
 
 	@Override
-	public void initFeedback() {}
+	public void initDevice() {}
 
 	@Override
 	public void clearFeedback() {}
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java
index 33993d3376e81ec3c9febde2ab568e1732b7496f..989dccaac2d9802ce8cc670393712ab494498759 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java
@@ -1,6 +1,7 @@
 package de.tobias.playpad.pad;
 
 import java.nio.file.Path;
+import java.util.UUID;
 
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.play.Pauseable;
@@ -9,21 +10,30 @@ import de.tobias.playpad.pad.listener.trigger.PadTriggerDurationListener;
 import de.tobias.playpad.pad.listener.trigger.PadTriggerStatusListener;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
 import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
 import de.tobias.playpad.registry.NoSuchComponentException;
-import javafx.beans.property.DoubleProperty;
+import de.tobias.playpad.volume.VolumeManager;
 import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.ReadOnlyIntegerProperty;
-import javafx.beans.property.SimpleDoubleProperty;
 import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
 
-public class Pad {
+public class Pad implements Cloneable {
+
+	private static final VolumeManager volumeManager;
+
+	static {
+		volumeManager = new VolumeManager();
+	}
 
 	// Verwaltung
+	private UUID uuid;
 	private IntegerProperty indexProperty = new SimpleIntegerProperty();
+	private IntegerProperty pageProperty = new SimpleIntegerProperty();
+
 	private StringProperty nameProperty = new SimpleStringProperty();
 	private ObjectProperty<PadStatus> statusProperty = new SimpleObjectProperty<>(PadStatus.EMPTY);
 
@@ -33,9 +43,6 @@ public class Pad {
 	// Settings
 	private PadSettings padSettings;
 
-	// Custom Volume
-	private transient DoubleProperty customVolumeProperty = new SimpleDoubleProperty(1.0);
-
 	// Global Listener (unabhängig von der UI), für Core Functions wie Play, Pause
 	private transient PadStatusListener padStatusListener;
 
@@ -47,20 +54,23 @@ public class Pad {
 
 	// Utils
 	private transient boolean eof;
+
 	private transient IPadViewController controller;
 	private transient Project project;
 
 	public Pad(Project project) {
 		this.project = project;
-		padSettings = new PadSettings();
+		this.uuid = UUID.randomUUID();
+		this.padSettings = new PadSettings();
 
 		initPadListener();
 		// Update Trigger ist nicht notwendig, da es in load(Element) ausgerufen wird
 	}
 
-	public Pad(Project project, int index) {
+	public Pad(Project project, int index, int page) {
 		this.project = project;
-		padSettings = new PadSettings();
+		this.uuid = UUID.randomUUID();
+		this.padSettings = new PadSettings();
 
 		setIndex(index);
 		setStatus(PadStatus.EMPTY);
@@ -69,13 +79,30 @@ public class Pad {
 		padSettings.updateTrigger();
 	}
 
-	public Pad(Project project, int index, String name, PadContent content) {
-		this(project, index);
+	public Pad(Project project, PadIndex index) {
+		this(project, index.getId(), index.getPage());
+	}
+
+	public Pad(Project project, int index, int page, String name, PadContent content) {
+		this(project, index, page);
 		setName(name);
 		setContent(content);
 	}
 
 	private void initPadListener() {
+		// Remov eold listener from propeties
+		if (padStatusListener != null && statusProperty != null) {
+			statusProperty.removeListener(padStatusListener);
+		}
+		if (padTriggerStatusListener != null && statusProperty != null) {
+			statusProperty.removeListener(padTriggerStatusListener);
+		}
+		if (padTriggerDurationListener != null && contentProperty != null) {
+			contentProperty.removeListener(padTriggerContentListener);
+			padTriggerContentListener.changed(contentProperty, getContent(), null);
+		}
+
+		// init new listener for properties
 		padStatusListener = new PadStatusListener(this);
 		statusProperty.addListener(padStatusListener);
 
@@ -95,6 +122,18 @@ public class Pad {
 		return indexProperty.get();
 	}
 
+	public UUID getUuid() {
+		return uuid;
+	}
+
+	void setUuid(UUID uuid) {
+		this.uuid = uuid;
+	}
+
+	public int getPage() {
+		return pageProperty.get();
+	}
+
 	public int getIndexReadable() {
 		return indexProperty.get() + 1;
 	}
@@ -107,6 +146,14 @@ public class Pad {
 		return indexProperty;
 	}
 
+	public void setPage(int page) {
+		pageProperty.set(page);
+	}
+
+	public PadIndex getPadIndex() {
+		return new PadIndex(getIndex(), getPage());
+	}
+
 	public String getName() {
 		return nameProperty.get();
 	}
@@ -167,12 +214,6 @@ public class Pad {
 		return padSettings;
 	}
 
-	public void setMasterVolume(double volume) {
-		if (getContent() != null) {
-			getContent().setMasterVolume(volume);
-		}
-	}
-
 	public boolean isEof() {
 		return eof;
 	}
@@ -187,22 +228,6 @@ public class Pad {
 			contentProperty.get().loadMedia();
 	}
 
-	public void throwException(Path path, Exception exception) {
-		if (project != null)
-			project.addException(this, path, exception);
-		setStatus(PadStatus.ERROR);
-	}
-
-	public void removeExceptionsForPad() {
-		if (project != null)
-			project.removeExceptions(this);
-	}
-
-	public void removeException(PadException exception) {
-		if (project != null)
-			project.removeException(exception);
-	}
-
 	public PadTriggerDurationListener getPadTriggerDurationListener() {
 		return padTriggerDurationListener;
 	}
@@ -239,10 +264,26 @@ public class Pad {
 		setStatus(PadStatus.EMPTY);
 
 		if (project != null) {
-			project.removeExceptions(this);
+			// TODO Remove Exceptions refer to pad
 		}
 	}
 
+	public void throwException(Path path, Exception exception) {
+		if (project != null)
+			project.addException(this, path, exception);
+		setStatus(PadStatus.ERROR);
+	}
+
+	public void removeExceptionsForPad() {
+		if (project != null)
+			project.removeExceptions(this);
+	}
+
+	public void removeException(PadException exception) {
+		if (project != null)
+			project.removeException(exception);
+	}
+
 	@Override
 	public String toString() {
 		return "Pad: " + indexProperty.get() + " - " + nameProperty.get();
@@ -252,16 +293,35 @@ public class Pad {
 		return (indexProperty.get() + 1) + " - " + nameProperty.get();
 	}
 
-	// TODO Reorder
-	public void setCustomVolume(double volume) {
-		customVolumeProperty.set(volume);
+	// Volume Manager
+	public static VolumeManager getVolumeManager() {
+		return volumeManager;
 	}
 
-	public double getCustomVolume() {
-		return customVolumeProperty.get();
-	}
+	// Clone
+	@Override
+	public Pad clone() throws CloneNotSupportedException {
+		Pad clone = (Pad) super.clone();
+
+		clone.uuid = UUID.randomUUID();
+		clone.indexProperty = new SimpleIntegerProperty(getIndex());
+		clone.pageProperty = new SimpleIntegerProperty(getPage());
+
+		clone.nameProperty = new SimpleStringProperty(getName());
+		clone.statusProperty = new SimpleObjectProperty<PadStatus>(getStatus());
+		if (getContent() != null) {
+			clone.contentProperty = new SimpleObjectProperty<PadContent>(getContent().clone());
+			clone.getContent().setPad(clone);
+		} else {
+			clone.contentProperty = new SimpleObjectProperty<PadContent>();
+		}
+
+		clone.padSettings = padSettings.clone();
+
+		clone.controller = null;
+		clone.project = project;
 
-	public DoubleProperty customVolumeProperty() {
-		return customVolumeProperty;
+		clone.initPadListener();
+		return clone;
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java b/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java
index ac129cacd5405fc967e5a1d2914473ff53229ccc..e932e8d641e7547ef7b9c54c3fd250545d94d514 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/PadSerializer.java
@@ -1,5 +1,7 @@
 package de.tobias.playpad.pad;
 
+import java.util.UUID;
+
 import org.dom4j.Element;
 
 import de.tobias.playpad.PlayPadPlugin;
@@ -7,20 +9,22 @@ import de.tobias.playpad.design.CartDesign;
 import de.tobias.playpad.design.DesignConnect;
 import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.project.Project;
 import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.registry.Registry;
 import de.tobias.playpad.settings.Fade;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.playpad.tigger.Trigger;
 import de.tobias.playpad.tigger.TriggerPoint;
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLSerializer;
 import de.tobias.utils.settings.UserDefaults;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLSerializer;
+import javafx.util.Duration;
 
 public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 
+	private static final String UUID_ATTR = "uuid";
 	private static final String INDEX_ATTR = "index";
 	private static final String NAME_ATTR = "name";
 	private static final String STATUS_ATTR = "status";
@@ -44,19 +48,18 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 	public static final String CONTENT_ELEMENT = "Content";
 	private static final String CONTENT_TYPE_ATTR = "type";
 
-	// TODO Remove project var
 	private Project project;
 
 	public PadSerializer(Project project) {
 		this.project = project;
 	}
 
-	public PadSerializer() {}
-
 	@Override
 	public Pad loadElement(Element element) {
 		Pad pad = new Pad(project);
 
+		if (element.attributeValue(UUID_ATTR) != null)
+			pad.setUuid(UUID.fromString(element.attributeValue(UUID_ATTR)));
 		pad.setIndex(Integer.valueOf(element.attributeValue(INDEX_ATTR)));
 		pad.setName(element.attributeValue(NAME_ATTR));
 		PadStatus status = PadStatus.valueOf(element.attributeValue(STATUS_ATTR));
@@ -75,8 +78,14 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 			padSettings.setTimeMode(TimeMode.valueOf(settingsElement.element(TIMEMODE_ELEMENT).getStringValue()));
 		if (settingsElement.element(FADE_ELEMENT) != null)
 			padSettings.setFade(Fade.load(settingsElement.element(FADE_ELEMENT)));
-		if (settingsElement.element(WARNING_ELEMENT) != null)
-			padSettings.setWarning(Warning.load(settingsElement.element(WARNING_ELEMENT)));
+		if (settingsElement.element(WARNING_ELEMENT) != null) {
+			try {
+				Duration duration = Duration.valueOf(settingsElement.element(WARNING_ELEMENT).getStringValue().replace(" ", ""));
+				padSettings.setWarning(duration);
+			} catch (Exception e) {
+				padSettings.setWarning(Duration.seconds(5));
+			}
+		}
 
 		// Laoyut
 		Element layoutsElement = settingsElement.element(LAYOUTS_ELEMENT);
@@ -143,7 +152,7 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 			} catch (NoSuchComponentException e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
-				pad.throwException(null, e);
+				// pad.throwException(null, e); TODO Throw exception to user
 			}
 		}
 
@@ -152,6 +161,7 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 
 	@Override
 	public void saveElement(Element element, Pad data) {
+		element.addAttribute(UUID_ATTR, data.getUuid().toString());
 		element.addAttribute(INDEX_ATTR, String.valueOf(data.getIndex()));
 		element.addAttribute(NAME_ATTR, data.getName());
 		if (data.getStatus() == PadStatus.EMPTY || data.getStatus() == PadStatus.ERROR) {
@@ -169,7 +179,7 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 		if (padSettings.isCustomTimeMode())
 			settingsElement.addElement(TIMEMODE_ELEMENT).addText(String.valueOf(padSettings.getTimeMode()));
 		if (padSettings.isCustomWarning())
-			padSettings.getWarning().save(settingsElement.addElement(WARNING_ELEMENT));
+			settingsElement.addElement(WARNING_ELEMENT).addText(padSettings.getWarning().toString());
 		if (padSettings.isCustomFade())
 			padSettings.getFade().save(settingsElement.addElement(FADE_ELEMENT));
 
@@ -199,10 +209,15 @@ public class PadSerializer implements XMLSerializer<Pad>, XMLDeserializer<Pad> {
 		}
 
 		// Content
-		if (data.getContent() != null) {
+		PadContent content = data.getContent();
+		if (content != null) {
 			Element contentElement = element.addElement(CONTENT_ELEMENT);
-			contentElement.addAttribute(CONTENT_TYPE_ATTR, data.getContent().getType());
-			data.getContent().save(contentElement);
+			contentElement.addAttribute(CONTENT_TYPE_ATTR, content.getType());
+			content.save(contentElement);
+
+			Module module = PlayPadPlugin.getRegistryCollection().getPadContents().getModule(content.getType());
+			// Für verschiedene Pad Typen wird hier das Modul gespeichert, damit das Projekt weis, welche notwendig sien beim öffnen
+			project.getProjectReference().addRequestedModule(module);
 		}
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadSettings.java b/PlayWallCore/src/de/tobias/playpad/pad/PadSettings.java
index 7c46e1ac6437b3ce2eacdf37ca5da79b62969767..698ac80e2d438c866fde83ff1fac944372f5ba8e 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/PadSettings.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/PadSettings.java
@@ -9,7 +9,6 @@ import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.settings.Fade;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.Warning;
 import de.tobias.playpad.tigger.Trigger;
 import de.tobias.playpad.tigger.TriggerPoint;
 import javafx.beans.binding.BooleanBinding;
@@ -19,15 +18,16 @@ import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleBooleanProperty;
 import javafx.beans.property.SimpleDoubleProperty;
 import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
 
-public class PadSettings {
+public class PadSettings implements Cloneable {
 
 	// Settings
 	private DoubleProperty volumeProperty = new SimpleDoubleProperty(1.0);
 	private BooleanProperty loopProperty = new SimpleBooleanProperty(false);
 	private ObjectProperty<TimeMode> timeModeProperty = new SimpleObjectProperty<>();
 	private ObjectProperty<Fade> fadeProperty = new SimpleObjectProperty<>();
-	private ObjectProperty<Warning> warningProperty = new SimpleObjectProperty<>();
+	private ObjectProperty<Duration> warningProperty = new SimpleObjectProperty<>();
 
 	private BooleanProperty customLayoutProperty = new SimpleBooleanProperty(false);
 	private HashMap<String, CartDesign> layouts = new HashMap<>();
@@ -123,7 +123,7 @@ public class PadSettings {
 		return warningProperty.isNotNull();
 	}
 
-	public Warning getWarning() {
+	public Duration getWarning() {
 		if (warningProperty.isNull().get()) {
 			if (Profile.currentProfile() != null) {
 				return Profile.currentProfile().getProfileSettings().getWarningFeedback();
@@ -132,11 +132,11 @@ public class PadSettings {
 		return warningProperty.get();
 	}
 
-	public void setWarning(Warning warning) {
+	public void setWarning(Duration warning) {
 		this.warningProperty.set(warning);
 	}
 
-	public ObjectProperty<Warning> warningProperty() {
+	public ObjectProperty<Duration> warningProperty() {
 		return warningProperty;
 	}
 
@@ -152,7 +152,7 @@ public class PadSettings {
 		return customLayoutProperty;
 	}
 
-	public CartDesign getLayout() {
+	public CartDesign getDesign() {
 		return getLayout(Profile.currentProfile().getProfileSettings().getLayoutType());
 	}
 
@@ -205,4 +205,40 @@ public class PadSettings {
 		}
 		return false;
 	}
+
+	@Override
+	public PadSettings clone() throws CloneNotSupportedException {
+		PadSettings settings = (PadSettings) super.clone();
+		settings.volumeProperty = new SimpleDoubleProperty(getVolume());
+		settings.loopProperty = new SimpleBooleanProperty(isLoop());
+
+		if (isCustomTimeMode())
+			settings.timeModeProperty = new SimpleObjectProperty<TimeMode>(getTimeMode());
+		else
+			settings.timeModeProperty = new SimpleObjectProperty<TimeMode>();
+
+		if (isCustomFade())
+			settings.fadeProperty = new SimpleObjectProperty<>(getFade());
+		else
+			settings.fadeProperty = new SimpleObjectProperty<>();
+
+		if (isCustomWarning())
+			settings.warningProperty = new SimpleObjectProperty<>(getWarning());
+		else
+			settings.warningProperty = new SimpleObjectProperty<>();
+
+		settings.customLayoutProperty = new SimpleBooleanProperty(isCustomLayout());
+		settings.layouts = new HashMap<>();
+		for (String key : layouts.keySet()) {
+			CartDesign clone = (CartDesign) layouts.get(key).clone();
+			settings.layouts.put(key, clone);
+		}
+
+		settings.triggers = new HashMap<>(); // TODO Trigger werden nicht Kopiert
+		settings.customSettings = new HashMap<>(); // TODO CustomSettings werden nicht Kopiert
+
+		settings.updateTrigger();
+
+		return settings;
+	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java
index d54338010dd6d7fbfbfff67f804816004e186d3f..31687a55309837b4319b84bee51d3f2f2febe26f 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java
@@ -20,7 +20,7 @@ import de.tobias.utils.util.ZipFile;
  * @version 5.1.0
  * @see Pad
  */
-public abstract class PadContent {
+public abstract class PadContent implements Cloneable {
 
 	// Refrence
 	private Pad pad;
@@ -33,6 +33,14 @@ public abstract class PadContent {
 		return pad;
 	}
 
+	/**
+	 * Never use this. only for cloning
+	 * @param pad
+	 */
+	public void setPad(Pad pad) {
+		this.pad = pad;
+	}
+
 	public abstract String getType();
 
 	public abstract void play();
@@ -63,7 +71,7 @@ public abstract class PadContent {
 	 */
 	public abstract void unloadMedia();
 
-	public abstract void setMasterVolume(double masterVolume);
+	public abstract void updateVolume();
 
 	@Override
 	protected void finalize() throws Throwable {
@@ -115,4 +123,10 @@ public abstract class PadContent {
 		return orginal;
 	}
 
+	@Override
+	public PadContent clone() throws CloneNotSupportedException {
+		PadContent clone = (PadContent) super.clone();
+		return clone;
+	}
+
 }
\ No newline at end of file
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/PadContentRegistry.java b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContentRegistry.java
similarity index 93%
rename from PlayWallCore/src/de/tobias/playpad/pad/PadContentRegistry.java
rename to PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContentRegistry.java
index 522a30692b022e4586e91bacfac5b01556fcd980..d3e6374a17468d79875453f51c8c579c86ab00ad 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/PadContentRegistry.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContentRegistry.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.pad;
+package de.tobias.playpad.pad.conntent;
 
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -7,7 +7,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import de.tobias.playpad.pad.conntent.PadContentConnect;
 import de.tobias.playpad.registry.ComponentRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/conntent/play/IVolume.java b/PlayWallCore/src/de/tobias/playpad/pad/conntent/play/IVolume.java
new file mode 100644
index 0000000000000000000000000000000000000000..f681dd20a0b8d43ef54e6554c3cbcd0d15133aab
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/pad/conntent/play/IVolume.java
@@ -0,0 +1,13 @@
+package de.tobias.playpad.pad.conntent.play;
+
+/**
+ * Schnittstelle für das Pad, sodass es Lautstärke erhält.
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ */
+public interface IVolume {
+
+	public void setFadeLevel(double level);
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/drag/PadDragMode.java b/PlayWallCore/src/de/tobias/playpad/pad/drag/PadDragMode.java
index 3637295c68de51794e91e3fc822d1498d471909b..f79faf279af0462a9eee5b7e0f9c7b638d93263f 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/drag/PadDragMode.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/drag/PadDragMode.java
@@ -2,12 +2,31 @@ package de.tobias.playpad.pad.drag;
 
 import de.tobias.playpad.Displayable;
 import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.page.PadIndex;
 
+/**
+ * Modus um ein Pad mit Drag and Drop zu verschieben.
+ * 
+ * @author tobias
+ *
+ * @since 6.0.0
+ */
 public abstract class PadDragMode implements Displayable, Comparable<PadDragMode> {
 
 	public abstract String getType();
 
-	public abstract void handle(int oldPad, int newPad, Project project);
+	/**
+	 * Führt die Drag and Drop Aktion aus, ändert das Datenmodell.
+	 * 
+	 * @param oldPad
+	 *            Alter Index
+	 * @param newPad
+	 *            Neuer Index
+	 * @param project
+	 *            Projekt zu den Pads
+	 * @return <code>true</code> Erfolgreiches DnD
+	 */
+	public abstract boolean handle(PadIndex oldPad, PadIndex newPad, Project project);
 
 	@Override
 	public int compareTo(PadDragMode o) {
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java b/PlayWallCore/src/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java
index 0bb27b286d84c52286513d028a82c93e40b65b36..83f168dc289032378a4838c6e326f9f037d7a8f9 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/listener/trigger/PadTriggerStatusListener.java
@@ -24,11 +24,11 @@ public class PadTriggerStatusListener implements ChangeListener<PadStatus> {
 	public void changed(ObservableValue<? extends PadStatus> observable, PadStatus oldValue, PadStatus newValue) {
 		if (!pad.isIgnoreTrigger()) {
 			PadSettings padSettings = pad.getPadSettings();
-			
+
 			// Execute Trigger
 			if (newValue == PadStatus.PLAY) { // TRIGGER FÜR START
 				executeTrigger(padSettings.getTriggers().get(TriggerPoint.START));
-			} else if (newValue == PadStatus.STOP) { // TRIGGER FÜR STOP
+			} else if (newValue == PadStatus.STOP || (oldValue == PadStatus.PLAY && newValue == PadStatus.READY)) { // TRIGGER FÜR STOP
 				executeTrigger(padSettings.getTriggers().get(TriggerPoint.EOF_STOP));
 			} else if (oldValue == PadStatus.PLAY && newValue == PadStatus.READY && pad.isEof()) { // TRIGGER FÜR EOF
 				executeTrigger(padSettings.getTriggers().get(TriggerPoint.EOF_STOP));
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/view/IPadContentView.java b/PlayWallCore/src/de/tobias/playpad/pad/view/IPadContentView.java
index d2cc68210ef72974fda13e91391e3577e8040d72..653ec8985e19d22082998c322664862e44e8bf1f 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/view/IPadContentView.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/view/IPadContentView.java
@@ -19,14 +19,8 @@ public interface IPadContentView {
 	 */
 	public Node getNode();
 
-	@Deprecated
-	public void unconnect();
-
 	/**
 	 * Deinitialisiert die View. Hier können mögliche Bindings und Listener entfernt werden.
 	 */
-	public default void deinit() {
-		// TODO Remove the default after remove unconnect from interface
-		unconnect();
-	}
+	public void deinit();
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/pad/view/IPadView.java b/PlayWallCore/src/de/tobias/playpad/pad/view/IPadView.java
index 67c3ce99cb1b6a3956df92cea0d6a50783f68d39..35ead4cba2c450296b96a171b7ba99adb49352e0 100644
--- a/PlayWallCore/src/de/tobias/playpad/pad/view/IPadView.java
+++ b/PlayWallCore/src/de/tobias/playpad/pad/view/IPadView.java
@@ -2,6 +2,7 @@ package de.tobias.playpad.pad.view;
 
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.viewcontroller.IPadViewController;
+import de.tobias.playpad.project.page.PadIndex;
 import javafx.css.PseudoClass;
 import javafx.scene.layout.Pane;
 
@@ -38,7 +39,7 @@ public interface IPadView {
 	public IPadViewController getViewController();
 
 	/**
-	 * Gibt das oberste GUI Element zurück, welche im MainView verwendet wird.
+	 * Gibt das oberste GUI Element des Pads zurück, welche im MainView verwendet wird.
 	 * 
 	 * @return root node
 	 */
@@ -116,12 +117,15 @@ public interface IPadView {
 	 * @param pad
 	 *            Pad
 	 */
-	public void addDefaultElement(Pad pad);
+	public void addDefaultElements(Pad pad);
 
 	/**
 	 * Fügt die StyleClasses der PadView hinzu. Die Methode wird vom Controller aufgerufen.
+	 * 
+	 * @param index
+	 *            Index von der Kachel
 	 */
-	public void applyStyleClasses(int index);
+	public void applyStyleClasses(PadIndex index);
 
 	/**
 	 * Entfernt die StyleClasses vom PadView. Die Methode wird vom Controller aufgerufen.
diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/AdvancedPlugin.java b/PlayWallCore/src/de/tobias/playpad/plugin/AdvancedPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..53ec30f551d93832e2605299af88c1e9820c011e
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/plugin/AdvancedPlugin.java
@@ -0,0 +1,16 @@
+package de.tobias.playpad.plugin;
+
+import de.tobias.updater.client.Updatable;
+
+/**
+ * Schnittatelle, von der Plugins erben, damit diese alle notwendigen Services unterstützen.
+ * 
+ * @author tobias - s0553746
+ *
+ */
+public interface AdvancedPlugin extends net.xeoh.plugins.base.Plugin {
+
+	public Module getModule();
+
+	public Updatable getUpdatable();
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Module.java b/PlayWallCore/src/de/tobias/playpad/plugin/Module.java
new file mode 100644
index 0000000000000000000000000000000000000000..19c04e6d4ffebce95722c596236ce2207de0cf26
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/plugin/Module.java
@@ -0,0 +1,55 @@
+package de.tobias.playpad.plugin;
+
+/**
+ * Ein Modul beschreibt ein Plugin. Es wird verwendet, um Components der Registry einem Mpdul zuzuordnen.
+ * 
+ * @author tobias - s0553746
+ *
+ */
+public class Module {
+
+	public final String name;
+	public final String identifier;
+
+	public Module(String name, String identifier) {
+		this.name = name;
+		this.identifier = identifier;
+	}
+
+	@Override
+	public String toString() {
+		return "Module [name=" + name + ", identifier=" + identifier + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Module other = (Module) obj;
+		if (identifier == null) {
+			if (other.identifier != null)
+				return false;
+		} else if (!identifier.equals(other.identifier))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/ModuleSerializer.java b/PlayWallCore/src/de/tobias/playpad/plugin/ModuleSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..109e0abf696f4d139df9cd3e3896ba65b2528670
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/plugin/ModuleSerializer.java
@@ -0,0 +1,25 @@
+package de.tobias.playpad.plugin;
+
+import org.dom4j.Element;
+
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLSerializer;
+
+public class ModuleSerializer implements XMLSerializer<Module>, XMLDeserializer<Module> {
+
+	private static final String NAME_ATTR = "name";
+	private static final String IDENTIFIER_ATTR = "id";
+
+	@Override
+	public Module loadElement(Element element) {
+		String name = element.attributeValue(NAME_ATTR);
+		String id = element.attributeValue(IDENTIFIER_ATTR);
+		return new Module(name, id);
+	}
+
+	@Override
+	public void saveElement(Element newElement, Module data) {
+		newElement.addAttribute(NAME_ATTR, data.name);
+		newElement.addAttribute(IDENTIFIER_ATTR, data.identifier);
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java b/PlayWallCore/src/de/tobias/playpad/plugin/PluginDescription.java
similarity index 71%
rename from PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java
rename to PlayWallCore/src/de/tobias/playpad/plugin/PluginDescription.java
index fcbe98abe97596e8ecc83b62c0eefa2ebb30d9a6..9b3357a88fb079f30efbb3eef7cac2b06e5abcf4 100644
--- a/PlayWallCore/src/de/tobias/playpad/plugin/Plugin.java
+++ b/PlayWallCore/src/de/tobias/playpad/plugin/PluginDescription.java
@@ -2,8 +2,9 @@ package de.tobias.playpad.plugin;
 
 import java.util.List;
 
-public class Plugin implements Comparable<Plugin> {
+public class PluginDescription implements Comparable<PluginDescription> {
 
+	private String id;
 	private String name;
 	private String fileName;
 	private String url;
@@ -14,8 +15,9 @@ public class Plugin implements Comparable<Plugin> {
 	private boolean active;
 	private List<String> dependencies;
 
-	public Plugin(String name, String fileName, String url, String version, long build, boolean active,
+	public PluginDescription(String id, String name, String fileName, String url, String version, long build, boolean active,
 			List<String> dependencies) {
+		this.id = id;
 		this.name = name;
 		this.fileName = fileName;
 		this.url = url;
@@ -25,6 +27,10 @@ public class Plugin implements Comparable<Plugin> {
 		this.dependencies = dependencies;
 	}
 
+	public String getId() {
+		return id;
+	}
+
 	public String getName() {
 		return name;
 	}
@@ -55,16 +61,16 @@ public class Plugin implements Comparable<Plugin> {
 
 	@Override
 	public boolean equals(Object obj) {
-		if (obj instanceof Plugin) {
-			Plugin p2 = (Plugin) obj;
-			return p2.active == active && p2.fileName.equals(fileName) && p2.name.equals(name) && p2.url.equals(url);
+		if (obj instanceof PluginDescription) {
+			PluginDescription p2 = (PluginDescription) obj;
+			return p2.active == active && p2.fileName.equals(fileName) && p2.id.equals(id) && p2.url.equals(url);
 		} else {
 			return super.equals(obj);
 		}
 	}
 
 	@Override
-	public int compareTo(Plugin o) {
+	public int compareTo(PluginDescription o) {
 		return getName().compareTo(o.getName());
 	}
 
diff --git a/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java b/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java
index 9cb3749a8f036e5f01a3cecb88c3a1e3eb5e577b..c01deacd4c44c4b35c14951581b06f384015b5e7 100644
--- a/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java
+++ b/PlayWallCore/src/de/tobias/playpad/plugin/Plugins.java
@@ -10,26 +10,28 @@ import java.util.List;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
+import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 
 public class Plugins {
 
-	private static List<Plugin> plugins;
+	private static List<PluginDescription> availablePlugins;
 
 	static {
-		plugins = new ArrayList<>();
+		availablePlugins = new ArrayList<>();
 	}
 
-	public static List<Plugin> load(String pluginInfoURL, boolean fetch) throws IOException {
-		if (plugins.isEmpty() || fetch) {
-			plugins.clear();
+	public static List<PluginDescription> loadDescriptionFromServer(String pluginInfoURL, boolean fetch) throws IOException {
+		if (availablePlugins.isEmpty() || fetch) {
+			availablePlugins.clear();
 			URL url = new URL(pluginInfoURL);
 
 			FileConfiguration cfg = YamlConfiguration.loadConfiguration(url.openStream());
 
 			// Iterate over all plugins that are online avialable
 			for (String key : cfg.getConfigurationSection("plugins").getKeys(false)) {
+				String id = cfg.getString("plugins." + key + ".id");
 				String name = new String(cfg.getString("plugins." + key + ".name").getBytes(), "UTF-8");
 				String pluginUrl = cfg.getString("plugins." + key + ".url");
 				String fileName = cfg.getString("plugins." + key + ".filename");
@@ -44,14 +46,49 @@ public class Plugins {
 				if (Files.exists(path))
 					active = true;
 
-				Plugin plugin = new Plugin(name, fileName, pluginUrl, version, build, active, dependencies);
-				plugins.add(plugin);
+				PluginDescription plugin = new PluginDescription(id, name, fileName, pluginUrl, version, build, active, dependencies);
+				availablePlugins.add(plugin);
 			}
 		}
-		return plugins;
+		return availablePlugins;
+	}
+
+	public static List<PluginDescription> getAvailablePlugins() {
+		return availablePlugins;
+	}
+
+	public static void loadDependencies(PluginDescription plugin) {
+		List<PluginDescription> dependencies = findDependencies(plugin);
+		dependencies.forEach(p ->
+		{
+			Path decPath = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, p.getFileName());
+			downloadPlugin(p, decPath);
+
+			// Add Plugin to classpath
+			PlayPadPlugin.getImplementation().loadPlugin(decPath.toUri());
+		});
 	}
 
-	public static List<Plugin> getPlugins() {
+	private static List<PluginDescription> findDependencies(PluginDescription plugin) {
+		List<PluginDescription> plugins = new ArrayList<>();
+		for (String dependencyName : plugin.getDependencies()) {
+			for (PluginDescription desc : Plugins.getAvailablePlugins()) {
+				if (desc.getName().equals(dependencyName)) {
+					plugins.add(desc);
+				}
+			}
+		}
 		return plugins;
 	}
+
+	public static void downloadPlugin(PluginDescription plugin, Path path) {
+		if (Files.notExists(path)) {
+			try {
+				Files.createDirectories(path.getParent());
+				Files.copy(new URL(plugin.getUrl()).openStream(), path);
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReference.java b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReference.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b3cecea7892323d0716d7f3cdd939a0d4d1d70f
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReference.java
@@ -0,0 +1,144 @@
+package de.tobias.playpad.profile.ref;
+
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import de.tobias.playpad.Displayable;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.playpad.settings.Profile;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+/**
+ * Container für Profile Referenzen
+ * 
+ * @author tobias
+ * 
+ * @see Profile
+ * @since 5.0.0
+ */
+public class ProfileReference implements Displayable {
+
+	private final UUID uuid;
+	private String name;
+	private Set<Module> requestedModules;
+
+	/**
+	 * Erstellt eine neue Referenz mit einer Random UUID.
+	 * 
+	 * @param name
+	 *            Name
+	 */
+	public ProfileReference(String name) {
+		this.name = name;
+		this.uuid = UUID.randomUUID();
+		requestedModules = new HashSet<>();
+		updateDisplayProperty();
+	}
+
+	/**
+	 * Erstellt eine neue Referenz mit Namen und UUID.
+	 * 
+	 * @param uuid
+	 *            UUID
+	 * @param name
+	 *            Name
+	 */
+	public ProfileReference(UUID uuid, String name) {
+		this.uuid = uuid;
+		this.name = name;
+		requestedModules = new HashSet<>();
+		updateDisplayProperty();
+	}
+
+	/**
+	 * Erstellt eine neue Referenz mit Namen und UUID.
+	 * 
+	 * @param uuid
+	 *            UUID
+	 * @param name
+	 *            Name
+	 */
+	public ProfileReference(UUID uuid, String name, Set<Module> requestedModules) {
+		this(uuid, name);
+		this.requestedModules = requestedModules;
+	}
+
+	/**
+	 * Gibt den Namen zurück
+	 * 
+	 * @return Name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Gibt die UUID zurück
+	 * 
+	 * @return uudi
+	 */
+	public UUID getUuid() {
+		return uuid;
+	}
+
+	/**
+	 * Setzt einen neuen Namen.
+	 * 
+	 * @param name
+	 *            Neuer Name
+	 */
+	public void setName(String name) {
+		this.name = name;
+		updateDisplayProperty();
+	}
+
+	public Set<Module> getRequestedModules() {
+		return requestedModules;
+	}
+
+	public void addRequestedModule(Module module) {
+		requestedModules.add(module);
+	}
+
+	/**
+	 * Gibt einen Pfad für einen Dateinamen in diesem Profile zurück.
+	 * 
+	 * @param name
+	 *            Name der Datei
+	 * @return Path für die Datei
+	 */
+	public Path getCustomFilePath(String name) {
+		return ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, getFileName(), name);
+	}
+
+	/**
+	 * Gibt den internen (File-) Namen des Profiles zurück.
+	 * 
+	 * @return Ordnernamen
+	 */
+	public String getFileName() {
+		return uuid.toString();
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
+
+	// Displayable
+	private StringProperty displayProperty = new SimpleStringProperty(toString());
+
+	@Override
+	public StringProperty displayProperty() {
+		return displayProperty;
+	}
+
+	private void updateDisplayProperty() {
+		displayProperty.set(toString());
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceList.java
similarity index 94%
rename from PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java
rename to PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceList.java
index 01bf7b7d7a68a3253c946e964ebfa14800796f31..dd53a96f93a4b924433cba69145a0599aa5034d2 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceList.java
+++ b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceList.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.settings;
+package de.tobias.playpad.profile.ref;
 
 import de.tobias.utils.list.UniqList;
 
@@ -14,6 +14,7 @@ final class ProfileReferenceList extends UniqList<ProfileReference> {
 
 	private static final long serialVersionUID = 1L;
 
+	@Override
 	public boolean contains(Object o) {
 		if (o instanceof String) {
 			for (ProfileReference reference : this) {
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceSerializer.java
similarity index 52%
rename from PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java
rename to PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceSerializer.java
index 3a281ef16c223a94c255b4d18591bcaf7423c2bd..879a33bd42523c0bed923f3a0573b19f7057a1ac 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReferenceSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferenceSerializer.java
@@ -1,11 +1,16 @@
-package de.tobias.playpad.settings;
+package de.tobias.playpad.profile.ref;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.UUID;
 
 import org.dom4j.Element;
 
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.playpad.plugin.ModuleSerializer;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLHandler;
+import de.tobias.utils.xml.XMLSerializer;
 
 /**
  * Util zum arbeiten mit XML und ProfileReference
@@ -19,13 +24,17 @@ public class ProfileReferenceSerializer implements XMLSerializer<ProfileReferenc
 
 	private static final String UUID_ATTR = "uuid";
 	private static final String NAME_ATTR = "name";
+	private static final String MODULE_ELEMENT = "Module";
 
 	@Override
 	public ProfileReference loadElement(Element element) {
 		UUID uuid = UUID.fromString(element.attributeValue(UUID_ATTR));
 		String name = element.attributeValue(NAME_ATTR);
 
-		ProfileReference ref = new ProfileReference(uuid, name);
+		XMLHandler<Module> handler = new XMLHandler<>(element);
+		Set<Module> modules = new HashSet<>(handler.loadElements(MODULE_ELEMENT, new ModuleSerializer()));
+
+		ProfileReference ref = new ProfileReference(uuid, name, modules);
 		return ref;
 	}
 
@@ -33,6 +42,9 @@ public class ProfileReferenceSerializer implements XMLSerializer<ProfileReferenc
 	public void saveElement(Element newElement, ProfileReference data) {
 		newElement.addAttribute(UUID_ATTR, data.getUuid().toString());
 		newElement.addAttribute(NAME_ATTR, data.getName());
+
+		XMLHandler<Module> handler = new XMLHandler<>(newElement);
+		handler.saveElements(MODULE_ELEMENT, data.getRequestedModules(), new ModuleSerializer());
 	}
 
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferences.java
similarity index 66%
rename from PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java
rename to PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferences.java
index c50d17723c8fb442c96fb1e6851b753c0eede9cd..741e9cacc47c12a4819739ab72f460f9edeac907 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileReference.java
+++ b/PlayWallCore/src/de/tobias/playpad/profile/ref/ProfileReferences.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.settings;
+package de.tobias.playpad.profile.ref;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -13,91 +13,21 @@ import org.dom4j.DocumentException;
 import org.dom4j.DocumentHelper;
 import org.dom4j.Element;
 
-import de.tobias.playpad.Displayable;
-import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.playpad.settings.Profile;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.util.FileUtils;
 import de.tobias.utils.util.FileUtils.FileActionAdapter;
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
+import de.tobias.utils.xml.XMLHandler;
 
-/**
- * Container für Profile Referenzen
- * 
- * @author tobias
- * 
- * @see Profile
- * @since 5.0.0
- */
-public class ProfileReference implements Displayable {
+public final class ProfileReferences {
 
-	private static final String DEFAULT_PROFILE_NAME = "Default";
-
-	private final UUID uuid;
-	private String name;
-
-	/**
-	 * Erstellt eine neue Referenz mit einer Random UUID.
-	 * 
-	 * @param name
-	 *            Name
-	 */
-	public ProfileReference(String name) {
-		this.name = name;
-		this.uuid = UUID.randomUUID();
-		updateDisplayProperty();
-	}
-
-	/**
-	 * Erstellt eine neue Referenz mit Namen und UUID.
-	 * 
-	 * @param uuid
-	 *            UUID
-	 * @param name
-	 *            Name
-	 */
-	public ProfileReference(UUID uuid, String name) {
-		this.uuid = uuid;
-		this.name = name;
-		updateDisplayProperty();
-	}
-
-	/**
-	 * Gibt den Namen zurück
-	 * 
-	 * @return Name
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Gibt die UUID zurück
-	 * 
-	 * @return uudi
-	 */
-	public UUID getUuid() {
-		return uuid;
-	}
-
-	/**
-	 * Setzt einen neuen Namen.
-	 * 
-	 * @param name
-	 *            Neuer Name
-	 */
-	public void setName(String name) {
-		this.name = name;
-		updateDisplayProperty();
-	}
-
-	// Verwaltungsmethoden für Profile Referenzen // TODO Extract in Extra Class
+	private ProfileReferences() {}
 
 	/**
 	 * Liste mit allen Referenzen
 	 */
-	private static List<ProfileReference> profiles = new ProfileReferenceList();
+	static List<ProfileReference> profiles = new ProfileReferenceList();
 
 	/**
 	 * Sucht eine Referenz zu einer UUID raus.
@@ -108,7 +38,7 @@ public class ProfileReference implements Displayable {
 	 */
 	public static ProfileReference getReference(UUID profile) {
 		for (ProfileReference ref : profiles) {
-			if (ref.uuid.equals(profile)) {
+			if (ref.getUuid().equals(profile)) {
 				return ref;
 			}
 		}
@@ -137,7 +67,7 @@ public class ProfileReference implements Displayable {
 	 */
 	public static Profile newProfile(String name) throws UnsupportedEncodingException, IOException {
 		ProfileReference ref = new ProfileReference(UUID.randomUUID(), name);
-		ProfileReference.addProfile(ref);
+		ProfileReferences.addProfile(ref);
 
 		Profile profile = new Profile(ref);
 		profile.save();
@@ -225,6 +155,7 @@ public class ProfileReference implements Displayable {
 	}
 
 	// Load and Save
+	private static final String DEFAULT_PROFILE_NAME = "Default";
 
 	private static final String FILE_NAME = "Profiles.xml";
 	private static final String ROOT_ELEMENT = "Settings";
@@ -239,20 +170,20 @@ public class ProfileReference implements Displayable {
 	 *             XML Fehler
 	 */
 	public static void loadProfiles() throws IOException, DocumentException {
-		profiles.clear();
+		ProfileReferences.profiles.clear();
 
 		Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME);
 
 		if (Files.exists(path)) {
 			// Load data from xml
 			XMLHandler<ProfileReference> handler = new XMLHandler<>(path);
-			profiles = handler.loadElements(PROFILE_ELEMENT, new ProfileReferenceSerializer());
-			System.out.println(profiles);
+			ProfileReferences.profiles = handler.loadElements(PROFILE_ELEMENT, new ProfileReferenceSerializer());
+			System.out.println("Find Profile: " + ProfileReferences.profiles);
 		}
 
 		// Add Default Element if list is empty
-		if (profiles.isEmpty()) {
-			Profile profile = newProfile(DEFAULT_PROFILE_NAME);
+		if (ProfileReferences.profiles.isEmpty()) {
+			Profile profile = ProfileReferences.newProfile(DEFAULT_PROFILE_NAME);
 			profile.save();
 		}
 	}
@@ -271,7 +202,7 @@ public class ProfileReference implements Displayable {
 
 		// Save data to xml
 		XMLHandler<ProfileReference> handler = new XMLHandler<>(root);
-		handler.saveElements(PROFILE_ELEMENT, profiles, new ProfileReferenceSerializer());
+		handler.saveElements(PROFILE_ELEMENT, ProfileReferences.profiles, new ProfileReferenceSerializer());
 
 		Path path = ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, FILE_NAME);
 		if (Files.notExists(path)) {
@@ -281,40 +212,4 @@ public class ProfileReference implements Displayable {
 		XMLHandler.save(path, document);
 	}
 
-	/**
-	 * Gibt einen Pfad für einen Dateinamen in diesem Profile zurück.
-	 * 
-	 * @param name
-	 *            Name der Datei
-	 * @return Path für die Datei
-	 */
-	public Path getCustomFilePath(String name) {
-		return ApplicationUtils.getApplication().getPath(PathType.CONFIGURATION, getFileName(), name);
-	}
-
-	/**
-	 * Gibt den internen (File-) Namen des Profiles zurück.
-	 * 
-	 * @return Ordnernamen
-	 */
-	public String getFileName() {
-		return uuid.toString();
-	}
-
-	@Override
-	public String toString() {
-		return name;
-	}
-
-	// Displayable
-	private StringProperty displayProperty = new SimpleStringProperty(toString());
-
-	@Override
-	public StringProperty displayProperty() {
-		return displayProperty;
-	}
-
-	private void updateDisplayProperty() {
-		displayProperty.set(toString());
-	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/project/Project.java b/PlayWallCore/src/de/tobias/playpad/project/Project.java
index 07f36d89fd320ef3579eccdff07d521c3e7e8b2b..100a296d8ac438e3a7fd450570b7339be4a4afb2 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/Project.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/Project.java
@@ -3,22 +3,29 @@ package de.tobias.playpad.project;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.UUID;
 
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.DocumentHelper;
 import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
 
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadException;
-import de.tobias.playpad.pad.PadSerializer;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.project.page.PadIndex;
+import de.tobias.playpad.project.page.Page;
+import de.tobias.playpad.project.page.PageSerializer;
+import de.tobias.playpad.project.ref.ProjectReference;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileNotFoundException;
-import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.utils.xml.XMLHandler;
 import javafx.application.Platform;
 import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.ReadOnlyIntegerProperty;
@@ -27,125 +34,124 @@ import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 
 /**
- * Hold all information about the pads and it's settings.
+ * Verwaltet alle Seiten, die jeweils die Kacheln enthalten.
  * 
  * @author tobias
  *
+ * @since 6.0.0
  */
 public class Project {
 
 	/**
 	 * Pattern für den Namen des Projekts
 	 */
-	public static final String PROJECT_NAME_PATTERN = "[\\p{L},0-9]{1}[\\p{L}\\s-_]{0,}";
+	public static final String PROJECT_NAME_PATTERN = "[\\p{L}0-9]{1}[\\p{L}\\s-_0-9]{0,}";
+
 	/**
 	 * Dateiendung für eine projekt Datei
 	 */
 	public static final String FILE_EXTENSION = ".xml";
 
-	/**
-	 * Die projektreferenz gibt auskunft über den Namen und die UUID des Projektes
-	 */
-	private ProjectReference ref;
-	/**
-	 * Liste mit allen Pads.
-	 */
-	private HashMap<Integer, Pad> pads;
+	private final List<Page> pages;
 
+	private final ProjectReference projectReference;
 	private ProjectSettings settings;
 
 	/**
 	 * Liste mit den aktuellen Laufzeitfehlern.
 	 */
 	private transient ObservableList<PadException> exceptions;
-
 	private transient IntegerProperty activePlayers;
 
-	/**
-	 * Erstellt ein neues leeres Projekt mit einer Referenz.
-	 * 
-	 * @param ref
-	 *            Referenz mit Namen des Projekts.
-	 */
 	public Project(ProjectReference ref) {
-		this.ref = ref;
-		this.pads = new HashMap<>();
+		this.projectReference = ref;
+		this.pages = new ArrayList<>();
 		this.settings = new ProjectSettings();
 
 		this.exceptions = FXCollections.observableArrayList();
 		this.activePlayers = new SimpleIntegerProperty();
 	}
 
-	/**
-	 * Gibt die Projekt Referenz zurück. Dazu zählen Name und UUID sowie das zugehörige Profile.
-	 * 
-	 * @return Referenz.
-	 */
-	public ProjectReference getRef() {
-		return ref;
+	public ProjectSettings getSettings() {
+		return settings;
 	}
 
-	// TODO Update in 5.1.0
-	/**
-	 * Gibt ein Pad an einem Index zurück. Sollte kein pad vorhanden sein (weil null, so wird vorher ein neues erzeugt.)
-	 * 
-	 * @param index
-	 *            Index
-	 * @return Pad am Index i
-	 */
-	public Pad getPad(int index) {
-		if (!pads.containsKey(index)) {
-			addPadForIndex(index);
-		}
-		return pads.get(index);
+	public ProjectReference getProjectReference() {
+		return projectReference;
+	}
+
+	public long getPlayedPlayers() {
+		return getPads().stream().filter(p -> p.getStatus() == PadStatus.PLAY || p.getStatus() == PadStatus.PAUSE).count();
+	}
+
+	public boolean hasPlayedPlayers() {
+		return getPlayedPlayers() != 0;
 	}
 
 	public Pad getPad(int x, int y, int page) {
-		if (x < settings.getColumns() && y < settings.getRows() && page < settings.getPageCount()) {
-			int id = (y * settings.getColumns() + x) + page * settings.getColumns() * settings.getRows();
-			return getPad(id);
+		return getPage(page).getPad(x, y);
+	}
+
+	public Pad getPad(PadIndex index) {
+		Page page = pages.get(index.getPage());
+		return page.getPad(index.getId());
+	}
+
+	public Pad getPad(UUID uuid) {
+		for (Page page : pages) {
+			for (Pad pad : page.getPads()) {
+				if (pad.getUuid().equals(uuid)) {
+					return pad;
+				}
+			}
 		}
 		return null;
 	}
 
-	/**
-	 * Gibt die Settings des Projectes zurück
-	 * 
-	 * @return
-	 */
-	public ProjectSettings getSettings() {
-		return settings;
+	public void setPad(PadIndex index, Pad pad) {
+		if (pad != null) {
+			// Remove Pad from old location
+			if (pad.getPage() != index.getPage()) {
+				Page oldPage = getPage(pad.getPage());
+				if (oldPage.getPad(pad.getIndex()).equals(pad)) {
+					oldPage.removePade(index.getId());
+				}
+			}
+		}
+		Page page = pages.get(index.getPage());
+		page.setPad(index.getId(), pad);
 	}
 
-	/**
-	 * Erstellt ein neues leeres Pad (mit Referenz zu diesem Projekt) am Index i.
-	 * 
-	 * @param index
-	 *            Index i
-	 */
-	private void addPadForIndex(int index) {
-		pads.put(index, new Pad(this, index));
+	public Collection<Pad> getPads() {
+		List<Pad> pads = new ArrayList<>();
+		pages.stream().map(page -> page.getPads()).forEach(pads::addAll);
+		return pads;
 	}
 
-	/**
-	 * Ersetz ein Pad an einem Index i.
-	 * 
-	 * @param index
-	 *            Index i
-	 * @param pad
-	 *            Neues Pad für den Index i
-	 */
-	public void setPad(int index, Pad pad) {
-		pad.setIndex(index);
-		pads.put(index, pad);
+	// Pages
+	public Page getPage(int index) {
+		if (index >= pages.size() && index < ProjectSettings.MAX_PAGES) {
+			pages.add(new Page(index, this));
+		}
+		return pages.get(index);
 	}
 
-	/*
-	 * Speichern und Laden
-	 */
+	public Collection<Page> getPages() {
+		// Create new page if all is empty (automaticlly)
+		if (pages.isEmpty()) {
+			pages.add(new Page(0, this));
+		}
+		return pages;
+	}
+
+	public void setPage(int index, Page page) {
+		pages.set(index, page);
+		page.setId(index);
+	}
 
 	private static final String ROOT_ELEMENT = "Project";
-	protected static final String PAD_ELEMENT = "Pad";
+	public static final String PAGE_ELEMENT = "Page";
+	public static final String PAD_ELEMENT = "Pad";
 	private static final String SETTINGS_ELEMENT = "Settings";
 
 	public static Project load(ProjectReference ref, boolean loadMedia, ProfileChooseable profileChooseable)
@@ -154,30 +160,38 @@ public class Project {
 
 		if (Files.exists(projectPath)) {
 			if (ref.getProfileReference() != null) {
-				Profile.load(ref.getProfileReference()); // Lädt das entsprechende Profile und aktiviert es
+				// Lädt das entsprechende Profile und aktiviert es
+				Profile.load(ref.getProfileReference());
 			} else {
-				Profile profile = profileChooseable.getUnkownProfile(); // Lädt Profile / Erstellt neues und hat es
-																		// gleich im Speicher
+				// Lädt Profile / Erstellt neues und hat es gleich im Speicher
+				Profile profile = profileChooseable.getUnkownProfile();
 				ref.setProfileReference(profile.getRef());
 			}
 
-			Project project = new Project(ref);
+			SAXReader reader = new SAXReader();
+			Document document = reader.read(Files.newInputStream(projectPath));
+			Element rootElement = document.getRootElement();
 
-			// Lädt Pads
-			XMLHandler<Pad> handler = new XMLHandler<>(projectPath);
-			List<Pad> pads = handler.loadElements(PAD_ELEMENT, new PadSerializer(project));
+			Project project = new Project(ref);
 
-			for (Pad pad : pads) {
-				if (loadMedia)
-					pad.loadContent();
-				project.pads.put(pad.getIndex(), pad);
+			// Lädt die Pages und somti auch die Pages
+			XMLHandler<Page> handler = new XMLHandler<>(rootElement);
+			List<Page> pages = handler.loadElements(PAGE_ELEMENT, new PageSerializer(project));
+			for (Page page : pages) {
+				project.pages.add(page);
 			}
 
 			// Lädt die Einstellungen
-			Element settingsElement = handler.getRootElement().element(SETTINGS_ELEMENT);
+			Element settingsElement = rootElement.element(SETTINGS_ELEMENT);
 			if (settingsElement != null)
 				project.settings = ProjectSettings.load(settingsElement);
 
+			// TODO Externalize, damit beim Start user feedback verbessert wird.
+			for (Pad pad : project.getPads()) {
+				if (loadMedia)
+					pad.loadContent();
+			}
+
 			return project;
 		} else {
 			throw new ProjectNotFoundException(ref);
@@ -185,14 +199,16 @@ public class Project {
 	}
 
 	public void save() throws IOException {
-		Path projectPath = ref.getProjectPath();
-		Document document = DocumentHelper.createDocument();
+		Path projectPath = projectReference.getProjectPath();
+		// Modules clearen und beim Speichern der pads neu setzen, damit alte Modules, die nicht gebracht werden, entfernt werden können.
+		projectReference.getRequestedModules().clear();
 
+		Document document = DocumentHelper.createDocument();
 		Element rootElement = document.addElement(ROOT_ELEMENT);
 
 		// Speichern der Pads
-		XMLHandler<Pad> handler = new XMLHandler<>(rootElement);
-		handler.saveElements(PAD_ELEMENT, pads.values(), new PadSerializer());
+		XMLHandler<Page> handler = new XMLHandler<>(rootElement);
+		handler.saveElements(PAGE_ELEMENT, pages, new PageSerializer(this));
 
 		// Speichern der Settings
 		Element settingsElement = rootElement.addElement(SETTINGS_ELEMENT);
@@ -205,10 +221,6 @@ public class Project {
 		XMLHandler.save(projectPath, document);
 	}
 
-	public HashMap<Integer, Pad> getPads() {
-		return pads;
-	}
-
 	public int getActivePlayers() {
 		return activePlayers.get();
 	}
@@ -266,9 +278,9 @@ public class Project {
 		return exceptions;
 	}
 
-	// Load Methods
+	// Utils
 	public void loadPadsContent() {
-		getPads().values().forEach(pad ->
+		getPads().forEach(pad ->
 		{
 			try {
 				pad.loadContent();
@@ -281,18 +293,60 @@ public class Project {
 
 	@Override
 	public String toString() {
-		return ref.getName() + " (" + ref.getUuid() + ")";
-	}
-
-	public int getPadCount() {
-		return pads.size();
+		return projectReference.getName() + " (" + projectReference.getUuid() + ")";
 	}
 
 	public void closeFile() {
-		pads.values().forEach(pad ->
+		getPads().forEach(pad ->
 		{
 			if (pad.getContent() != null)
 				pad.getContent().unloadMedia();
 		});
 	}
+
+	public void removePage(Page page) {
+		pages.remove(page.getId());
+		// Neue Interne Indies für die Pages
+		for (int i = page.getId(); i < pages.size(); i++) {
+			Page tempPage = pages.get(i);
+			tempPage.setId(i);
+		}
+	}
+
+	public boolean addPage() {
+		int index = pages.size();
+		return addPage(new Page(index, this));
+	}
+
+	public boolean addPage(Page page) {
+		if (pages.size() == ProjectSettings.MAX_PAGES) {
+			return false;
+		}
+
+		int newIndex = pages.size();
+
+		page.setId(newIndex);
+		pages.add(page);
+
+		return true;
+	}
+
+	/**
+	 * Find pads, which name starts with a given string
+	 * 
+	 * @param name
+	 *            search key
+	 * @return found pads in project
+	 */
+	public List<Pad> findPads(String name) {
+		List<Pad> result = new ArrayList<>();
+		for (Pad pad : getPads()) {
+			if (pad.getStatus() != PadStatus.EMPTY) {
+				if (pad.getName().startsWith(name)) {
+					result.add(pad);
+				}
+			}
+		}
+		return result;
+	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java
index 756c508a2f5e922ea8609f02905b295ce50d2456..8157c6eced8f924a8ed37b952fe53ee06e644e07 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectExporter.java
@@ -16,7 +16,8 @@ import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadSerializer;
-import de.tobias.playpad.settings.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.project.ref.ProjectReference;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
@@ -116,7 +117,7 @@ public class ProjectExporter {
 			if (padObj instanceof Element) {
 				Element padElement = (Element) padObj;
 
-				PadSerializer serializer = new PadSerializer();
+				PadSerializer serializer = new PadSerializer(null);
 				Pad pad = serializer.loadElement(padElement);
 
 				if (pad.getContent() != null) {
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java
index 57ebef70dc69976a9c3c1c20afd0c11549659e30..735671ecd611101132d67291ee4c8e203d362109 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectImporter.java
@@ -16,8 +16,11 @@ import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.PadSerializer;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
+import de.tobias.playpad.project.ref.ProjectReference;
+import de.tobias.playpad.project.ref.ProjectReferences;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.settings.ProfileReference;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
@@ -69,7 +72,7 @@ public class ProjectImporter {
 			UUID localProfileUUID = null;
 			if (includeProfile) {
 				// Dieser Dialog wird aufgerufen, wenn das Profile bereits existiert, wenn nicht wird es direkt importiert
-				if (ProfileReference.getProfiles().contains(profileName)) {
+				if (ProfileReferences.getProfiles().contains(profileName)) {
 					profileName = importable.replaceProfile(profileName);
 				}
 
@@ -97,7 +100,7 @@ public class ProjectImporter {
 					});
 
 					ProfileReference profileRef = new ProfileReference(localProfileUUID, profileName);
-					ProfileReference.addProfile(profileRef);
+					ProfileReferences.addProfile(profileRef);
 				} else {
 					Profile profile = chooseable.getUnkownProfile();
 					if (profile != null) {
@@ -120,13 +123,13 @@ public class ProjectImporter {
 
 				zip.getFile(projectFile, localFile);
 
-				if (ProjectReference.getProjects().contains(projectName)) {
+				if (ProjectReferences.getProjects().contains(projectName)) {
 					projectName = importable.replaceProject(projectName);
 				}
 
 				ProjectReference projectRef = new ProjectReference(localProjectUUID, projectName,
-						ProfileReference.getReference(localProfileUUID));
-				ProjectReference.addProject(projectRef);
+						ProfileReferences.getReference(localProfileUUID));
+				ProjectReferences.addProject(projectRef);
 
 				// Import Media
 				if (includeMedia) {
@@ -162,7 +165,7 @@ public class ProjectImporter {
 			if (padObj instanceof Element) {
 				Element padElement = (Element) padObj;
 
-				PadSerializer serializer = new PadSerializer();
+				PadSerializer serializer = new PadSerializer(null);
 				Pad pad = serializer.loadElement(padElement);
 
 				if (pad.getContent() != null) {
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectNotFoundException.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectNotFoundException.java
index ae80b4f021bb642ac7388cc72051ae26ba901051..49f97343e35713cfc8d67aede79bed34c896abfd 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectNotFoundException.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectNotFoundException.java
@@ -1,5 +1,7 @@
 package de.tobias.playpad.project;
 
+import de.tobias.playpad.project.ref.ProjectReference;
+
 public class ProjectNotFoundException extends Exception {
 
 	private static final long serialVersionUID = 1L;
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectSettings.java b/PlayWallCore/src/de/tobias/playpad/project/ProjectSettings.java
index 31e1cc9e2a50f208f91ee9065d44a8aa7c44b371..487e1d2603f12ad3e1eeed2a5266aab757623c38 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectSettings.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ProjectSettings.java
@@ -13,17 +13,12 @@ public class ProjectSettings {
 	public static final int MAX_COLUMNS = 10;
 	public static final int MAX_ROWS = 10;
 
-	@Storable private int pageCount = 2;
 	@Storable private int columns = 6;
 	@Storable private int rows = 5;
 
 	private boolean useMediaPath = false;
 	private Path mediaPath = null;
 
-	public int getPageCount() {
-		return pageCount;
-	}
-
 	/**
 	 * Returns the value of colums (Number of cells form left to right)
 	 * 
@@ -50,12 +45,6 @@ public class ProjectSettings {
 		return useMediaPath;
 	}
 
-	public void setPageCount(int pageCount) {
-		if (pageCount > MAX_PAGES)
-			pageCount = MAX_PAGES;
-		this.pageCount = pageCount;
-	}
-
 	public void setColumns(int columns) {
 		if (columns > MAX_COLUMNS)
 			columns = MAX_COLUMNS;
@@ -78,15 +67,12 @@ public class ProjectSettings {
 
 	private static final String ROWS_ELEMENT = "Rows";
 	private static final String COLUMNS_ELEMENT = "Columns";
-	private static final String PAGE_COUNT_ELEMENT = "PageCount";
 
 	private static final String MEDIA_PATH_ELEMENT = "MediaPath";
 	private static final String MEDIA_PATH_ACTIVE_ATTR = "active";
 
 	public static ProjectSettings load(Element element) {
 		ProjectSettings settings = new ProjectSettings();
-		if (element.element(PAGE_COUNT_ELEMENT) != null)
-			settings.setPageCount(Integer.valueOf(element.element(PAGE_COUNT_ELEMENT).getStringValue()));
 		if (element.element(COLUMNS_ELEMENT) != null)
 			settings.setColumns(Integer.valueOf(element.element(COLUMNS_ELEMENT).getStringValue()));
 		if (element.element(ROWS_ELEMENT) != null)
@@ -102,7 +88,6 @@ public class ProjectSettings {
 	}
 
 	public void save(Element element) {
-		element.addElement(PAGE_COUNT_ELEMENT).addText(String.valueOf(pageCount));
 		element.addElement(COLUMNS_ELEMENT).addText(String.valueOf(columns));
 		element.addElement(ROWS_ELEMENT).addText(String.valueOf(rows));
 
diff --git a/PlayWallCore/src/de/tobias/playpad/project/page/PadIndex.java b/PlayWallCore/src/de/tobias/playpad/project/page/PadIndex.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8e3e6fd495e721e72668cafd7cbe1f6b6624a8a
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/project/page/PadIndex.java
@@ -0,0 +1,62 @@
+package de.tobias.playpad.project.page;
+
+import java.io.Serializable;
+
+/**
+ * Struktur um den Index eines Pads zu beschrieben.
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ */
+public class PadIndex implements Serializable {
+
+	private static final long serialVersionUID = 2026743397726990321L;
+
+	private final int id;
+	private final int page;
+
+	public PadIndex(int id, int page) {
+		this.id = id;
+		this.page = page;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + id;
+		result = prime * result + page;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		PadIndex other = (PadIndex) obj;
+		if (id != other.id)
+			return false;
+		if (page != other.page)
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return id + "-" + page;
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/project/page/Page.java b/PlayWallCore/src/de/tobias/playpad/project/page/Page.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ccea70164543c0d4f500d66ec2743060ffd8fd6
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/project/page/Page.java
@@ -0,0 +1,116 @@
+package de.tobias.playpad.project.page;
+
+import java.util.Collection;
+import java.util.HashMap;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.project.Project;
+import de.tobias.playpad.project.ProjectSettings;
+
+/**
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ */
+public class Page implements Cloneable {
+
+	private int id;
+	private String name;
+	private HashMap<Integer, Pad> pads;
+
+	private transient Project projectReference;
+
+	public Page(int id, Project reference) {
+		this.id = id;
+		this.name = "";
+		this.pads = new HashMap<>();
+
+		this.projectReference = reference;
+	}
+
+	public Page(int id, String name, Project reference) {
+		this.id = id;
+		this.name = name;
+		this.pads = new HashMap<>();
+
+		this.projectReference = reference;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+		for (Pad pad : pads.values()) {
+			pad.setPage(id);
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Project getProjectReference() {
+		return projectReference;
+	}
+
+	public Pad getPad(int id) {
+		if (!pads.containsKey(id)) {
+			// Create new pad for id
+			setPad(id, new Pad(projectReference, id, this.id));
+		}
+		return pads.get(id);
+	}
+
+	public Pad getPad(int x, int y) {
+		ProjectSettings settings = projectReference.getSettings();
+		if (x < settings.getColumns() && y < settings.getRows()) {
+			int id = y * settings.getColumns() + x;
+			return getPad(id);
+		}
+		return null;
+	}
+
+	public void setPad(int id, Pad pad) {
+		if (pad == null) {
+			pads.remove(id);
+		} else {
+			pads.put(id, pad);
+			pad.setPage(this.id);
+			pad.setIndex(id);
+		}
+	}
+
+	public Collection<Pad> getPads() {
+		return pads.values();
+	}
+
+	public void removePade(int id) {
+		pads.remove(id);
+	}
+
+	@Override
+	public String toString() {
+		return "Page [id=" + id + "]";
+	}
+
+	@Override
+	public Page clone() throws CloneNotSupportedException {
+		Page clone = (Page) super.clone();
+		clone.id = id;
+		clone.name = name;
+		clone.projectReference = projectReference;
+		clone.pads = new HashMap<>();
+		for (int key : pads.keySet()) {
+			Pad padClone = pads.get(key).clone();
+			clone.pads.put(key, padClone);
+		}
+		return clone;
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/project/page/PageSerializer.java b/PlayWallCore/src/de/tobias/playpad/project/page/PageSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..31b482bf2d35c862c8293892296ca33ac54d77ac
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/project/page/PageSerializer.java
@@ -0,0 +1,56 @@
+package de.tobias.playpad.project.page;
+
+import java.util.List;
+
+import org.dom4j.Element;
+
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadSerializer;
+import de.tobias.playpad.project.Project;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLHandler;
+import de.tobias.utils.xml.XMLSerializer;
+
+public class PageSerializer implements XMLSerializer<Page>, XMLDeserializer<Page> {
+
+	private static final String ID_ATTR = "id";
+	private static final String NAME_ATTR = "name";
+
+	private Project project;
+
+	/**
+	 * Für Deserialize
+	 * 
+	 * @param project
+	 *            Project Reference
+	 */
+	public PageSerializer(Project project) {
+		this.project = project;
+	}
+
+	@Override
+	public Page loadElement(Element element) {
+		int id = Integer.valueOf(element.attributeValue(ID_ATTR));
+		String name = element.attributeValue(NAME_ATTR);
+
+		XMLHandler<Pad> handler = new XMLHandler<>(element);
+		List<Pad> pads = handler.loadElements(Project.PAD_ELEMENT, new PadSerializer(project));
+
+		Page page = new Page(id, name, project);
+		for (Pad pad : pads) {
+			pad.setPage(id);
+			page.setPad(pad.getIndex(), pad);
+		}
+
+		return page;
+	}
+
+	@Override
+	public void saveElement(Element newElement, Page data) {
+		newElement.addAttribute(ID_ATTR, String.valueOf(data.getId()));
+		newElement.addAttribute(NAME_ATTR, data.getName());
+
+		XMLHandler<Pad> handler = new XMLHandler<>(newElement);
+		handler.saveElements(Project.PAD_ELEMENT, data.getPads(), new PadSerializer(project));
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReference.java b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReference.java
new file mode 100644
index 0000000000000000000000000000000000000000..b993267893bec2724d27a4701adcfaa9652eb276
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReference.java
@@ -0,0 +1,152 @@
+package de.tobias.playpad.project.ref;
+
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import de.tobias.playpad.Displayable;
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.project.Project;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+public class ProjectReference implements Displayable {
+
+	/**
+	 * Name + XML
+	 */
+	private UUID uuid;
+	private String name;
+
+	private ProfileReference profileReference;
+	private Set<Module> requestedModules;
+
+	private long lastMofied;
+
+	public ProjectReference(UUID uuid, String name, ProfileReference profileReference) {
+		this.uuid = uuid;
+		this.name = name;
+		this.lastMofied = System.currentTimeMillis();
+		this.profileReference = profileReference;
+		requestedModules = new HashSet<>();
+
+		updateDisplayProperty();
+	}
+
+	public ProjectReference(UUID uuid, String name, ProfileReference profileReference, Set<Module> modules) {
+		this.uuid = uuid;
+		this.name = name;
+		this.lastMofied = System.currentTimeMillis();
+		this.profileReference = profileReference;
+		requestedModules = modules;
+
+		updateDisplayProperty();
+	}
+
+	public ProjectReference(UUID uuid, String name, long lastMofied, ProfileReference profileReference) {
+		this.uuid = uuid;
+		this.name = name;
+		this.lastMofied = lastMofied;
+		this.profileReference = profileReference;
+		requestedModules = new HashSet<>();
+
+		updateDisplayProperty();
+	}
+
+	public ProjectReference(UUID uuid, String name, long lastMofied, ProfileReference profileReference, Set<Module> requestedModules) {
+		this.uuid = uuid;
+		this.name = name;
+		this.lastMofied = lastMofied;
+		this.profileReference = profileReference;
+		this.requestedModules = requestedModules;
+
+		updateDisplayProperty();
+	}
+
+	public UUID getUuid() {
+		return uuid;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setLastMofied(long lastMofied) {
+		this.lastMofied = lastMofied;
+	}
+
+	public long getLastMofied() {
+		return lastMofied;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+		updateDisplayProperty();
+	}
+
+	public Set<Module> getRequestedModules() {
+		return requestedModules;
+	}
+
+	public void addRequestedModule(Module module) {
+		requestedModules.add(module);
+	}
+
+	public Set<Module> getMissedModules() {
+		Set<Module> missedModules = new HashSet<>();
+		Collection<Module> activeModules = PlayPadPlugin.getImplementation().getModules();
+		for (Module requested : requestedModules) {
+			if (!activeModules.contains(requested)) {
+				missedModules.add(requested);
+			}
+		}
+
+		for (Module requested : profileReference.getRequestedModules()) {
+			if (!activeModules.contains(requested)) {
+				missedModules.add(requested);
+			}
+		}
+		return missedModules;
+	}
+
+	public ProfileReference getProfileReference() {
+		return profileReference;
+	}
+
+	public void setProfileReference(ProfileReference profileReference) {
+		this.profileReference = profileReference;
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
+
+	public String getFileName() {
+		return uuid + Project.FILE_EXTENSION;
+	}
+
+	public Path getProjectPath() {
+		App application = ApplicationUtils.getApplication();
+		Path projectPath = application.getPath(PathType.DOCUMENTS, getFileName());
+		return projectPath;
+	}
+
+	private StringProperty displayProperty = new SimpleStringProperty(toString());
+
+	@Override
+	public StringProperty displayProperty() {
+		return displayProperty;
+	}
+
+	private void updateDisplayProperty() {
+		displayProperty.set(toString());
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceList.java
similarity index 58%
rename from PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java
rename to PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceList.java
index a9a172d9097d6b2646fefd35b3084a34fada0123..00db638dab61961b81fb688e3c997c730687d64e 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceList.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceList.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.project;
+package de.tobias.playpad.project.ref;
 
 import de.tobias.utils.list.UniqList;
 
@@ -14,24 +14,22 @@ final class ProjectReferenceList extends UniqList<ProjectReference> {
 
 	private static final long serialVersionUID = 1L;
 
+	@Override
 	public boolean contains(Object o) {
 		if (o instanceof String) {
-			for (ProjectReference item : this) {
-				if (item.getName().equals(o)) {
+			for (ProjectReference reference : this) {
+				if (reference.getName().equals(o)) {
 					return true;
-				} else if (item.toString().equals(o)) {
+				} else if (reference.toString().equals(o)) {
 					return true;
 				}
 			}
 		} else if (o instanceof ProjectReference) {
-			for (ProjectReference item : this) {
-				if (item.getName() == o) {
+			for (ProjectReference reference : this) {
+				if (reference.getName() == o) {
+					return true;
+				} else if (reference.getName().equals(((ProjectReference) o).getName())) { // TODO Check
 					return true;
-				} else {
-					ProjectReference projectRef = (ProjectReference) o;
-					if (item.getName().equals(projectRef.getName())) {
-						return true;
-					}
 				}
 			}
 		}
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceSerializer.java
similarity index 62%
rename from PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java
rename to PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceSerializer.java
index 009b68e7171f8ed1ef6bdd1442070abf48a6fe3f..448e369358aef6bf48c9791c129f900a64852f18 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectReferenceSerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferenceSerializer.java
@@ -1,23 +1,30 @@
-package de.tobias.playpad.project;
+package de.tobias.playpad.project.ref;
 
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.UUID;
 
 import org.dom4j.Element;
 
-import de.tobias.playpad.settings.ProfileReference;
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.playpad.plugin.ModuleSerializer;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLHandler;
+import de.tobias.utils.xml.XMLSerializer;
 
 public class ProjectReferenceSerializer implements XMLDeserializer<ProjectReference>, XMLSerializer<ProjectReference> {
 
 	private static final String UUID_ATTR = "uuid";
 	private static final String NAME_ATTR = "name";
 	private static final String PROFILE_ATTR = "profile";
+	private static final String MODULE_ELEMENT = "Module";
 
 	@Override
 	public ProjectReference loadElement(Element element) {
@@ -25,14 +32,16 @@ public class ProjectReferenceSerializer implements XMLDeserializer<ProjectRefere
 		String name = element.attributeValue(NAME_ATTR);
 		UUID profile = UUID.fromString(element.attributeValue(PROFILE_ATTR));
 
-		ProfileReference profileRef = ProfileReference.getReference(profile);
-		ProjectReference ref = new ProjectReference(uuid, name, profileRef);
+		XMLHandler<Module> handler = new XMLHandler<>(element);
+		Set<Module> modules = new HashSet<>(handler.loadElements(MODULE_ELEMENT, new ModuleSerializer()));
+
+		ProfileReference profileRef = ProfileReferences.getReference(profile);
+		ProjectReference ref = new ProjectReference(uuid, name, profileRef, modules);
 
 		Path projectPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, ref.getFileName());
 		if (Files.exists(projectPath)) {
 			try {
 				ref.setLastMofied(Files.getLastModifiedTime(projectPath).toMillis());
-				ref.setSize(Files.size(projectPath));
 			} catch (IOException e) {
 				e.printStackTrace();
 			}
@@ -45,5 +54,8 @@ public class ProjectReferenceSerializer implements XMLDeserializer<ProjectRefere
 		newElement.addAttribute(UUID_ATTR, data.getUuid().toString());
 		newElement.addAttribute(NAME_ATTR, data.getName());
 		newElement.addAttribute(PROFILE_ATTR, data.getProfileReference().getUuid().toString());
+
+		XMLHandler<Module> handler = new XMLHandler<>(newElement);
+		handler.saveElements(MODULE_ELEMENT, data.getRequestedModules(), new ModuleSerializer());
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferences.java
similarity index 57%
rename from PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java
rename to PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferences.java
index d69e9cb119cafa29ba63c53f0848dc13f0fcd939..feabcc448ff93cc1d8ab2697fdc785f57a646054 100644
--- a/PlayWallCore/src/de/tobias/playpad/project/ProjectReference.java
+++ b/PlayWallCore/src/de/tobias/playpad/project/ref/ProjectReferences.java
@@ -1,4 +1,4 @@
-package de.tobias.playpad.project;
+package de.tobias.playpad.project.ref;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -14,89 +14,25 @@ import org.dom4j.DocumentException;
 import org.dom4j.DocumentHelper;
 import org.dom4j.Element;
 
-import de.tobias.playpad.Displayable;
-import de.tobias.playpad.settings.ProfileReference;
-import de.tobias.playpad.xml.XMLHandler;
-import de.tobias.utils.application.App;
+import de.tobias.playpad.project.Project;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
+import de.tobias.utils.xml.XMLHandler;
 
-public class ProjectReference implements Displayable {
+public final class ProjectReferences {
+
+	private ProjectReferences() {}
 
 	private static List<ProjectReference> projects = new ProjectReferenceList();
 	private static boolean loadedProjectOverview = false;
 
-	/**
-	 * Name + XML
-	 */
-	private UUID uuid;
-	private String name;
-
-	private ProfileReference profileReference;
-
-	private long size;
-	private long lastMofied;
-
-	public ProjectReference(UUID uuid, String name, ProfileReference profileReference) {
-		this.uuid = uuid;
-		this.name = name;
-		this.lastMofied = System.currentTimeMillis();
-		this.size = 0;
-		this.profileReference = profileReference;
-		updateDisplayProperty();
-	}
-
-	public ProjectReference(UUID uuid, String name, long size, long lastMofied, ProfileReference profileReference) {
-		this.uuid = uuid;
-		this.name = name;
-		this.size = size;
-		this.lastMofied = lastMofied;
-		this.profileReference = profileReference;
-		updateDisplayProperty();
-	}
-
-	public UUID getUuid() {
-		return uuid;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public long getSize() {
-		return size;
-	}
-
-	public void setSize(long size) {
-		this.size = size;
-	}
-
-	public void setLastMofied(long lastMofied) {
-		this.lastMofied = lastMofied;
-	}
-
-	public long getLastMofied() {
-		return lastMofied;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-		updateDisplayProperty();
-	}
-
-	public ProfileReference getProfileReference() {
-		return profileReference;
-	}
-
-	public void setProfileReference(ProfileReference profileReference) {
-		this.profileReference = profileReference;
-	}
-
-	@Override
-	public String toString() {
-		return name;
+	public static ProjectReference getProject(UUID project) {
+		for (ProjectReference ref : projects) {
+			if (ref.getUuid().equals(project)) {
+				return ref;
+			}
+		}
+		return null;
 	}
 
 	public static void addProject(ProjectReference item) throws UnsupportedEncodingException, IOException {
@@ -125,8 +61,8 @@ public class ProjectReference implements Displayable {
 	}
 
 	private static void duplicateFiles(ProjectReference currentProject, ProjectReference newProjectReference) throws IOException {
-		Path oldPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, currentProject.getFileName());
-		Path newPath = ApplicationUtils.getApplication().getPath(PathType.DOCUMENTS, newProjectReference.getFileName());
+		Path oldPath = currentProject.getProjectPath();
+		Path newPath = newProjectReference.getProjectPath();
 		Files.copy(oldPath, newPath, StandardCopyOption.COPY_ATTRIBUTES);
 	}
 
@@ -179,40 +115,7 @@ public class ProjectReference implements Displayable {
 
 		List<ProjectReference> items = new ArrayList<>();
 		projects.forEach(item -> items.add(item));
-		items.sort((ProjectReference o1, ProjectReference o2) ->
-		{
-			return Long.compare(o2.lastMofied, o1.lastMofied);
-		});
+		items.sort((o1, o2) -> Long.compare(o2.getLastMofied(), o1.getLastMofied()));
 		return items;
 	}
-
-	public String getFileName() {
-		return uuid + Project.FILE_EXTENSION;
-	}
-
-	public Path getProjectPath() {
-		App application = ApplicationUtils.getApplication();
-		Path projectPath = application.getPath(PathType.DOCUMENTS, getFileName());
-		return projectPath;
-	}
-
-	public static ProjectReference getProject(UUID project) {
-		for (ProjectReference ref : projects) {
-			if (ref.uuid.equals(project)) {
-				return ref;
-			}
-		}
-		return null;
-	}
-
-	private StringProperty displayProperty = new SimpleStringProperty(toString());
-
-	@Override
-	public StringProperty displayProperty() {
-		return displayProperty;
-	}
-
-	private void updateDisplayProperty() {
-		displayProperty.set(toString());
-	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/registry/ComponentRegistry.java b/PlayWallCore/src/de/tobias/playpad/registry/ComponentRegistry.java
index cccd5a8f5e96f649a1d2d2bece319b86bbd0dccf..d5e4d04a52bc1e667d14096be4a7bb58696fa7dd 100644
--- a/PlayWallCore/src/de/tobias/playpad/registry/ComponentRegistry.java
+++ b/PlayWallCore/src/de/tobias/playpad/registry/ComponentRegistry.java
@@ -11,6 +11,8 @@ import org.dom4j.DocumentException;
 import org.dom4j.Element;
 import org.dom4j.io.SAXReader;
 
+import de.tobias.playpad.plugin.Module;
+
 /**
  * Eine Implementierung für eine Registry.
  * 
@@ -24,19 +26,23 @@ import org.dom4j.io.SAXReader;
 public class ComponentRegistry<C> implements Registry<C> {
 
 	private HashMap<String, C> components;
+	// Zu einem Component die zugehörigen Meta Daten (das Modul)
+	private HashMap<String, Module> modules;
 	private String name;
 
 	public ComponentRegistry(String name) {
-		components = new HashMap<>();
+		this.components = new HashMap<>();
+		this.modules = new HashMap<>();
 		this.name = name;
 	}
 
 	@Override
-	public void registerComponent(C component, String id) throws IllegalArgumentException {
+	public void registerComponent(C component, String id, Module module) throws IllegalArgumentException {
 		if (components.containsKey(id)) {
 			throw new IllegalArgumentException("A components already exists with this id: " + id);
 		}
 		components.put(id, component);
+		modules.put(id, module);
 		System.out.println("Registered: " + name + "#" + id);
 	}
 
@@ -59,7 +65,7 @@ public class ComponentRegistry<C> implements Registry<C> {
 	}
 
 	@Override
-	public void loadComponentsFromFile(URL url, ClassLoader loader)
+	public void loadComponentsFromFile(URL url, ClassLoader loader, Module module)
 			throws IOException, DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
 		if (url == null) {
 			throw new IOException("URL not found: " + url);
@@ -77,9 +83,13 @@ public class ComponentRegistry<C> implements Registry<C> {
 				@SuppressWarnings("unchecked") Class<C> clazz = (Class<C>) loader.loadClass(element.getStringValue());
 				C component = clazz.newInstance();
 
-				registerComponent(component, type);
+				registerComponent(component, type, module);
 			}
 		}
 	}
 
+	@Override
+	public Module getModule(String id) {
+		return modules.get(id);
+	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/registry/DefaultComponentRegistry.java b/PlayWallCore/src/de/tobias/playpad/registry/DefaultComponentRegistry.java
index f085a26114c6048cad549a7b17e7f7e1c6adeaed..a8b2dae1e98a084ff8401420129acbe109257393 100644
--- a/PlayWallCore/src/de/tobias/playpad/registry/DefaultComponentRegistry.java
+++ b/PlayWallCore/src/de/tobias/playpad/registry/DefaultComponentRegistry.java
@@ -8,6 +8,8 @@ import org.dom4j.DocumentException;
 import org.dom4j.Element;
 import org.dom4j.io.SAXReader;
 
+import de.tobias.playpad.plugin.Module;
+
 public class DefaultComponentRegistry<C> extends ComponentRegistry<C> implements DefaultRegistry<C> {
 
 	private C defaultValue;
@@ -46,7 +48,7 @@ public class DefaultComponentRegistry<C> extends ComponentRegistry<C> implements
 	}
 
 	@Override
-	public void loadComponentsFromFile(URL url, ClassLoader loader)
+	public void loadComponentsFromFile(URL url, ClassLoader loader, Module module)
 			throws IOException, DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
 		if (url == null) {
 			throw new IOException("URL not found: " + url);
@@ -64,7 +66,7 @@ public class DefaultComponentRegistry<C> extends ComponentRegistry<C> implements
 				@SuppressWarnings("unchecked") Class<C> clazz = (Class<C>) loader.loadClass(element.getStringValue());
 				C component = clazz.newInstance();
 
-				registerComponent(component, type);
+				registerComponent(component, type, module);
 
 				if (element.attributeValue("default") != null) {
 					String defaultValue = element.attributeValue("default");
diff --git a/PlayWallCore/src/de/tobias/playpad/registry/Registry.java b/PlayWallCore/src/de/tobias/playpad/registry/Registry.java
index 74fe650f172da5b046918e653534dd56613ee6af..df4ff3af7f836393d50fc52817f84bdd4a5ed74c 100644
--- a/PlayWallCore/src/de/tobias/playpad/registry/Registry.java
+++ b/PlayWallCore/src/de/tobias/playpad/registry/Registry.java
@@ -3,6 +3,8 @@ package de.tobias.playpad.registry;
 import java.util.Collection;
 import java.util.Set;
 
+import de.tobias.playpad.plugin.Module;
+
 /**
  * Dieses Interface definiert Methoden bei Arbeit mit Komponenten, die durch Plugins zum Programm hinzugefügt werden können.
  * 
@@ -40,4 +42,13 @@ public interface Registry<C> extends WriteOnlyRegistry<C> {
 	 * @return Implementierungen
 	 */
 	public Collection<C> getComponents();
+
+	/**
+	 * Gibt das Module zurück.
+	 * 
+	 * @param id
+	 *            id der Komponente.
+	 * @return Module
+	 */
+	public Module getModule(String id);
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/registry/WriteOnlyRegistry.java b/PlayWallCore/src/de/tobias/playpad/registry/WriteOnlyRegistry.java
index 8a6f8859539d0734ff7b0899f973c38974a5a582..5326d6b212858937a49ef131323c9c63b4f0f847 100644
--- a/PlayWallCore/src/de/tobias/playpad/registry/WriteOnlyRegistry.java
+++ b/PlayWallCore/src/de/tobias/playpad/registry/WriteOnlyRegistry.java
@@ -5,6 +5,8 @@ import java.net.URL;
 
 import org.dom4j.DocumentException;
 
+import de.tobias.playpad.plugin.Module;
+
 /**
  * Eine Schnittstelle um Komponenten zu registrieren, aber nicht auszulesen.
  * 
@@ -24,10 +26,12 @@ public interface WriteOnlyRegistry<C> {
 	 *            Komponente
 	 * @param id
 	 *            ID
+	 * @param module
+	 *            Module zu dem diese Komponente gehört
 	 * @throws IllegalArgumentException
 	 *             Die Komponete gibt es bereits.
 	 */
-	public void registerComponent(C component, String id) throws IllegalArgumentException;
+	public void registerComponent(C component, String id, Module module) throws IllegalArgumentException;
 
 	/**
 	 * Lädt aus einer XML Datei die Komponenten Deklaration und registriert diese automatisch.
@@ -36,6 +40,8 @@ public interface WriteOnlyRegistry<C> {
 	 *            URL zur Deklaration
 	 * @param loader
 	 *            ClassLoader
+	 * @param module
+	 *            Module zu dem diese Komponente gehört
 	 * @throws IOException
 	 *             Fehler beim Laden der Datei.
 	 * @throws DocumentException
@@ -47,16 +53,16 @@ public interface WriteOnlyRegistry<C> {
 	 * @throws InstantiationException
 	 *             Die Klasse konnte nicht instanziert werden
 	 */
-	public void loadComponentsFromFile(URL url, ClassLoader loader)
+	public void loadComponentsFromFile(URL url, ClassLoader loader, Module module)
 			throws IOException, DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException;
 
-	public default void loadComponentsFromFile(String name)
+	public default void loadComponentsFromFile(String name, Module module)
 			throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, DocumentException {
-		loadComponentsFromFile(getClass().getClassLoader().getResource(name), getClass().getClassLoader());
+		loadComponentsFromFile(getClass().getClassLoader().getResource(name), getClass().getClassLoader(), module);
 	}
 
-	public default void loadComponentsFromFile(String name, ClassLoader loader)
+	public default void loadComponentsFromFile(String name, ClassLoader loader, Module module)
 			throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, DocumentException {
-		loadComponentsFromFile(loader.getResource(name), loader);
+		loadComponentsFromFile(loader.getResource(name), loader, module);
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/Fade.java b/PlayWallCore/src/de/tobias/playpad/settings/Fade.java
index 48c9d864b835df013f86031d27131dfbf4a77cb4..0a30c6032cd1fbd883998fedf3b833fc64b96202 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/Fade.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/Fade.java
@@ -2,8 +2,20 @@ package de.tobias.playpad.settings;
 
 import org.dom4j.Element;
 
+import de.tobias.playpad.pad.PadSettings;
 import javafx.util.Duration;
 
+/**
+ * Einstellungen zum Fading, zusammengefasst in dieser Klasse.
+ * 
+ * @author tobias
+ * 
+ * @since 6.0.0
+ * 
+ * @see ProfileSettings#getFade()
+ * @see PadSettings#getFade()
+ *
+ */
 public class Fade {
 
 	private Duration fadeIn;
@@ -14,19 +26,48 @@ public class Fade {
 	private boolean fadeOutPause;
 	private boolean fadeOutStop;
 
+	/**
+	 * Erstellt ein neues Fading mit den Default Werten. (Fade Dauer: 0 sec)
+	 */
 	public Fade() {
-		fadeIn = Duration.ZERO;
-		fadeOut = Duration.ZERO;
-
-		fadeInStart = false;
-		fadeInPause = true;
-		fadeOutPause = true;
-		fadeOutStop = true;
+		this(Duration.ZERO, Duration.ZERO);
 	}
 
+	/**
+	 * Erstellt einen neues Fading mit Custom Zeiten und Default Einstellungen für Play, Pause, Stop.
+	 * 
+	 * @param fadeIn
+	 *            Fade In Dauer
+	 * @param fadeOut
+	 *            Fade Out Dauer
+	 */
 	public Fade(Duration fadeIn, Duration fadeOut) {
+		this(fadeIn, fadeOut, false, true, true, true);
+	}
+
+	/**
+	 * Erstellt ein Fading mit Custom Werten.
+	 * 
+	 * @param fadeIn
+	 *            Fade In Dauer
+	 * @param fadeOut
+	 *            Fade Out Dauer
+	 * @param fadeInStart
+	 *            Fade beim Start
+	 * @param fadeInPause
+	 *            Fade nach Pause
+	 * @param fadeOutPause
+	 *            Fade vor Pause
+	 * @param fadeOutStop
+	 *            Fade vor Stop
+	 */
+	public Fade(Duration fadeIn, Duration fadeOut, boolean fadeInStart, boolean fadeInPause, boolean fadeOutPause, boolean fadeOutStop) {
 		this.fadeIn = fadeIn;
 		this.fadeOut = fadeOut;
+		this.fadeInStart = fadeInStart;
+		this.fadeInPause = fadeInPause;
+		this.fadeOutPause = fadeOutPause;
+		this.fadeOutStop = fadeOutStop;
 	}
 
 	public Duration getFadeIn() {
@@ -77,6 +118,10 @@ public class Fade {
 		this.fadeOutStop = fadeOutStop;
 	}
 
+	/*
+	 * Serialize
+	 */
+
 	private static final String FADE_OUT = "FadeOut";
 	private static final String FADE_IN = "FadeIn";
 
@@ -114,7 +159,9 @@ public class Fade {
 				fade.setFadeOutStop(Boolean.valueOf(fadeOutElement.attributeValue(ON_STOP_ATTR)));
 			fade.setFadeOut(Duration.valueOf(fadeOutElement.getStringValue().replace(" ", "")));
 			return fade;
-		} catch (Exception e) {}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 		return null;
 	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/GlobalSettings.java b/PlayWallCore/src/de/tobias/playpad/settings/GlobalSettings.java
index 3caa9fa0d669543ae5b71f6e3b9734c14f5a2233..477780f824bea0aa9ca25b59726b283783688ddb 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/GlobalSettings.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/GlobalSettings.java
@@ -16,7 +16,7 @@ import org.dom4j.io.XMLWriter;
 
 import de.tobias.playpad.PlayPad;
 import de.tobias.playpad.settings.keys.KeyCollection;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.settings.Storable;
@@ -147,7 +147,7 @@ public class GlobalSettings {
 
 	// Save & Load Data
 
-	private static final String KEYS_ELEMENT = "Keys";
+	public static final String KEYS_ELEMENT = "Keys";
 	private static final String AUTO_UPDATE_ELEMENT = "AutoUpdate";
 	private static final String IGNORE_UPDATE_ELEMENT = "IgnoreUpdate";
 	private static final String UPDATE_CHANNEL_ELEMENT = "UpdateChannel";
@@ -177,9 +177,6 @@ public class GlobalSettings {
 			Document document = reader.read(Files.newInputStream(savePath));
 			Element root = document.getRootElement();
 
-			if (root.element(KEYS_ELEMENT) != null)
-				settings.keyCollection.load(root.element(KEYS_ELEMENT));
-
 			if (root.element(AUTO_UPDATE_ELEMENT) != null) {
 				settings.setAutoUpdate(Boolean.valueOf(root.element(AUTO_UPDATE_ELEMENT).getStringValue()));
 			}
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java
index 2516305ee7b7e610aa892aeb91666cbbbabcd942..cd8b78e90bf865042eca8da35b54b1f833f0a3d1 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/Profile.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/Profile.java
@@ -14,6 +14,8 @@ import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.MappingList;
 import de.tobias.playpad.design.DesignConnect;
 import de.tobias.playpad.design.GlobalDesign;
+import de.tobias.playpad.profile.ref.ProfileReference;
+import de.tobias.playpad.profile.ref.ProfileReferences;
 import de.tobias.playpad.registry.DefaultRegistry;
 import de.tobias.playpad.registry.NoSuchComponentException;
 import de.tobias.utils.application.App;
@@ -26,7 +28,7 @@ public class Profile {
 	private static final String MAPPING_XML = "Mapping.xml";
 	private static final String LAYOUT_XML = "Layout.xml";
 
-	public static final String profileNameEx = "[\\p{L},0-9]{1}[\\p{L}\\s-_]{0,}";
+	public static final String profileNameEx = "[\\p{L}0-9]{1}[\\p{L}\\s-_0-9]{0,}";
 
 	private static List<ProfileListener> listeners = new ArrayList<>();
 	private static Profile currentProfile;
@@ -38,7 +40,13 @@ public class Profile {
 	private MappingList mappings;
 	private HashMap<String, GlobalDesign> layouts;
 
-	Profile(ProfileReference ref) {
+	/**
+	 * Use {@link ProfileReferences#addProfile(ProfileReference)} instead
+	 * 
+	 * @param ref
+	 *            Ref
+	 */
+	public Profile(ProfileReference ref) {
 		this.ref = ref;
 		this.profileSettings = new ProfileSettings();
 		this.mappings = new MappingList(this);
@@ -139,6 +147,8 @@ public class Profile {
 	}
 
 	public void save() throws UnsupportedEncodingException, IOException {
+		ref.getRequestedModules().clear();
+
 		PlayPadPlugin.getImplementation().getSettingsListener().forEach(l ->
 		{
 			try {
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileNotFoundException.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileNotFoundException.java
index ddf59e72d88f646e644a6139b03fca3c4c569073..ab1cb36b5a12c8c1d3a15bbd1666472a742b9b25 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileNotFoundException.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileNotFoundException.java
@@ -1,5 +1,7 @@
 package de.tobias.playpad.settings;
 
+import de.tobias.playpad.profile.ref.ProfileReference;
+
 public class ProfileNotFoundException extends Exception {
 
 	private static final long serialVersionUID = 1L;
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java
index 0c3e79c73f2dfd192423ee37cc4f9993ed28b021..2bddc8675cdfef0c1910b0804f37cf7be74bfcb9 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/ProfileSettings.java
@@ -46,7 +46,7 @@ public class ProfileSettings implements SettingsSerializable {
 
 	// Cart Settings
 	@Storable private boolean multiplePlayer = true;
-	@Storable private Warning warningFeedback = new Warning(Duration.seconds(5));
+	@Storable private Duration warningTime = Duration.seconds(5);
 
 	@Storable private DoubleProperty volumeProperty = new SimpleDoubleProperty(1.0);
 
@@ -80,8 +80,8 @@ public class ProfileSettings implements SettingsSerializable {
 		return mainLayoutType;
 	}
 
-	public Warning getWarningFeedback() {
-		return warningFeedback;
+	public Duration getWarningFeedback() {
+		return warningTime;
 	}
 
 	public boolean isMidiActive() {
@@ -129,8 +129,8 @@ public class ProfileSettings implements SettingsSerializable {
 		this.mainLayoutType = mainLayoutType;
 	}
 
-	public void setWarningFeedback(Warning warningFeedback) {
-		this.warningFeedback = warningFeedback;
+	public void setWarningTime(Duration warningTime) {
+		this.warningTime = warningTime;
 	}
 
 	public void setMidiActive(boolean midiActive) {
@@ -210,9 +210,11 @@ public class ProfileSettings implements SettingsSerializable {
 			}
 
 			if (root.element(WARNING_ELEMENT) != null) {
-				Warning warning = Warning.load(root.element(WARNING_ELEMENT));
-				if (warning != null) {
-					profileSettings.setWarningFeedback(warning);
+				try {
+					Duration duration = Duration.valueOf(root.element(WARNING_ELEMENT).getStringValue().replace(" ", ""));
+					profileSettings.setWarningTime(duration);
+				} catch (Exception e) {
+					profileSettings.setWarningTime(Duration.seconds(5));
 				}
 			}
 
@@ -266,7 +268,7 @@ public class ProfileSettings implements SettingsSerializable {
 		root.addElement(LAYOUT_TYPE_ELEMENT).addText(layoutType);
 		root.addElement(MAIN_LAYOUT_TYPE_ELEMENT).addText(mainLayoutType);
 
-		warningFeedback.save(root.addElement(WARNING_ELEMENT));
+		root.addElement(WARNING_ELEMENT).addText(warningTime.toString());
 		fade.save(root.addElement(FADE_ELEMENT));
 		root.addElement(TIME_DISPLAY_ELEMENT).addText(player_timeDisplayMode.name());
 
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/Warning.java b/PlayWallCore/src/de/tobias/playpad/settings/Warning.java
deleted file mode 100644
index 56de8f3d2bdbb892aff6966cd72384500d339cb5..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/settings/Warning.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.tobias.playpad.settings;
-
-import org.dom4j.Element;
-
-import de.tobias.utils.settings.SettingsSerializable;
-import de.tobias.utils.settings.Storable;
-import javafx.util.Duration;
-
-public class Warning implements SettingsSerializable{
-
-	private static final long serialVersionUID = 1L;
-	
-	@Storable private Duration time;
-
-	public Warning() {
-		time = Duration.seconds(5);
-	}
-
-	public Warning(Duration time) {
-		this.time = time;
-	}
-
-	public Duration getTime() {
-		return time;
-	}
-
-	public void setTime(Duration time) {
-		this.time = time;
-	}
-
-	private static final String TIME_ELEMENT = "Time";
-
-	public static Warning load(Element feedbackElement) {
-		try {
-			if (feedbackElement.element(TIME_ELEMENT) != null) {
-				Duration dutation = Duration.valueOf(feedbackElement.element(TIME_ELEMENT).getStringValue().replace(" ", ""));
-				Warning warning = new Warning(dutation);
-				return warning;
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		return null;
-	}
-
-	public Element save(Element feedbackElement) {
-		feedbackElement.addElement(TIME_ELEMENT).addText(time.toString());
-		return feedbackElement;
-	}
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/keys/Key.java b/PlayWallCore/src/de/tobias/playpad/settings/keys/Key.java
index 7ae9e3c5bf7f7a64ef8970e00bf2fe5efc5f8bee..a3d75334e9b5b3b3f4874afc57e820d08d7a6b9d 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/keys/Key.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/keys/Key.java
@@ -5,6 +5,13 @@ import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
 import javafx.scene.input.KeyCombination;
 
+/**
+ * Eine Tastenkombination für das Mapping zum Menü.
+ * 
+ * @author tobias
+ *
+ * @since 5.1.0
+ */
 public class Key implements Displayable {
 
 	private String id;
@@ -15,10 +22,32 @@ public class Key implements Displayable {
 	private boolean meta;
 	private boolean shift;
 
+	/**
+	 * Erstellt eine leere Tastenkombination.
+	 * 
+	 * @param id
+	 *            ID für die Speicherung
+	 */
 	public Key(String id) {
 		this.id = id;
 	}
 
+	/**
+	 * Erstellt eine Vollständige Tastenkombination mit ID und Datenwerten.
+	 * 
+	 * @param id
+	 *            ID f+r doe Speicherung
+	 * @param key
+	 *            Taste
+	 * @param ctrl
+	 *            ctrl
+	 * @param alt
+	 *            alt
+	 * @param meta
+	 *            meta (Mac: CMD)
+	 * @param shift
+	 *            shift
+	 */
 	public Key(String id, String key, boolean ctrl, boolean alt, boolean meta, boolean shift) {
 		this.id = id;
 
@@ -83,26 +112,30 @@ public class Key implements Displayable {
 		return id;
 	}
 
+	/**
+	 * Gibt die Tastenkombination als String für das Menü in JavaFX zurück.
+	 * 
+	 * @return
+	 */
 	public String getKeyCode() {
 		StringBuilder builder = new StringBuilder();
 
 		if (ctrl)
 			builder.append("ctrl+");
-
 		if (alt)
 			builder.append("alt+");
-
 		if (meta)
 			builder.append("meta+");
-
 		if (shift)
 			builder.append("shift+");
-
 		builder.append(key);
 
 		return builder.toString();
 	}
 
+	/**
+	 * Gibt die Tastenkombination von JavaFX geparsed zurück. Diese wird dann für das Menü und die Darstellung verwendet.
+	 */
 	@Override
 	public String toString() {
 		if (!getKeyCode().isEmpty())
@@ -115,11 +148,15 @@ public class Key implements Displayable {
 			return "";
 	}
 
-	private StringProperty displayProperty = new SimpleStringProperty();
+	private transient StringProperty displayProperty = new SimpleStringProperty();
 
 	@Override
 	public StringProperty displayProperty() {
 		displayProperty.set(toString());
 		return displayProperty;
 	}
+
+	public boolean isEmpty() {
+		return key.isEmpty() && !ctrl && !shift & !meta && !alt;
+	}
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollection.java b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollection.java
index 85518577e5cff024333007fdca3a82db9d375e76..09711f389e8ea95d133820ce7a49cd26b15773e4 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollection.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollection.java
@@ -1,18 +1,23 @@
 package de.tobias.playpad.settings.keys;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.ResourceBundle;
+import java.util.stream.Collectors;
 
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
 import org.dom4j.io.SAXReader;
 
-import de.tobias.playpad.xml.XMLHandler;
+import de.tobias.playpad.settings.GlobalSettings;
 import de.tobias.utils.util.OS;
+import de.tobias.utils.xml.XMLHandler;
 
 /**
  * Verwaltung der Tastenkombinationen für das Menu.
@@ -24,32 +29,66 @@ import de.tobias.utils.util.OS;
 public class KeyCollection {
 
 	// Schlüssel: ID, Value: Key
-	private HashMap<String, Key> keys;
-	private HashMap<String, String> names;
+	private HashMap<String, KeyCollectionEntry> keys;
 
+	/**
+	 * Erstellt ein neues, leeres Mapping.
+	 */
 	public KeyCollection() {
 		keys = new HashMap<>();
-		names = new HashMap<>();
 	}
 
-	public void register(Key key) {
-		if (!keys.containsKey(key.getId())) {
-			if (!keysConflict(key)) {
-				keys.put(key.getId(), key);
+	/**
+	 * Fügt eine Taste zum Mapping hinzu.
+	 * 
+	 * @param entry
+	 *            Taste
+	 * @throws KeyConflictException
+	 *             Registrierung fehlgeschlagen, weil Key bereits vorhanden.
+	 */
+	public void register(KeyCollectionEntry entry) throws KeyConflictException {
+		if (!keys.containsKey(entry.getKey().getId())) {
+			if (!keysConflict(entry.getKey())) {
+				keys.put(entry.getKey().getId(), entry);
+			} else {
+				throw new KeyConflictException(entry.getKey());
 			}
 		}
 	}
 
+	/**
+	 * Name des Keys.
+	 * 
+	 * @param id
+	 *            ID der Kombination
+	 * @return Localized Name
+	 */
 	public String getName(String id) {
-		return names.get(id);
+		KeyCollectionEntry keyCollectionEntry = keys.get(id);
+		if (keyCollectionEntry != null) {
+			return keyCollectionEntry.getName();
+		} else {
+			return null;
+		}
 	}
 
 	public Key getKey(String id) {
-		return keys.get(id);
+		KeyCollectionEntry keyCollectionEntry = keys.get(id);
+		if (keyCollectionEntry != null) {
+			return keyCollectionEntry.getKey();
+		} else {
+			return null;
+		}
+	}
+
+	private void updateKey(Key key) {
+		KeyCollectionEntry keyCollectionEntry = keys.get(key.getId());
+		if (keyCollectionEntry != null)
+			keyCollectionEntry.setKey(key);
 	}
 
 	public Collection<Key> getKeys() {
-		return keys.values();
+		return keys.values().stream().map(KeyCollectionEntry::getKey).collect(Collectors.toList());
 	}
 
 	/**
@@ -66,32 +105,58 @@ public class KeyCollection {
 		key.setKey("");
 	}
 
+	/**
+	 * Prüft ob es einen Konflikt zu anderen Key Combinations gibt.
+	 * 
+	 * @param key
+	 *            Test Objekt
+	 * @return <code>true</code> Konflikt.
+	 */
 	public boolean keysConflict(Key key) {
-		for (Key k : keys.values()) {
-			if (k.getKeyCode().equals(key.getKeyCode())) {
+		for (KeyCollectionEntry k : keys.values()) {
+			if (k.getKey().getKeyCode().equals(key.getKeyCode()) && !key.isEmpty()) {
 				return true;
 			}
 		}
 		return false;
 	}
-	
+
+	/**
+	 * Sucht nach den konkreten Konflikten.
+	 * 
+	 * @param key
+	 *            Test Objekt
+	 * @return Liste der Konflikte.
+	 */
 	public List<Key> getConflicts(Key key) {
 		List<Key> conflicts = new ArrayList<>();
-		for (Key k : keys.values()) {
-			if (k.getKeyCode().equals(key.getKeyCode())) {
-				conflicts.add(k);
+		for (KeyCollectionEntry k : keys.values()) {
+			if (k.getKey().getKeyCode().equals(key.getKeyCode())) {
+				conflicts.add(k.getKey());
 			}
 		}
 		return conflicts;
 	}
 
+	/*
+	 * Speicher & Laden
+	 */
+
 	private static final String KEY_ELEMENT = "Key";
 
-	public void load(Element element) {
-		XMLHandler<Key> handler = new XMLHandler<>(element);
-		List<Key> keys = handler.loadElements(KEY_ELEMENT, new KeySerializer());
-		for (Key key : keys) {
-			register(key);
+	public void load(Path path) throws DocumentException, IOException {
+		if (Files.exists(path)) {
+			SAXReader reader = new SAXReader();
+			Document document = reader.read(Files.newInputStream(path));
+			Element root = document.getRootElement();
+
+			if (root.element(GlobalSettings.KEYS_ELEMENT) != null) {
+				XMLHandler<Key> handler = new XMLHandler<>(root.element(GlobalSettings.KEYS_ELEMENT));
+				List<Key> keys = handler.loadElements(KEY_ELEMENT, new KeySerializer());
+				for (Key key : keys) {
+					updateKey(key);
+				}
+			}
 		}
 	}
 
@@ -103,6 +168,14 @@ public class KeyCollection {
 	private static final String WINDOWS_KEYS = "Windows";
 	private static final String MAC_KEYS = "Mac";
 
+	/**
+	 * Lädt die Default Liste an vorhanden Keys.
+	 * 
+	 * @param classPath
+	 *            Pfad zu der XML Datei mit den Keys.
+	 * @param bundle
+	 *            ResourceBundle für die Namen der Kombinationen.
+	 */
 	public void loadDefaultFromFile(String classPath, ResourceBundle bundle) {
 		SAXReader reader = new SAXReader();
 		try {
@@ -124,9 +197,14 @@ public class KeyCollection {
 
 						String name = loadName(keyElement, bundle);
 						Key key = keySerializer.loadElement(keyElement);
-
-						names.put(key.getId(), name);
-						register(key);
+						KeyCollectionEntry entry = new KeyCollectionEntry(name, key);
+
+						try {
+							register(entry);
+						} catch (KeyConflictException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
 					}
 				}
 			}
@@ -135,6 +213,15 @@ public class KeyCollection {
 		}
 	}
 
+	/**
+	 * Lädt den Namen des Keys auf dem Bundle anhand der XML Eintrages.
+	 * 
+	 * @param element
+	 *            XML Eintrag
+	 * @param bundle
+	 *            ResourceBundle
+	 * @return Name oder null
+	 */
 	private String loadName(Element element, ResourceBundle bundle) {
 		String name = element.attributeValue("name");
 		if (name != null) {
@@ -143,6 +230,12 @@ public class KeyCollection {
 		return null;
 	}
 
+	/**
+	 * Change an Interal Key with this new settings
+	 * 
+	 * @param newKey
+	 *            virtal copy.
+	 */
 	public void editKey(Key newKey) {
 		Key savedKey = getKey(newKey.getId());
 
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollectionEntry.java b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollectionEntry.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d90cf8f5e8f0aa606ea34748fc998bf0269fb8f
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyCollectionEntry.java
@@ -0,0 +1,32 @@
+package de.tobias.playpad.settings.keys;
+
+/**
+ * Datenstruktur für die KeyCollection, zum speichern der Einträge.
+ * 
+ * @author tobias
+ *
+ * @since 6.0.0
+ */
+class KeyCollectionEntry {
+
+	private final String name;
+	private Key key;
+
+	public KeyCollectionEntry(String name, Key key) {
+		this.name = name;
+		this.key = key;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Key getKey() {
+		return key;
+	}
+
+	public void setKey(Key key) {
+		this.key = key;
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyConflictException.java b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyConflictException.java
new file mode 100644
index 0000000000000000000000000000000000000000..6590027a19c382cd001bae0d3800d28d8da2a111
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeyConflictException.java
@@ -0,0 +1,17 @@
+package de.tobias.playpad.settings.keys;
+
+/**
+ * Exception wenn Key nicht hinzugefügt werden kann, aufgrund eines Konflikts.
+ * 
+ * @author tobias
+ *
+ * @since 6.0.0
+ */
+public class KeyConflictException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	public KeyConflictException(Key key) {
+		super("Key: " + key.toString() + " cannot be used, caused by an conflict");
+	}
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeySerializer.java b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeySerializer.java
index cb8e7fc7a9d30c60e6b56f769758fe81fd05e391..7a393b0e9fab97ba149c0f3fe05164748b88d068 100644
--- a/PlayWallCore/src/de/tobias/playpad/settings/keys/KeySerializer.java
+++ b/PlayWallCore/src/de/tobias/playpad/settings/keys/KeySerializer.java
@@ -2,8 +2,8 @@ package de.tobias.playpad.settings.keys;
 
 import org.dom4j.Element;
 
-import de.tobias.playpad.xml.XMLDeserializer;
-import de.tobias.playpad.xml.XMLSerializer;
+import de.tobias.utils.xml.XMLDeserializer;
+import de.tobias.utils.xml.XMLSerializer;
 
 public class KeySerializer implements XMLSerializer<Key>, XMLDeserializer<Key> {
 
@@ -14,6 +14,7 @@ public class KeySerializer implements XMLSerializer<Key>, XMLDeserializer<Key> {
 	private static final String META_ATTR = "meta";
 	private static final String SHIFT_ATTR = "shift";
 
+	@Override
 	public Key loadElement(Element element) {
 		boolean shift = false;
 		if (element.attributeValue(SHIFT_ATTR) != null) {
diff --git a/PlayWallCore/src/de/tobias/playpad/update/Updatable.java b/PlayWallCore/src/de/tobias/playpad/update/Updatable.java
deleted file mode 100644
index 88c493aec8cd4b9741f2e46dadfb71df421aec90..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/update/Updatable.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package de.tobias.playpad.update;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Path;
-
-public interface Updatable {
-
-	public int getCurrentBuild();
-
-	public String getCurrentVersion();
-
-	public int getNewBuild();
-
-	public String getNewVersion();
-
-	public boolean isUpdateAvailable();
-	
-	public void loadInformation(UpdateChannel channel) throws IOException, URISyntaxException;
-
-	public URL getDownloadPath();
-	
-	public Path getLocalPath();
-	
-	public String name();
-
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java b/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java
deleted file mode 100644
index ca0367b83d6e1209be9076f625caafde2e759364..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/update/UpdateChannel.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.tobias.playpad.update;
-
-public enum UpdateChannel {
-
-	STABLE("stable"),
-	BETA("beta");
-
-	private String name;
-
-	private UpdateChannel(String name) {
-		this.name = name;
-	}
-
-	@Override
-	public String toString() {
-		return name;
-	}
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java b/PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java
deleted file mode 100644
index 9b2274c4c31ced8afdd4342024a88c6ea83d5083..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/update/UpdateRegistery.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package de.tobias.playpad.update;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
-
-import de.tobias.utils.util.OS;
-import de.tobias.utils.util.SystemUtils;
-import net.minidev.json.JSONArray;
-import net.minidev.json.JSONObject;
-import net.minidev.json.JSONStyle;
-
-public class UpdateRegistery {
-
-	private static List<Updatable> updatables = new ArrayList<>();
-	private static List<Updatable> availableUpdates = new ArrayList<>();
-
-	public static void registerUpdateable(Updatable updatable) {
-		updatables.add(updatable);
-	}
-
-	public static List<Updatable> getAvailableUpdates() {
-		return availableUpdates;
-	}
-
-	public static List<Updatable> lookupUpdates(UpdateChannel channel) {
-		availableUpdates.clear();
-		for (Updatable updatable : UpdateRegistery.updatables) {
-			try {
-				updatable.loadInformation(channel);
-				if (updatable.isUpdateAvailable()) {
-					availableUpdates.add(updatable);
-				}
-			} catch (IOException | URISyntaxException e) {
-
-			}
-		}
-		return availableUpdates;
-	}
-
-	private static final String DOWNLOAD_PATH = "downloadPath";
-	private static final String FILES = "files";
-	private static final String LOCAL = "local";
-	private static final String URL = "url";
-	private static final String EXECUTE_FILE = "executePath";
-
-	public static String buildParamaterString(String downloadPath) {
-		JSONObject data = new JSONObject();
-		data.put(DOWNLOAD_PATH, downloadPath);
-
-		JSONArray array = new JSONArray();
-		for (Updatable updatable : availableUpdates) {
-			JSONObject file = new JSONObject();
-			file.put(URL, updatable.getDownloadPath().toString());
-			file.put(LOCAL, updatable.getLocalPath().toString());
-			array.add(file);
-		}
-		data.put(FILES, array);
-		try {
-			data.put(EXECUTE_FILE, SystemUtils.getRunPath().toString());
-		} catch (URISyntaxException e) {
-			e.printStackTrace();
-		}
-
-		String json = data.toJSONString(JSONStyle.MAX_COMPRESS);
-		return json;
-	}
-
-	public static boolean needsAdminPermission() {
-		for (Updatable updatable : availableUpdates) {
-			if (!Files.isWritable(updatable.getLocalPath())) {
-				return true;
-			}
-			if (OS.isWindows()) {
-				try {
-					if (Files.getOwner(updatable.getLocalPath()).getName().toLowerCase().contains("admin")) {
-						return true;
-					}
-				} catch (IOException e) {}
-			}
-		}
-		return false;
-	}
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java
index 4a6bb28d49299a18a4dac4725e04e72fe68ddf06..6cdbcf12808a8620c7f69d7b4e2c213faf6e7dd1 100644
--- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java
+++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java
@@ -7,8 +7,10 @@ import de.tobias.playpad.pad.view.IPadView;
 import de.tobias.playpad.settings.keys.KeyCollection;
 import de.tobias.playpad.view.main.MainLayoutConnect;
 import de.tobias.playpad.view.main.MainLayoutHandler;
+import de.tobias.utils.ui.Alertable;
 import de.tobias.utils.ui.NotificationHandler;
 import de.tobias.utils.ui.scene.NotificationPane;
+import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.event.EventType;
 import javafx.scene.Parent;
@@ -25,7 +27,7 @@ import javafx.stage.Stage;
  * @since 5.1.0
  *
  */
-public interface IMainViewController extends NotificationHandler {
+public interface IMainViewController extends NotificationHandler, Alertable {
 
 	/**
 	 * Setzt die Grid Farbe.
@@ -118,14 +120,6 @@ public interface IMainViewController extends NotificationHandler {
 	 */
 	public MidiListener getMidiHandler();
 
-	/**
-	 * Setzt das Globale Volume bei den Kacheln des aktuellen Projekts.
-	 * 
-	 * @param doubleValue
-	 *            [0..1]
-	 */
-	public void setGlobalVolume(double doubleValue);
-
 	/**
 	 * Setzt das MainLayout des Hauptfensters.
 	 * 
@@ -157,4 +151,8 @@ public interface IMainViewController extends NotificationHandler {
 	 * @return NotificationPane
 	 */
 	public NotificationPane getNotificationPane();
+
+	public <T extends Event> void addListenerForPads(EventHandler<? super T> handler, EventType<T> eventType);
+	
+	public <T extends Event> void removeListenerForPads(EventHandler<? super T> handler, EventType<T> eventType);
 }
diff --git a/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java b/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..805fc4387578b4f6601b8beb2a73d58a7970e470
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java
@@ -0,0 +1,19 @@
+package de.tobias.playpad.volume;
+
+import de.tobias.playpad.pad.Pad;
+
+/**
+ * Interface, um das Volume eines Pad zu beeinflussen. Es muss dem VolumeManager hinzugefügt werden.
+ * 
+ * @author tobias
+ *
+ * @sinve 6.0.0
+ * 
+ * @see VolumeManager#addFilter(VolumeFilter)
+ */
+@FunctionalInterface
+public interface VolumeFilter {
+
+	double getVolume(Pad pad);
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java b/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a809d40be62223c8fa99ab307f68912547594bf
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java
@@ -0,0 +1,36 @@
+package de.tobias.playpad.volume;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.tobias.playpad.pad.Pad;
+
+public class VolumeManager {
+
+	private List<VolumeFilter> filters;
+
+	public VolumeManager() {
+		this.filters = new ArrayList<>();
+	}
+
+	public void addFilter(VolumeFilter filter) {
+		filters.add(filter);
+	}
+
+	public void removeFilter(VolumeFilter filter) {
+		filters.remove(filter);
+	}
+
+	public double computeVolume(Pad pad) {
+		double volume = 1;
+		for (VolumeFilter filter : filters) {
+			volume *= filter.getVolume(pad);
+
+			if (volume == 0) {
+				break;
+			}
+		}
+		return volume;
+	}
+
+}
diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java
deleted file mode 100644
index 44581a3fffa50762840ba748a4a6206a103cc67b..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/xml/XMLDeserializer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package de.tobias.playpad.xml;
-
-import org.dom4j.Element;
-
-/**
- * Schnittstelle um ein Object auf einem XML Tree zu deserialisieren.
- * 
- * @author tobias
- *
- * @param <T>
- *            Typ der Daten
- */
-public interface XMLDeserializer<T> {
-
-	/**
-	 * Lädt ein Object auf XML Daten.
-	 * 
-	 * @param element
-	 *            XML Objekt
-	 * @return Daten aus dem XML
-	 */
-	public T loadElement(Element element);
-
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java
deleted file mode 100644
index b106b92fc33910801ec9e8346818b42eb24fcaba..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/xml/XMLHandler.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package de.tobias.playpad.xml;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.dom4j.io.OutputFormat;
-import org.dom4j.io.SAXReader;
-import org.dom4j.io.XMLWriter;
-
-/**
- * Util Methods zum Laden von XML Files.
- * 
- * @author tobias
- * 
- * @since 5.0.1
- */
-public class XMLHandler<T> {
-
-	private Element rootElement;
-
-	/**
-	 * Lädt ein XML Dokument und speichert sich den RootNode.
-	 * 
-	 * @param path
-	 *            Path zu XML Datei
-	 * @throws DocumentException
-	 *             Fehler in der XML Datei
-	 * @throws IOException
-	 *             IO Fehler (Bsp. Datei nicht vorhanden)
-	 */
-	public XMLHandler(Path path) throws DocumentException, IOException {
-		if (Files.exists(path)) {
-			SAXReader reader = new SAXReader();
-			Document document = reader.read(Files.newInputStream(path));
-			rootElement = document.getRootElement();
-		} else {
-			throw new FileNotFoundException(path.toString());
-		}
-	}
-
-	/**
-	 * Erstellt einen neuen Handler mit einem RootElement.
-	 * 
-	 * @param rootElement
-	 *            RootElement
-	 */
-	public XMLHandler(Element rootElement) {
-		this.rootElement = rootElement;
-	}
-
-	/**
-	 * Lädt ein Datenrecord auf einem Array von Daten
-	 * 
-	 * @param listElementTag
-	 *            Datentype
-	 * @param deserializer
-	 *            Deserializer
-	 * @return Liste von Daten
-	 */
-	public List<T> loadElements(String listElementTag, XMLDeserializer<T> deserializer) {
-		List<T> list = new ArrayList<>();
-
-		for (Object object : rootElement.elements(listElementTag)) {
-			if (object instanceof Element) {
-				Element element = (Element) object;
-				T data = deserializer.loadElement(element);
-				if (data != null) {
-					list.add(data);
-				}
-			}
-		}
-
-		return list;
-	}
-
-	/**
-	 * Speichert eine Liste von Objekten mittels Serializer.
-	 * 
-	 * @param listElementTag
-	 *            Name der XML Element
-	 * @param list
-	 *            Liste der Daten
-	 * @param serializer
-	 *            Serializer
-	 */
-	public void saveElements(String listElementTag, Iterable<T> list, XMLSerializer<T> serializer) {
-		for (T data : list) {
-			Element element = rootElement.addElement(listElementTag);
-			serializer.saveElement(element, data);
-		}
-	}
-
-	/**
-	 * Speichert eine XML in einem Path.
-	 * 
-	 * @param path
-	 *            Path der Datei
-	 * @param document
-	 *            XML Document
-	 * @throws UnsupportedEncodingException
-	 *             Falsches Encoding
-	 * @throws IOException
-	 *             IO Fehler (Bsp. File nicht vorhanden)
-	 */
-	public static void save(Path path, Document document) throws UnsupportedEncodingException, IOException {
-		if (Files.exists(path)) {
-			XMLWriter writer = new XMLWriter(Files.newOutputStream(path), OutputFormat.createPrettyPrint());
-			writer.write(document);
-			writer.close();
-		} else {
-			throw new FileNotFoundException(path.toString());
-		}
-	}
-
-	/**
-	 * Gibt das RootElement zurück.
-	 * 
-	 * @return Root Element
-	 */
-	public Element getRootElement() {
-		return rootElement;
-	}
-}
diff --git a/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java b/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java
deleted file mode 100644
index 824741866bf6a72c89126febc81415cecb63869a..0000000000000000000000000000000000000000
--- a/PlayWallCore/src/de/tobias/playpad/xml/XMLSerializer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.tobias.playpad.xml;
-
-import org.dom4j.Element;
-
-/**
- * Schnittstelle um ein Object in eine XML Struktur zu überführen.
- * 
- * @author tobias
- *
- * @param <T>
- *            Typ der Daten
- */
-public interface XMLSerializer<T> {
-
-	/**
-	 * Überführt ein Object in eine XML Struktur. Dafür wird bereits ein XML Object angelegt, zu dem Attribute und Sub Elemente hinzugefügt
-	 * werden können.
-	 * 
-	 * @param newElement
-	 *            XML Object
-	 * @param data
-	 *            Daten
-	 */
-	public void saveElement(Element newElement, T data);
-
-}
diff --git a/PlayWallNative/.gitignore b/PlayWallNative/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ae3c1726048cd06b9a143e0376ed46dd9b9a8d53
--- /dev/null
+++ b/PlayWallNative/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/PlayWallNativeMac/.classpath b/PlayWallNativeMac/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..8c57eb3223230feab989aa8b9f629d671ba77223
--- /dev/null
+++ b/PlayWallNativeMac/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/YML"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/libUtils"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugins"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Updater"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/PlayWallNativeMac/.gitignore b/PlayWallNativeMac/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ae3c1726048cd06b9a143e0376ed46dd9b9a8d53
--- /dev/null
+++ b/PlayWallNativeMac/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/PlayWallNativeMac/.project b/PlayWallNativeMac/.project
new file mode 100644
index 0000000000000000000000000000000000000000..da9501320a3b89805da1867b6827d4d216efe0fc
--- /dev/null
+++ b/PlayWallNativeMac/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>PlayWallNativeMac</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/PlayWallNativeMac/.settings/org.eclipse.jdt.core.prefs b/PlayWallNativeMac/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..3a21537071bf4118b9e1ee864cb4bc258aa48211
--- /dev/null
+++ b/PlayWallNativeMac/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/NativeAudio.java b/PlayWallNativeMac/src/de/tobias/playpad/NativeAudio.java
new file mode 100644
index 0000000000000000000000000000000000000000..cee1d7277008783ef91cb119ce8b389791e4540e
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/NativeAudio.java
@@ -0,0 +1,58 @@
+package de.tobias.playpad;
+
+public class NativeAudio {
+
+	public static native void initialize();
+	
+	public static native void play(int id);
+
+	public static native void pause(int id);
+
+	public static native void stop(int id);
+
+	public static native void setLoop(int id, boolean loop);
+
+	public static native double getVolume(int id);
+
+	public static native void setVolume(int id, double volume);
+
+	public static native boolean load(int id, String path);
+
+	public static native void dispose(int id);
+
+	public static native double getDuration(int id);
+
+	public static native double getPosition(int id);
+	
+	public static void onPeakMeter(int id, float left, float right) {
+		if (delegate != null) {
+			delegate.onPeakMeter(id, left, right);
+		}
+	}
+
+	public static void onPositionChanged(int id, double position) {
+		if (delegate != null) {
+			delegate.onPositionChanged(id, position);
+		}
+	}
+	
+	public static void onFinish(int id) {
+		if (delegate != null) {
+			delegate.onFinish(id);
+		}
+	}
+
+	private static NativeAudioDelegate delegate;
+
+	public static void setDelegate(NativeAudioDelegate delegate) {
+		NativeAudio.delegate = delegate;
+	}
+
+	public interface NativeAudioDelegate {
+		public void onFinish(int id);
+		
+		public void onPeakMeter(int id, float left, float right);
+		
+		public void onPositionChanged(int id, double position);
+	}
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/Waveform.java b/PlayWallNativeMac/src/de/tobias/playpad/Waveform.java
new file mode 100644
index 0000000000000000000000000000000000000000..f01873a01df7c0f3e1eb998941e3bd73b63519f6
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/Waveform.java
@@ -0,0 +1,7 @@
+package de.tobias.playpad;
+
+public class Waveform {
+
+	public static native float[] createWaveform(String path);
+
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/libNativeAudio.dylib b/PlayWallNativeMac/src/de/tobias/playpad/libNativeAudio.dylib
new file mode 100644
index 0000000000000000000000000000000000000000..14afa4716652379483939e006f1d32ba3adde6bb
Binary files /dev/null and b/PlayWallNativeMac/src/de/tobias/playpad/libNativeAudio.dylib differ
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandler.java b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..85e2368f1626d303894424847088d3a43199fd56
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandler.java
@@ -0,0 +1,136 @@
+package de.tobias.playpad.namac;
+
+import java.nio.file.Path;
+
+import de.tobias.playpad.NativeAudio;
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.Peakable;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
+
+public class NativeAudioMacHandler extends AudioHandler implements Peakable {
+
+	private static int counter = 0;
+
+	private final int id;
+	ObjectProperty<Duration> positionProperty;
+	private ObjectProperty<Duration> durationProperty;
+	private boolean isLoaded;
+
+	private DoubleProperty leftPeak;
+	private DoubleProperty rightPeak;
+
+	public NativeAudioMacHandler(PadContent content) {
+		super(content);
+
+		id = counter++;
+		positionProperty = new SimpleObjectProperty<>();
+		durationProperty = new SimpleObjectProperty<>();
+
+		leftPeak = new SimpleDoubleProperty();
+		rightPeak = new SimpleDoubleProperty();
+	}
+
+	protected int getId() {
+		return id;
+	}
+
+	@Override
+	public void play() {
+		NativeAudio.setLoop(id, getContent().getPad().getPadSettings().isLoop());
+		NativeAudio.play(id);
+	}
+
+	@Override
+	public void pause() {
+		NativeAudio.pause(id);
+	}
+
+	@Override
+	public void stop() {
+		NativeAudio.stop(id);
+	}
+
+	@Override
+	public Duration getPosition() {
+		return positionProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return positionProperty;
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public void setVolume(double volume) {
+		NativeAudio.setVolume(id, volume);
+
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return isLoaded;
+	}
+
+	@Override
+	public void loadMedia(Path[] paths) {
+		Platform.runLater(() ->
+		{
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getView().showBusyView(true);
+			}
+		});
+		Worker.runLater(() ->
+		{
+			isLoaded = NativeAudio.load(id, paths[0].toString());
+			if (isLoaded) {
+				Platform.runLater(() ->
+				{
+					durationProperty.set(Duration.seconds(NativeAudio.getDuration(id)));
+					getContent().getPad().setStatus(PadStatus.READY);
+					if (getContent().getPad().isPadVisible()) {
+						getContent().getPad().getController().getView().showBusyView(false);
+					}
+				});
+			}
+		});
+	}
+
+	@Override
+	public void unloadMedia() {
+		NativeAudio.dispose(id);
+	}
+
+	@Override
+	public DoubleProperty audioLevelProperty(Channel channel) {
+		if (channel == Channel.LEFT) {
+			return leftPeak;
+		} else if (channel == Channel.RIGHT) {
+			return rightPeak;
+		}
+		return null;
+	}
+
+	@Override
+	public double getAudioLevel(Channel channel) {
+		return audioLevelProperty(channel).get();
+	}
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandlerConnect.java b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f70f7588854c5ee2ea078a3ea8eeca14c283c87
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacHandlerConnect.java
@@ -0,0 +1,79 @@
+package de.tobias.playpad.namac;
+
+import java.util.HashMap;
+
+import de.tobias.playpad.NativeAudio;
+import de.tobias.playpad.NativeAudio.NativeAudioDelegate;
+import de.tobias.playpad.audio.AudioCapability;
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.AudioHandlerConnect;
+import de.tobias.playpad.audio.Peakable.Channel;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
+import javafx.util.Duration;
+
+public class NativeAudioMacHandlerConnect extends AudioHandlerConnect implements NativeAudioDelegate {
+
+	private static final HashMap<Integer, NativeAudioMacHandler> handlers = new HashMap<>();
+
+	public NativeAudioMacHandlerConnect() {
+		NativeAudio.initialize();
+		NativeAudio.setDelegate(this);
+	}
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		NativeAudioMacHandler nativeAudioMacHandler = new NativeAudioMacHandler(content);
+		handlers.put(nativeAudioMacHandler.getId(), nativeAudioMacHandler);
+		return nativeAudioMacHandler;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioHandlerSettingsViewController() {
+		return null;
+	}
+
+	@Override
+	public String getType() {
+		return "Native";
+	}
+
+	@Override
+	public void onFinish(int id) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			PadContent content = nativeAudioMacHandler.getContent();
+			if (content != null) {
+				content.getPad().setStatus(PadStatus.STOP);
+			}
+		}
+	}
+	
+	@Override
+	public void onPositionChanged(int id, double position) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			nativeAudioMacHandler.positionProperty.set(Duration.seconds(position));
+		}
+	}
+	
+	@Override
+	public void onPeakMeter(int id, float left, float right) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			nativeAudioMacHandler.audioLevelProperty(Channel.LEFT).set(left);
+			nativeAudioMacHandler.audioLevelProperty(Channel.RIGHT).set(right);
+		}
+	}
+
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		return false;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		return null;
+	}
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPlugin.java b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..c17700df5886fbb5b70cfdb30bcf07c6bbab364d
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPlugin.java
@@ -0,0 +1,7 @@
+package de.tobias.playpad.namac;
+
+import de.tobias.playpad.plugin.AdvancedPlugin;
+
+public interface NativeAudioMacPlugin extends AdvancedPlugin {
+
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPluginImpl.java b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPluginImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7ad651a68ba87a8a6bf3636b70b75c145a413ba
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacPluginImpl.java
@@ -0,0 +1,81 @@
+package de.tobias.playpad.namac;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.updater.client.Updatable;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.IOUtils;
+import de.tobias.utils.util.OS;
+import net.xeoh.plugins.base.annotations.PluginImplementation;
+import net.xeoh.plugins.base.annotations.events.PluginLoaded;
+import net.xeoh.plugins.base.annotations.events.Shutdown;
+
+@PluginImplementation
+public class NativeAudioMacPluginImpl implements NativeAudioMacPlugin {
+
+	private static final String ASSETS = "de/tobias/playpad/";
+
+	private static final String NAME = "NativeAudioMac";
+	private static final String IDENTIFIER = "de.tobias.playpad.namac.NativeAudioMacPluginImpl";
+
+	private Module module;
+	private Updatable updatable;
+
+	@PluginLoaded
+	public void onLoaded(NativeAudioMacPlugin plugin) {
+		module = new Module(NAME, IDENTIFIER);
+		updatable = new NativeAudioMacUpdater();
+
+		try {
+			prepareBridging();
+
+			if (OS.isMacOS()) {
+				AudioRegistry registry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
+				registry.registerComponent(new NativeAudioMacHandlerConnect(), "NativeMac", module);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void prepareBridging() throws IOException {
+		App app = ApplicationUtils.getApplication();
+		Path resourceFolder = app.getPath(PathType.LIBRARY, "namac");
+		if (Files.notExists(resourceFolder)) {
+			Files.createDirectories(resourceFolder);
+		}
+
+		Path dest = copyResource(resourceFolder, ASSETS, "libNativeAudio.dylib");
+		System.load(dest.toString());
+	}
+
+	private Path copyResource(Path resourceFolder, String packageName, String file) throws IOException {
+		Path dest = resourceFolder.resolve(file);
+		IOUtils.copy(getClass().getClassLoader().getResourceAsStream(packageName + file), dest);
+		System.out.println("Copied: " + file);
+		return dest;
+	}
+
+	@Shutdown
+	public void onShutdown() {
+
+	}
+
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updatable;
+	}
+
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacUpdater.java b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..487b700f97fe1493aefe9de9805c1f31452b42e3
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/namac/NativeAudioMacUpdater.java
@@ -0,0 +1,79 @@
+package de.tobias.playpad.namac;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Path;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+
+public class NativeAudioMacUpdater implements Updatable {
+
+	private int newBuild;
+	private String newVersion;
+	private URL remotePath;
+
+	private String localFileName;
+	private String name;
+
+	@Override
+	public int getCurrentBuild() {
+		return 1;
+	}
+
+	@Override
+	public String getCurrentVersion() {
+		return "1.0";
+	}
+
+	@Override
+	public int getNewBuild() {
+		return newBuild;
+	}
+
+	@Override
+	public String getNewVersion() {
+		return newVersion;
+	}
+
+	@Override
+	public void loadInformation(UpdateChannel channel) throws IOException {
+		App app = ApplicationUtils.getMainApplication();
+		URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml");
+		FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream());
+
+		newBuild = config.getInt("plugins.namac.build");
+		newVersion = config.getString("plugins.namac.version");
+		remotePath = new URL(config.getString("plugins.namac.url"));
+		localFileName = config.getString("plugins.namac.filename");
+		name = config.getString("plugins.namac.name");
+
+	}
+
+	@Override
+	public boolean isUpdateAvailable() {
+		return getCurrentBuild() < getNewBuild();
+	}
+
+	@Override
+	public URL getDownloadPath() {
+		return remotePath;
+	}
+
+	@Override
+	public Path getLocalPath() {
+		return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName);
+	}
+
+	@Override
+	public String name() {
+		return name;
+	}
+
+}
diff --git a/PlayWallNativeMac/src/de/tobias/playpad/view/WaveformView.java b/PlayWallNativeMac/src/de/tobias/playpad/view/WaveformView.java
new file mode 100644
index 0000000000000000000000000000000000000000..25029d49df5806ebd6ac9bbeba23d7941aeb091c
--- /dev/null
+++ b/PlayWallNativeMac/src/de/tobias/playpad/view/WaveformView.java
@@ -0,0 +1,39 @@
+package de.tobias.playpad.view;
+
+import javafx.scene.paint.Color;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+
+public class WaveformView extends Path {
+
+	public WaveformView(float[] data) {
+		getElements().add(new MoveTo(0, 0));
+
+		double width2 = data.length / 1200.0;
+		int width = data.length / 10000;
+		System.out.println(data.length);
+		System.out.println(width);
+
+		int i = 0;
+		for (i = 0; i < data.length; i += width) {
+			if (i < data.length) {
+				LineTo lineTo = new LineTo(i / width2, data[i] * 50.0);
+				MoveTo moveTo = new MoveTo(i / width2, data[i] * 50.0);
+
+				getElements().addAll(lineTo, moveTo);
+			}
+		}
+		for (; i >= 0; i -= width) {
+			if (i >= 0 && i < data.length) {
+				LineTo lineTo = new LineTo(i / width2, -data[i] * 50.0);
+				MoveTo moveTo = new MoveTo(i / width2, -data[i] * 50.0);
+
+				getElements().addAll(lineTo, moveTo);
+			}
+		}
+		getElements().add(new LineTo(0, 0));
+		getElements().add(new MoveTo(0, 0));
+		setFill(Color.BLACK);
+	}
+}
diff --git a/PlayWallNativeMac/src/de_tobias_playpad_NativeAudio.h b/PlayWallNativeMac/src/de_tobias_playpad_NativeAudio.h
new file mode 100644
index 0000000000000000000000000000000000000000..4bd710308b879f953bd90b3e96a9aa1ec1e2ef92
--- /dev/null
+++ b/PlayWallNativeMac/src/de_tobias_playpad_NativeAudio.h
@@ -0,0 +1,85 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class de_tobias_playpad_NativeAudio */
+
+#ifndef _Included_de_tobias_playpad_NativeAudio
+#define _Included_de_tobias_playpad_NativeAudio
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    play
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_play
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    pause
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_pause
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    stop
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_stop
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getVolume
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getVolume
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    setVolume
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_setVolume
+  (JNIEnv *, jclass, jint, jdouble);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    load
+ * Signature: (ILjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_de_tobias_playpad_NativeAudio_load
+  (JNIEnv *, jclass, jint, jstring);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    dispose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_dispose
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getDuration
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getDuration
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getPosition
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getPosition
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/PlayWallNativeMac/src/de_tobias_playpad_Waveform.h b/PlayWallNativeMac/src/de_tobias_playpad_Waveform.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0e45dcb853ff654b6c6e50ca73a8d9fc6ac183
--- /dev/null
+++ b/PlayWallNativeMac/src/de_tobias_playpad_Waveform.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class de_tobias_playpad_Waveform */
+
+#ifndef _Included_de_tobias_playpad_Waveform
+#define _Included_de_tobias_playpad_Waveform
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     de_tobias_playpad_Waveform
+ * Method:    initialize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_Waveform_initialize
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     de_tobias_playpad_Waveform
+ * Method:    createWaveform
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_Waveform_createWaveform
+  (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/PlayWallNativeMac/test/de/tobias/playpad/NativeAudioTest.java b/PlayWallNativeMac/test/de/tobias/playpad/NativeAudioTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fe58a6cf60fba757ed8d1a7938d11149af87b5c
--- /dev/null
+++ b/PlayWallNativeMac/test/de/tobias/playpad/NativeAudioTest.java
@@ -0,0 +1,20 @@
+package de.tobias.playpad;
+
+public class NativeAudioTest {
+	
+	public static void main(String[] args) {
+		System.load("/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWallNative/libNativeAudio.dylib");
+
+		NativeAudio.load(0, "/Users/tobias/Downloads/03%20Hymn%20For%20The%20Weekend.mp3.wav");
+		System.out.println(NativeAudio.getDuration(0));
+		NativeAudio.play(0);
+		
+		while (true) {
+			try {
+				Thread.sleep(100);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/PlayWallNativeMac/test/de/tobias/playpad/WaveformTest.java b/PlayWallNativeMac/test/de/tobias/playpad/WaveformTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..704d8b6eb7971ccaf75343790d49ffb86f45199f
--- /dev/null
+++ b/PlayWallNativeMac/test/de/tobias/playpad/WaveformTest.java
@@ -0,0 +1,38 @@
+package de.tobias.playpad;
+
+import de.tobias.playpad.view.WaveformView;
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+public class WaveformTest extends Application {
+
+	public static void main(String[] args) {
+		System.load("/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWallNative/libNativeAudio.dylib");
+
+		launch(args);
+	}
+
+	@Override
+	public void start(Stage primaryStage) throws Exception {
+		float[] data = Waveform.createWaveform("/Users/tobias/Music/iTunes/iTunes Media/Music/Coldplay/Mylo Xyloto/04 Charlie Brown.mp3");
+		float[] data2 = Waveform.createWaveform("/Users/tobias/Downloads/TNT-Loop.wav");
+		WaveformView view = new WaveformView(data);
+		WaveformView view2 = new WaveformView(data2);
+
+		WritableImage image = new WritableImage(1200, 150);
+		view.snapshot(null, image);
+		WritableImage image2 = new WritableImage(1200, 150);
+		view2.snapshot(null, image2);
+
+		VBox root = new VBox(new ImageView(image), new ImageView(image2));
+		Scene scene = new Scene(root);
+
+		primaryStage.setScene(scene);
+		primaryStage.show();
+	}
+
+}
diff --git a/PlayWallNativeWin/.classpath b/PlayWallNativeWin/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..709ee3891c7490ab21accfb7f66c61054b14fbe7
--- /dev/null
+++ b/PlayWallNativeWin/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/YML"/>
+	<classpathentry kind="lib" path="j4n/jni4net.j-0.8.8.0.jar"/>
+	<classpathentry kind="lib" path="j4n/NativeAudio.j4n.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/libUtils"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Updater"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/PlayWallNativeWin/.gitignore b/PlayWallNativeWin/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ae3c1726048cd06b9a143e0376ed46dd9b9a8d53
--- /dev/null
+++ b/PlayWallNativeWin/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/PlayWallNativeWin/.project b/PlayWallNativeWin/.project
new file mode 100644
index 0000000000000000000000000000000000000000..f859d19b4ac27ba37188d2fb96f24ea765eccd5f
--- /dev/null
+++ b/PlayWallNativeWin/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>PlayWallNativeWin</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/PlayWallNativeWin/.settings/org.eclipse.jdt.core.prefs b/PlayWallNativeWin/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..bb35fa0a87b032ee9d0b128004c1edbd464f07bf
--- /dev/null
+++ b/PlayWallNativeWin/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/PlayWallNativeWin/MANIFEST.MF b/PlayWallNativeWin/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..eeb2a06cb316a736ee9a6705b198d6a0156eed29
--- /dev/null
+++ b/PlayWallNativeWin/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path: . nawin/jni4net.j-0.8.8.0.jar nawin/NativeAudio.j4n.jar
diff --git a/PlayWallNativeWin/j4n/NAudio.dll b/PlayWallNativeWin/j4n/NAudio.dll
new file mode 100644
index 0000000000000000000000000000000000000000..9dd5ae7de34d2bc2dcf934eb027fa60d20237c3d
Binary files /dev/null and b/PlayWallNativeWin/j4n/NAudio.dll differ
diff --git a/PlayWallNativeWin/j4n/NativeAudio.dll b/PlayWallNativeWin/j4n/NativeAudio.dll
new file mode 100644
index 0000000000000000000000000000000000000000..84e9062fc0bfc9f77ca8d9b9b2ce1f6e7c218aaa
Binary files /dev/null and b/PlayWallNativeWin/j4n/NativeAudio.dll differ
diff --git a/PlayWallNativeWin/j4n/NativeAudio.j4n.dll b/PlayWallNativeWin/j4n/NativeAudio.j4n.dll
new file mode 100644
index 0000000000000000000000000000000000000000..027e55fe7f081795f015ee94eebc9343253ce83f
Binary files /dev/null and b/PlayWallNativeWin/j4n/NativeAudio.j4n.dll differ
diff --git a/PlayWallNativeWin/j4n/NativeAudio.j4n.jar b/PlayWallNativeWin/j4n/NativeAudio.j4n.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7c16f4dcfe164f54f971cea054c321b18743aafa
Binary files /dev/null and b/PlayWallNativeWin/j4n/NativeAudio.j4n.jar differ
diff --git a/PlayWallNativeWin/j4n/NativeAudio.proxygen.xml b/PlayWallNativeWin/j4n/NativeAudio.proxygen.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e339777e6fbcaf610050cca93491a9dfdabd518
--- /dev/null
+++ b/PlayWallNativeWin/j4n/NativeAudio.proxygen.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<jni4net-proxygen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://jni4net.sf.net/0.8.8.0/toolConfig.xsd">
+  <TargetDirJvm>.\jvm</TargetDirJvm>
+  <TargetDirClr>.\clr</TargetDirClr>
+  <AssemblyReference Assembly="NativeAudio.dll" Generate="true" />
+</jni4net-proxygen>
\ No newline at end of file
diff --git a/PlayWallNativeWin/j4n/build.cmd b/PlayWallNativeWin/j4n/build.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..93c3e641600b8a6f4a57703ad63cb7c157bcdc3d
--- /dev/null
+++ b/PlayWallNativeWin/j4n/build.cmd
@@ -0,0 +1,21 @@
+@echo off
+if not exist target mkdir target
+if not exist target\classes mkdir target\classes
+
+
+echo compile classes
+javac -nowarn -d target\classes -sourcepath jvm -cp "d:\programmieren\git-java\playwall\playwallnativewin\j4n\jni4net.j-0.8.8.0.jar"; "jvm\nativeaudio\LoopStream.java" "jvm\nativeaudio\NativeAudio.java" 
+IF %ERRORLEVEL% NEQ 0 goto end
+
+
+echo NativeAudio.j4n.jar 
+jar cvf NativeAudio.j4n.jar  -C target\classes "nativeaudio\LoopStream.class"  -C target\classes "nativeaudio\NativeAudio.class"  > nul 
+IF %ERRORLEVEL% NEQ 0 goto end
+
+
+echo NativeAudio.j4n.dll 
+csc /nologo /warn:0 /t:library /out:NativeAudio.j4n.dll /recurse:clr\*.cs  /reference:"D:\Programmieren\Git-Java\PlayWall\PlayWallNativeWin\j4n\NativeAudio.dll" /reference:"D:\Programmieren\Git-Java\PlayWall\PlayWallNativeWin\j4n\NAudio.dll" /reference:"D:\Programmieren\Git-Java\PlayWall\PlayWallNativeWin\j4n\jni4net.n-0.8.8.0.dll"
+IF %ERRORLEVEL% NEQ 0 goto end
+
+
+:end
diff --git a/PlayWallNativeWin/j4n/clr/nativeaudio/LoopStream.generated.cs b/PlayWallNativeWin/j4n/clr/nativeaudio/LoopStream.generated.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cf1228582af0be39daa9c6762b55c7506df0e570
--- /dev/null
+++ b/PlayWallNativeWin/j4n/clr/nativeaudio/LoopStream.generated.cs
@@ -0,0 +1,89 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by jni4net. See http://jni4net.sourceforge.net/ 
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace NativeAudio {
+    
+    
+    #region Component Designer generated code 
+    public partial class LoopStream_ {
+        
+        public static global::java.lang.Class _class {
+            get {
+                return global::NativeAudio.@__LoopStream.staticClass;
+            }
+        }
+    }
+    #endregion
+    
+    #region Component Designer generated code 
+    [global::net.sf.jni4net.attributes.JavaProxyAttribute(typeof(global::NativeAudio.LoopStream), typeof(global::NativeAudio.LoopStream_))]
+    [global::net.sf.jni4net.attributes.ClrWrapperAttribute(typeof(global::NativeAudio.LoopStream), typeof(global::NativeAudio.LoopStream_))]
+    internal sealed partial class @__LoopStream : global::java.lang.Object {
+        
+        internal new static global::java.lang.Class staticClass;
+        
+        private @__LoopStream(global::net.sf.jni4net.jni.JNIEnv @__env) : 
+                base(@__env) {
+        }
+        
+        private static void InitJNI(global::net.sf.jni4net.jni.JNIEnv @__env, java.lang.Class @__class) {
+            global::NativeAudio.@__LoopStream.staticClass = @__class;
+        }
+        
+        private static global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod> @__Init(global::net.sf.jni4net.jni.JNIEnv @__env, global::java.lang.Class @__class) {
+            global::System.Type @__type = typeof(__LoopStream);
+            global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod> methods = new global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod>();
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "getEnableLooping", "EnableLooping0", "()Z"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "setEnableLooping", "EnableLooping1", "(Z)V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "__ctorLoopStream0", "__ctorLoopStream0", "(Lnet/sf/jni4net/inj/IClrProxy;Lsystem/io/Stream;)V"));
+            return methods;
+        }
+        
+        private static bool EnableLooping0(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()Z
+            // ()Z
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            bool @__return = default(bool);
+            try {
+            global::NativeAudio.LoopStream @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.LoopStream>(@__env, @__obj);
+            @__return = ((bool)(@__real.EnableLooping));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static void EnableLooping1(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj, bool value) {
+            // (Z)V
+            // (Z)V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.LoopStream @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.LoopStream>(@__env, @__obj);
+            @__real.EnableLooping = value;
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void @__ctorLoopStream0(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__class, global::net.sf.jni4net.utils.JniLocalHandle @__obj, global::net.sf.jni4net.utils.JniLocalHandle sourceStream) {
+            // (Lsystem/io/Stream;)V
+            // (LNAudio/Wave/WaveStream;)V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.LoopStream @__real = new global::NativeAudio.LoopStream(global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NAudio.Wave.WaveStream>(@__env, sourceStream));
+            global::net.sf.jni4net.utils.Convertor.InitProxy(@__env, @__obj, @__real);
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        new internal sealed class ContructionHelper : global::net.sf.jni4net.utils.IConstructionHelper {
+            
+            public global::net.sf.jni4net.jni.IJvmProxy CreateProxy(global::net.sf.jni4net.jni.JNIEnv @__env) {
+                return new global::NativeAudio.@__LoopStream(@__env);
+            }
+        }
+    }
+    #endregion
+}
diff --git a/PlayWallNativeWin/j4n/clr/nativeaudio/NativeAudio.generated.cs b/PlayWallNativeWin/j4n/clr/nativeaudio/NativeAudio.generated.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ea98eeed7f0c8d0a291dcdbab386ce7a7c5f7e44
--- /dev/null
+++ b/PlayWallNativeWin/j4n/clr/nativeaudio/NativeAudio.generated.cs
@@ -0,0 +1,206 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by jni4net. See http://jni4net.sourceforge.net/ 
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace NativeAudio {
+    
+    
+    #region Component Designer generated code 
+    public partial class NativeAudio_ {
+        
+        public static global::java.lang.Class _class {
+            get {
+                return global::NativeAudio.@__NativeAudio.staticClass;
+            }
+        }
+    }
+    #endregion
+    
+    #region Component Designer generated code 
+    [global::net.sf.jni4net.attributes.JavaProxyAttribute(typeof(global::NativeAudio.NativeAudio), typeof(global::NativeAudio.NativeAudio_))]
+    [global::net.sf.jni4net.attributes.ClrWrapperAttribute(typeof(global::NativeAudio.NativeAudio), typeof(global::NativeAudio.NativeAudio_))]
+    internal sealed partial class @__NativeAudio : global::java.lang.Object {
+        
+        internal new static global::java.lang.Class staticClass;
+        
+        private @__NativeAudio(global::net.sf.jni4net.jni.JNIEnv @__env) : 
+                base(@__env) {
+        }
+        
+        private static void InitJNI(global::net.sf.jni4net.jni.JNIEnv @__env, java.lang.Class @__class) {
+            global::NativeAudio.@__NativeAudio.staticClass = @__class;
+        }
+        
+        private static global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod> @__Init(global::net.sf.jni4net.jni.JNIEnv @__env, global::java.lang.Class @__class) {
+            global::System.Type @__type = typeof(__NativeAudio);
+            global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod> methods = new global::System.Collections.Generic.List<global::net.sf.jni4net.jni.JNINativeMethod>();
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "load", "load0", "(Ljava/lang/String;)Z"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "play", "play1", "()V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "pause", "pause2", "()V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "stop", "stop3", "()V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "getDuration", "getDuration4", "()D"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "getPosition", "getPosition5", "()D"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "isPlaying", "isPlaying6", "()Z"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "setVolume", "setVolume7", "(F)V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "setLoop", "setLoop8", "(Z)V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "setDevice", "setDevice9", "(Ljava/lang/String;)V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "getDevices", "getDevices10", "()[Ljava/lang/String;"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "unload", "unload11", "()V"));
+            methods.Add(global::net.sf.jni4net.jni.JNINativeMethod.Create(@__type, "__ctorNativeAudio0", "__ctorNativeAudio0", "(Lnet/sf/jni4net/inj/IClrProxy;)V"));
+            return methods;
+        }
+        
+        private static bool load0(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj, global::net.sf.jni4net.utils.JniLocalHandle path) {
+            // (Ljava/lang/String;)Z
+            // (LSystem/String;)Z
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            bool @__return = default(bool);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__return = ((bool)(@__real.load(global::net.sf.jni4net.utils.Convertor.StrongJ2CString(@__env, path))));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static void play1(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()V
+            // ()V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.play();
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void pause2(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()V
+            // ()V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.pause();
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void stop3(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()V
+            // ()V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.stop();
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static double getDuration4(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()D
+            // ()D
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            double @__return = default(double);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__return = ((double)(@__real.getDuration()));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static double getPosition5(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()D
+            // ()D
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            double @__return = default(double);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__return = ((double)(@__real.getPosition()));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static bool isPlaying6(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()Z
+            // ()Z
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            bool @__return = default(bool);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__return = ((bool)(@__real.isPlaying()));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static void setVolume7(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj, float volume) {
+            // (F)V
+            // (F)V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.setVolume(volume);
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void setLoop8(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj, bool loop) {
+            // (Z)V
+            // (Z)V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.setLoop(loop);
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void setDevice9(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj, global::net.sf.jni4net.utils.JniLocalHandle name) {
+            // (Ljava/lang/String;)V
+            // (LSystem/String;)V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.setDevice(global::net.sf.jni4net.utils.Convertor.StrongJ2CString(@__env, name));
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static global::net.sf.jni4net.utils.JniHandle getDevices10(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__class) {
+            // ()[Ljava/lang/String;
+            // ()[LSystem/String;
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            global::net.sf.jni4net.utils.JniHandle @__return = default(global::net.sf.jni4net.utils.JniHandle);
+            try {
+            @__return = global::net.sf.jni4net.utils.Convertor.ArrayStrongC2JString(@__env, global::NativeAudio.NativeAudio.getDevices());
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+            return @__return;
+        }
+        
+        private static void unload11(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()V
+            // ()V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = global::net.sf.jni4net.utils.Convertor.StrongJp2C<global::NativeAudio.NativeAudio>(@__env, @__obj);
+            @__real.unload();
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        private static void @__ctorNativeAudio0(global::System.IntPtr @__envp, global::net.sf.jni4net.utils.JniLocalHandle @__class, global::net.sf.jni4net.utils.JniLocalHandle @__obj) {
+            // ()V
+            // ()V
+            global::net.sf.jni4net.jni.JNIEnv @__env = global::net.sf.jni4net.jni.JNIEnv.Wrap(@__envp);
+            try {
+            global::NativeAudio.NativeAudio @__real = new global::NativeAudio.NativeAudio();
+            global::net.sf.jni4net.utils.Convertor.InitProxy(@__env, @__obj, @__real);
+            }catch (global::System.Exception __ex){@__env.ThrowExisting(__ex);}
+        }
+        
+        new internal sealed class ContructionHelper : global::net.sf.jni4net.utils.IConstructionHelper {
+            
+            public global::net.sf.jni4net.jni.IJvmProxy CreateProxy(global::net.sf.jni4net.jni.JNIEnv @__env) {
+                return new global::NativeAudio.@__NativeAudio(@__env);
+            }
+        }
+    }
+    #endregion
+}
diff --git a/PlayWallNativeWin/j4n/generate.bat b/PlayWallNativeWin/j4n/generate.bat
new file mode 100644
index 0000000000000000000000000000000000000000..f7636d55f59799fde55275cadbf2e0e004a3c39e
--- /dev/null
+++ b/PlayWallNativeWin/j4n/generate.bat
@@ -0,0 +1 @@
+proxygen.exe NativeAudio.dll -wd .
\ No newline at end of file
diff --git a/PlayWallNativeWin/j4n/jni4net.j-0.8.8.0.jar b/PlayWallNativeWin/j4n/jni4net.j-0.8.8.0.jar
new file mode 100644
index 0000000000000000000000000000000000000000..922c2ad94d8c7a0a75f3613450819eb02e6d2757
Binary files /dev/null and b/PlayWallNativeWin/j4n/jni4net.j-0.8.8.0.jar differ
diff --git a/PlayWallNativeWin/j4n/jni4net.n-0.8.8.0.dll b/PlayWallNativeWin/j4n/jni4net.n-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..2c7dc61711aea95d4a9d27f72ee9b540625ec0da
Binary files /dev/null and b/PlayWallNativeWin/j4n/jni4net.n-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/j4n/jni4net.n.w32.v40-0.8.8.0.dll b/PlayWallNativeWin/j4n/jni4net.n.w32.v40-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..e90e34defd278af539cd5d40a44f5d5f6b3b983d
Binary files /dev/null and b/PlayWallNativeWin/j4n/jni4net.n.w32.v40-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/j4n/jni4net.n.w64.v40-0.8.8.0.dll b/PlayWallNativeWin/j4n/jni4net.n.w64.v40-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..6ff98f1eca73982a4d293447484864290d2d2170
Binary files /dev/null and b/PlayWallNativeWin/j4n/jni4net.n.w64.v40-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/j4n/jvm/nativeaudio/LoopStream.java b/PlayWallNativeWin/j4n/jvm/nativeaudio/LoopStream.java
new file mode 100644
index 0000000000000000000000000000000000000000..e11a08759b9cfef51fba8e8931747e57d5fb0409
--- /dev/null
+++ b/PlayWallNativeWin/j4n/jvm/nativeaudio/LoopStream.java
@@ -0,0 +1,45 @@
+// ------------------------------------------------------------------------------
+//  <autogenerated>
+//      This code was generated by jni4net. See http://jni4net.sourceforge.net/ 
+// 
+//      Changes to this file may cause incorrect behavior and will be lost if 
+//      the code is regenerated.
+//  </autogenerated>
+// ------------------------------------------------------------------------------
+
+package nativeaudio;
+
+@net.sf.jni4net.attributes.ClrType
+public class LoopStream extends system.io.Stream {
+    
+    //<generated-proxy>
+    private static system.Type staticType;
+    
+    protected LoopStream(net.sf.jni4net.inj.INJEnv __env, long __handle) {
+            super(__env, __handle);
+    }
+    
+    @net.sf.jni4net.attributes.ClrConstructor("(LNAudio/Wave/WaveStream;)V")
+    public LoopStream(system.io.Stream sourceStream) {
+            super(((net.sf.jni4net.inj.INJEnv)(null)), 0);
+        nativeaudio.LoopStream.__ctorLoopStream0(this, sourceStream);
+    }
+    
+    @net.sf.jni4net.attributes.ClrMethod("(Lsystem/io/Stream;)V")
+    private native static void __ctorLoopStream0(net.sf.jni4net.inj.IClrProxy thiz, system.io.Stream sourceStream);
+    
+    @net.sf.jni4net.attributes.ClrMethod("()Z")
+    public native boolean getEnableLooping();
+    
+    @net.sf.jni4net.attributes.ClrMethod("(Z)V")
+    public native void setEnableLooping(boolean value);
+    
+    public static system.Type typeof() {
+        return nativeaudio.LoopStream.staticType;
+    }
+    
+    private static void InitJNI(net.sf.jni4net.inj.INJEnv env, system.Type staticType) {
+        nativeaudio.LoopStream.staticType = staticType;
+    }
+    //</generated-proxy>
+}
diff --git a/PlayWallNativeWin/j4n/jvm/nativeaudio/NativeAudio.java b/PlayWallNativeWin/j4n/jvm/nativeaudio/NativeAudio.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffd1aef71ce846ebd29eabbde1dccc280081003f
--- /dev/null
+++ b/PlayWallNativeWin/j4n/jvm/nativeaudio/NativeAudio.java
@@ -0,0 +1,75 @@
+// ------------------------------------------------------------------------------
+//  <autogenerated>
+//      This code was generated by jni4net. See http://jni4net.sourceforge.net/ 
+// 
+//      Changes to this file may cause incorrect behavior and will be lost if 
+//      the code is regenerated.
+//  </autogenerated>
+// ------------------------------------------------------------------------------
+
+package nativeaudio;
+
+@net.sf.jni4net.attributes.ClrType
+public class NativeAudio extends system.Object {
+    
+    //<generated-proxy>
+    private static system.Type staticType;
+    
+    protected NativeAudio(net.sf.jni4net.inj.INJEnv __env, long __handle) {
+            super(__env, __handle);
+    }
+    
+    @net.sf.jni4net.attributes.ClrConstructor("()V")
+    public NativeAudio() {
+            super(((net.sf.jni4net.inj.INJEnv)(null)), 0);
+        nativeaudio.NativeAudio.__ctorNativeAudio0(this);
+    }
+    
+    @net.sf.jni4net.attributes.ClrMethod("()V")
+    private native static void __ctorNativeAudio0(net.sf.jni4net.inj.IClrProxy thiz);
+    
+    @net.sf.jni4net.attributes.ClrMethod("(LSystem/String;)Z")
+    public native boolean load(java.lang.String path);
+    
+    @net.sf.jni4net.attributes.ClrMethod("()V")
+    public native void play();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()V")
+    public native void pause();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()V")
+    public native void stop();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()D")
+    public native double getDuration();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()D")
+    public native double getPosition();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()Z")
+    public native boolean isPlaying();
+    
+    @net.sf.jni4net.attributes.ClrMethod("(F)V")
+    public native void setVolume(float volume);
+    
+    @net.sf.jni4net.attributes.ClrMethod("(Z)V")
+    public native void setLoop(boolean loop);
+    
+    @net.sf.jni4net.attributes.ClrMethod("(LSystem/String;)V")
+    public native void setDevice(java.lang.String name);
+    
+    @net.sf.jni4net.attributes.ClrMethod("()[LSystem/String;")
+    public native static java.lang.String[] getDevices();
+    
+    @net.sf.jni4net.attributes.ClrMethod("()V")
+    public native void unload();
+    
+    public static system.Type typeof() {
+        return nativeaudio.NativeAudio.staticType;
+    }
+    
+    private static void InitJNI(net.sf.jni4net.inj.INJEnv env, system.Type staticType) {
+        nativeaudio.NativeAudio.staticType = staticType;
+    }
+    //</generated-proxy>
+}
diff --git a/PlayWallNativeWin/j4n/proxygen.exe b/PlayWallNativeWin/j4n/proxygen.exe
new file mode 100644
index 0000000000000000000000000000000000000000..816db4ef246603f6313670c111e4de0957905d56
Binary files /dev/null and b/PlayWallNativeWin/j4n/proxygen.exe differ
diff --git a/PlayWallNativeWin/j4n/proxygen.exe.config b/PlayWallNativeWin/j4n/proxygen.exe.config
new file mode 100644
index 0000000000000000000000000000000000000000..88c3d408ec7ed3687fcf214d01aa502f4bd0e89f
--- /dev/null
+++ b/PlayWallNativeWin/j4n/proxygen.exe.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <startup>
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
+    <supportedRuntime version="v2.0.50727"/>
+  </startup>
+</configuration>
\ No newline at end of file
diff --git a/PlayWallNativeWin/j4n/target/classes/nativeaudio/LoopStream.class b/PlayWallNativeWin/j4n/target/classes/nativeaudio/LoopStream.class
new file mode 100644
index 0000000000000000000000000000000000000000..cbde588f149720bb84608ad2bcc8ae43d1ac4250
Binary files /dev/null and b/PlayWallNativeWin/j4n/target/classes/nativeaudio/LoopStream.class differ
diff --git a/PlayWallNativeWin/j4n/target/classes/nativeaudio/NativeAudio.class b/PlayWallNativeWin/j4n/target/classes/nativeaudio/NativeAudio.class
new file mode 100644
index 0000000000000000000000000000000000000000..95dcb66bfa41ce732ba8934419c2def276b6ae7a
Binary files /dev/null and b/PlayWallNativeWin/j4n/target/classes/nativeaudio/NativeAudio.class differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPlugin.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..15c41b1901399365f4dd11536445f9b73fd73355
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPlugin.java
@@ -0,0 +1,7 @@
+package de.tobias.playpad.nawin;
+
+import de.tobias.playpad.plugin.AdvancedPlugin;
+
+public interface NativeAudioWinPlugin extends AdvancedPlugin {
+
+}
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPluginImpl.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPluginImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d49e1dd889bcd824b7483d834c1e47508342948
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinPluginImpl.java
@@ -0,0 +1,99 @@
+package de.tobias.playpad.nawin;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.PlayPadPlugin;
+import de.tobias.playpad.audio.AudioRegistry;
+import de.tobias.playpad.nawin.audio.NativeAudioWinHandlerConnect;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.updater.client.Updatable;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.util.IOUtils;
+import de.tobias.utils.util.OS;
+import net.sf.jni4net.Bridge;
+import net.xeoh.plugins.base.annotations.PluginImplementation;
+import net.xeoh.plugins.base.annotations.events.PluginLoaded;
+import net.xeoh.plugins.base.annotations.events.Shutdown;
+
+@PluginImplementation
+public class NativeAudioWinPluginImpl implements NativeAudioWinPlugin {
+
+	private static final String ASSETS = "de/tobias/playpad/nawin/assets/";
+
+	private static final String NAME = "NativeAudioWin";
+	private static final String IDENTIFIER = "de.tobias.playpad.nawin.NativeAudioWinPluginImpl";
+
+	private Module module;
+	private Updatable updatable;
+
+	@PluginLoaded
+	public void onLoaded(NativeAudioWinPlugin plugin) {
+		module = new Module(NAME, IDENTIFIER);
+		updatable = new NativeAudioWinUpdater();
+
+		try {
+			prepareBridging();
+			bridgeCsharp();
+
+			if (OS.isWindows()) {
+				AudioRegistry registry = PlayPadPlugin.getRegistryCollection().getAudioHandlers();
+				registry.registerComponent(new NativeAudioWinHandlerConnect(), "NativeWin", module);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void prepareBridging() throws IOException {
+		App app = ApplicationUtils.getApplication();
+		if (!app.isDebug()) {
+			Path resourceFolder = app.getPath(PathType.LIBRARY, "nawin");
+			if (Files.notExists(resourceFolder)) {
+				Files.createDirectories(resourceFolder);
+			}
+
+			copyResource(resourceFolder, ASSETS, "jni4net.j-0.8.8.0.jar");
+			copyResource(resourceFolder, ASSETS, "jni4net.n-0.8.8.0.dll");
+			copyResource(resourceFolder, ASSETS, "jni4net.n.w32.v40-0.8.8.0.dll");
+			copyResource(resourceFolder, ASSETS, "jni4net.n.w64.v40-0.8.8.0.dll");
+			copyResource(resourceFolder, ASSETS, "NativeAudio.dll");
+			copyResource(resourceFolder, ASSETS, "NativeAudio.j4n.dll");
+			copyResource(resourceFolder, ASSETS, "NativeAudio.j4n.jar");
+			copyResource(resourceFolder, ASSETS, "NAudio.dll");
+		}
+	}
+
+	private void copyResource(Path resourceFolder, String packageName, String file) throws IOException {
+		IOUtils.copy(getClass().getClassLoader().getResourceAsStream(packageName + file), resourceFolder.resolve(file));
+		System.out.println("Copied: " + file);
+	}
+
+	private void bridgeCsharp() throws IOException {
+		Bridge.setVerbose(true);
+		Bridge.init();
+
+		App app = ApplicationUtils.getApplication();
+		Path resourceFolder = app.getPath(PathType.LIBRARY, "nawin");
+
+		Bridge.LoadAndRegisterAssemblyFrom(resourceFolder.resolve("NativeAudio.j4n.dll").toFile());
+	}
+
+	@Shutdown
+	public void onShutdown() {
+
+	}
+
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updatable;
+	}
+}
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinUpdater.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7a027b6c338a35588a064ba62c811c019475cb5
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/NativeAudioWinUpdater.java
@@ -0,0 +1,79 @@
+package de.tobias.playpad.nawin;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Path;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
+import de.tobias.utils.application.App;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+
+public class NativeAudioWinUpdater implements Updatable {
+
+	private int newBuild;
+	private String newVersion;
+	private URL remotePath;
+
+	private String localFileName;
+	private String name;
+
+	@Override
+	public int getCurrentBuild() {
+		return 2;
+	}
+
+	@Override
+	public String getCurrentVersion() {
+		return "1.1";
+	}
+
+	@Override
+	public int getNewBuild() {
+		return newBuild;
+	}
+
+	@Override
+	public String getNewVersion() {
+		return newVersion;
+	}
+
+	@Override
+	public void loadInformation(UpdateChannel channel) throws IOException {
+		App app = ApplicationUtils.getMainApplication();
+		URL url = new URL(app.getInfo().getUpdateURL() + "/" + channel + "/plugins.yml");
+		FileConfiguration config = YamlConfiguration.loadConfiguration(url.openStream());
+
+		newBuild = config.getInt("plugins.nawin.build");
+		newVersion = config.getString("plugins.nawin.version");
+		remotePath = new URL(config.getString("plugins.nawin.url"));
+		localFileName = config.getString("plugins.nawin.filename");
+		name = config.getString("plugins.nawin.name");
+
+	}
+
+	@Override
+	public boolean isUpdateAvailable() {
+		return getCurrentBuild() < getNewBuild();
+	}
+
+	@Override
+	public URL getDownloadPath() {
+		return remotePath;
+	}
+
+	@Override
+	public Path getLocalPath() {
+		return ApplicationUtils.getApplication().getPath(PathType.LIBRARY, localFileName);
+	}
+
+	@Override
+	public String name() {
+		return name;
+	}
+
+}
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NAudio.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NAudio.dll
new file mode 100644
index 0000000000000000000000000000000000000000..9dd5ae7de34d2bc2dcf934eb027fa60d20237c3d
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NAudio.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.dll
new file mode 100644
index 0000000000000000000000000000000000000000..84e9062fc0bfc9f77ca8d9b9b2ce1f6e7c218aaa
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.dll
new file mode 100644
index 0000000000000000000000000000000000000000..027e55fe7f081795f015ee94eebc9343253ce83f
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.jar b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7c16f4dcfe164f54f971cea054c321b18743aafa
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/NativeAudio.j4n.jar differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/Test-Sound.wav b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/Test-Sound.wav
new file mode 100644
index 0000000000000000000000000000000000000000..1a627d7c84165c6131c47134b1ca1f4fcb0bf3be
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/Test-Sound.wav differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.j-0.8.8.0.jar b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.j-0.8.8.0.jar
new file mode 100644
index 0000000000000000000000000000000000000000..922c2ad94d8c7a0a75f3613450819eb02e6d2757
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.j-0.8.8.0.jar differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n-0.8.8.0.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..2c7dc61711aea95d4a9d27f72ee9b540625ec0da
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w32.v40-0.8.8.0.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w32.v40-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..e90e34defd278af539cd5d40a44f5d5f6b3b983d
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w32.v40-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w64.v40-0.8.8.0.dll b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w64.v40-0.8.8.0.dll
new file mode 100644
index 0000000000000000000000000000000000000000..6ff98f1eca73982a4d293447484864290d2d2170
Binary files /dev/null and b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/jni4net.n.w64.v40-0.8.8.0.dll differ
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/nawinSettings.fxml b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/nawinSettings.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..3bc628651c3be6d86bd71a62dc915fa7b1d6f0fd
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/assets/nawinSettings.fxml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<HBox spacing="14.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <ComboBox fx:id="soundCardComboBox" layoutX="118.0" layoutY="14.0" prefHeight="26.0" prefWidth="241.0" />
+      <Button fx:id="testButton" layoutX="372.0" layoutY="14.0" mnemonicParsing="false" onAction="#testButtonHandler" />
+   </children>
+</HBox>
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioSettingsViewController.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioSettingsViewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..21665a0bf7d79d134bded2f8755dfb411c68a9cf
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioSettingsViewController.java
@@ -0,0 +1,112 @@
+package de.tobias.playpad.nawin.audio;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
+import de.tobias.utils.application.ApplicationUtils;
+import de.tobias.utils.application.container.PathType;
+import de.tobias.utils.ui.icon.FontAwesomeType;
+import de.tobias.utils.ui.icon.FontIcon;
+import de.tobias.utils.util.IOUtils;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import nativeaudio.NativeAudio;
+
+public class NativeAudioSettingsViewController extends AudioHandlerViewController {
+
+	@FXML private ComboBox<String> soundCardComboBox;
+	@FXML private Button testButton;
+
+	private boolean isChanged;
+
+	private NativeAudio audioPlayer;
+
+	public NativeAudioSettingsViewController() {
+		super("nawinSettings", "de/tobias/playpad/nawin/assets/", null);
+
+		testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+
+		soundCardComboBox.getItems().setAll(NativeAudio.getDevices());
+
+		String name = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo()
+				.get(NativeAudioWinHandler.SOUND_CARD);
+		for (String info : NativeAudio.getDevices()) {
+			if (info.equals(name)) {
+				soundCardComboBox.getSelectionModel().select(info);
+				break;
+			}
+		}
+
+		// ersten Auswählen wenn keiner ausgewählt ist, damit keine Probleme
+		// auftreten da keiene Soundkarte ausgewäht ist
+		if (soundCardComboBox.getSelectionModel().getSelectedItem() == null) {
+			soundCardComboBox.getSelectionModel().selectFirst();
+		}
+
+		soundCardComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, c) -> {
+			if (audioPlayer != null) {
+				audioPlayer.stop();
+				audioPlayer = null;
+				testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+			}
+
+			isChanged = true;
+			Profile.currentProfile().getProfileSettings().getAudioUserInfo().put(NativeAudioWinHandler.SOUND_CARD, c);
+		});
+	}
+
+	@FXML
+	private void testButtonHandler(ActionEvent event) {
+		Path file = ApplicationUtils.getApplication().getPath(PathType.RESOURCES, "Test-Sound.wav");
+		if (Files.notExists(file)) {
+			InputStream iStr = getClass().getClassLoader()
+					.getResourceAsStream("de/tobias/playpad/nawin/assets/Test-Sound.wav");
+			try {
+				Files.createDirectories(file.getParent());
+				IOUtils.copy(iStr, file);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+		if (audioPlayer == null) {
+			audioPlayer = new NativeAudio();
+			audioPlayer.load(file.toString());
+			audioPlayer.setDevice(soundCardComboBox.getValue());
+		}
+		if (audioPlayer.isPlaying()) {
+			audioPlayer.stop();
+			audioPlayer = null;
+			testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY));
+		} else {
+			audioPlayer.play();
+			Worker.runLater(() -> {
+				while (audioPlayer != null && audioPlayer.isPlaying()) {
+					try {
+						Thread.sleep(50);
+					} catch (InterruptedException e) {
+						e.printStackTrace();
+					}
+				}
+				if (audioPlayer != null)
+					audioPlayer.stop();
+				Platform.runLater(() -> testButton.setGraphic(new FontIcon(FontAwesomeType.PLAY)));
+			});
+			testButton.setGraphic(new FontIcon(FontAwesomeType.STOP));
+		}
+	}
+
+	@Override
+	public boolean isChanged() {
+		return isChanged;
+	}
+}
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandler.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d7853e0ac4d7751c833966b875d3a1a127a53d5
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandler.java
@@ -0,0 +1,186 @@
+package de.tobias.playpad.nawin.audio;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.Soundcardable;
+import de.tobias.playpad.pad.Pad;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.settings.Profile;
+import javafx.application.Platform;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
+import nativeaudio.NativeAudio;
+
+public class NativeAudioWinHandler extends AudioHandler implements Soundcardable {
+
+	public static final String SOUND_CARD = "SoundCard";
+
+	private NativeAudio audioHandler;
+	private ObjectProperty<Duration> durationProperty;
+	private ObjectProperty<Duration> positionProperty;
+
+	private static Thread positionThread;
+	private static List<NativeAudioWinHandler> playedHandlers = new ArrayList<>();
+	private static final int SLEEP_TIME_POSITION = 50;
+
+	static {
+		positionThread = new Thread(() ->
+		{
+			while (true) {
+				try {
+					if (playedHandlers.isEmpty()) {
+						synchronized (positionThread) {
+							positionThread.wait();
+						}
+					}
+
+					for (Iterator<NativeAudioWinHandler> iterator = playedHandlers.iterator(); iterator.hasNext();) {
+						NativeAudioWinHandler handler = iterator.next();
+						Pad pad = handler.getContent().getPad();
+
+						if (handler.audioHandler != null) {
+							if (!handler.audioHandler.isPlaying()) {
+								if (!pad.getPadSettings().isLoop()) {
+									System.out.println("Stop");
+									pad.setEof(true);
+
+									// Remove from Loop and Stop
+									iterator.remove();
+									Platform.runLater(() -> pad.setStatus(PadStatus.STOP));
+								}
+							}
+						}
+
+						Duration position = Duration.millis(handler.audioHandler.getPosition());
+
+						// Update der Zeit
+						Platform.runLater(() -> handler.positionProperty.set(position));
+					}
+
+					Thread.sleep(SLEEP_TIME_POSITION);
+				} catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+		positionThread.start();
+	}
+
+	public NativeAudioWinHandler(PadContent content) {
+		super(content);
+		durationProperty = new SimpleObjectProperty<>();
+		positionProperty = new SimpleObjectProperty<>();
+	}
+
+	@Override
+	public void play() {
+		audioHandler.setLoop(getContent().getPad().getPadSettings().isLoop());
+
+		audioHandler.play();
+
+		boolean start = false;
+		if (playedHandlers.isEmpty()) {
+			start = true;
+		}
+
+		if (!playedHandlers.contains(this))
+			playedHandlers.add(this);
+		if (start) {
+			synchronized (positionThread) {
+				positionThread.notify();
+			}
+		}
+	}
+
+	@Override
+	public void pause() {
+		audioHandler.pause();
+		if (playedHandlers.contains(this))
+			playedHandlers.remove(this);
+	}
+
+	@Override
+	public void stop() {
+		audioHandler.stop();
+		if (playedHandlers.contains(this))
+			playedHandlers.remove(this);
+	}
+
+	@Override
+	public Duration getPosition() {
+		return positionProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return positionProperty;
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public void setVolume(double volume) {
+		if (audioHandler != null) {
+			audioHandler.setVolume((float) volume);
+		}
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return audioHandler != null;
+	}
+
+	@Override
+	public void loadMedia(Path[] paths) {
+		Platform.runLater(() ->
+		{
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getView().showBusyView(true);
+			}
+		});
+		if (audioHandler == null)
+			audioHandler = new NativeAudio();
+		audioHandler.load(paths[0].toString());
+
+		String name = (String) Profile.currentProfile().getProfileSettings().getAudioUserInfo().get(NativeAudioWinHandler.SOUND_CARD);
+		audioHandler.setDevice(name);
+
+		Platform.runLater(() ->
+		{
+			durationProperty.set(Duration.millis(audioHandler.getDuration()));
+			getContent().getPad().setStatus(PadStatus.READY);
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getView().showBusyView(false);
+			}
+		});
+	}
+
+	@Override
+	public void unloadMedia() {
+		audioHandler.unload();
+		audioHandler = null;
+	}
+
+	@Override
+	public void setOutputDevice(String name) {
+		audioHandler.setDevice(name);
+	}
+
+}
diff --git a/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandlerConnect.java b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..57239777045fb95a608f912e6719ea4fde6eb935
--- /dev/null
+++ b/PlayWallNativeWin/src/de/tobias/playpad/nawin/audio/NativeAudioWinHandlerConnect.java
@@ -0,0 +1,42 @@
+package de.tobias.playpad.nawin.audio;
+
+import de.tobias.playpad.audio.AudioCapability;
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.AudioHandlerConnect;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
+
+public class NativeAudioWinHandlerConnect extends AudioHandlerConnect {
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		return new NativeAudioWinHandler(content);
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioHandlerSettingsViewController() {
+		return null;
+	}
+
+	@Override
+	public String getType() {
+		return "NativeWin";
+	}
+	
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		for (Class<?> clazz : NativeAudioWinHandler.class.getInterfaces()) {
+			if (clazz.equals(audioCapability.getAudioFeature()))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		if (audioCapablility == AudioCapability.SOUNDCARD) {
+			return new NativeAudioSettingsViewController();
+		}
+		return null;
+	}
+}
diff --git a/PlayWallPlugins/.classpath b/PlayWallPlugins/.classpath
index dff7fdd8d23f0ac9b407b77addb5d79e1997cc9f..a6483b754d078603c9f404278f592d1cada08d7e 100644
--- a/PlayWallPlugins/.classpath
+++ b/PlayWallPlugins/.classpath
@@ -13,5 +13,6 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ControlFx"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/YML"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Updater"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java
index 13aec012801daff5a9206c7ec8ed05d980b0e042..0a063bd8592dff1f43a1cebe95536392fe966cdd 100644
--- a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java
+++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/ActionsPlugin.java
@@ -1,7 +1,7 @@
 package de.tobias.playpad.actionsplugin;
 
-import net.xeoh.plugins.base.Plugin;
+import de.tobias.playpad.plugin.AdvancedPlugin;
 
-public interface ActionsPlugin extends Plugin {
+public interface ActionsPlugin extends AdvancedPlugin {
 
 }
diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties
index 6659bdcf4fa25d66e2b12da2973d3ee84aade5d4..beb7f31a16f60ddf7c9ee09dcbe949e05fa58b70 100644
--- a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties
+++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/assets/actions_de.properties
@@ -1,2 +1,2 @@
 muteaction.name=Ton stumm schalten
-stopaction.name=Stopp
\ No newline at end of file
+stopaction.name=Stop
\ No newline at end of file
diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java
index e698c26478e0e502356409b33536c839ee0a7948..0c286fdd56bb436caddbbdc3c08520cc648e0878 100644
--- a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java
+++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginImpl.java
@@ -9,12 +9,13 @@ import org.dom4j.DocumentException;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.ActionConnect;
 import de.tobias.playpad.actionsplugin.ActionsPlugin;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.WindowListener;
 import de.tobias.playpad.registry.Registry;
 import de.tobias.playpad.settings.Profile;
 import de.tobias.playpad.settings.ProfileListener;
-import de.tobias.playpad.update.UpdateRegistery;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.ui.HUD;
 import de.tobias.utils.ui.icon.FontIcon;
 import de.tobias.utils.ui.icon.MaterialDesignIcon;
@@ -35,6 +36,12 @@ import net.xeoh.plugins.base.annotations.events.Shutdown;
 @PluginImplementation
 public class ActionsPluginImpl implements ActionsPlugin, ChangeListener<Boolean>, ProfileListener {
 
+	private static final String NAME = "ActionsPlugin";
+	private static final String IDENTIFIER = "de.tobias.playpad.actions.impl.ActionsPluginImpl";
+
+	private static Module module;
+	private static ActionsPluginUpdater updater;
+	
 	private static ResourceBundle bundle;
 	public static CheckMenuItem muteMenuItem;
 
@@ -100,12 +107,13 @@ public class ActionsPluginImpl implements ActionsPlugin, ChangeListener<Boolean>
 			};
 		}
 
-		UpdateRegistery.registerUpdateable(new ActionsPluginUpdater());
 		Profile.registerListener(this);
+		module = new Module(NAME, IDENTIFIER);
+		updater = new ActionsPluginUpdater();
 
 		try {
 			Registry<ActionConnect> padContents = PlayPadPlugin.getRegistryCollection().getActions();
-			padContents.loadComponentsFromFile("de/tobias/playpad/actionsplugin/assets/Actions.xml", getClass().getClassLoader());
+			padContents.loadComponentsFromFile("de/tobias/playpad/actionsplugin/assets/Actions.xml", getClass().getClassLoader(), module);
 		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException | DocumentException e) {
 			e.printStackTrace();
 		}
@@ -162,4 +170,14 @@ public class ActionsPluginImpl implements ActionsPlugin, ChangeListener<Boolean>
 			}
 		});
 	}
+
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updater;
+	}
 }
diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java
index 23e473ca7bcea6212eba271ec9e5c3d1e05e4416..1b7f0f3ac590c8fc8169ec3a23c41fe5afd1cd35 100644
--- a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java
+++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/impl/ActionsPluginUpdater.java
@@ -7,8 +7,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
diff --git a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java
index b417358e2a044cc8940383a012d45127d50b6c5b..cc77ec62a7a5cb1d1cf4f1c3df4645e4a57cd353 100644
--- a/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java
+++ b/PlayWallPlugins/actionsplugin/de/tobias/playpad/actionsplugin/stopaction/StopAction.java
@@ -27,7 +27,7 @@ public class StopAction extends Action {
 
 	@Override
 	public void performAction(InputType type, Project project, IMainViewController mainViewController) {
-		for (Pad pad : project.getPads().values()) {
+		for (Pad pad : project.getPads()) {
 			if (pad.getStatus() == PadStatus.PLAY || pad.getStatus() == PadStatus.PAUSE)
 				pad.setStatus(PadStatus.STOP, true);
 		}
diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java
index abda3de1f2a37514e3f7180328e2f2fc3ca0adb2..fe0c9a54f1ce2eb82593e3011ee54cada9eeaf94 100644
--- a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java
+++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/AwakePlugin.java
@@ -1,7 +1,7 @@
 package de.tobias.playpad.awakeplugin;
 
-import net.xeoh.plugins.base.Plugin;
+import de.tobias.playpad.plugin.AdvancedPlugin;
 
-public interface AwakePlugin extends Plugin {
+public interface AwakePlugin extends AdvancedPlugin {
 
 }
diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java
index ead13c66e180a23982c29bc06f9354e0d6fd2059..6609f50a45576fad6763fa0c5d510cfb065159dc 100644
--- a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java
+++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginImpl.java
@@ -12,13 +12,14 @@ import org.dom4j.DocumentException;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.awakeplugin.AwakePlugin;
 import de.tobias.playpad.awakeplugin.AwakeSettings;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.SettingsListener;
 import de.tobias.playpad.plugin.WindowListener;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.update.UpdateRegistery;
 import de.tobias.playpad.view.main.MenuType;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
 import de.tobias.playpad.viewcontroller.main.MenuToolbarViewController;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.ui.icon.FontAwesomeType;
@@ -40,6 +41,12 @@ import net.xeoh.plugins.base.annotations.events.Shutdown;
 @PluginImplementation
 public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewController>, EventHandler<ActionEvent>, SettingsListener {
 
+	private static final String NAME = "AwakePlugin";
+	private static final String IDENTIFIER = "de.tobias.playpad.awakeplugin.impl.AwakePluginImpl";
+
+	private Module module;
+	private Updatable updatable;
+
 	private static final String SETTINGS_FILENAME = "Awake.xml";
 
 	private CheckMenuItem activeMenu;
@@ -53,7 +60,8 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 	public void onLoad(AwakePlugin plugin) {
 		bundle = Localization.loadBundle("de/tobias/playpad/awakeplugin/assets/awake", getClass().getClassLoader());
 
-		UpdateRegistery.registerUpdateable(new AwakePluginUpdater());
+		module = new Module(NAME, IDENTIFIER);
+		updatable = new AwakePluginUpdater();
 
 		if (OS.getType() == OSType.Windows) {
 			try {
@@ -80,13 +88,13 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 	public void onDisable() {
 		System.out.println("Disable Awake Plugin");
 	}
-
+// TODO Server path anpassen mit UpdateChannel
 	private Path loadLibMac() throws IOException {
 		Path folder = ApplicationUtils.getApplication().getPath(PathType.LIBRARY, "awakelib.dylib");
 		if (Files.notExists(folder)) {
 			Files.createFile(folder);
-			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/libAwake/libAwakeLib.dylib");
-			System.out.println("Downlaod " + url);
+			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/stable/plugins/libAwake/libAwakeLib.dylib");
+			System.out.println("Download " + url);
 			IOUtils.copy(url.openStream(), folder);
 		}
 		return folder;
@@ -100,15 +108,15 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 
 		if (Files.notExists(jnaFile)) {
 			Files.createDirectories(folder);
-			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/jna/jna.jar");
-			System.out.println("Downlaod " + url);
+			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/stable/plugins/jna/jna.jar");
+			System.out.println("Download " + url);
 			IOUtils.copy(url.openStream(), jnaFile);
 		}
 
 		if (Files.notExists(jnaPlatformFile)) {
 			Files.createDirectories(folder);
-			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/plugins/jna/jna-platform.jar");
-			System.out.println("Downlaod " + url);
+			URL url = new URL(ApplicationUtils.getApplication().getInfo().getUpdateURL() + "/stable/plugins/jna/jna-platform.jar");
+			System.out.println("Download " + url);
 			IOUtils.copy(url.openStream(), jnaPlatformFile);
 		}
 	}
@@ -120,7 +128,7 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 		try {
 			settings = AwakeSettings.load(path);
 		} catch (NoSuchFileException e) {
-			System.out.println("No Awake.xml config on folder");
+			System.out.println("No Awake.xml config in folder");
 		} catch (DocumentException | IOException e) {
 			e.printStackTrace();
 		}
@@ -181,7 +189,7 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 		}
 	}
 
-	public void activeSleep(boolean activate) {
+	private void activeSleep(boolean activate) {
 		if (activate) {
 			if (OS.getType() == OSType.Windows) {
 				Kernel32.INSTANCE.SetThreadExecutionState(Kernel32.ES_CONTINUOUS | Kernel32.ES_DISPLAY_REQUIRED | Kernel32.ES_SYSTEM_REQUIRED);
@@ -196,4 +204,14 @@ public class AwakePluginImpl implements AwakePlugin, WindowListener<IMainViewCon
 			}
 		}
 	}
+
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updatable;
+	}
 }
diff --git a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java
index f01105e81cf501a47e51f9889ab0de6cd0772eca..30e9472ee227d248c1f6d780114abb90ff1380f6 100644
--- a/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java
+++ b/PlayWallPlugins/awakeplugin/de/tobias/playpad/awakeplugin/impl/AwakePluginUpdater.java
@@ -7,8 +7,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java
index 93b16f1acdd36bc81219fabae3c646090bf5b386..7bac7c99575712af4df4987be1ae337b4c3df8ed 100644
--- a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java
+++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/EqualizerPlugin.java
@@ -1,8 +1,7 @@
 package de.tobias.playpad.equalizerplugin.main;
 
-import net.xeoh.plugins.base.Plugin;
+import de.tobias.playpad.plugin.AdvancedPlugin;
 
-
-public interface EqualizerPlugin extends Plugin {
+public interface EqualizerPlugin extends AdvancedPlugin {
 
 }
diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java
index 92c5255726809d7b30ee09b4158ccfcdaa2ce47f..e45b66e579f232a0f788d4b11fb0403642f60a95 100644
--- a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java
+++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginImpl.java
@@ -11,17 +11,17 @@ import de.tobias.playpad.equalizerplugin.main.Equalizer;
 import de.tobias.playpad.equalizerplugin.main.EqualizerPlugin;
 import de.tobias.playpad.pad.Pad;
 import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.PadListener;
 import de.tobias.playpad.plugin.WindowListener;
-import de.tobias.playpad.update.UpdateRegistery;
 import de.tobias.playpad.view.main.MenuType;
 import de.tobias.playpad.viewcontroller.main.IMainViewController;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
 import de.tobias.utils.util.Localization;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
-import javafx.fxml.FXML;
 import javafx.scene.control.MenuItem;
 import javafx.scene.media.AudioEqualizer;
 import javafx.scene.media.EqualizerBand;
@@ -33,6 +33,12 @@ import net.xeoh.plugins.base.annotations.events.Shutdown;
 @PluginImplementation
 public class EqualizerPluginImpl implements EqualizerPlugin, WindowListener<IMainViewController>, EventHandler<ActionEvent>, PadListener {
 
+	private static final String NAME = "Equalizer";
+	private static final String IDENTIFIER = "de.tobias.playpad.videoplugin.main.impl.EqualizerPluginImpl";
+
+	private Module module;
+	private Updatable updatable;
+
 	private Stage mainStage;
 	private EqualizerViewController equalizerViewController;
 	private static ResourceBundle bundle;
@@ -52,7 +58,8 @@ public class EqualizerPluginImpl implements EqualizerPlugin, WindowListener<IMai
 			e.printStackTrace();
 		}
 
-		UpdateRegistery.registerUpdateable(new EqualizerPluginUpdater());
+		updatable = new EqualizerPluginUpdater();
+		module = new Module(NAME, IDENTIFIER);
 
 		PlayPadPlugin.getImplementation().addMainViewListener(this);
 		PlayPadPlugin.getImplementation().addPadListener(this);
@@ -115,7 +122,7 @@ public class EqualizerPluginImpl implements EqualizerPlugin, WindowListener<IMai
 		}
 	}
 
-	@FXML
+	@Override
 	public void handle(ActionEvent event) {
 		if (equalizerViewController == null) {
 			equalizerViewController = new EqualizerViewController(mainStage);
@@ -126,4 +133,14 @@ public class EqualizerPluginImpl implements EqualizerPlugin, WindowListener<IMai
 			equalizerViewController.getStage().show();
 		}
 	}
+
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updatable;
+	}
 }
\ No newline at end of file
diff --git a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java
index 276150dd42dacbf386a23da14716c1ee3a3b08d5..b3f3eeabc7857679a82727095878121c0b2a87a6 100644
--- a/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java
+++ b/PlayWallPlugins/equalizerplugin/de/tobias/playpad/equalizerplugin/main/impl/EqualizerPluginUpdater.java
@@ -7,8 +7,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java
index 1508fc74c06a2e3892c4bb90150670da800e2713..f3b49ca01f45b03ea7e562a6bbcf0b59240081d7 100644
--- a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java
+++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/LaunchpadPlugin.java
@@ -1,7 +1,7 @@
 package de.tobias.playpad.launchpadplugin;
 
-import net.xeoh.plugins.base.Plugin;
+import de.tobias.playpad.plugin.AdvancedPlugin;
 
-public interface LaunchpadPlugin extends Plugin {
+public interface LaunchpadPlugin extends AdvancedPlugin {
 
 }
diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java
index 1b0ced1716cfb8f829707e68c83a024b877425cb..a72e595c3f76eb3080ef1969bd88f15013f41324 100644
--- a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java
+++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchPadPluginUpdater.java
@@ -7,8 +7,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java
index fabff9d69c470b5bb7a76feffae9889d44c91606..c10a73e8915de7dbaf2ccb24688abbccac7bf934 100644
--- a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java
+++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/impl/LaunchpadPluginImpl.java
@@ -6,7 +6,8 @@ import de.tobias.playpad.launchpadplugin.LaunchpadPlugin;
 import de.tobias.playpad.launchpadplugin.midi.device.mk2.LaunchPadMK2;
 import de.tobias.playpad.launchpadplugin.midi.device.s.LaunchPadS;
 import de.tobias.playpad.midi.device.DeviceRegistry;
-import de.tobias.playpad.update.UpdateRegistery;
+import de.tobias.playpad.plugin.Module;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.util.Localization;
 import net.xeoh.plugins.base.annotations.PluginImplementation;
 import net.xeoh.plugins.base.annotations.events.PluginLoaded;
@@ -15,18 +16,23 @@ import net.xeoh.plugins.base.annotations.events.Shutdown;
 @PluginImplementation
 public class LaunchpadPluginImpl implements LaunchpadPlugin {
 
+	private static final String NAME = "LaunchPadPlugin";
+	private static final String IDENTIFIER = "de.tobias.playpad.launchpadplugin.impl.LaunchpadPluginImpl";
+
 	private static ResourceBundle bundle;
+	private LaunchPadPluginUpdater updater;
+	private Module module;
 
 	@PluginLoaded
 	public void onLoaded(LaunchpadPlugin plugin) {
 		bundle = Localization.loadBundle("de/tobias/playpad/launchpadplugin/assets/launchpad", LaunchpadPluginImpl.class.getClassLoader());
-
-		UpdateRegistery.registerUpdateable(new LaunchPadPluginUpdater());
+		updater = new LaunchPadPluginUpdater();
+		module = new Module(NAME, IDENTIFIER);
 
 		DeviceRegistry deviceFactory = DeviceRegistry.getFactoryInstance();
-
 		deviceFactory.registerDevice(LaunchPadMK2.NAME, LaunchPadMK2.class);
 		deviceFactory.registerDevice(LaunchPadS.NAME, LaunchPadS.class);
+
 		System.out.println("Enable LaunchPad Plugin");
 	}
 
@@ -39,4 +45,13 @@ public class LaunchpadPluginImpl implements LaunchpadPlugin {
 		return bundle;
 	}
 
+	@Override
+	public Module getModule() {
+		return module;
+	}
+
+	@Override
+	public Updatable getUpdatable() {
+		return updater;
+	}
 }
diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java
index 01a33d47e0a9d1dde2fe6c4e5f2e69faebf200d5..389b2ab772f3d47d0d62e3f20cf0ba05cfead83e 100644
--- a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java
+++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/mk2/LaunchPadMK2.java
@@ -19,6 +19,8 @@ import javafx.scene.paint.Color;
 public class LaunchPadMK2 extends Device implements DeviceColorAssociatorConnector {
 
 	public static final String NAME = "Launchpad MK2";
+
+	// Modern Colors mapped to the colors of the launchpad
 	private static Map<String, String> mapProperties;
 
 	public LaunchPadMK2() {
@@ -41,7 +43,8 @@ public class LaunchPadMK2 extends Device implements DeviceColorAssociatorConnect
 	}
 
 	@Override
-	public void initFeedback() {}
+	public void initDevice() {
+	}
 
 	@Override
 	public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) {
@@ -114,14 +117,16 @@ public class LaunchPadMK2 extends Device implements DeviceColorAssociatorConnect
 
 	@Override
 	public DisplayableFeedbackColor map(Color color) {
-		try {
-			URL resource = getClass().getClassLoader().getResource("de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map");
-			mapProperties = MapParser.load(resource);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
+		// TEST Ist das nötig
+		// try {
+		// URL resource = getClass().getClassLoader().getResource("de/tobias/playpad/launchpadplugin/assets/launchpad_mk2.map");
+		// mapProperties = MapParser.load(resource);
+		// } catch (Exception e) {
+		// e.printStackTrace();
+		// }
 		if (mapProperties.containsKey(color.toString())) {
-			return LaunchPadMK2Color.valueOf(mapProperties.get(color.toString()));
+			String nameOfConst = mapProperties.get(color.toString());
+			return LaunchPadMK2Color.valueOf(nameOfConst);
 		}
 		return null;
 	}
diff --git a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java
index 64b9651e27d0de4f83858259eec37c8a2ed7a902..693d49e063b5beac6f5b8565ffbbc1e19875d03f 100644
--- a/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java
+++ b/PlayWallPlugins/launchpadplugin/de/tobias/playpad/launchpadplugin/midi/device/s/LaunchPadS.java
@@ -26,7 +26,7 @@ public class LaunchPadS extends Device implements DeviceColorAssociatorConnector
 	}
 
 	@Override
-	public void initFeedback() {
+	public void initDevice() {
 		// Flash Enable
 		try {
 			Midi.getInstance().sendMessage(176, 0, 40);
@@ -37,7 +37,7 @@ public class LaunchPadS extends Device implements DeviceColorAssociatorConnector
 
 	@Override
 	public void handleFeedback(FeedbackMessage type, int key, Feedback feedback) {
-		initFeedback();
+		initDevice();
 
 		int command = 144;
 
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContent.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContent.java
index 9c310081e55225e2ea8fd37d05ddd2526ef9c891..65f08624ca734bdecaec52e42ab43a5c4d8fb773 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContent.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContent.java
@@ -1,6 +1,5 @@
 package de.tobias.playpad.mediaplugin.image;
 
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -45,8 +44,7 @@ public class ImageContent extends PadContent {
 	}
 
 	@Override
-	public void setMasterVolume(double masterVolume) {
-	}
+	public void updateVolume() {}
 
 	@Override
 	public String getType() {
@@ -74,12 +72,15 @@ public class ImageContent extends PadContent {
 		if (Files.exists(path)) {
 			getPad().setStatus(PadStatus.READY);
 		} else {
-			getPad().throwException(path, new FileNotFoundException());
+			// getPad().throwException(path, new FileNotFoundException()); TODO Error Handling User
 		}
 	}
 
 	@Override
 	public void unloadMedia() {
+		// First Stop the pad (if playing)
+		getPad().setStatus(PadStatus.STOP);
+
 		Platform.runLater(() ->
 		{
 			if (getPad() != null) {
@@ -132,4 +133,12 @@ public class ImageContent extends PadContent {
 		}
 	}
 
+	@Override
+	public PadContent clone() throws CloneNotSupportedException {
+		ImageContent clone = (ImageContent) super.clone();
+		clone.path = Paths.get(path.toUri());
+		clone.loadMedia();
+		return clone;
+	}
+
 }
\ No newline at end of file
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContentConntect.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContentConntect.java
index 53e049cd4799802c5ab74d5d44d6c3ab5cedf81d..fabd24a886e9c823f5a661b1a1b6f51bd7bf5cfa 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContentConntect.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/image/ImageContentConntect.java
@@ -119,7 +119,7 @@ public class ImageContentConntect extends PadContentConnect {
 		}
 
 		@Override
-		public void unconnect() {
+		public void deinit() {
 			nameLabel.textProperty().unbind();
 		}
 
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/MediaPlugin.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/MediaPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..13771b03fc38d046adfb1b2b25a96ad9ee9474da
--- /dev/null
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/MediaPlugin.java
@@ -0,0 +1,8 @@
+package de.tobias.playpad.mediaplugin.main;
+
+import de.tobias.playpad.plugin.AdvancedPlugin;
+
+
+public interface MediaPlugin extends AdvancedPlugin {
+
+}
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java
deleted file mode 100644
index 715650a73a239e4c1a948a52e363958577b22f1f..0000000000000000000000000000000000000000
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/VideoPlugin.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.tobias.playpad.mediaplugin.main;
-
-import net.xeoh.plugins.base.Plugin;
-
-
-public interface VideoPlugin extends Plugin {
-
-}
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java
index 7b71b3255ffa67ac72acbcee2bd858ecb636e47e..8229a6c7e7c0043185c5363d635b6738989eda2d 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginImpl.java
@@ -9,13 +9,14 @@ import org.dom4j.DocumentException;
 
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.action.ActionConnect;
-import de.tobias.playpad.mediaplugin.main.VideoPlugin;
+import de.tobias.playpad.mediaplugin.main.MediaPlugin;
 import de.tobias.playpad.mediaplugin.main.VideoSettings;
 import de.tobias.playpad.pad.conntent.PadContentConnect;
+import de.tobias.playpad.plugin.Module;
 import de.tobias.playpad.plugin.SettingsListener;
 import de.tobias.playpad.registry.Registry;
 import de.tobias.playpad.settings.Profile;
-import de.tobias.playpad.update.UpdateRegistery;
+import de.tobias.updater.client.Updatable;
 import de.tobias.utils.ui.HUD;
 import de.tobias.utils.ui.icon.FontAwesomeType;
 import de.tobias.utils.ui.icon.FontIcon;
@@ -33,8 +34,14 @@ import net.xeoh.plugins.base.annotations.events.PluginLoaded;
 import net.xeoh.plugins.base.annotations.events.Shutdown;
 
 @PluginImplementation
-public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeListener<Boolean> {
+public class MediaPluginImpl implements MediaPlugin, SettingsListener, ChangeListener<Boolean> {
 
+	private static final String NAME = "MediaPlugin";
+	private static final String IDENTIFIER = "de.tobias.playpad.videoplugin.main.impl.VideoPluginImpl";
+
+	private static Module module;
+	private static MediaPluginUpdater updater;
+	
 	private static MediaPluginImpl instance;
 	private MediaViewController videoViewController;
 	private VideoSettings settings = new VideoSettings();
@@ -46,8 +53,12 @@ public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeLis
 	private static final String SETTINGS_FILENAME = "Media.xml";
 
 	@PluginLoaded
-	public void onEnable(VideoPlugin plugin) {
+	public void onEnable(MediaPlugin plugin) {
+		// Init
 		instance = this;
+		updater = new MediaPluginUpdater();
+		module = new Module(NAME, IDENTIFIER);
+
 		blindProperty = new SimpleBooleanProperty();
 
 		bundle = Localization.loadBundle("de/tobias/playpad/mediaplugin/assets/video", getClass().getClassLoader());
@@ -56,7 +67,7 @@ public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeLis
 		// Load Content Types
 		try {
 			Registry<PadContentConnect> padContents = PlayPadPlugin.getRegistryCollection().getPadContents();
-			padContents.loadComponentsFromFile("de/tobias/playpad/mediaplugin/assets/PadContent.xml", getClass().getClassLoader());
+			padContents.loadComponentsFromFile("de/tobias/playpad/mediaplugin/assets/PadContent.xml", getClass().getClassLoader(), module);
 		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException | DocumentException e) {
 			e.printStackTrace();
 		}
@@ -83,11 +94,9 @@ public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeLis
 			});
 		}
 
-		UpdateRegistery.registerUpdateable(new MediaPluginUpdater());
-
 		try {
 			Registry<ActionConnect> padContents = PlayPadPlugin.getRegistryCollection().getActions();
-			padContents.loadComponentsFromFile("de/tobias/playpad/mediaplugin/assets/Actions.xml", getClass().getClassLoader());
+			padContents.loadComponentsFromFile("de/tobias/playpad/mediaplugin/assets/Actions.xml", getClass().getClassLoader(), module);
 		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException | DocumentException e) {
 			e.printStackTrace();
 		}
@@ -161,4 +170,14 @@ public class MediaPluginImpl implements VideoPlugin, SettingsListener, ChangeLis
 			}
 		});
 	}
+	
+	@Override
+	public Module getModule() {
+		return module;
+	}
+	
+	@Override
+	public Updatable getUpdatable() {
+		return updater;
+	}
 }
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java
index af6501af8ef2759eb21310878740d5d4f5ad33b2..70cc827e0101fa468233942e5270c31eeb421898 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaPluginUpdater.java
@@ -7,8 +7,8 @@ import java.nio.file.Path;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 
-import de.tobias.playpad.update.Updatable;
-import de.tobias.playpad.update.UpdateChannel;
+import de.tobias.updater.client.Updatable;
+import de.tobias.updater.client.UpdateChannel;
 import de.tobias.utils.application.App;
 import de.tobias.utils.application.ApplicationUtils;
 import de.tobias.utils.application.container.PathType;
@@ -24,12 +24,12 @@ public class MediaPluginUpdater implements Updatable {
 
 	@Override
 	public int getCurrentBuild() {
-		return 6;
+		return 7;
 	}
 
 	@Override
 	public String getCurrentVersion() {
-		return "4.2";
+		return "4.2.1";
 	}
 
 	@Override
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java
index d3451a5e691f47b44b6fc4d628be9cc9ef9f3c64..69ab186cec6a0db0cbf54f99bef470613dac3f19 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/main/impl/MediaSettingsTabViewController.java
@@ -124,7 +124,7 @@ public class MediaSettingsTabViewController extends ProfileSettingsTabViewContro
 	public boolean validSettings() {
 		return true;
 	}
-
+	
 	@Override
 	public Task<Void> getTask(ProfileSettings settings, Project project, IMainViewController controller) {
 		return new Task<Void>() {
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java
index b4a36a3aac7c1defa53feeed5d9985fc40a6292c..0d49f9f637e3abb231dfc96e339de3b89522856d 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContent.java
@@ -15,7 +15,7 @@ import de.tobias.playpad.pad.conntent.PadContent;
 import de.tobias.playpad.pad.conntent.play.Durationable;
 import de.tobias.playpad.pad.conntent.play.Pauseable;
 import de.tobias.playpad.project.ProjectExporter;
-import de.tobias.playpad.settings.Profile;
+import de.tobias.playpad.volume.VolumeManager;
 import de.tobias.utils.util.ZipFile;
 import javafx.application.Platform;
 import javafx.beans.property.ObjectProperty;
@@ -40,7 +40,6 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 	private transient ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>();
 
 	private transient ChangeListener<Number> padVolumeListener;
-	private transient ChangeListener<Number> customVolumeListener;
 
 	private transient boolean holdLastFrame = false;
 
@@ -48,12 +47,7 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 		super(pad);
 		padVolumeListener = (a, b, c) ->
 		{
-			player.setVolume(c.doubleValue() * Profile.currentProfile().getProfileSettings().getVolume() * getPad().getCustomVolume());
-		};
-		customVolumeListener = (a, b, c) ->
-		{
-			player.setVolume(
-					getPad().getPadSettings().getVolume() * Profile.currentProfile().getProfileSettings().getVolume() * c.doubleValue());
+			updateVolume();
 		};
 	}
 
@@ -78,9 +72,11 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 	}
 
 	@Override
-	public void setMasterVolume(double masterVolume) {
+	public void updateVolume() {
 		if (player != null) {
-			player.setVolume(getPad().getPadSettings().getVolume() * masterVolume * getPad().getCustomVolume());
+			VolumeManager manager = Pad.getVolumeManager();
+			double volume = manager.computeVolume(getPad());
+			player.setVolume(volume);
 		}
 	}
 
@@ -91,7 +87,6 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 
 	@Override
 	public void play() {
-		getPad().setCustomVolume(1.0);
 		getPad().setEof(false);
 		MediaPluginImpl.getInstance().getVideoViewController().setMediaPlayer(player, getPad());
 		if (holdLastFrame) {
@@ -192,7 +187,7 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 						getPad().getController().getView().showBusyView(false);
 					}
 				});
-				getPad().throwException(path, player.getError());
+				// getPad().throwException(path, player.getError()); TODO Error Handling User
 			});
 			player.setOnEndOfMedia(() ->
 			{
@@ -209,17 +204,18 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 			positionProperty.bind(player.currentTimeProperty());
 
 			getPad().getPadSettings().volumeProperty().addListener(padVolumeListener);
-			getPad().customVolumeProperty().addListener(customVolumeListener);
 		}
 	}
 
 	@Override
 	public void unloadMedia() {
+		// First Stop the pad (if playing)
+		getPad().setStatus(PadStatus.STOP);
+
 		durationProperty.unbind();
 		positionProperty.unbind();
 
 		getPad().getPadSettings().volumeProperty().removeListener(padVolumeListener);
-		getPad().customVolumeProperty().removeListener(customVolumeListener);
 
 		player = null;
 		media = null;
@@ -276,4 +272,12 @@ public class VideoContent extends PadContent implements Pauseable, Durationable
 			e.printStackTrace();
 		}
 	}
+
+	@Override
+	public PadContent clone() throws CloneNotSupportedException {
+		VideoContent clone = (VideoContent) super.clone();
+		clone.path = Paths.get(path.toUri());
+		clone.loadMedia();
+		return clone;
+	}
 }
\ No newline at end of file
diff --git a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java
index 4fd611c04cf87898c2e1e6f476aaf90754653cdc..394e41c66b502ce4239858454656bdc102fbef95 100644
--- a/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java
+++ b/PlayWallPlugins/mediaplugin/de/tobias/playpad/mediaplugin/video/VideoContentConntect.java
@@ -87,7 +87,7 @@ public class VideoContentConntect extends PadContentConnect {
 		}
 
 		@Override
-		public void unconnect() {
+		public void deinit() {
 			nameLabel.textProperty().unbind();
 		}
 	}