diff --git a/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginLoader.java b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginLoader.java
new file mode 100644
index 0000000..f6b7f70
--- /dev/null
+++ b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginLoader.java
@@ -0,0 +1,7 @@
+package com.g2forge.habitat.plugin;
+
+import com.g2forge.alexandria.adt.collection.ICollection;
+
+public interface IPluginLoader
{
+ public ICollection extends P> load();
+}
diff --git a/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginService.java b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginService.java
new file mode 100644
index 0000000..1a80150
--- /dev/null
+++ b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginService.java
@@ -0,0 +1,7 @@
+package com.g2forge.habitat.plugin;
+
+import com.g2forge.alexandria.adt.collection.ICollection;
+
+public interface IPluginService {
+ public ICollection> load();
+}
diff --git a/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginSystem.java b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginSystem.java
new file mode 100644
index 0000000..e8a8ce1
--- /dev/null
+++ b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/IPluginSystem.java
@@ -0,0 +1,5 @@
+package com.g2forge.habitat.plugin;
+
+public interface IPluginSystem {
+ public IPluginLoader
load(Class
type);
+}
diff --git a/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginDescriptor.java b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginDescriptor.java
new file mode 100644
index 0000000..8013288
--- /dev/null
+++ b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginDescriptor.java
@@ -0,0 +1,33 @@
+package com.g2forge.habitat.plugin;
+
+import java.util.List;
+
+import com.g2forge.alexandria.java.function.IConsumer2;
+import com.g2forge.alexandria.java.function.IFunction1;
+import com.g2forge.alexandria.java.function.ISupplier;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import lombok.Singular;
+
+@Data
+@Builder(toBuilder = true)
+@RequiredArgsConstructor
+public class PluginDescriptor
{
+ @Data
+ @Builder(toBuilder = true)
+ @RequiredArgsConstructor
+ public static class Dependency {
+ protected final Class type;
+
+ protected final IConsumer2 super T, ? super U> callback;
+ }
+
+ @Singular
+ protected final List> dependencies;
+
+ protected final ISupplier constructor;
+
+ protected final IFunction1 super B, ? extends P> builder;
+}
diff --git a/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginSystem.java b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginSystem.java
new file mode 100644
index 0000000..5cb63c5
--- /dev/null
+++ b/ha-plugin/src/main/java/com/g2forge/habitat/plugin/PluginSystem.java
@@ -0,0 +1,44 @@
+package com.g2forge.habitat.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.g2forge.alexandria.adt.collection.DStreamCollection;
+import com.g2forge.alexandria.adt.collection.ICollection;
+import com.g2forge.alexandria.annotations.note.Note;
+import com.g2forge.alexandria.annotations.note.NoteType;
+import com.g2forge.alexandria.java.function.ISupplier;
+import com.g2forge.alexandria.java.type.ref.ITypeRef;
+import com.g2forge.alexandria.service.BasicServiceLoader;
+import com.g2forge.alexandria.service.IServiceLoader;
+
+import lombok.Getter;
+
+public class PluginSystem implements IPluginSystem {
+ @Getter(lazy = true)
+ private static final IPluginSystem standard = new PluginSystem();
+
+ @Note(type = NoteType.TODO, issue = "G2-1628")
+ protected P instantiate(PluginDescriptor
descriptor) {
+ final ISupplier constructor = descriptor.getConstructor();
+ final B builder = constructor.get();
+ return descriptor.getBuilder().apply(builder);
+ }
+
+ @Override
+ public
IPluginLoader
load(Class
type) {
+ return new IPluginLoader
() {
+ @Override
+ public ICollection extends P> load() {
+ final IServiceLoader loader = new BasicServiceLoader<>(IPluginService.class);
+ final List