diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 8a0e6a6a..79d41fb2 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,10 +6,14 @@
+
+
+
+
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index c0bce708..de3187bd 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -2,6 +2,7 @@
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 24a060cb..78462726 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,6 +3,7 @@
+
\ No newline at end of file
diff --git a/example/acf-example.iml b/example/acf-example.iml
new file mode 100644
index 00000000..c4d04c3e
--- /dev/null
+++ b/example/acf-example.iml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ PAPER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/dependency-reduced-pom.xml b/example/dependency-reduced-pom.xml
new file mode 100644
index 00000000..bb545d00
--- /dev/null
+++ b/example/dependency-reduced-pom.xml
@@ -0,0 +1,104 @@
+
+
+ 4.0.0
+ co.aikar.commands
+ example-plugin
+ ACFExample
+ 1.0-SNAPSHOT
+ Example / Test for ACF
+ https://github.com/aikar/commands
+
+ clean package
+
+
+ true
+ src/main/resources
+
+
+
+
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+ maven-shade-plugin
+ 2.4
+
+
+ package
+
+ shade
+
+
+ true
+
+
+
+
+
+
+
+
+ destroystokyo-repo
+ https://repo.destroystokyo.com/repository/maven-public/
+
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+
+
+
+ com.destroystokyo.paper
+ paper-api
+ 1.11.2-R0.1-SNAPSHOT
+ provided
+
+
+ commons-lang
+ commons-lang
+
+
+ json-simple
+ com.googlecode.json-simple
+
+
+ jsr305
+ com.google.code.findbugs
+
+
+ guava
+ com.google.guava
+
+
+ gson
+ com.google.code.gson
+
+
+ ebean
+ org.avaje
+
+
+ snakeyaml
+ org.yaml
+
+
+ bungeecord-chat
+ net.md-5
+
+
+ asm-all
+ org.ow2.asm
+
+
+
+
+
+ UTF-8
+
+
+
diff --git a/example/pom.xml b/example/pom.xml
new file mode 100644
index 00000000..c302071b
--- /dev/null
+++ b/example/pom.xml
@@ -0,0 +1,108 @@
+
+
+
+
+ 4.0.0
+
+ co.aikar.commands
+ example-plugin
+ 1.0-SNAPSHOT
+ jar
+
+ ACFExample
+
+ Example / Test for ACF
+
+ UTF-8
+
+ https://github.com/aikar/commands
+
+
+ ${project.artifactId}
+ clean package
+
+
+ 3.1
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.4.1
+
+ ${project.build.directory}/dependency-reduced-pom.xml
+
+
+
+ package
+
+ shade
+
+
+ true
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ destroystokyo-repo
+ https://repo.destroystokyo.com/repository/maven-public/
+
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+
+
+
+
+ com.destroystokyo.paper
+ paper-api
+ 1.11.2-R0.1-SNAPSHOT
+ provided
+
+
+ co.aikar.commands
+ acf
+ 0.2.0-SNAPSHOT
+
+
+
diff --git a/example/src/main/java/co/aikar/commands/example/ACFExample.java b/example/src/main/java/co/aikar/commands/example/ACFExample.java
new file mode 100644
index 00000000..ae5bd593
--- /dev/null
+++ b/example/src/main/java/co/aikar/commands/example/ACFExample.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package co.aikar.commands.example;
+
+import co.aikar.commands.ACF;
+import co.aikar.commands.CommandManager;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public final class ACFExample extends JavaPlugin {
+
+ private static ACFExample plugin;
+ private static CommandManager commandManager;
+ @Override
+ public void onEnable() {
+ plugin = this;
+ registerCommands();
+ }
+
+ private void registerCommands() {
+ commandManager = ACF.createManager(this);
+ commandManager.getCommandContexts().registerContext(SomeObject.class, SomeObject.getContextResolver());
+ commandManager.registerCommand(new SomeCommand());
+ }
+
+ public static ACFExample getPlugin() {
+ return plugin;
+ }
+
+ public static CommandManager getCommandManager() {
+ return commandManager;
+ }
+}
diff --git a/example/src/main/java/co/aikar/commands/example/SomeCommand.java b/example/src/main/java/co/aikar/commands/example/SomeCommand.java
new file mode 100644
index 00000000..e94e63fd
--- /dev/null
+++ b/example/src/main/java/co/aikar/commands/example/SomeCommand.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package co.aikar.commands.example;
+
+import co.aikar.commands.BaseCommand;
+import co.aikar.commands.annotation.CommandAlias;
+import co.aikar.commands.annotation.CommandPermission;
+import co.aikar.commands.annotation.Default;
+import co.aikar.commands.annotation.Optional;
+import co.aikar.commands.annotation.Subcommand;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+@CommandAlias("acf|somecommand|sc|somcom")
+public class SomeCommand extends BaseCommand {
+
+ @Subcommand("test")
+ @CommandAlias("acftest|acft")
+ public void onCommand(CommandSender sender, SomeObject someObject) {
+ sender.sendMessage("You got an object of type: " + someObject.getClass().getName() + " with a value of: " + someObject.getValue());
+ }
+
+ @Subcommand("admin")
+ @CommandPermission("some.perm")
+ @CommandAlias("acfadmin|acfa")
+ public void onAdminCommand(Player player) {
+ player.sendMessage("You got permission!");
+ }
+
+ @Subcommand("optional")
+ @CommandAlias("acfoptional|acfo")
+ public void onOptional(CommandSender sender, @Optional String opt) {
+ if (opt == null) {
+ sender.sendMessage("You did not supply an option.");
+ } else {
+ sender.sendMessage("You supplied: " + opt);
+ }
+ }
+ @Subcommand("default")
+ @CommandAlias("acfdefault|acfd")
+ public void onTestDefault(CommandSender sender, @Default("Unknown User") String name) {
+ sender.sendMessage("Hello, " + name);
+ }
+
+
+}
diff --git a/example/src/main/java/co/aikar/commands/example/SomeObject.java b/example/src/main/java/co/aikar/commands/example/SomeObject.java
new file mode 100644
index 00000000..0f6064f6
--- /dev/null
+++ b/example/src/main/java/co/aikar/commands/example/SomeObject.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package co.aikar.commands.example;
+
+import co.aikar.commands.CommandContexts;
+import co.aikar.commands.InvalidCommandArgument;
+import co.aikar.commands.annotation.CommandCompletion;
+import co.aikar.commands.contexts.ContextResolver;
+
+public abstract class SomeObject {
+ private final Integer thisValue;
+
+ SomeObject(Integer thisValue) {
+ this.thisValue = thisValue;
+ }
+ public Integer getValue() {
+ return this.thisValue;
+ }
+
+ public static ContextResolver getContextResolver() {
+ return (c) -> {
+ String first = c.popFirstArg();
+ if (first == null) {
+ throw new InvalidCommandArgument("Must supply a number");
+ }
+ if ("1".equals(first)) {
+ return new Test1();
+ } else if ("2".equals(first)) {
+ return new Test2();
+ } else {
+ try {
+ return new TestOther(Integer.parseInt(first));
+ } catch (NumberFormatException ignored) {
+ throw new InvalidCommandArgument("Must be a valid number");
+ }
+ }
+ };
+ }
+
+ public static class Test1 extends SomeObject {
+ Test1() {
+ super(1);
+ }
+ }
+ public static class Test2 extends SomeObject {
+ Test2() {
+ super(2);
+ }
+ }
+ public static class TestOther extends SomeObject {
+ TestOther(Integer other) {
+ super(other);
+ }
+ }
+}
diff --git a/example/src/main/resources/plugin.yml b/example/src/main/resources/plugin.yml
new file mode 100644
index 00000000..75eded25
--- /dev/null
+++ b/example/src/main/resources/plugin.yml
@@ -0,0 +1,7 @@
+name: ACFExample
+version: ${project.version}
+main: co.aikar.commands.example.ACFExample
+prefix: ACF
+authors: [Aikar]
+description: Example / Test for ACF
+website: https://github.com/aikar/commands