diff --git a/pom.xml b/pom.xml
index a1f4babf..0d0dc9dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,8 +43,8 @@
 
 	
 		UTF-8
-		1.7
-		1.7
+		1.8
+		1.8
 	
 	
 	
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Command.java b/src/main/java/fr/zcraft/zlib/components/commands2/Command.java
new file mode 100644
index 00000000..2a9706b4
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Command.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.exceptions.CommandException;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This class represents a registered command.
+ * @param  The command runnable type this command is bound to.
+ */
+public class Command {
+
+    private final String name;
+    private final Class runnableClass;
+    private final boolean isCommandGroup;
+    private final List> subCommands;
+    private final List parameters;
+    private final List flags;
+
+    Command(Class runnableClass, String name, boolean isCommandGroup, List> subCommands, List parameters, List flags) {
+        this.runnableClass = runnableClass;
+        this.name = name;
+        this.isCommandGroup = isCommandGroup;
+        this.subCommands = subCommands;
+        this.parameters = parameters;
+        this.flags = flags;
+    }
+
+    public Context extends CommandRunnable> makeContext(CommandSender sender, String[] arguments) throws CommandException {
+        return ContextGenerator.makeContext(this, sender, arguments, Optional.empty());
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean nameMatches(String string) {
+        return string.equalsIgnoreCase(name);
+    }
+
+    public Class getRunnableClass() {
+        return runnableClass;
+    }
+
+    public boolean isCommandGroup() {
+        return isCommandGroup;
+    }
+
+    public List> getSubCommands() {
+        return subCommands;
+    }
+
+    public Optional> getSubCommand(String name) {
+        for(SubCommand, T> subCommand : subCommands) {
+            if(subCommand.getCommand().nameMatches(name)) return Optional.of(subCommand);
+        }
+        return Optional.empty();
+    }
+
+    public List getParameters() {
+        return parameters;
+    }
+
+    public List getFlags() {
+        return flags;
+    }
+
+    public Optional getFlag(String shortName) {
+        for(Flag flag: flags) {
+            if(flag.getName().equals(shortName)) return Optional.of(flag);
+        }
+        return Optional.empty();
+    }
+
+    public Optional getShortFlag(String shortName) {
+        for(Flag flag: flags) {
+            if(flag.getShortName().equals(shortName)) return Optional.of(flag);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/CommandExecutor.java b/src/main/java/fr/zcraft/zlib/components/commands2/CommandExecutor.java
new file mode 100644
index 00000000..9b8ee528
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/CommandExecutor.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.util.List;
+
+class CommandExecutor implements TabCompleter, org.bukkit.command.CommandExecutor {
+
+    public CommandExecutor(Command command) {
+
+    }
+
+    @Override
+    public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
+        throw new NotImplementedException();
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/CommandGenerator.java b/src/main/java/fr/zcraft/zlib/components/commands2/CommandGenerator.java
new file mode 100644
index 00000000..f8b7fee5
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/CommandGenerator.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.annotations.Subcommand;
+import fr.zcraft.zlib.components.commands2.exceptions.CommandConfigurationException;
+import fr.zcraft.zlib.components.commands2.exceptions.UnhandledParameterType;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * This class contains various utilities to generate Command objects from their bound runnable class.
+ */
+class CommandGenerator {
+    static public  Command fromClass(Class runnableClass, String name)  {
+        if(isCommandGroup(runnableClass)) {
+            return fromEnumClass(runnableClass, name);
+        } else {
+            return fromPlainClass(runnableClass, name);
+        }
+    }
+
+    static private boolean isCommandGroup(Class extends CommandRunnable> runnableClass) {
+        return Enum.class.isAssignableFrom(runnableClass);
+    }
+
+    static private  Command fromEnumClass(final Class runnableClass, String name) {
+        List> subcommands = Arrays.stream(runnableClass.getDeclaredFields())
+                .filter(Field::isEnumConstant)
+                .map(f -> subcommandFromField(f, runnableClass))
+                .collect(Collectors.toList());
+
+        return new Command<>(runnableClass, name, true, subcommands, new ArrayList<>(), new ArrayList<>());
+    }
+
+    static private List getCommandParameters(Class extends CommandRunnable> runnableClass) throws UnhandledParameterType {
+        return Arrays.stream(runnableClass.getDeclaredFields())
+                .filter(f -> !isFlagField(f))
+                .map(CommandGenerator::parameterFromField)
+                .collect(Collectors.toList());
+    }
+
+    static private List getCommandFlags(Class extends CommandRunnable> runnableClass) throws UnhandledParameterType {
+        return Arrays.stream(runnableClass.getDeclaredFields())
+                .filter(CommandGenerator::isFlagField)
+                .map(CommandGenerator::flagFromField)
+                .collect(Collectors.toList());
+    }
+
+    static private boolean isFlagField(Field field) {
+        return field.getAnnotation(fr.zcraft.zlib.components.commands2.annotations.Flag.class) != null;
+    }
+
+    static private Parameter parameterFromField(Field field) throws UnhandledParameterType {
+        return new Parameter(field.getType(), field, findTypeConverter(field), field.getName(), null, isFieldRequired(field));
+    }
+
+    static private Flag flagFromField(Field field) throws UnhandledParameterType {
+        Class> type = field.getType();
+        fr.zcraft.zlib.components.commands2.annotations.Flag flagAnnotation = field.getAnnotation(fr.zcraft.zlib.components.commands2.annotations.Flag.class);
+        String shortName = flagAnnotation.shortName();
+
+        if(boolean.class.isAssignableFrom(type)) {
+            return new Flag(type, field, null, field.getName(), shortName,null, false, false);
+        }
+
+        boolean isRequired = isFieldRequired(field);
+        return new Flag(type, field, findTypeConverter(field), field.getName(), shortName, null, isRequired, true);
+    }
+
+    static private Class> getFieldType(Field field) {
+        Class> type = field.getType();
+        if(Optional.class.isAssignableFrom(type)) {
+            ParameterizedType ptype = (ParameterizedType) field.getGenericType();
+            type = (Class>) ptype.getActualTypeArguments()[0];
+        }
+        return type;
+    }
+
+    static private  ParameterTypeConverter findTypeConverter(Field field) throws UnhandledParameterType {
+        Class> type = getFieldType(field);
+        Optional> typeConverter = Commands.findTypeConverter(type);
+        if(!typeConverter.isPresent()) throw new UnhandledParameterType(type, field);
+        return typeConverter.get();
+    }
+
+    static private boolean isFieldRequired(Field f) {
+        return !Optional.class.isAssignableFrom(f.getType());
+    }
+
+    static private  Command fromPlainClass(Class runnableClass, String name) {
+        return new Command<>(runnableClass, name, false, new ArrayList<>(), getCommandParameters(runnableClass), getCommandFlags(runnableClass));
+    }
+
+    static private  SubCommand, T> subcommandFromField(Field field, Class parentCommandClass) {
+        Subcommand subcommand = field.getAnnotation(Subcommand.class);
+        if(subcommand == null) throw new CommandConfigurationException(parentCommandClass, "Missing subcommand annotation on field: " + field.getName());
+
+        String commandName = subcommand.name();
+        if(commandName.isEmpty()) commandName = field.getName().toLowerCase();
+        Command> innerCommand = fromClass(subcommand.value(), commandName);
+        Object parentFieldValue;
+        try {
+            field.setAccessible(true);
+            parentFieldValue = field.get(null);
+            if(!parentCommandClass.isInstance(parentFieldValue)) {
+                throw new CommandConfigurationException(parentCommandClass, "Invalid enum field: " + field.getName());
+            }
+        } catch (IllegalAccessException e) {
+            throw new CommandConfigurationException(parentCommandClass, "Unable to access field: " + field.getName());
+        }
+
+        @SuppressWarnings ("unchecked")
+        T parentValue = (T) parentFieldValue;
+
+        return new SubCommand<>(innerCommand, parentValue, field);
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/CommandRunnable.java b/src/main/java/fr/zcraft/zlib/components/commands2/CommandRunnable.java
new file mode 100644
index 00000000..92476cbd
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/CommandRunnable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.exceptions.CommandException;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+
+public interface CommandRunnable {
+    default void run(Context context) throws CommandException {
+        throw new NotImplementedException();
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/CommandSender.java b/src/main/java/fr/zcraft/zlib/components/commands2/CommandSender.java
new file mode 100644
index 00000000..d87097de
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/CommandSender.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+public class CommandSender {
+    private org.bukkit.command.CommandSender bukkitSender;
+
+    CommandSender() {}
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Commands.java b/src/main/java/fr/zcraft/zlib/components/commands2/Commands.java
new file mode 100644
index 00000000..f2a00e42
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Commands.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.converters.IntegerTypeConverter;
+import fr.zcraft.zlib.components.commands2.converters.URITypeConverter;
+import fr.zcraft.zlib.components.commands2.exceptions.CommandException;
+import fr.zcraft.zlib.components.commands2.exceptions.CommandNotFoundException;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * The entry point for the zLib Commands component.
+ */
+public abstract class Commands
+{
+    private Commands() {}
+
+    static private final Map> commandRegistry = new HashMap<>();
+    static private final Map, ParameterTypeConverter>> typeConverterRegistry = new HashMap<>();
+
+    /**
+     * Registers a new command.
+     * @param command The command runnable to be registered
+     * @param name The name of the command
+     */
+    static public void register(Class extends CommandRunnable> command, String name) {
+        name = name.toLowerCase();
+        if(commandRegistry.containsKey(name)) throw new IllegalArgumentException("Command already registered : " + name);
+
+        commandRegistry.put(name, CommandGenerator.fromClass(command, name));
+    }
+
+    /**
+     * Registers a new command parameter type converter.
+     * You must register a new converter before using any types in your commands that zLib doesn't support out of the box.
+     * Additional type converters must be registered before any commands using the type are.
+     * @param parameterTypeConverter The type converter to register
+     */
+    static public void registerParameterTypeConverter(ParameterTypeConverter> parameterTypeConverter) {
+        //TODO: Raise exception if already registered
+        typeConverterRegistry.put(parameterTypeConverter.getType(), parameterTypeConverter);
+    }
+
+    /**
+     * Finds the registered command matching the given name.
+     * @param commandName The name of the command
+     * @return The matching command
+     * @throws CommandNotFoundException If no matching command is found
+     */
+    static public Command findCommand(String commandName) throws CommandNotFoundException {
+        Command command = commandRegistry.get(commandName.toLowerCase());
+        if(command == null) throw new CommandNotFoundException(commandName);
+        return command;
+    }
+
+    /**
+     * Finds the registered command parameter type converter handling the given type.
+     * @param type The type used to look up the matching type converter
+     * @return The registered command parameter type converter, if found
+     */
+    static public Optional> findTypeConverter(Class> type) {
+        return Optional.ofNullable(typeConverterRegistry.get(type));
+    }
+
+    /**
+     * Creates a new Command execution context for the given command.
+     * @param commandName The name of the command
+     * @param sender The command sender the command originated from
+     * @param arguments The command arguments
+     * @return The newly created context
+     * @throws CommandException If the command is not found, or if an error occured when parsing the arguments
+     */
+    static public Context> makeContext(String commandName, CommandSender sender, String[] arguments) throws CommandException {
+        return findCommand(commandName).makeContext(sender, arguments);
+    }
+
+    // REGISTER ALL THE TYPES
+    static {
+        registerParameterTypeConverter(new IntegerTypeConverter());
+        registerParameterTypeConverter(new URITypeConverter());
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Context.java b/src/main/java/fr/zcraft/zlib/components/commands2/Context.java
new file mode 100644
index 00000000..498e9717
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Context.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import java.util.Optional;
+
+/**
+ * This class represents a command execution context.
+ * It contains all the data related to command execution, such as the command sender, arguments, etc.
+ * @param  The command runnable type this command is bound to.
+ */
+public class Context {
+
+    private final T runnable;
+    private final CommandSender sender;
+    private final String[] args;
+    private final Command parentCommand;
+    private final Optional parentContext;
+    private final Optional> matchedSubCommand;
+
+    Context(T runnable, CommandSender sender, String[] args, Command command, Optional parentContext, Optional> matchedSubCommand) {
+        this.runnable = runnable;
+        this.sender = sender;
+        this.args = args;
+        this.parentCommand = command;
+        this.parentContext = parentContext;
+        this.matchedSubCommand = matchedSubCommand;
+    }
+
+    public T getCommandRunnable() {
+        return this.runnable;
+    }
+
+    public CommandSender sender() {
+        return this.sender;
+    }
+
+    public String[] getArgs() {
+        return args;
+    }
+
+    public Command getParentCommand() {
+        return parentCommand;
+    }
+
+    public Optional getParentContext() {
+        return parentContext;
+    }
+
+    public Optional> getMatchedSubCommand() {
+        return matchedSubCommand;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/ContextGenerator.java b/src/main/java/fr/zcraft/zlib/components/commands2/ContextGenerator.java
new file mode 100644
index 00000000..d9f54982
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/ContextGenerator.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.exceptions.*;
+import fr.zcraft.zlib.tools.reflection.Reflection;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This class contains various utilities to generate Context objects from arguments matched against their bound Command class.
+ */
+abstract class ContextGenerator {
+    private ContextGenerator() {}
+
+    private static  Context makeEnumContext(Command command, CommandSender sender, String[] arguments, Optional parentContext) throws ArgumentException {
+        if(arguments.length < 1) throw new MissingSubcommandException(command);
+        SubCommand, T> subCommand = command.getSubCommand(arguments[0]).orElseThrow(() -> new UnknownSubcommandException(command, arguments[0], 0));
+        return new Context<>(subCommand.getParentEnumValue(), sender, arguments, command, parentContext, Optional.of(subCommand));
+    }
+
+    static Context extends CommandRunnable> makeContext(Command extends CommandRunnable> command, CommandSender sender, String[] arguments, Optional parentContext) throws ArgumentException {
+        if(!command.isCommandGroup()) {
+            return makePlainClassContext(command, sender, arguments, parentContext);
+        }
+
+        Context> context = makeEnumContext(command, sender, arguments, parentContext);
+        SubCommand, ? extends CommandRunnable> subCommand = context.getMatchedSubCommand().orElseThrow(NullPointerException::new);
+        try {
+            return makeContext(subCommand.getCommand(), sender, Arrays.copyOfRange(arguments, 1, arguments.length), Optional.of(context));
+        } catch(ArgumentException e) {
+            e.setArgumentPosition(e.getArgumentPosition().map(i -> i + 1));
+            throw e;
+        }
+    }
+
+    private static  Context makePlainClassContext(Command command, CommandSender sender, String[] arguments, Optional parentContext) throws ArgumentException {
+        T runnable = instanciateCommandRunnable(command);
+        List parameters = command.getParameters();
+        List flags = command.getFlags();
+        List remainingFlags = new ArrayList<>(flags);
+
+        int argumentsI = 0;
+        int parametersI = 0;
+
+        for(; argumentsI < arguments.length; ++argumentsI) {
+            String argument = arguments[argumentsI];
+            Flag flag = null;
+            if(argument.startsWith("--")) {
+                argument = argument.substring(2);
+                Optional oflag = command.getFlag(argument);
+                if (!oflag.isPresent()) throw new UnknownFlagException(argument, argumentsI);
+                flag = oflag.get();
+            } else if(argument.startsWith("-")) {
+                argument = argument.substring(1);
+                Optional oflag = command.getShortFlag(argument);
+                if (!oflag.isPresent()) throw new UnknownFlagException(argument, argumentsI);
+                flag = oflag.get();
+            }
+
+            if(flag != null) {
+                if (!remainingFlags.remove(flag)) throw new FlagAlreadyDefinedException(flag, argument, argumentsI);
+                if (!flag.hasValue()) {
+                    setRunnableField(runnable, flag, true);
+                } else {
+                    if (argumentsI + 1 >= arguments.length) throw new FlagMissingValueException(flag, argumentsI);
+                    ++argumentsI;
+                    Object runnableValue = convertFieldType(flag, arguments[argumentsI], argumentsI);
+                    if (flag.isRequired()) {
+                        setRunnableField(runnable, flag, runnableValue);
+                    } else {
+                        setRunnableField(runnable, flag,  Optional.of(runnableValue));
+                    }
+                }
+                continue;
+            }
+
+            if(parametersI >= parameters.size()) throw new ExtraArgumentException(arguments[argumentsI], argumentsI);
+            Parameter parameter = parameters.get(argumentsI);
+            setRunnableField(runnable, parameter, convertFieldType(parameter, arguments[argumentsI], argumentsI));
+            ++parametersI;
+        }
+
+        //Look for missing required parameters
+        for(; parametersI < parameters.size(); ++parametersI) {
+            Parameter parameter = parameters.get(parametersI);
+            if(parameter.isRequired()) {
+                throw new MissingParameterException(parameter);
+            }
+            setRunnableField(runnable, parameter, Optional.empty());
+        }
+
+        //Look for missing required flags
+        for(Flag f: remainingFlags) {
+            if(f.isRequired()) throw new MissingRequiredFlagException(f);
+            if(f.hasValue()) {
+                setRunnableField(runnable, f, Optional.empty());
+            } else {
+                setRunnableField(runnable, f, false);
+            }
+        }
+
+
+        return new Context<>(runnable, sender, arguments, command, parentContext, Optional.empty());
+    }
+
+    static private void setRunnableField(CommandRunnable runnable, Field field, Object value) {
+        try {
+            field.getRunnableField().set(runnable, value);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException("Unable to set runnable class field : " + runnable.getClass() + "." + field.getRunnableField().getName(), e);
+        }
+    }
+
+    static private  T instanciateCommandRunnable(Command command) {
+        try {
+            return Reflection.instantiate(command.getRunnableClass());
+        } catch(Exception e) {
+            throw new RuntimeException("Unable to instanciate Command runnable class : " + command.getRunnableClass().getName(), e);
+        }
+    }
+
+    static private Object convertFieldType(Field parameter, String argument, int argumentPosition) throws InvalidArgumentException {
+        try {
+            return parameter.getTypeConverter().fromArgument(argument);
+        } catch (ParameterTypeConverterException e) {
+            throw new InvalidArgumentException(e, argument, argumentPosition);
+        }
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Field.java b/src/main/java/fr/zcraft/zlib/components/commands2/Field.java
new file mode 100644
index 00000000..e235c283
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Field.java
@@ -0,0 +1,45 @@
+package fr.zcraft.zlib.components.commands2;
+
+class Field {
+    private final Class> parameterType;
+    private final java.lang.reflect.Field runnableField;
+    private final ParameterTypeConverter> typeConverter;
+
+    private final String name;
+    private final String about;
+    private final boolean isRequired;
+
+    Field(Class> parameterType, java.lang.reflect.Field runnableField, ParameterTypeConverter> typeConverter, String name, String about, boolean isRequired) {
+        this.parameterType = parameterType;
+        this.runnableField = runnableField;
+        this.typeConverter = typeConverter;
+
+        this.name = name;
+        this.about = about;
+        this.isRequired = isRequired;
+    }
+
+    public Class> getParameterType() {
+        return parameterType;
+    }
+
+    public ParameterTypeConverter> getTypeConverter() {
+        return typeConverter;
+    }
+
+    public java.lang.reflect.Field getRunnableField() {
+        return runnableField;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getAbout() {
+        return about;
+    }
+
+    public boolean isRequired() {
+        return isRequired;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Flag.java b/src/main/java/fr/zcraft/zlib/components/commands2/Flag.java
new file mode 100644
index 00000000..2bfcdcc8
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Flag.java
@@ -0,0 +1,21 @@
+package fr.zcraft.zlib.components.commands2;
+
+public class Flag extends Field {
+    private final boolean hasValue;
+    private final String shortName;
+
+    Flag(Class> parameterType, java.lang.reflect.Field runnableField, ParameterTypeConverter> typeConverter, String name, String shortName, String about, boolean isRequired, boolean hasValue) {
+        super(parameterType, runnableField, typeConverter, name, about, isRequired);
+        this.hasValue = hasValue;
+        this.shortName = shortName;
+    }
+
+    public boolean hasValue() {
+        return hasValue;
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+}
+
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/Parameter.java b/src/main/java/fr/zcraft/zlib/components/commands2/Parameter.java
new file mode 100644
index 00000000..644dd25c
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/Parameter.java
@@ -0,0 +1,7 @@
+package fr.zcraft.zlib.components.commands2;
+
+public class Parameter extends Field {
+    Parameter(Class> parameterType, java.lang.reflect.Field runnableField, ParameterTypeConverter> typeConverter, String name, String about, boolean isRequired) {
+        super(parameterType, runnableField, typeConverter, name, about, isRequired);
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/ParameterTypeConverter.java b/src/main/java/fr/zcraft/zlib/components/commands2/ParameterTypeConverter.java
new file mode 100644
index 00000000..7ed872d7
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/ParameterTypeConverter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.exceptions.ParameterTypeConverterException;
+
+/**
+ * An interface used to parse types from command arguments.
+ * @param 
+ */
+public interface ParameterTypeConverter {
+    Class getType();
+    T fromArgument(String argument) throws ParameterTypeConverterException;
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/SubCommand.java b/src/main/java/fr/zcraft/zlib/components/commands2/SubCommand.java
new file mode 100644
index 00000000..a14454c3
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/SubCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class contains information about a command's subcommand.
+ * @param 
+ * @param 
+ */
+public class SubCommand {
+    private final Command command;
+    private final Parent parentEnumValue;
+    private final Field parentField;
+
+    SubCommand(Command command, Parent parentEnumValue, Field parentField) {
+        this.command = command;
+        this.parentEnumValue = parentEnumValue;
+        this.parentField = parentField;
+    }
+
+    public Command getCommand() {
+        return command;
+    }
+
+    public Parent getParentEnumValue() {
+        return parentEnumValue;
+    }
+
+    public Field getParentField() {
+        return parentField;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/annotations/About.java b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/About.java
new file mode 100644
index 00000000..1af8b9d7
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/About.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface About {
+    String value();
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Flag.java b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Flag.java
new file mode 100644
index 00000000..d1dce9c5
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Flag.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Flag {
+    String shortName() default "";
+    String name() default "";
+    String[] names() default {};
+    String[] additionalNames() default {};
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Subcommand.java b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Subcommand.java
new file mode 100644
index 00000000..2eef68a3
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/annotations/Subcommand.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.annotations;
+
+import fr.zcraft.zlib.components.commands2.CommandRunnable;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Subcommand {
+    Class extends CommandRunnable> value();
+    String name() default "";
+    String[] aliases() default {};
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/converters/IntegerTypeConverter.java b/src/main/java/fr/zcraft/zlib/components/commands2/converters/IntegerTypeConverter.java
new file mode 100644
index 00000000..cb22a386
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/converters/IntegerTypeConverter.java
@@ -0,0 +1,20 @@
+package fr.zcraft.zlib.components.commands2.converters;
+
+import fr.zcraft.zlib.components.commands2.ParameterTypeConverter;
+import fr.zcraft.zlib.components.commands2.exceptions.ParameterTypeConverterException;
+
+public class IntegerTypeConverter implements ParameterTypeConverter {
+    @Override
+    public Class getType() {
+        return Integer.class;
+    }
+
+    @Override
+    public Integer fromArgument(String argument) throws ParameterTypeConverterException {
+        try {
+            return Integer.parseInt(argument);
+        } catch(NumberFormatException e) {
+            throw new ParameterTypeConverterException("Invalid integer", e);
+        }
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/converters/URITypeConverter.java b/src/main/java/fr/zcraft/zlib/components/commands2/converters/URITypeConverter.java
new file mode 100644
index 00000000..64cc2710
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/converters/URITypeConverter.java
@@ -0,0 +1,23 @@
+package fr.zcraft.zlib.components.commands2.converters;
+
+import fr.zcraft.zlib.components.commands2.ParameterTypeConverter;
+import fr.zcraft.zlib.components.commands2.exceptions.ParameterTypeConverterException;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class URITypeConverter implements ParameterTypeConverter {
+    @Override
+    public Class getType() {
+        return URI.class;
+    }
+
+    @Override
+    public URI fromArgument(String argument) throws ParameterTypeConverterException {
+        try {
+            return new URI(argument);
+        } catch (URISyntaxException e) {
+            throw new ParameterTypeConverterException("Invalid URI", e);
+        }
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ArgumentException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ArgumentException.java
new file mode 100644
index 00000000..d5d11760
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ArgumentException.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import java.util.Optional;
+
+public abstract class ArgumentException extends CommandException {
+    private final Optional argument;
+    private Optional argumentPosition;
+
+    public ArgumentException() {
+        this(Optional.empty(), Optional.empty());
+    }
+
+    public ArgumentException(String argument) {
+        this(Optional.of(argument), Optional.empty());
+    }
+
+    public ArgumentException(String argument, int argumentPosition) {
+        this(Optional.of(argument), Optional.of(argumentPosition));
+    }
+
+    public ArgumentException(Optional argument, Optional argumentPosition) {
+        this.argument = argument;
+        this.argumentPosition = argumentPosition;
+    }
+
+    public Optional getArgument() {
+        return argument;
+    }
+
+    public Optional getArgumentPosition() {
+        return argumentPosition;
+    }
+
+    public void setArgumentPosition(Optional argumentPosition) {
+        this.argumentPosition = argumentPosition;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandConfigurationException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandConfigurationException.java
new file mode 100644
index 00000000..d76d7dbd
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandConfigurationException.java
@@ -0,0 +1,19 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class CommandConfigurationException extends RuntimeException {
+    private final Class> runnableClass;
+    private final String errorMessage;
+
+    public CommandConfigurationException(Class> runnableClass, String errorMessage) {
+        this.runnableClass = runnableClass;
+        this.errorMessage = errorMessage;
+    }
+
+    public Class> getRunnableClass() {
+        return runnableClass;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandException.java
new file mode 100644
index 00000000..12cff7a0
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class CommandException extends Exception
+{
+
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandNotFoundException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandNotFoundException.java
new file mode 100644
index 00000000..04e9e5b7
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/CommandNotFoundException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class CommandNotFoundException extends CommandException {
+    private final String commandName;
+
+    public CommandNotFoundException(String commandName) {
+        this.commandName = commandName;
+    }
+
+    public String getCommandName() {
+        return commandName;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ExtraArgumentException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ExtraArgumentException.java
new file mode 100644
index 00000000..5a8fd926
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ExtraArgumentException.java
@@ -0,0 +1,7 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class ExtraArgumentException extends ArgumentException {
+    public ExtraArgumentException(String argument, int position) {
+        super(argument, position);
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagAlreadyDefinedException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagAlreadyDefinedException.java
new file mode 100644
index 00000000..d71f8340
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagAlreadyDefinedException.java
@@ -0,0 +1,16 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Flag;
+
+public class FlagAlreadyDefinedException extends ArgumentException {
+    private final Flag flag;
+
+    public FlagAlreadyDefinedException(Flag flag, String argument, int position) {
+        super(argument, position);
+        this.flag = flag;
+    }
+
+    public Flag getFlag() {
+        return flag;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagMissingValueException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagMissingValueException.java
new file mode 100644
index 00000000..cf8a5d3d
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/FlagMissingValueException.java
@@ -0,0 +1,18 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Flag;
+
+import java.util.Optional;
+
+public class FlagMissingValueException extends ArgumentException {
+    private final Flag flag;
+
+    public FlagMissingValueException(Flag flag, int position) {
+        super(Optional.empty(), Optional.of(position));
+        this.flag = flag;
+    }
+
+    public Flag getFlag() {
+        return flag;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/InvalidArgumentException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/InvalidArgumentException.java
new file mode 100644
index 00000000..6b56457e
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/InvalidArgumentException.java
@@ -0,0 +1,22 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import java.util.Optional;
+
+public class InvalidArgumentException extends ArgumentException {
+    private final String parseErrorMessage;
+    private final Optional parseErrorCause;
+
+    public InvalidArgumentException(ParameterTypeConverterException sourceException, String argument, int position) {
+        super(argument, position);
+        this.parseErrorMessage = sourceException.getParseErrorMessage();
+        this.parseErrorCause = sourceException.getParseErrorCause();
+    }
+
+    public String getParseErrorMessage() {
+        return parseErrorMessage;
+    }
+
+    public Optional getParseErrorCause() {
+        return parseErrorCause;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingArgumentException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingArgumentException.java
new file mode 100644
index 00000000..db819108
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingArgumentException.java
@@ -0,0 +1,5 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class MissingArgumentException extends ArgumentException {
+
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingParameterException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingParameterException.java
new file mode 100644
index 00000000..4f23cf43
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingParameterException.java
@@ -0,0 +1,15 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Parameter;
+
+public class MissingParameterException extends ArgumentException {
+    private final Parameter flag;
+
+    public MissingParameterException(Parameter flag) {
+        this.flag = flag;
+    }
+
+    public Parameter getFlag() {
+        return flag;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingRequiredFlagException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingRequiredFlagException.java
new file mode 100644
index 00000000..ce5c8bb1
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingRequiredFlagException.java
@@ -0,0 +1,15 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Flag;
+
+public class MissingRequiredFlagException extends ArgumentException {
+    private final Flag flag;
+
+    public MissingRequiredFlagException(Flag flag) {
+        this.flag = flag;
+    }
+
+    public Flag getFlag() {
+        return flag;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingSubcommandException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingSubcommandException.java
new file mode 100644
index 00000000..23c83b6e
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/MissingSubcommandException.java
@@ -0,0 +1,15 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Command;
+
+public class MissingSubcommandException extends ArgumentException {
+    private final Command> parentCommand;
+
+    public MissingSubcommandException(Command> parentCommand) {
+        this.parentCommand = parentCommand;
+    }
+
+    public Command> getParentCommand() {
+        return parentCommand;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ParameterTypeConverterException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ParameterTypeConverterException.java
new file mode 100644
index 00000000..7c6e65ea
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/ParameterTypeConverterException.java
@@ -0,0 +1,29 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import java.util.Optional;
+
+public class ParameterTypeConverterException extends Exception {
+    private final String parseErrorMessage;
+    private final Optional cause;
+
+    public ParameterTypeConverterException(String parseErrorMessage) {
+        this(parseErrorMessage, Optional.empty());
+    }
+
+    public ParameterTypeConverterException(String parseErrorMessage, Throwable cause) {
+        this(parseErrorMessage, Optional.of(cause));
+    }
+
+    public ParameterTypeConverterException(String parseErrorMessage, Optional cause) {
+        this.parseErrorMessage = parseErrorMessage;
+        this.cause = cause;
+    }
+
+    public String getParseErrorMessage() {
+        return parseErrorMessage;
+    }
+
+    public Optional getParseErrorCause() {
+        return cause;
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnhandledParameterType.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnhandledParameterType.java
new file mode 100644
index 00000000..075dd8ae
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnhandledParameterType.java
@@ -0,0 +1,27 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import java.lang.reflect.Field;
+
+public class UnhandledParameterType extends CommandConfigurationException {
+    private final Class> type;
+    private final Field field;
+
+    public UnhandledParameterType(Class> type, Field field) {
+        super(field.getDeclaringClass(), "");
+        this.type = type;
+        this.field = field;
+    }
+
+    public Class> getType() {
+        return type;
+    }
+
+    private Field getField() {
+        return field;
+    }
+
+    @Override
+    public String getMessage() {
+        return "Type error in " + field.getDeclaringClass().getName() + "." + field.getName() + " : no parameter type converters found for type " + type.getName();
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownFlagException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownFlagException.java
new file mode 100644
index 00000000..965acaa5
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownFlagException.java
@@ -0,0 +1,7 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+public class UnknownFlagException extends ArgumentException {
+    public UnknownFlagException(String argument, int position) {
+        super(argument, position);
+    }
+}
diff --git a/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownSubcommandException.java b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownSubcommandException.java
new file mode 100644
index 00000000..a7833360
--- /dev/null
+++ b/src/main/java/fr/zcraft/zlib/components/commands2/exceptions/UnknownSubcommandException.java
@@ -0,0 +1,16 @@
+package fr.zcraft.zlib.components.commands2.exceptions;
+
+import fr.zcraft.zlib.components.commands2.Command;
+
+public class UnknownSubcommandException extends ArgumentException {
+    private final Command> parentCommand;
+
+    public UnknownSubcommandException(Command> parentCommand, String argument, int position) {
+        super(argument, position);
+        this.parentCommand = parentCommand;
+    }
+
+    public Command> getParentCommand() {
+        return parentCommand;
+    }
+}
diff --git a/src/test/java/fr/zcraft/zlib/components/commands2/CommandsTest.java b/src/test/java/fr/zcraft/zlib/components/commands2/CommandsTest.java
new file mode 100644
index 00000000..692fb8fa
--- /dev/null
+++ b/src/test/java/fr/zcraft/zlib/components/commands2/CommandsTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2;
+
+import fr.zcraft.zlib.components.commands2.bb.BBCommand;
+import fr.zcraft.zlib.components.commands2.exceptions.CommandException;
+import fr.zcraft.zlib.components.commands2.iom.CreateCommand;
+import fr.zcraft.zlib.components.commands2.iom.IoMCommand;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Optional;
+
+public class CommandsTest
+{
+    static private final CommandSender sender = new CommandSender();
+    @Test
+    public void iomTest() throws CommandException, URISyntaxException {
+        Commands.register(IoMCommand.class, "maptool");
+        Commands.register(CreateCommand.class, "tomap");
+
+        Context> mapToolContext = Commands.makeContext("maptool", sender, new String[]{"list"});
+        Assert.assertEquals(Optional.of(IoMCommand.LIST), mapToolContext.getParentContext().map(Context::getCommandRunnable));
+        Assert.assertTrue(mapToolContext.getCommandRunnable() instanceof IoMCommand.ListCommand);
+
+        Context> createContext = Commands.makeContext("maptool", sender, new String[]{"create", "http://example.com/test.png", "-w", "42", "--stretch"});
+        Assert.assertTrue(createContext.getCommandRunnable() instanceof CreateCommand);
+        CreateCommand createRunnable = (CreateCommand) createContext.getCommandRunnable();
+
+        Assert.assertEquals(new URI("http://example.com/test.png"), createRunnable.imageURI);
+        Assert.assertEquals(Optional.of(42), createRunnable.width);
+        Assert.assertEquals(Optional.empty(), createRunnable.height);
+        Assert.assertEquals(true, createRunnable.stretch);
+        Assert.assertEquals(false, createRunnable.cover);
+
+    }
+
+    @Test
+    public void bbTest() throws CommandException {
+        Commands.registerParameterTypeConverter(new BBCommand.BBItemParamConverter());
+        Commands.register(BBCommand.class, "bb");
+
+        Context> bbContext = Commands.makeContext("bb", sender, new String[]{"saw"});
+        Assert.assertTrue(bbContext.getCommandRunnable() instanceof BBCommand);
+        BBCommand bbRunnable = (BBCommand) bbContext.getCommandRunnable();
+        Assert.assertEquals("saw", bbRunnable.item.itemType);
+        Assert.assertEquals(Optional.empty(), bbRunnable.amount);
+    }
+}
diff --git a/src/test/java/fr/zcraft/zlib/components/commands2/bb/BBCommand.java b/src/test/java/fr/zcraft/zlib/components/commands2/bb/BBCommand.java
new file mode 100644
index 00000000..593d3828
--- /dev/null
+++ b/src/test/java/fr/zcraft/zlib/components/commands2/bb/BBCommand.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright or © or Copr. ZLib contributors (2015 - 2016)
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+
+package fr.zcraft.zlib.components.commands2.bb;
+
+import fr.zcraft.zlib.components.commands2.CommandRunnable;
+import fr.zcraft.zlib.components.commands2.ParameterTypeConverter;
+import fr.zcraft.zlib.components.commands2.exceptions.ParameterTypeConverterException;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+public class BBCommand implements CommandRunnable {
+    public BBItem item;
+    public Optional amount;
+
+    static public class BBItem {
+        static public final String[] items = {"saw", "stonecutter"};
+        public final String itemType;
+
+        public BBItem(String itemType) {
+            this.itemType = itemType;
+        }
+    }
+
+    static public class BBItemParamConverter implements ParameterTypeConverter {
+        @Override
+        public Class getType() {
+            return BBItem.class;
+        }
+
+        @Override
+        public BBItem fromArgument(String argument) throws ParameterTypeConverterException {
+            argument = argument.toLowerCase();
+            if(!Arrays.asList(BBItem.items).contains(argument)) throw new ParameterTypeConverterException("Invalid item name");
+            return new BBItem(argument);
+        }
+    }
+}
diff --git a/src/test/java/fr/zcraft/zlib/components/commands2/iom/CreateCommand.java b/src/test/java/fr/zcraft/zlib/components/commands2/iom/CreateCommand.java
new file mode 100644
index 00000000..003331e9
--- /dev/null
+++ b/src/test/java/fr/zcraft/zlib/components/commands2/iom/CreateCommand.java
@@ -0,0 +1,35 @@
+package fr.zcraft.zlib.components.commands2.iom;
+
+import fr.zcraft.zlib.components.commands2.CommandRunnable;
+import fr.zcraft.zlib.components.commands2.Context;
+import fr.zcraft.zlib.components.commands2.annotations.About;
+import fr.zcraft.zlib.components.commands2.annotations.Flag;
+
+import java.net.URI;
+import java.util.Optional;
+
+public class CreateCommand implements CommandRunnable {
+
+    @About("The URI")
+    public URI imageURI;
+
+    @About("The width")
+    @Flag(shortName = "w")
+    public Optional width;
+
+    @About("The height")
+    @Flag(shortName = "h")
+    public Optional height;
+
+    @Flag
+    public boolean stretch;
+
+    @Flag
+    public boolean cover;
+
+    @Override
+    public void run(Context context) {
+        System.out.println("Hello world !");
+    }
+
+}
diff --git a/src/test/java/fr/zcraft/zlib/components/commands2/iom/IoMCommand.java b/src/test/java/fr/zcraft/zlib/components/commands2/iom/IoMCommand.java
new file mode 100644
index 00000000..de6d592e
--- /dev/null
+++ b/src/test/java/fr/zcraft/zlib/components/commands2/iom/IoMCommand.java
@@ -0,0 +1,22 @@
+package fr.zcraft.zlib.components.commands2.iom;
+
+import fr.zcraft.zlib.components.commands2.exceptions.CommandException;
+import fr.zcraft.zlib.components.commands2.CommandRunnable;
+import fr.zcraft.zlib.components.commands2.Context;
+import fr.zcraft.zlib.components.commands2.annotations.Subcommand;
+
+public enum IoMCommand implements CommandRunnable {
+    @Subcommand(CreateCommand.class)
+    CREATE,
+    @Subcommand(ListCommand.class)
+    LIST,
+    ;
+
+    static public class ListCommand implements CommandRunnable {
+
+        @Override
+        public void run(Context context) throws CommandException {
+
+        }
+    }
+}
diff --git a/src/test/resources/help/belovedblocks.fr_FR.txt b/src/test/resources/help/belovedblocks.fr_FR.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks.fr_FR.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks.txt b/src/test/resources/help/belovedblocks.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give.fr_FR.txt b/src/test/resources/help/belovedblocks/give.fr_FR.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give.fr_FR.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give.txt b/src/test/resources/help/belovedblocks/give.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give/block.fr_FR.txt b/src/test/resources/help/belovedblocks/give/block.fr_FR.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give/block.fr_FR.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give/block.txt b/src/test/resources/help/belovedblocks/give/block.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give/block.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give/tool.fr_FR.txt b/src/test/resources/help/belovedblocks/give/tool.fr_FR.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give/tool.fr_FR.txt
@@ -0,0 +1 @@
+ 
diff --git a/src/test/resources/help/belovedblocks/give/tool.txt b/src/test/resources/help/belovedblocks/give/tool.txt
new file mode 100644
index 00000000..8d1c8b69
--- /dev/null
+++ b/src/test/resources/help/belovedblocks/give/tool.txt
@@ -0,0 +1 @@
+