| 
						 
						
						
						
						 
					 | 
					 | 
					@@ -1,27 +1,53 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					package envoy.client.data.commands;
 | 
					 | 
					 | 
					 | 
					package envoy.client.data.commands;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.*;
 | 
					 | 
					 | 
					 | 
					import java.util.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import java.util.concurrent.atomic.AtomicBoolean;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.function.Consumer;
 | 
					 | 
					 | 
					 | 
					import java.util.function.Consumer;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.logging.*;
 | 
					 | 
					 | 
					 | 
					import java.util.logging.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.regex.Pattern;
 | 
					 | 
					 | 
					 | 
					import java.util.regex.Pattern;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.stream.Collectors;
 | 
					 | 
					 | 
					 | 
					import java.util.stream.Collectors;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import javafx.application.Platform;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import javafx.scene.control.Alert;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import javafx.scene.control.Alert.AlertType;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import envoy.util.EnvoyLog;
 | 
					 | 
					 | 
					 | 
					import envoy.util.EnvoyLog;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/**
 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * This class stores all {@link SystemCommand}s used.
 | 
					 | 
					 | 
					 | 
					 * Stores all {@link SystemCommand}s used.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * SystemCommands can be called using an activator char and the text that needs
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * to be present behind the activator.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * Additionally offers the option to request recommendations for a partial input
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * String.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 *
 | 
					 | 
					 | 
					 | 
					 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @author Leon Hofmeister
 | 
					 | 
					 | 
					 | 
					 * @author Leon Hofmeister
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
					 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */
 | 
					 | 
					 | 
					 | 
					 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					public final class SystemCommandMap {
 | 
					 | 
					 | 
					 | 
					public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						private final Map<String, SystemCommand> systemCommands = new HashMap<>();
 | 
					 | 
					 | 
					 | 
						private final Character						activator;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
						private final Map<String, SystemCommand>	systemCommands	= new HashMap<>();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						private final Pattern commandPattern = Pattern.compile("^[a-zA-Z0-9_:!\\(\\)\\?\\.\\,\\;\\-]+$");
 | 
					 | 
					 | 
					 | 
						private final Pattern						commandPattern	= Pattern.compile("^[a-zA-Z0-9_:!/\\(\\)\\?\\.\\,\\;\\-]+$");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						private static final Logger logger = EnvoyLog.getLogger(SystemCommandMap.class);
 | 
					 | 
					 | 
					 | 
						private static final Logger logger = EnvoyLog.getLogger(SystemCommandMap.class);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * Creates a new {@code SystemCommandMap} with the given char as activator.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * If this Character is null, any text used as input will be treated as a system
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * command.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @param activator the char to use as activator for commands
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.3-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						public SystemCommandMap(Character activator) { this.activator = activator; }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * Creates a new {@code SystemCommandMap} with '/' as activator.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.3-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						public SystemCommandMap() { activator = '/'; }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Adds a new command to the map if the command name is valid.
 | 
					 | 
					 | 
					 | 
						 * Adds a new command to the map if the command name is valid.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -39,19 +65,16 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * This method checks if the input String is a key in the map and returns the
 | 
					 | 
					 | 
					 | 
						 * This method checks if the input String is a key in the map and returns the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * wrapped System command if present.
 | 
					 | 
					 | 
					 | 
						 * wrapped System command if present.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * It will return an empty optional if the value after the slash is not a key in
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * the map, which is a valid case (i.e. input="3/4" and "4" is not a key in the
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * map).
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * <p>
 | 
					 | 
					 | 
					 | 
						 * <p>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Usage example:<br>
 | 
					 | 
					 | 
					 | 
						 * Usage example:<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code SystemCommandMap systemCommands = new SystemCommandMap();}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code SystemCommandMap systemCommands = new SystemCommandMap('*');}<br>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code Button button = new  Button();}
 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.add("example", new SystemCommand(text -> {}, 1, null,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code systemCommands.add("example", text -> button.setText(text.get(0), 1);}<br>
 | 
					 | 
					 | 
					 | 
						 * ""));}<br>
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code ....}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code ....}<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * user input: {@code "/example xyz ..."}<br>
 | 
					 | 
					 | 
					 | 
						 * user input: {@code "*example xyz ..."}<br>
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code systemCommands.get("example xyz ...")} or
 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.get("example xyz ...")} or
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code systemCommands.get("/example xyz ...")}
 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.get("*example xyz ...")}
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * result: {@code Optional<SystemCommand>}
 | 
					 | 
					 | 
					 | 
						 * result: {@code Optional<SystemCommand>.get() != null}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param input the input string given by the user
 | 
					 | 
					 | 
					 | 
						 * @param input the input string given by the user
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @return the wrapped system command, if present
 | 
					 | 
					 | 
					 | 
						 * @return the wrapped system command, if present
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -60,33 +83,36 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public Optional<SystemCommand> get(String input) { return Optional.ofNullable(systemCommands.get(getCommand(input.toLowerCase()))); }
 | 
					 | 
					 | 
					 | 
						public Optional<SystemCommand> get(String input) { return Optional.ofNullable(systemCommands.get(getCommand(input.toLowerCase()))); }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * This method ensures that the "/" of a {@link SystemCommand} is stripped.<br>
 | 
					 | 
					 | 
					 | 
						 * This method ensures that the activator of a {@link SystemCommand} is
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * stripped.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * It only checks the word beginning from the first non-blank position in the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * input.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * It returns the command as (most likely) entered as key in the map for the
 | 
					 | 
					 | 
					 | 
						 * It returns the command as (most likely) entered as key in the map for the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * first word of the text.<br>
 | 
					 | 
					 | 
					 | 
						 * first word of the text.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * It should only be called on strings that contain a "/" at position 0/-1.
 | 
					 | 
					 | 
					 | 
						 * Activators in the middle of the word will be disregarded.
 | 
				
			
			
				
				
					
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param raw the input
 | 
					 | 
					 | 
					 | 
						 * @param raw the input
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @return the command as entered in the map
 | 
					 | 
					 | 
					 | 
						 * @return the command as entered in the map
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @apiNote this method will (most likely) not return anything useful if
 | 
					 | 
					 | 
					 | 
						 * @apiNote this method will (most likely) not return anything useful if
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *          whatever is entered after the slash is not a system command. Only
 | 
					 | 
					 | 
					 | 
						 *          whatever is entered after the activator is not a system command.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *          exception: for recommendation purposes.
 | 
					 | 
					 | 
					 | 
						 *          Only exception: for recommendation purposes.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public String getCommand(String raw) {
 | 
					 | 
					 | 
					 | 
						public String getCommand(String raw) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var trimmed = raw.stripLeading();
 | 
					 | 
					 | 
					 | 
							final var trimmed = raw.stripLeading();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// Entering only a slash should not throw an error
 | 
					 | 
					 | 
					 | 
							// Entering only the activator should not throw an error
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (trimmed.length() == 1 && trimmed.charAt(0) == '/') return "";
 | 
					 | 
					 | 
					 | 
							if (trimmed.length() == 1 && activator != null && activator.equals(trimmed.charAt(0))) return "";
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							else {
 | 
					 | 
					 | 
					 | 
							else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								final var index = trimmed.indexOf(' ');
 | 
					 | 
					 | 
					 | 
								final var index = trimmed.indexOf(' ');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return trimmed.substring(trimmed.charAt(0) == '/' ? 1 : 0, index < 1 ? trimmed.length() : index);
 | 
					 | 
					 | 
					 | 
								return trimmed.substring(activator != null && activator.equals(trimmed.charAt(0)) ? 1 : 0, index < 1 ? trimmed.length() : index);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							}
 | 
					 | 
					 | 
					 | 
							}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Examines whether a key can be put in the map and logs it with
 | 
					 | 
					 | 
					 | 
						 * Examines whether a key can be put in the map and logs it with
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code Level.WARNING} if that key violates API constrictions.<br>
 | 
					 | 
					 | 
					 | 
						 * {@code Level.WARNING} if that key violates API constrictions.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * (allowed chars are <b>a-zA-Z0-9_:!()?.,;-</b>)
 | 
					 | 
					 | 
					 | 
						 * (allowed chars are <b>a-zA-Z0-9_:!/()?.,;-</b>)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * <p>
 | 
					 | 
					 | 
					 | 
						 * <p>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * The approach to not throw an exception was taken so that an ugly try-catch
 | 
					 | 
					 | 
					 | 
						 * The approach to not throw an exception was taken so that an ugly try-catch
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * block for every addition to the system commands map could be avoided, an
 | 
					 | 
					 | 
					 | 
						 * block for every addition to the system commands map could be avoided, an
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -100,59 +126,86 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var valid = commandPattern.matcher(command).matches();
 | 
					 | 
					 | 
					 | 
							final var valid = commandPattern.matcher(command).matches();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!valid) logger.log(Level.WARNING,
 | 
					 | 
					 | 
					 | 
							if (!valid) logger.log(Level.WARNING,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									"The command \"" + command
 | 
					 | 
					 | 
					 | 
									"The command \"" + command
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											+ "\" is not valid. As it will cause problems in execution, it will not be entered into the map. Only the characters "
 | 
					 | 
					 | 
					 | 
											+ "\" is not valid. As it might cause problems when executed, it will not be entered into the map. Only the characters "
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											+ commandPattern + "are allowed");
 | 
					 | 
					 | 
					 | 
											+ commandPattern + "are allowed");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return valid;
 | 
					 | 
					 | 
					 | 
							return valid;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Takes a 'raw' string (the whole input) and checks if "/" is the first visible
 | 
					 | 
					 | 
					 | 
						 * Takes a 'raw' string (the whole input) and checks if the activator is the
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * character and then checks if a command is present after that "/". If that is
 | 
					 | 
					 | 
					 | 
						 * first visible character and then checks if a command is present after that
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * the case, it will be executed.
 | 
					 | 
					 | 
					 | 
						 * activator. If that is the case, it will be executed.
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * <p>
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param raw the raw input string
 | 
					 | 
					 | 
					 | 
						 * @param raw the raw input string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @return whether a command could be found
 | 
					 | 
					 | 
					 | 
						 * @return whether a command could be found and successfully executed
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public boolean executeIfAnyPresent(String raw) {
 | 
					 | 
					 | 
					 | 
						public boolean executeIfPresent(String raw) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// possibly a command was detected and could be executed
 | 
					 | 
					 | 
					 | 
							// possibly a command was detected and could be executed
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	raw2			= raw.stripLeading();
 | 
					 | 
					 | 
					 | 
							final var	raw2			= raw.stripLeading();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	commandFound	= raw2.startsWith("/") ? executeIfPresent(raw2) : false;
 | 
					 | 
					 | 
					 | 
							final var	commandFound	= activator == null || raw2.startsWith(activator.toString()) ? executeAvailableCommand(raw2) : false;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// the command was executed successfully - no further checking needed
 | 
					 | 
					 | 
					 | 
							// the command was executed successfully - no further checking needed
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (commandFound) logger.log(Level.FINE, "executed system command " + getCommand(raw2));
 | 
					 | 
					 | 
					 | 
							if (commandFound) logger.log(Level.FINE, "executed system command " + getCommand(raw2));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return commandFound;
 | 
					 | 
					 | 
					 | 
							return commandFound;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * Retrieves the recommendations based on the current input entered.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * The first word is used for the recommendations and
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * it does not matter if the activator is at its beginning or not.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * If recommendations are present, the given function will be executed on the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * recommendations.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * Otherwise nothing will be done.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @param input  the input string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @param action the action that should be taken for the recommendations, if any
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 *               are present
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						public void requestRecommendations(String input, Consumer<Set<String>> action) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							final var partialCommand = getCommand(input);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							// Get the expected commands
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							final var recommendations = recommendCommands(partialCommand);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (recommendations.isEmpty()) return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							// Execute the given action
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							else action.accept(recommendations);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * This method checks if the input String is a key in the map and executes the
 | 
					 | 
					 | 
					 | 
						 * This method checks if the input String is a key in the map and executes the
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * wrapped System command if present.
 | 
					 | 
					 | 
					 | 
						 * wrapped System command if present.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Its intended usage is after a "/" has been detected in the input String.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * It will do nothing if the value after the slash is not a key in
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * the map, which is a valid case (i.e. input="3/4" and "4" is not a key in the
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * map).
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * <p>
 | 
					 | 
					 | 
					 | 
						 * <p>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Usage example:<br>
 | 
					 | 
					 | 
					 | 
						 * Usage example:<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code SystemCommandMap systemCommands = new SystemCommandMap();}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code SystemCommandMap systemCommands = new SystemCommandMap('*');}<br>
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code Button button = new Button();}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code Button button = new Button();}<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code systemCommands.add("example", (words)-> button.setText(words.get(0), 1);}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.add("example", new SystemCommand(text ->
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * {button.setText(text.get(0))}, 1, null,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * ""));}<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code ....}<br>
 | 
					 | 
					 | 
					 | 
						 * {@code ....}<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * user input: {@code "/example xyz ..."}<br>
 | 
					 | 
					 | 
					 | 
						 * user input: {@code "*example xyz ..."}<br>
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * {@code systemCommands.executeIfPresent("example xyz ...")}
 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.executeIfPresent("example xyz ...")} or
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * {@code systemCommands.executeIfPresent("*example xyz ...")}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * result: {@code button.getText()=="xyz"}
 | 
					 | 
					 | 
					 | 
						 * result: {@code button.getText()=="xyz"}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param input the input string given by the user
 | 
					 | 
					 | 
					 | 
						 * @param input the input string given by the user
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @return whether a command could be found
 | 
					 | 
					 | 
					 | 
						 * @return whether a command could be found and successfully executed
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public boolean executeIfPresent(String input) {
 | 
					 | 
					 | 
					 | 
						private boolean executeAvailableCommand(String input) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	command	= getCommand(input);
 | 
					 | 
					 | 
					 | 
							final var	command			= getCommand(input);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	value	= get(command);
 | 
					 | 
					 | 
					 | 
							final var	value			= get(command);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							final var	commandExecuted	= new AtomicBoolean(value.isPresent());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							value.ifPresent(systemCommand -> {
 | 
					 | 
					 | 
					 | 
							value.ifPresent(systemCommand -> {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// Splitting the String so that the leading command including the first " " is
 | 
					 | 
					 | 
					 | 
								// Splitting the String so that the leading command including the first " " is
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// removed and only as many following words as allowed by the system command
 | 
					 | 
					 | 
					 | 
								// removed and only as many following words as allowed by the system command
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// persist
 | 
					 | 
					 | 
					 | 
								// persist
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								final var arguments = extractArguments(input, systemCommand);
 | 
					 | 
					 | 
					 | 
								final var arguments = extractArguments(input, systemCommand);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// Executing the function
 | 
					 | 
					 | 
					 | 
								// Executing the function
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								try {
 | 
					 | 
					 | 
					 | 
								try {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									systemCommand.call(arguments);
 | 
					 | 
					 | 
					 | 
									systemCommand.call(arguments);
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -161,11 +214,23 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											String.format(
 | 
					 | 
					 | 
					 | 
											String.format(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													"System command %s could not be performed correctly because the user is a dumbass and could not write a parseable number.",
 | 
					 | 
					 | 
					 | 
													"System command %s could not be performed correctly because the user is a dumbass and could not write a parseable number.",
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
													command));
 | 
					 | 
					 | 
					 | 
													command));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									Platform.runLater(() -> {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										final var alert = new Alert(AlertType.ERROR);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										alert.setContentText("Please enter a readable number as argument.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										alert.showAndWait();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									commandExecuted.set(false);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} catch (final Exception e) {
 | 
					 | 
					 | 
					 | 
								} catch (final Exception e) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									logger.log(Level.WARNING, "System command " + command + " threw an exception: ", e);
 | 
					 | 
					 | 
					 | 
									logger.log(Level.WARNING, "System command " + command + " threw an exception: ", e);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									Platform.runLater(() -> {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										final var alert = new Alert(AlertType.ERROR);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										alert.setContentText("Could not execute system command: Internal error. Please insult the responsible programmer.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
										alert.showAndWait();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									commandExecuted.set(false);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								}
 | 
					 | 
					 | 
					 | 
								}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							});
 | 
					 | 
					 | 
					 | 
							});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return value.isPresent();
 | 
					 | 
					 | 
					 | 
							return commandExecuted.get();
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -177,12 +242,15 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						private List<String> extractArguments(String input, SystemCommand systemCommand) {
 | 
					 | 
					 | 
					 | 
						private List<String> extractArguments(String input, SystemCommand systemCommand) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// no more arguments follow after the command (e.g. text = "/DABR")
 | 
					 | 
					 | 
					 | 
							// no more arguments follow after the command (e.g. text = "/DABR")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var indexOfSpace = input.indexOf(" ");
 | 
					 | 
					 | 
					 | 
							final var indexOfSpace = input.indexOf(" ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (indexOfSpace < 0) return supplementDefaults(new String[] {}, systemCommand);
 | 
					 | 
					 | 
					 | 
							if (indexOfSpace < 0) return supplementDefaults(new String[] {}, systemCommand);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// the arguments behind a system command
 | 
					 | 
					 | 
					 | 
							// the arguments behind a system command
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	remainingString		= input.substring(indexOfSpace + 1);
 | 
					 | 
					 | 
					 | 
							final var	remainingString		= input.substring(indexOfSpace + 1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	numberOfArguments	= systemCommand.getNumberOfArguments();
 | 
					 | 
					 | 
					 | 
							final var	numberOfArguments	= systemCommand.getNumberOfArguments();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// splitting those arguments and supplying default values
 | 
					 | 
					 | 
					 | 
							// splitting those arguments and supplying default values
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	textArguments		= remainingString.split(" ", -1);
 | 
					 | 
					 | 
					 | 
							final var	textArguments		= remainingString.split(" ", -1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var	originalArguments	= numberOfArguments >= 0 ? Arrays.copyOfRange(textArguments, 0, numberOfArguments) : textArguments;
 | 
					 | 
					 | 
					 | 
							final var	originalArguments	= numberOfArguments >= 0 ? Arrays.copyOfRange(textArguments, 0, numberOfArguments) : textArguments;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -190,37 +258,17 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return arguments;
 | 
					 | 
					 | 
					 | 
							return arguments;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Retrieves the recommendations based on the current input entered.<br>
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * The first word is used for the recommendations and
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * it does not matter if the "/" is at its beginning or not.<br>
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * If none are present, nothing will be done.<br>
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Otherwise the given function will be executed on the recommendations.<br>
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param input  the input string
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param action the action that should be taken for the recommendations, if any
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *               are present
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public void requestRecommendations(String input, Consumer<Set<String>> action) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var partialCommand = getCommand(input);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// Get the expected commands
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							final var recommendations = recommendCommands(partialCommand);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (recommendations.isEmpty()) return;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// Execute the given action
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							else action.accept(recommendations);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Recommends commands based upon the currently entered input.<br>
 | 
					 | 
					 | 
					 | 
						 * Recommends commands based upon the currently entered input.<br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * In the current implementation, all we check is whether a key contains this
 | 
					 | 
					 | 
					 | 
						 * In the current implementation, all that gets checked is whether a key
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * input. This might be updated later on.
 | 
					 | 
					 | 
					 | 
						 * contains this input. This might be updated later on.
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param partialCommand the partially entered command
 | 
					 | 
					 | 
					 | 
						 * @param partialCommand the partially entered command
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @return a set of all commands that match this input
 | 
					 | 
					 | 
					 | 
						 * @return a set of all commands that match this input
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						private Set<String> recommendCommands(String partialCommand) {
 | 
					 | 
					 | 
					 | 
						private Set<String> recommendCommands(String partialCommand) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// current implementation only looks if input is contained within a command,
 | 
					 | 
					 | 
					 | 
							// current implementation only looks if input is contained within a command,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// might be updated
 | 
					 | 
					 | 
					 | 
							// might be updated
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return systemCommands.keySet()
 | 
					 | 
					 | 
					 | 
							return systemCommands.keySet()
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -231,11 +279,8 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/**
 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Supplies the default values for arguments if none are present in the text for
 | 
					 | 
					 | 
					 | 
						 * Supplies the default values for arguments if none are present in the text for
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * any argument. <br>
 | 
					 | 
					 | 
					 | 
						 * any argument. <br>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * Will only work for {@code SystemCommand}s whose argument counter is bigger
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * than 1.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 *
 | 
					 | 
					 | 
					 | 
						 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param textArguments the arguments that were parsed from the text
 | 
					 | 
					 | 
					 | 
						 * @param textArguments the arguments that were parsed from the text
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @param toEvaluate    the system command whose default values should be used
 | 
					 | 
					 | 
					 | 
						 * @param toEvaluate    the system command whose default values should be used
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -253,6 +298,7 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (toEvaluate.getNumberOfArguments() > 0) for (var index = 0; index < numberOfArguments; index++) {
 | 
					 | 
					 | 
					 | 
							if (toEvaluate.getNumberOfArguments() > 0) for (var index = 0; index < numberOfArguments; index++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								String textArg = null;
 | 
					 | 
					 | 
					 | 
								String textArg = null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (index < textArguments.length) textArg = textArguments[index];
 | 
					 | 
					 | 
					 | 
								if (index < textArguments.length) textArg = textArguments[index];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// Set the argument at position index to the current argument of the text, if it
 | 
					 | 
					 | 
					 | 
								// Set the argument at position index to the current argument of the text, if it
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// is present. Otherwise the default for that argument will be taken if present.
 | 
					 | 
					 | 
					 | 
								// is present. Otherwise the default for that argument will be taken if present.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// In the worst case, an empty String will be used.
 | 
					 | 
					 | 
					 | 
								// In the worst case, an empty String will be used.
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -266,4 +312,10 @@ public final class SystemCommandMap {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 */
 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						public Map<String, SystemCommand> getSystemCommands() { return systemCommands; }
 | 
					 | 
					 | 
					 | 
						public Map<String, SystemCommand> getSystemCommands() { return systemCommands; }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @return the activator of any command in this map. Can be null.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 * @since Envoy Client v0.3-beta
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						public Character getActivator() { return activator; }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						 
						
						
						
						 
					 | 
					 | 
					 
 | 
				
			
			
		
	
										
									
								
							
there is a typo