diff --git a/.gitignore b/.gitignore
index 524f096..7069cce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,44 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
+
+.idea
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+.kotlin
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..bbaa5b3
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ com.nerosoft
+ Mediator
+ 1.0.0
+
+
+ 25
+ 25
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/nerosoft/mediator/Command.java b/src/main/java/com/nerosoft/mediator/Command.java
new file mode 100644
index 0000000..5d36f1f
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Command.java
@@ -0,0 +1,12 @@
+package com.nerosoft.mediator;
+
+import com.nerosoft.mediator.internal.Message;
+import com.nerosoft.mediator.internal.Validatable;
+
+/**
+ * Represents a command that can be sent to the mediator.
+ * A command is an instruction to perform a specific action, and it typically does not expect a response.
+ * Commands are used to change the state of the system or to trigger some behavior.
+ */
+public interface Command extends Message, Validatable {
+}
diff --git a/src/main/java/com/nerosoft/mediator/Event.java b/src/main/java/com/nerosoft/mediator/Event.java
new file mode 100644
index 0000000..8f7fbfe
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Event.java
@@ -0,0 +1,10 @@
+package com.nerosoft.mediator;
+
+import com.nerosoft.mediator.internal.Message;
+
+/**
+ * Represents an event that can be published to the mediator.
+ * An event is a notification of something that has happened, and it typically does not expect a response.
+ */
+public interface Event extends Message {
+}
diff --git a/src/main/java/com/nerosoft/mediator/Handler.java b/src/main/java/com/nerosoft/mediator/Handler.java
new file mode 100644
index 0000000..0b30b29
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Handler.java
@@ -0,0 +1,4 @@
+package com.nerosoft.mediator;
+
+public interface Handler {
+}
diff --git a/src/main/java/com/nerosoft/mediator/Mediator.java b/src/main/java/com/nerosoft/mediator/Mediator.java
new file mode 100644
index 0000000..b2fabb6
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Mediator.java
@@ -0,0 +1,41 @@
+package com.nerosoft.mediator;
+
+/**
+ * Defines the Mediator interface for handling commands, queries, and events.
+ * The Mediator pattern promotes loose coupling between components by centralizing communication.
+ * This interface can be implemented to create a concrete mediator that manages the interactions between various components in the system.
+ */
+public interface Mediator {
+
+ /**
+ * Sends a command to the appropriate handler.
+ * @param command the command to be sent
+ * @param the type of the command
+ */
+ void send(T command);
+
+ /**
+ * Executes a query and returns the result.
+ * @param query the query to be executed
+ * @param the type of the query
+ * @param the type of the result
+ * @return the result of the query
+ */
+ , R> R execute(T query);
+
+ /**
+ * Executes a query and provides the result to the specified response handler.
+ * @param query the query to be executed
+ * @param response the response handler
+ * @param the type of the query
+ * @param the type of the result
+ */
+ , R> void execute(T query, R response);
+
+ /**
+ * Publishes an event to all interested handlers.
+ * @param event the event to be published
+ * @param the type of the event
+ */
+ void publish(T event);
+}
diff --git a/src/main/java/com/nerosoft/mediator/Middleware.java b/src/main/java/com/nerosoft/mediator/Middleware.java
new file mode 100644
index 0000000..c0fd905
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Middleware.java
@@ -0,0 +1,24 @@
+package com.nerosoft.mediator;
+
+import com.nerosoft.mediator.internal.Message;
+import com.nerosoft.mediator.internal.MiddlewareDelegate;
+
+/**
+ * Represents a middleware that can be used in the mediator pipeline.
+ * Middleware can be used to perform additional processing on messages before they are handled by their respective handlers.
+ * This can include tasks such as logging, validation, authentication,
+ * or any other cross-cutting concerns that you want to apply to messages as they pass through the mediator.
+ * Middleware can be added to the mediator pipeline to intercept messages and perform actions before or after the main handling logic is executed.
+ * This allows you to separate concerns and keep your handlers focused on their specific tasks, while still allowing for additional processing to be applied to messages in a consistent and reusable way.
+ */
+@FunctionalInterface
+public interface Middleware {
+
+ /**
+ * Executes the middleware logic for the given message and then invokes the next middleware or handler in the chain.
+ * @param message the message to be processed by the middleware
+ * @param next the delegate to invoke the next middleware or handler in the chain
+ * @return the result of the next middleware or handler
+ */
+ Object handle(Message message, MiddlewareDelegate next);
+}
diff --git a/src/main/java/com/nerosoft/mediator/PipelinedMediator.java b/src/main/java/com/nerosoft/mediator/PipelinedMediator.java
new file mode 100644
index 0000000..0c094fa
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/PipelinedMediator.java
@@ -0,0 +1,23 @@
+package com.nerosoft.mediator;
+
+public class PipelinedMediator implements Mediator {
+ @Override
+ public void send(T command) {
+
+ }
+
+ @Override
+ public , R> R execute(T query) {
+ return null;
+ }
+
+ @Override
+ public , R> void execute(T query, R response) {
+
+ }
+
+ @Override
+ public void publish(T event) {
+
+ }
+}
diff --git a/src/main/java/com/nerosoft/mediator/Query.java b/src/main/java/com/nerosoft/mediator/Query.java
new file mode 100644
index 0000000..bff3642
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Query.java
@@ -0,0 +1,13 @@
+package com.nerosoft.mediator;
+
+import com.nerosoft.mediator.internal.Message;
+import com.nerosoft.mediator.internal.Validatable;
+
+/**
+ * Represents a query that can be sent to the mediator.
+ * A query is a request for data or information, and it typically expects a response of type R.
+ *
+ * @param the type of the response expected from the query.
+ */
+public interface Query extends Message, Validatable {
+}
diff --git a/src/main/java/com/nerosoft/mediator/Validator.java b/src/main/java/com/nerosoft/mediator/Validator.java
new file mode 100644
index 0000000..7dadb32
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/Validator.java
@@ -0,0 +1,20 @@
+package com.nerosoft.mediator;
+
+import com.nerosoft.mediator.internal.Message;
+import com.nerosoft.mediator.internal.Validatable;
+import com.nerosoft.mediator.validation.ValidationResult;
+
+/**
+ * Defines a contract for validating messages before they are processed by the mediator.
+ * Implementations of this interface can be used to ensure that messages meet certain criteria or constraints before they are handled by the appropriate handlers in the mediator pattern.
+ * @param the type of message to be validated. Only messages that extend the Validatable class can be validated using this interface, ensuring that the validation logic is specific to the types of messages being processed in the mediator pattern.
+ */
+public interface Validator {
+
+ /**
+ * Validates the given message and returns a ValidationResult indicating whether the validation was successful or if there were any errors.
+ * @param message the message to be validated
+ * @return the result of the validation, including any error messages if the validation failed
+ */
+ ValidationResult validate(T message);
+}
diff --git a/src/main/java/com/nerosoft/mediator/internal/Message.java b/src/main/java/com/nerosoft/mediator/internal/Message.java
new file mode 100644
index 0000000..3f1d00f
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/internal/Message.java
@@ -0,0 +1,4 @@
+package com.nerosoft.mediator.internal;
+
+public interface Message {
+}
diff --git a/src/main/java/com/nerosoft/mediator/internal/MiddlewareDelegate.java b/src/main/java/com/nerosoft/mediator/internal/MiddlewareDelegate.java
new file mode 100644
index 0000000..e573a8c
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/internal/MiddlewareDelegate.java
@@ -0,0 +1,21 @@
+package com.nerosoft.mediator.internal;
+
+/**
+ * The next invocation of the middleware chain.
+ * To invoke the next middleware or handler in the chain, call the invoke() method on this delegate.
+ * This delegate is passed to each middleware and handler in the chain, allowing them to control when the next middleware is invoked.
+ * Middleware and handlers can choose to invoke the next middleware immediately,
+ * or they can perform some processing before invoking the next middleware.
+ * This allows for flexible control over the flow of the middleware chain,
+ * enabling middleware to perform tasks such as logging, validation, authentication, or any other cross-cutting concerns before the main handling logic is executed.
+ * By using this delegate, middleware and handlers can ensure that the next middleware in the chain is invoked at the appropriate time,
+ * allowing for a consistent and reusable way to apply additional processing to messages as they pass through the mediator.
+ */
+@FunctionalInterface
+public interface MiddlewareDelegate {
+ /**
+ * Invokes the next middleware or handler in the chain.
+ * @return the result of the next middleware or handler
+ */
+ Object invoke();
+}
diff --git a/src/main/java/com/nerosoft/mediator/internal/Validatable.java b/src/main/java/com/nerosoft/mediator/internal/Validatable.java
new file mode 100644
index 0000000..e743974
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/internal/Validatable.java
@@ -0,0 +1,9 @@
+package com.nerosoft.mediator.internal;
+
+/**
+ * Represents a marker interface for objects that can be validated.
+ * This interface is used to indicate that a class has validation logic associated with it, and it can be used in conjunction with the Validator interface to perform validation on instances of classes that implement Validatable.
+ * By implementing this interface, a class can be recognized as being subject to validation rules, allowing for a consistent approach to validating objects within the mediator pattern.
+ */
+public interface Validatable {
+}
diff --git a/src/main/java/com/nerosoft/mediator/validation/ValidationException.java b/src/main/java/com/nerosoft/mediator/validation/ValidationException.java
new file mode 100644
index 0000000..05ac7a0
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/validation/ValidationException.java
@@ -0,0 +1,54 @@
+package com.nerosoft.mediator.validation;
+
+import java.util.List;
+
+/**
+ * Represents an exception that is thrown when validation fails in the mediator pattern.
+ * This exception encapsulates the details of the validation failure,
+ * including a list of error messages that describe the reasons for the failure.
+ * The ValidationException class extends RuntimeException,
+ * allowing it to be thrown without the need for explicit handling in the code that performs validation.
+ * By providing a dedicated exception for validation failures,
+ * it allows for better error handling and improved code readability when dealing with validation logic in the mediator pattern.
+ * The ValidationException class also provides a method to retrieve the ValidationResult associated with the exception,
+ * allowing for easy access to the details of the validation failure when catching the exception.
+ * Overall, this class serves as a clear and consistent way to represent validation failures in the mediator pattern,
+ * promoting better error handling and improved code readability when dealing with validation logic in the application.
+ */
+public class ValidationException extends RuntimeException {
+ private final transient ValidationResult result;
+
+ /**
+ * Creates a new ValidationException with the specified list of error messages.
+ * @param errors the list of error messages describing the validation failure
+ */
+ private ValidationException(List errors) {
+ super("Validation failed: " + String.join(", ", errors));
+ this.result = ValidationResult.failure(errors);
+ }
+
+ /**
+ * Creates a new ValidationException with the specified list of error messages.
+ * @param message the error message describing the validation failure
+ */
+ public ValidationException(String message) {
+ super(message);
+ this.result = ValidationResult.failure(message);
+ }
+
+ /**
+ * Gets the ValidationResult associated with this exception, which contains the details of the validation failure, including any error messages.
+ * @return the ValidationResult associated with this exception
+ */
+ public ValidationResult getResult() {
+ return result;
+ }
+
+ /**
+ * Gets the list of error messages describing the validation failure.
+ * @return the list of error messages describing the validation failure
+ */
+ public List getErrors() {
+ return result.getErrors();
+ }
+}
diff --git a/src/main/java/com/nerosoft/mediator/validation/ValidationResult.java b/src/main/java/com/nerosoft/mediator/validation/ValidationResult.java
new file mode 100644
index 0000000..9ec2fda
--- /dev/null
+++ b/src/main/java/com/nerosoft/mediator/validation/ValidationResult.java
@@ -0,0 +1,48 @@
+package com.nerosoft.mediator.validation;
+
+import java.util.List;
+
+/**
+ * Defines the result of a validation operation, which can be either successful or failed with a list of error messages.
+ * This class provides static factory methods to create success or failure results, and it allows checking the status of the validation and retrieving any error messages if the validation failed.
+ * The ValidationResult class is designed to be immutable and thread-safe, making it suitable for use in concurrent environments where multiple threads may be performing validation operations simultaneously.
+ * By encapsulating the validation result in a dedicated class, it promotes a clear and consistent way to handle validation outcomes throughout the application, allowing for better error handling and improved code readability when dealing with validation logic in the mediator pattern.
+ */
+public final class ValidationResult {
+ private static final ValidationResult SUCCESS = new ValidationResult(List.of());
+
+ private final List errors;
+
+ public ValidationResult(List errors) {
+ this.errors = errors;
+ }
+
+ public static ValidationResult success() {
+ return SUCCESS;
+ }
+
+ public static ValidationResult failure(List errors) {
+ return new ValidationResult(errors);
+ }
+
+ public static ValidationResult failure(String message) {
+ return new ValidationResult(List.of(message));
+ }
+
+ public List getErrors() {
+ return errors;
+ }
+
+ public boolean isSuccess() {
+ return errors.isEmpty();
+ }
+
+ public boolean isFailure() {
+ return !isSuccess();
+ }
+
+ @Override
+ public String toString() {
+ return isSuccess()? "ValidationResult{success}" : "ValidationResult{failure, errors=" + errors + "}";
+ }
+}