diff --git a/Pilz.Plugins.Advanced/Pilz.Plugins.Advanced.csproj b/Pilz.Plugins.Advanced/Pilz.Plugins.Advanced.csproj
index 652ff13..46d765a 100644
--- a/Pilz.Plugins.Advanced/Pilz.Plugins.Advanced.csproj
+++ b/Pilz.Plugins.Advanced/Pilz.Plugins.Advanced.csproj
@@ -9,7 +9,7 @@
True
- 2.0.0
+ 2.1.0
diff --git a/Pilz.Plugins.Advanced/PluginFeature.cs b/Pilz.Plugins.Advanced/PluginFeature.cs
new file mode 100644
index 0000000..4864206
--- /dev/null
+++ b/Pilz.Plugins.Advanced/PluginFeature.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telerik.WinControls;
+
+namespace Pilz.Plugins.Advanced
+{
+ public abstract class PluginFeature
+ {
+ public string Type { get; init; }
+ public virtual string? Name { get; init; }
+ public virtual RadSvgImage? Icon { get; set; }
+ public virtual bool Enabled { get; set; } = true;
+
+ protected PluginFeature(string functionType)
+ {
+ Type = functionType;
+ }
+
+ protected PluginFeature(string functionType, string? functionName) : this(functionType)
+ {
+ Name = functionName;
+ }
+ }
+}
diff --git a/Pilz.Plugins.Advanced/PluginFeatureController.cs b/Pilz.Plugins.Advanced/PluginFeatureController.cs
new file mode 100644
index 0000000..c301a13
--- /dev/null
+++ b/Pilz.Plugins.Advanced/PluginFeatureController.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Pilz.Plugins.Advanced
+{
+ public sealed class PluginFeatureController
+ {
+ ///
+ /// The default public instance that can be used by plugins and the interface providing software.
+ ///
+ public static PluginFeatureController Instance { get; private set; } = new();
+
+ private readonly List features = new();
+
+ ///
+ /// Returns a collection of all registred instances.
+ ///
+ public IReadOnlyList Features => features.AsReadOnly();
+
+ ///
+ /// A wrapper for all registred instances.
+ ///
+ public ModuleController Modules { get; init; }
+ ///
+ /// A wrapper for all registred instances.
+ ///
+ public FunctionController Functions { get; init; }
+
+ public PluginFeatureController()
+ {
+ Functions = new(this);
+ Modules = new(this);
+ }
+
+ public void Register(PluginFeature module)
+ {
+ if (!features.Contains(module))
+ features.Add(module);
+ }
+
+ public void Unregister(PluginFeature module)
+ {
+ features.Remove(module);
+ }
+
+ public class ModuleController
+ {
+ private readonly PluginFeatureController controller;
+
+ public ModuleController(PluginFeatureController controller)
+ {
+ this.controller = controller;
+ }
+
+ public IEnumerable GetAll()
+ {
+ return controller.features.OfType();
+ }
+
+ public IEnumerable Get(string moduleType)
+ {
+ return GetAll().Where(n => n.Type == moduleType);
+ }
+ }
+
+ public class FunctionController
+ {
+ private readonly PluginFeatureController controller;
+
+ public FunctionController(PluginFeatureController controller)
+ {
+ this.controller = controller;
+ }
+
+ public IEnumerable GetAll()
+ {
+ return controller.features.OfType();
+ }
+
+ public IEnumerable Get(string functionType)
+ {
+ return GetAll().Where(n => n.Type == functionType);
+ }
+
+ public void ExecuteAll(string functionType)
+ {
+ foreach (var function in Get(functionType))
+ function.Execute();
+ }
+
+ public void ExecuteAll(string functionType, params object?[]? @params)
+ {
+ foreach (var function in Get(functionType))
+ function.Execute(@params);
+ }
+
+ public void ExecuteAll(string functionType, PluginFunctionParameter @params)
+ {
+ foreach (var function in Get(functionType))
+ function.Execute(@params);
+ }
+
+ public IEnumerable