You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by ma...@apache.org on 2015/10/14 18:20:21 UTC

[2/2] syncope git commit: added info and help command, some bugfix and code improvements, SYNCOPE-158

added info and help command, some bugfix and code improvements, SYNCOPE-158


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4133c240
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4133c240
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4133c240

Branch: refs/heads/master
Commit: 4133c2402e491342d0c32a1a6c5a9bb7d5a8870b
Parents: ae88f40
Author: massi <ma...@tirasa.net>
Authored: Wed Oct 14 18:20:09 2015 +0200
Committer: massi <ma...@tirasa.net>
Committed: Wed Oct 14 18:20:09 2015 +0200

----------------------------------------------------------------------
 .../apache/syncope/client/cli/ArgsManager.java  |   2 +-
 .../org/apache/syncope/client/cli/Input.java    |  37 +-
 .../apache/syncope/client/cli/SyncopeAdm.java   |  13 +-
 .../client/cli/commands/AbstractCommand.java    |  12 +
 .../cli/commands/ConfigurationCommand.java      |  69 ++--
 .../client/cli/commands/HelpCommand.java        | 115 +++++++
 .../client/cli/commands/InfoCommand.java        | 340 +++++++++++++++++++
 .../client/cli/commands/LoggerCommand.java      |  53 +--
 .../cli/commands/NotificationCommand.java       |  33 +-
 .../client/cli/commands/PolicyCommand.java      |  41 ++-
 .../client/cli/commands/ReportCommand.java      |  76 +++--
 .../client/cli/commands/SchemaCommand.java      |  49 ++-
 .../cli/commands/install/InstallCommand.java    |   7 +-
 .../syncope/client/cli/messages/Messages.java   |  40 +++
 .../client/cli/messages/UsageMessages.java      |  40 ---
 .../syncope/client/cli/util/CommandUtils.java   |  74 ++++
 16 files changed, 803 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/ArgsManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/ArgsManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/ArgsManager.java
index f323dce..926b4dd 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/ArgsManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/ArgsManager.java
@@ -25,7 +25,7 @@ public final class ArgsManager {
 
     public static void validator(final String[] args) throws IllegalArgumentException {
         if (args.length == 0) {
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException("Syntax error: no options");
         } else if (!"install".equalsIgnoreCase(args[0])) {
             final File configFile = new File(InstallConfigFileTemplate.FILE_PATH);
             if (!configFile.exists()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/Input.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/Input.java b/client/cli/src/main/java/org/apache/syncope/client/cli/Input.java
index a7092e7..6e2aeeb 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/Input.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/Input.java
@@ -18,21 +18,11 @@
  */
 package org.apache.syncope.client.cli;
 
-import java.util.List;
 import org.apache.syncope.client.cli.commands.AbstractCommand;
+import org.apache.syncope.client.cli.util.CommandUtils;
 
 public class Input {
 
-    private boolean ssl = false;
-
-    private String host = "localhost";
-
-    private String port = "9080";
-
-    private String username = "admin";
-
-    private String password = "password";
-
     private final AbstractCommand command;
 
     private String option;
@@ -42,7 +32,7 @@ public class Input {
     public Input(final String[] args)
             throws InstantiationException, IllegalAccessException, IllegalArgumentException {
 
-        command = fromArgs(args[0]);
+        command = CommandUtils.fromArgs(args[0]);
 
         if (args.length > 1) {
             option = args[1];
@@ -77,7 +67,7 @@ public class Input {
     public String firstParameter() {
         return parameters[0];
     }
-    
+
     public String lastParameter() {
         return parameters[parameters.length - 1];
     }
@@ -90,27 +80,6 @@ public class Input {
         return new PairParameter(pairParameterArray[0], pairParameterArray[1]);
     }
 
-    private AbstractCommand fromArgs(final String arg)
-            throws InstantiationException, IllegalAccessException, IllegalArgumentException {
-
-        final CommandClassScanner ccs = new CommandClassScanner();
-        final List<Class<? extends AbstractCommand>> commands = ccs.getComponentClasses();
-
-        Class<? extends AbstractCommand> commandClass = null;
-        for (Class<? extends AbstractCommand> cmd : commands) {
-            if (arg.equals(cmd.getAnnotation(Command.class).name())) {
-                commandClass = cmd;
-            }
-        }
-
-        if (commandClass == null) {
-            throw new IllegalArgumentException();
-        }
-
-        return commandClass.newInstance();
-
-    }
-
     public class PairParameter {
 
         private final String key;

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/SyncopeAdm.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/SyncopeAdm.java b/client/cli/src/main/java/org/apache/syncope/client/cli/SyncopeAdm.java
index 2f762e7..0340043 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/SyncopeAdm.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/SyncopeAdm.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.cli;
 
 import org.apache.syncope.client.cli.commands.AbstractCommand;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,7 +35,10 @@ public final class SyncopeAdm {
             + "    report --help \n"
             + "    policy --help \n"
             + "    entitlement --help \n"
-            + "    schema --help \n";
+            + "    schema --help \n"
+            + "    install --help \n"
+            + "    info --help\n"
+            + "    help\n";
 
     public static void main(final String[] args) {
         LOG.debug("Starting with args \n");
@@ -45,14 +49,11 @@ public final class SyncopeAdm {
             final AbstractCommand command = input.getCommand();
             command.execute(input);
         } catch (final IllegalAccessException | InstantiationException e) {
-            LOG.error("Error in main", e);
-            e.printStackTrace();
             System.out.println(HELP_MESSAGE);
         } catch (final IllegalArgumentException ex) {
             LOG.error("Error in main", ex);
-            if (ex.getMessage().startsWith("It seems you need to setup")) {
-                System.out.println(ex.getMessage());
-            } else {
+            Messages.printMessage(ex.getMessage());
+            if (!ex.getMessage().startsWith("It seems you")) {
                 System.out.println(HELP_MESSAGE);
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/AbstractCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/AbstractCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/AbstractCommand.java
index b374e33..7f272fe 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/AbstractCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/AbstractCommand.java
@@ -18,9 +18,21 @@
  */
 package org.apache.syncope.client.cli.commands;
 
+import java.util.List;
 import org.apache.syncope.client.cli.Input;
 
 public abstract class AbstractCommand {
 
     public abstract void execute(final Input input);
+
+    protected String helpMessage(final String command, final List<String> options) {
+        final StringBuilder helpMessageBuilder = new StringBuilder(String.format("Usage: %s [options]\n", command));
+        helpMessageBuilder.append("  Options:\n");
+        for (final String option : options) {
+            helpMessageBuilder.append("    ").append(option).append("\n");
+        }
+        return helpMessageBuilder.toString();
+    }
+
+    public abstract String getHelpMessage();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ConfigurationCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ConfigurationCommand.java
index 282e2d1..51e7cb8 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ConfigurationCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ConfigurationCommand.java
@@ -21,6 +21,8 @@ package org.apache.syncope.client.cli.commands;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.SequenceInputStream;
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
@@ -29,7 +31,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.client.cli.util.XMLUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -46,7 +48,7 @@ public class ConfigurationCommand extends AbstractCommand {
 
     private static final String EXPORT_FILE_NAME = "/content.xml";
 
-    private static final String HELP_MESSAGE = "Usage: config [options]\n"
+    private static final String HELP_MESSAGE = "Usage: configuration [options]\n"
             + "  Options:\n"
             + "    --help \n"
             + "    --list \n"
@@ -105,12 +107,12 @@ public class ConfigurationCommand extends AbstractCommand {
                     }
                     System.out.println("");
                 } catch (final Exception ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                     break;
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "configuration --read {CONF-NAME} {CONF-NAME} [...]");
                 if (parameters.length >= 1) {
                     AttrTO attrTO;
@@ -123,11 +125,11 @@ public class ConfigurationCommand extends AbstractCommand {
                             System.out.println("");
                         } catch (final SyncopeClientException | WebServiceException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Configuration " + parameters[0] + " doesn't exist!");
+                                Messages.printMessage("Configuration " + parameters[0] + " doesn't exist!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete configuration " + parameters[0]);
+                                Messages.printMessage("You cannot delete configuration " + parameters[0]);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                             break;
                         }
@@ -137,7 +139,7 @@ public class ConfigurationCommand extends AbstractCommand {
                 }
                 break;
             case UPDATE:
-                final String updateErrorMessage = UsageMessages.optionCommandMessage(
+                final String updateErrorMessage = Messages.optionCommandMessage(
                         "configuration --update {CONF-NAME}={CONF-VALUE} {CONF-NAME}={CONF-VALUE} [...]");
                 if (parameters.length >= 1) {
                     Input.PairParameter pairParameter = null;
@@ -154,20 +156,20 @@ public class ConfigurationCommand extends AbstractCommand {
                             System.out.println("    - readonly: " + attrTO.isReadonly());
                             System.out.println("");
                         } catch (final IllegalArgumentException ex) {
-                            UsageMessages.printErrorMessage(ex.getMessage(), updateErrorMessage);
+                            Messages.printMessage(ex.getMessage(), updateErrorMessage);
                             break;
                         } catch (final SyncopeClientException | WebServiceException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         "Configuration " + pairParameter.getKey() + " doesn't exist!");
                             } else if (ex.getMessage().startsWith("InvalidValues")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         pairParameter.getValue() + " is not a valid value for "
                                         + pairParameter.getKey());
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete configuration " + parameters[0]);
+                                Messages.printMessage("You cannot delete configuration " + parameters[0]);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                             break;
                         }
@@ -177,7 +179,7 @@ public class ConfigurationCommand extends AbstractCommand {
                 }
                 break;
             case CREATE:
-                final String createErrorMessage = UsageMessages.optionCommandMessage(
+                final String createErrorMessage = Messages.optionCommandMessage(
                         "configuration --create {CONF-NAME}={CONF-VALUE} {CONF-NAME}={CONF-VALUE} [...]");
                 if (parameters.length >= 1) {
                     Input.PairParameter pairParameter = null;
@@ -194,15 +196,15 @@ public class ConfigurationCommand extends AbstractCommand {
                             System.out.println("    - readonly: " + attrTO.isReadonly());
                             System.out.println("");
                         } catch (final IllegalArgumentException ex) {
-                            UsageMessages.printErrorMessage(ex.getMessage(), createErrorMessage);
+                            Messages.printMessage(ex.getMessage(), createErrorMessage);
                             break;
                         } catch (final SyncopeClientException | WebServiceException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         "Configuration schema "
                                         + pairParameter.getKey() + " doesn't exist! Create it before.");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                             break;
                         }
@@ -212,7 +214,7 @@ public class ConfigurationCommand extends AbstractCommand {
                 }
                 break;
             case DELETE:
-                final String deleteErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteErrorMessage = Messages.optionCommandMessage(
                         "configuration --delete {CONF-NAME} {CONF-NAME} [...]");
                 if (parameters.length >= 1) {
                     for (final String parameter : parameters) {
@@ -221,11 +223,11 @@ public class ConfigurationCommand extends AbstractCommand {
                             System.out.println("\n - Conf " + parameter + " deleted!\n");
                         } catch (final SyncopeClientException | WebServiceException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Configuration " + parameter + " doesn't exist!");
+                                Messages.printMessage("Configuration " + parameter + " doesn't exist!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete configuration", parameter);
+                                Messages.printMessage("You cannot delete configuration", parameter);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                             break;
                         }
@@ -235,7 +237,7 @@ public class ConfigurationCommand extends AbstractCommand {
                 }
                 break;
             case EXPORT:
-                final String exportErrorMessage = UsageMessages.optionCommandMessage(
+                final String exportErrorMessage = Messages.optionCommandMessage(
                         "configuration --export {WHERE-DIR}");
                 if (parameters.length == 1) {
                     try {
@@ -243,24 +245,24 @@ public class ConfigurationCommand extends AbstractCommand {
                                 parameters[0] + EXPORT_FILE_NAME);
                         System.out.println(" - " + parameters[0] + EXPORT_FILE_NAME + " successfully created");
                     } catch (final IOException ex) {
-                        UsageMessages.printErrorMessage(ex.getMessage());
+                        Messages.printMessage(ex.getMessage());
                     } catch (ParserConfigurationException | SAXException | TransformerConfigurationException ex) {
                         LOG.error("Error creating content.xml file in {} directory", parameters[0], ex);
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 "Error creating " + parameters[0] + EXPORT_FILE_NAME + " " + ex.getMessage());
                         break;
                     } catch (final TransformerException ex) {
                         LOG.error("Error creating content.xml file in {} directory", parameters[0], ex);
                         if (ex.getCause() instanceof FileNotFoundException) {
-                            UsageMessages.printErrorMessage("Permission denied on " + parameters[0]);
+                            Messages.printMessage("Permission denied on " + parameters[0]);
                         } else {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error creating " + parameters[0] + EXPORT_FILE_NAME + " " + ex.getMessage());
                         }
                         break;
                     } catch (final SyncopeClientException ex) {
                         LOG.error("Error calling configuration service", ex);
-                        UsageMessages.printErrorMessage("Error calling configuration service " + ex.getMessage());
+                        Messages.printMessage("Error calling configuration service " + ex.getMessage());
                         break;
                     }
                 } else {
@@ -277,6 +279,11 @@ public class ConfigurationCommand extends AbstractCommand {
                 break;
         }
     }
+    
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
 
     private enum Options {
 
@@ -311,5 +318,13 @@ public class ConfigurationCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/HelpCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/HelpCommand.java
new file mode 100644
index 0000000..c4008eb
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/HelpCommand.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.messages.Messages;
+import org.apache.syncope.client.cli.util.CommandUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(name = "help")
+public class HelpCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HelpCommand.class);
+
+    @Override
+    public void execute(final Input input) {
+        LOG.debug("Option: {}", input.getOption());
+        LOG.debug("Parameters:");
+        for (final String parameter : input.getParameters()) {
+            LOG.debug("   > " + parameter);
+        }
+
+        if (StringUtils.isBlank(input.getOption())) {
+            input.setOption(Options.HELP.getOptionName());
+        }
+
+        switch (Options.fromName(input.getOption())) {
+            case HELP:
+                final StringBuilder generalHelpBuilder = new StringBuilder("General help\n");
+                try {
+                    for (final AbstractCommand command : CommandUtils.commands()) {
+                        generalHelpBuilder.append("Command: ")
+                                .append(command.getClass().getAnnotation(Command.class).name())
+                                .append("\n")
+                                .append(command.getHelpMessage())
+                                .append("\n")
+                                .append(" \n");
+                    }
+                    System.out.println(generalHelpBuilder.toString());
+                } catch (final IllegalAccessException | IllegalArgumentException | InstantiationException e) {
+                    Messages.printMessage(e.getMessage());
+                }
+                break;
+            default:
+                System.out.println(input.getOption() + " is not a valid option.");
+                System.out.println("");
+                System.out.println(helpMessage("help", Options.toList()));
+                break;
+        }
+    }
+
+    @Override
+    public String getHelpMessage() {
+        return helpMessage("help", Options.toList());
+    }
+
+    private enum Options {
+
+        HELP("--print");
+
+        private final String optionName;
+
+        private Options(final String optionName) {
+            this.optionName = optionName;
+        }
+
+        public String getOptionName() {
+            return optionName;
+        }
+
+        public boolean equalsOptionName(final String otherName) {
+            return (otherName == null) ? false : optionName.equals(otherName);
+        }
+
+        public static Options fromName(final String name) {
+            Options optionToReturn = HELP;
+            for (final Options option : Options.values()) {
+                if (option.equalsOptionName(name)) {
+                    optionToReturn = option;
+                }
+            }
+            return optionToReturn;
+        }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/InfoCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/InfoCommand.java
new file mode 100644
index 0000000..e6e1378
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/InfoCommand.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.SyncopeServices;
+import org.apache.syncope.client.cli.messages.Messages;
+import org.apache.syncope.common.lib.to.SyncopeTO;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(name = "info")
+public class InfoCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(InfoCommand.class);
+
+    @Override
+    public void execute(final Input input) {
+        LOG.debug("Option: {}", input.getOption());
+        LOG.debug("Parameters:");
+        for (final String parameter : input.getParameters()) {
+            LOG.debug("   > " + parameter);
+        }
+
+        if (StringUtils.isBlank(input.getOption())) {
+            input.setOption(Options.HELP.getOptionName());
+        }
+
+        final SyncopeService syncopeService = SyncopeServices.get(SyncopeService.class);
+        final SyncopeTO syncopeTO = syncopeService.info();
+        switch (Options.fromName(input.getOption())) {
+            case VERSION:
+                try {
+                    Messages.printMessage("Syncope version: " + syncopeTO.getVersion());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PWD_RESET_ALLOWED:
+                try {
+                    Messages.printMessage("Password reset allowed: " + syncopeTO.isPwdResetAllowed());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PWD_RESET_WITH_SECURITY_QUESTION:
+                try {
+                    Messages.printMessage("Password reset requiring security question: "
+                            + syncopeTO.isPwdResetRequiringSecurityQuestions());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case SELF_REG_ALLOWED:
+                try {
+                    Messages.printMessage("Self registration allowed: " + syncopeTO.isSelfRegAllowed());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PROVISIONING_MANAGER:
+                try {
+                    Messages.printMessage(
+                            "Any object provisioning manager class: " + syncopeTO.getAnyObjectProvisioningManager(),
+                            "User       provisioning manager class: " + syncopeTO.getUserProvisioningManager(),
+                            "Group      provisioning manager class: " + syncopeTO.getGroupProvisioningManager());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case WORKFLOW_ADAPTER:
+                try {
+                    Messages.printMessage(
+                            "Any object workflow adapter class: " + syncopeTO.getAnyObjectWorkflowAdapter(),
+                            "User       workflow adapter class: " + syncopeTO.getUserWorkflowAdapter(),
+                            "Group      workflow adapter class: " + syncopeTO.getGroupWorkflowAdapter());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case ACCOUNT_RULES:
+                try {
+                    for (final String accountRule : syncopeTO.getAccountRules()) {
+                        Messages.printMessage("Account rule: " + accountRule);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case CONNID_LOCATION:
+                try {
+                    for (final String location : syncopeTO.getConnIdLocations()) {
+                        Messages.printMessage("ConnId location: " + location);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case LOGIC_ACTIONS:
+                try {
+                    for (final String logic : syncopeTO.getLogicActions()) {
+                        Messages.printMessage("Logic action: " + logic);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case MAIL_TEMPLATES:
+                try {
+                    for (final String template : syncopeTO.getMailTemplates()) {
+                        Messages.printMessage("Mail template: " + template);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case MAPPING_ITEM_TRANSFORMERS:
+                try {
+                    for (final String tranformer : syncopeTO.getMappingItemTransformers()) {
+                        Messages.printMessage("Mapping item tranformer: " + tranformer);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PASSWORD_RULES:
+                try {
+                    for (final String rules : syncopeTO.getPasswordRules()) {
+                        Messages.printMessage("Password rule: " + rules);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PROPAGATION_ACTIONS:
+                try {
+                    for (final String action : syncopeTO.getPropagationActions()) {
+                        Messages.printMessage("Propagation action: " + action);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PUSH_ACTIONS:
+                try {
+                    for (final String action : syncopeTO.getPushActions()) {
+                        Messages.printMessage("Push action: " + action);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PUSH_CORRELATION_ACTIONS:
+                try {
+                    for (final String rule : syncopeTO.getPushCorrelationRules()) {
+                        Messages.printMessage("Push correlation rule: " + rule);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case REPORTLETS:
+                try {
+                    for (final String reportlet : syncopeTO.getReportlets()) {
+                        Messages.printMessage("Reportlet: " + reportlet);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case SYNC_ACTIONS:
+                try {
+                    for (final String action : syncopeTO.getSyncActions()) {
+                        Messages.printMessage("Sync action: " + action);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case SYNC_CORRELATION_RULES:
+                try {
+                    for (final String rule : syncopeTO.getSyncCorrelationRules()) {
+                        Messages.printMessage("Sync correlation rule: " + rule);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case TASK_JOBS:
+                try {
+                    for (final String job : syncopeTO.getTaskJobs()) {
+                        Messages.printMessage("Task job: " + job);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case VALIDATORS:
+                try {
+                    for (final String validator : syncopeTO.getValidators()) {
+                        Messages.printMessage("Validator: " + validator);
+                    }
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case PASSWORD_GENERATOR:
+                try {
+                    Messages.printMessage(
+                            "Password generator class: " + syncopeTO.getPasswordGenerator());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case VIR_ATTR_CACHE:
+                try {
+                    Messages.printMessage(
+                            "Virtual attribute cache class: " + syncopeTO.getVirAttrCache());
+                } catch (final Exception ex) {
+                    Messages.printMessage(ex.getMessage());
+                    break;
+                }
+                break;
+            case HELP:
+                System.out.println(helpMessage("info", Options.toList()));
+                break;
+            default:
+                System.out.println(input.getOption() + " is not a valid option.");
+                System.out.println("");
+                System.out.println(helpMessage("info", Options.toList()));
+                break;
+        }
+    }
+
+    @Override
+    public String getHelpMessage() {
+        return helpMessage("info", Options.toList());
+    }
+
+    private enum Options {
+
+        VERSION("--version"),
+        PWD_RESET_ALLOWED("--pwd-reset-allowed"),
+        PWD_RESET_WITH_SECURITY_QUESTION("--pwd-reset-with-question"),
+        SELF_REG_ALLOWED("--self-reg-allowed"),
+        PROVISIONING_MANAGER("--provisioning-manager-classes"),
+        WORKFLOW_ADAPTER("--workflow-adapter-classes"),
+        ACCOUNT_RULES("--account-rules-classes"),
+        CONNID_LOCATION("--connid-locations"),
+        LOGIC_ACTIONS("--logic-actions"),
+        MAIL_TEMPLATES("--mail-templates"),
+        MAPPING_ITEM_TRANSFORMERS("--mapping-item-transformers"),
+        PASSWORD_RULES("--password-rules"),
+        PROPAGATION_ACTIONS("--propagation-actions"),
+        PUSH_ACTIONS("--push-actions"),
+        PUSH_CORRELATION_ACTIONS("--push-correlation-actions"),
+        REPORTLETS("--reportlets"),
+        SYNC_ACTIONS("--sync-actions"),
+        SYNC_CORRELATION_RULES("--sync-correlation-rules"),
+        TASK_JOBS("--task-jobs"),
+        VALIDATORS("--validators"),
+        PASSWORD_GENERATOR("--password-generator"),
+        VIR_ATTR_CACHE("--vir-attr-cache"),
+        HELP("--help");
+
+        private final String optionName;
+
+        private Options(final String optionName) {
+            this.optionName = optionName;
+        }
+
+        public String getOptionName() {
+            return optionName;
+        }
+
+        public boolean equalsOptionName(final String otherName) {
+            return (otherName == null) ? false : optionName.equals(otherName);
+        }
+
+        public static Options fromName(final String name) {
+            Options optionToReturn = HELP;
+            for (final Options option : Options.values()) {
+                if (option.equalsOptionName(name)) {
+                    optionToReturn = option;
+                }
+            }
+            return optionToReturn;
+        }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
index 00f12b1..e1ab746 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/LoggerCommand.java
@@ -18,12 +18,14 @@
  */
 package org.apache.syncope.client.cli.commands;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.LoggerTO;
 import org.apache.syncope.common.lib.types.LoggerLevel;
@@ -76,11 +78,11 @@ public class LoggerCommand extends AbstractCommand {
                         System.out.println("");
                     }
                 } catch (final SyncopeClientException ex) {
-                    UsageMessages.printErrorMessage("Error: " + ex.getMessage());
+                    Messages.printMessage("Error: " + ex.getMessage());
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "logger --read {LOG-NAME} {LOG-NAME} [...]");
                 if (parameters.length >= 1) {
                     for (final String parameter : parameters) {
@@ -92,10 +94,10 @@ public class LoggerCommand extends AbstractCommand {
                             System.out.println("");
                         } catch (final SyncopeClientException | WebServiceException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         "Logger " + parameter + " doesn't exist!");
                             } else {
-                                UsageMessages.printErrorMessage("Error: " + ex.getMessage());
+                                Messages.printMessage("Error: " + ex.getMessage());
                             }
                         }
                     }
@@ -104,7 +106,7 @@ public class LoggerCommand extends AbstractCommand {
                 }
                 break;
             case UPDATE:
-                final String updateErrorMessage = UsageMessages.optionCommandMessage(
+                final String updateErrorMessage = Messages.optionCommandMessage(
                         "logger --update {LOG-NAME}={LOG-LEVEL} {LOG-NAME}={LOG-LEVEL} [...]");
 
                 if (parameters.length >= 1) {
@@ -121,19 +123,19 @@ public class LoggerCommand extends AbstractCommand {
                             System.out.println("");
                         } catch (final WebServiceException | SyncopeClientException | IllegalArgumentException ex) {
                             if (ex.getMessage().startsWith("No enum constant org.apache.syncope.common.lib.types.")) {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                                 System.out.println("Try with:");
                                 for (final LoggerLevel level : LoggerLevel.values()) {
                                     System.out.println("  *** " + level.name());
                                 }
                                 System.out.println("");
                             } else if ("Parameter syntax error!".equalsIgnoreCase(ex.getMessage())) {
-                                UsageMessages.printErrorMessage(ex.getMessage(), updateErrorMessage);
+                                Messages.printMessage(ex.getMessage(), updateErrorMessage);
                             } else if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         "Logger " + pairParameter.getKey() + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage(), updateErrorMessage);
+                                Messages.printMessage(ex.getMessage(), updateErrorMessage);
                             }
                             break;
                         }
@@ -143,7 +145,7 @@ public class LoggerCommand extends AbstractCommand {
                 }
                 break;
             case UPDATE_ALL:
-                final String updateAllErrorMessage = UsageMessages.optionCommandMessage(
+                final String updateAllErrorMessage = Messages.optionCommandMessage(
                         "logger --update-all {LOG-LEVEL}");
 
                 if (parameters.length == 1) {
@@ -157,14 +159,14 @@ public class LoggerCommand extends AbstractCommand {
                             System.out.println("");
                         } catch (final WebServiceException | SyncopeClientException | IllegalArgumentException ex) {
                             if (ex.getMessage().startsWith("No enum constant org.apache.syncope.common.lib.types.")) {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                                 System.out.println("Try with:");
                                 for (final LoggerLevel level : LoggerLevel.values()) {
                                     System.out.println("  *** " + level.name());
                                 }
                                 System.out.println("");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage(), updateAllErrorMessage);
+                                Messages.printMessage(ex.getMessage(), updateAllErrorMessage);
                             }
                             break;
                         }
@@ -174,7 +176,7 @@ public class LoggerCommand extends AbstractCommand {
                 }
                 break;
             case CREATE:
-                final String createErrorMessage = UsageMessages.optionCommandMessage(
+                final String createErrorMessage = Messages.optionCommandMessage(
                         "logger --create {LOG-NAME}={LOG-LEVEL} {LOG-NAME}={LOG-LEVEL} [...]");
 
                 if (parameters.length >= 1) {
@@ -193,14 +195,14 @@ public class LoggerCommand extends AbstractCommand {
                             System.out.println("");
                         } catch (final WebServiceException | SyncopeClientException | IllegalArgumentException ex) {
                             if (ex.getMessage().startsWith("No enum constant org.apache.syncope.common.lib.types.")) {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                                 System.out.println("Try with:");
                                 for (final LoggerLevel level : LoggerLevel.values()) {
                                     System.out.println("  *** " + level.name());
                                 }
                                 System.out.println("");
                             } else if ("Parameter syntax error!".equalsIgnoreCase(ex.getMessage())) {
-                                UsageMessages.printErrorMessage(ex.getMessage(), createErrorMessage);
+                                Messages.printMessage(ex.getMessage(), createErrorMessage);
                             }
                             break;
                         }
@@ -210,7 +212,7 @@ public class LoggerCommand extends AbstractCommand {
                 }
                 break;
             case DELETE:
-                final String deleteErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteErrorMessage = Messages.optionCommandMessage(
                         "logger --delete {LOG-NAME} {LOG-NAME} [...]");
 
                 if (parameters.length >= 1) {
@@ -220,10 +222,10 @@ public class LoggerCommand extends AbstractCommand {
                             System.out.println("\n - Logger " + parameter + " deleted!\n");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(
+                                Messages.printMessage(
                                         "Logger " + parameter + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         }
                     }
@@ -240,6 +242,11 @@ public class LoggerCommand extends AbstractCommand {
                 System.out.println(HELP_MESSAGE);
         }
     }
+    
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
 
     private enum Options {
 
@@ -274,6 +281,14 @@ public class LoggerCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/NotificationCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/NotificationCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/NotificationCommand.java
index 9028617..a903268 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/NotificationCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/NotificationCommand.java
@@ -18,12 +18,14 @@
  */
 package org.apache.syncope.client.cli.commands;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.rest.api.service.NotificationService;
@@ -66,11 +68,11 @@ public class NotificationCommand extends AbstractCommand {
                         System.out.println(notificationTO);
                     }
                 } catch (final SyncopeClientException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "notification --read {NOTIFICATION-ID} {NOTIFICATION-ID} [...]");
                 if (parameters.length >= 1) {
                     for (final String parameter : parameters) {
@@ -80,9 +82,9 @@ public class NotificationCommand extends AbstractCommand {
                             System.out.println("Error reading " + parameter + ". It isn't a valid notification id");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Notification " + parameter + " doesn't exists!");
+                                Messages.printMessage("Notification " + parameter + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         }
                     }
@@ -91,7 +93,7 @@ public class NotificationCommand extends AbstractCommand {
                 }
                 break;
             case DELETE:
-                final String deleteErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteErrorMessage = Messages.optionCommandMessage(
                         "notification --delete {NOTIFICATION-ID} {NOTIFICATION-ID} [...]");
 
                 if (parameters.length >= 1) {
@@ -101,12 +103,12 @@ public class NotificationCommand extends AbstractCommand {
                             System.out.println("\n - Notification " + parameter + " deleted!\n");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Notification " + parameter + " doesn't exists!");
+                                Messages.printMessage("Notification " + parameter + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid notification id");
                         }
                     }
@@ -123,6 +125,11 @@ public class NotificationCommand extends AbstractCommand {
                 System.out.println(HELP_MESSAGE);
         }
     }
+    
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
 
     private enum Options {
 
@@ -154,6 +161,14 @@ public class NotificationCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+        
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/PolicyCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/PolicyCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/PolicyCommand.java
index d17419f..11d59b8 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/PolicyCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/PolicyCommand.java
@@ -18,12 +18,14 @@
  */
 package org.apache.syncope.client.cli.commands;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
@@ -64,7 +66,7 @@ public class PolicyCommand extends AbstractCommand {
         final PolicyService policyService = SyncopeServices.get(PolicyService.class);
         switch (Options.fromName(input.getOption())) {
             case LIST_POLICY:
-                final String listPolicyErrorMessage = UsageMessages.optionCommandMessage(
+                final String listPolicyErrorMessage = Messages.optionCommandMessage(
                         "Usage: policy --list-policy {POLICY-TYPE}\n"
                         + "   Policy type: ACCOUNT / PASSWORD / SYNC / PUSH");
                 if (parameters.length == 1) {
@@ -73,9 +75,9 @@ public class PolicyCommand extends AbstractCommand {
                             System.out.println(policyTO);
                         }
                     } catch (final SyncopeClientException ex) {
-                        UsageMessages.printErrorMessage(ex.getMessage());
+                        Messages.printMessage(ex.getMessage());
                     } catch (final IllegalArgumentException ex) {
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 "Error: " + parameters[0] + " isn't a valid policy type, try with:");
                         for (final PolicyType type : PolicyType.values()) {
                             System.out.println("  *** " + type.name());
@@ -87,20 +89,20 @@ public class PolicyCommand extends AbstractCommand {
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "Usage: policy --read {POLICY-ID} {POLICY-ID} [...]");
                 if (parameters.length >= 1) {
                     for (final String parameter : parameters) {
                         try {
                             System.out.println(policyService.read(Long.valueOf(parameter)));
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid policy id");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Policy " + parameter + " doesn't exists!");
+                                Messages.printMessage("Policy " + parameter + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         }
                     }
@@ -109,7 +111,7 @@ public class PolicyCommand extends AbstractCommand {
                 }
                 break;
             case DELETE:
-                final String deleteErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteErrorMessage = Messages.optionCommandMessage(
                         "Usage: policy --delete {POLICY-ID} {POLICY-ID} [...]");
 
                 if (parameters.length >= 1) {
@@ -120,14 +122,14 @@ public class PolicyCommand extends AbstractCommand {
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             System.out.println("Error:");
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Policy " + parameter + " doesn't exists!");
+                                Messages.printMessage("Policy " + parameter + " doesn't exists!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete policy " + parameter);
+                                Messages.printMessage("You cannot delete policy " + parameter);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid policy id");
                         }
                     }
@@ -144,6 +146,11 @@ public class PolicyCommand extends AbstractCommand {
                 System.out.println(HELP_MESSAGE);
         }
     }
+    
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
 
     private enum Options {
 
@@ -175,6 +182,14 @@ public class PolicyCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+        
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ReportCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ReportCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ReportCommand.java
index ffa8ecd..dfd8d46 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ReportCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/ReportCommand.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.cli.commands;
 
 import java.io.IOException;
 import java.io.SequenceInputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import javax.xml.parsers.ParserConfigurationException;
@@ -29,7 +30,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.client.cli.util.XMLUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ReportExecTO;
@@ -87,7 +88,7 @@ public class ReportCommand extends AbstractCommand {
                         System.out.println(reportTO);
                     }
                 } catch (final SyncopeClientException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case LIST_JOBS:
@@ -104,24 +105,24 @@ public class ReportCommand extends AbstractCommand {
                         }
                     }
                 } catch (final SyncopeClientException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --read {REPORT-ID} {REPORT-ID} [...]");
                 if (parameters.length >= 1) {
                     for (final String parameter : parameters) {
                         try {
                             System.out.println(reportService.read(Long.valueOf(parameter)));
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid report id");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Report " + parameter + " doesn't exists!");
+                                Messages.printMessage("Report " + parameter + " doesn't exists!");
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         }
                     }
@@ -130,7 +131,7 @@ public class ReportCommand extends AbstractCommand {
                 }
                 break;
             case DELETE:
-                final String deleteErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --execute {REPORT-ID}");
 
                 if (parameters.length == 1) {
@@ -140,14 +141,14 @@ public class ReportCommand extends AbstractCommand {
                             System.out.println(" - Report " + parameter + " deleted!");
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Report " + parameter + " doesn't exists!");
+                                Messages.printMessage("Report " + parameter + " doesn't exists!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete report " + parameter);
+                                Messages.printMessage("You cannot delete report " + parameter);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid report id");
                         }
                     }
@@ -156,7 +157,7 @@ public class ReportCommand extends AbstractCommand {
                 }
                 break;
             case EXECUTE:
-                final String executeErrorMessage = UsageMessages.optionCommandMessage(
+                final String executeErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --execute {REPORT-ID}");
 
                 if (parameters.length == 1) {
@@ -173,14 +174,14 @@ public class ReportCommand extends AbstractCommand {
                     } catch (final WebServiceException | SyncopeClientException ex) {
                         System.out.println("Error:");
                         if (ex.getMessage().startsWith("NotFound")) {
-                            UsageMessages.printErrorMessage("Report " + parameters[0] + " doesn't exists!");
+                            Messages.printMessage("Report " + parameters[0] + " doesn't exists!");
                         } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                            UsageMessages.printErrorMessage("You cannot delete report " + parameters[0]);
+                            Messages.printMessage("You cannot delete report " + parameters[0]);
                         } else {
-                            UsageMessages.printErrorMessage(ex.getMessage());
+                            Messages.printMessage(ex.getMessage());
                         }
                     } catch (final NumberFormatException ex) {
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 "Error reading " + parameters[0] + ". It isn't a valid report id");
                     }
                 } else {
@@ -188,7 +189,7 @@ public class ReportCommand extends AbstractCommand {
                 }
                 break;
             case READ_EXECUTION:
-                final String readExecutionErrorMessage = UsageMessages.optionCommandMessage(
+                final String readExecutionErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --read-execution {EXECUTION-ID} {EXECUTION-ID} [...]");
 
                 if (parameters.length >= 1) {
@@ -203,14 +204,14 @@ public class ReportCommand extends AbstractCommand {
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             System.out.println("Error:");
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage(" - Report " + parameter + " doesn't exists!");
+                                Messages.printMessage(" - Report " + parameter + " doesn't exists!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                                UsageMessages.printErrorMessage("You cannot delete report " + parameter);
+                                Messages.printMessage("You cannot delete report " + parameter);
                             } else {
-                                UsageMessages.printErrorMessage(ex.getMessage());
+                                Messages.printMessage(ex.getMessage());
                             }
                         } catch (final NumberFormatException ex) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Error reading " + parameter + ". It isn't a valid report id");
                         }
                     }
@@ -219,7 +220,7 @@ public class ReportCommand extends AbstractCommand {
                 }
                 break;
             case DELETE_EXECUTION:
-                final String deleteExecutionErrorMessage = UsageMessages.optionCommandMessage(
+                final String deleteExecutionErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --delete-execution {EXECUTION-ID} {EXECUTION-ID} [...]");
 
                 if (parameters.length >= 1) {
@@ -246,7 +247,7 @@ public class ReportCommand extends AbstractCommand {
                 }
                 break;
             case EXPORT_EXECUTION_RESULT:
-                final String exportExecutionErrorMessage = UsageMessages.optionCommandMessage(
+                final String exportExecutionErrorMessage = Messages.optionCommandMessage(
                         "Usage: report --export-execution-result {EXECUTION-ID} {EXECUTION-ID} [...] {FORMAT}\n"
                         + "          Format: CSV / HTML / PDF / XML / RTF");
 
@@ -262,28 +263,28 @@ public class ReportCommand extends AbstractCommand {
                                 case XML:
                                     final String xmlFinalName = "export_" + exportId + ".xml";
                                     XMLUtils.createXMLFile(report, xmlFinalName);
-                                    UsageMessages.printErrorMessage(xmlFinalName + " successfully created");
+                                    Messages.printMessage(xmlFinalName + " successfully created");
                                     break;
                                 case CSV:
-                                    UsageMessages.printErrorMessage(format + " doesn't supported");
+                                    Messages.printMessage(format + " doesn't supported");
                                     break;
                                 case PDF:
-                                    UsageMessages.printErrorMessage(format + " doesn't supported");
+                                    Messages.printMessage(format + " doesn't supported");
                                     break;
                                 case HTML:
-                                    UsageMessages.printErrorMessage(format + " doesn't supported");
+                                    Messages.printMessage(format + " doesn't supported");
                                     break;
                                 case RTF:
-                                    UsageMessages.printErrorMessage(format + " doesn't supported");
+                                    Messages.printMessage(format + " doesn't supported");
                                     break;
                                 default:
-                                    UsageMessages.printErrorMessage(format + " doesn't supported");
+                                    Messages.printMessage(format + " doesn't supported");
                                     break;
                             }
                         } catch (final WebServiceException | SyncopeClientException ex) {
                             System.out.println("Error:");
                             if (ex.getMessage().startsWith("NotFound")) {
-                                UsageMessages.printErrorMessage("Report " + parameter + " doesn't exists!");
+                                Messages.printMessage("Report " + parameter + " doesn't exists!");
                             } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
                                 System.out.println(" - You cannot delete report " + parameter);
                             } else {
@@ -317,6 +318,11 @@ public class ReportCommand extends AbstractCommand {
                 System.out.println(HELP_MESSAGE);
         }
     }
+    
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
 
     private enum Options {
 
@@ -353,5 +359,13 @@ public class ReportCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+        
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/SchemaCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/SchemaCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/SchemaCommand.java
index 3c182c7..3b9cf18 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/SchemaCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/SchemaCommand.java
@@ -18,13 +18,15 @@
  */
 package org.apache.syncope.client.cli.commands;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.client.cli.messages.UsageMessages;
+import org.apache.syncope.client.cli.messages.Messages;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
@@ -67,7 +69,7 @@ public class SchemaCommand extends AbstractCommand {
         final SchemaService schemaService = SyncopeServices.get(SchemaService.class);
         switch (Options.fromName(input.getOption())) {
             case LIST:
-                final String listErrorMessage = UsageMessages.optionCommandMessage(
+                final String listErrorMessage = Messages.optionCommandMessage(
                         "schema --list {SCHEMA-TYPE}\n"
                         + "   Schema type: PLAIN / DERIVED / VIRTUAL");
                 if (parameters.length == 1) {
@@ -95,9 +97,9 @@ public class SchemaCommand extends AbstractCommand {
                         }
                         System.out.println("");
                     } catch (final SyncopeClientException ex) {
-                        UsageMessages.printErrorMessage(ex.getMessage());
+                        Messages.printMessage(ex.getMessage());
                     } catch (final IllegalArgumentException ex) {
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 input.firstParameter() + " isn't a valid schema type, try with:");
                         for (final SchemaType type : SchemaType.values()) {
                             System.out.println("  *** " + type.name());
@@ -120,7 +122,7 @@ public class SchemaCommand extends AbstractCommand {
                         System.out.println("");
                     }
                 } catch (final SyncopeClientException | WebServiceException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case LIST_PLAIN:
@@ -134,7 +136,7 @@ public class SchemaCommand extends AbstractCommand {
                     }
                     System.out.println("");
                 } catch (final SyncopeClientException | WebServiceException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case LIST_DERIVED:
@@ -146,7 +148,7 @@ public class SchemaCommand extends AbstractCommand {
                     }
                     System.out.println("");
                 } catch (final SyncopeClientException | WebServiceException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case LIST_VIRTUAL:
@@ -157,11 +159,11 @@ public class SchemaCommand extends AbstractCommand {
                     }
                     System.out.println("");
                 } catch (final SyncopeClientException | WebServiceException ex) {
-                    UsageMessages.printErrorMessage(ex.getMessage());
+                    Messages.printMessage(ex.getMessage());
                 }
                 break;
             case READ:
-                final String readErrorMessage = UsageMessages.optionCommandMessage(
+                final String readErrorMessage = Messages.optionCommandMessage(
                         "schema --read {SCHEMA-TYPE} {SCHEMA-KEY}\n"
                         + "   Schema type: PLAIN / DERIVED / VIRTUAL");
                 if (parameters.length >= 2) {
@@ -212,15 +214,15 @@ public class SchemaCommand extends AbstractCommand {
                         }
                     } catch (final SyncopeClientException | WebServiceException ex) {
                         if (ex.getMessage().startsWith("NotFound")) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Schema " + parameters[0] + " doesn't exists!");
                         } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                            UsageMessages.printErrorMessage("You cannot delete schema " + parameters[0]);
+                            Messages.printMessage("You cannot delete schema " + parameters[0]);
                         } else {
-                            UsageMessages.printErrorMessage(ex.getMessage());
+                            Messages.printMessage(ex.getMessage());
                         }
                     } catch (final IllegalArgumentException ex) {
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 parameters[0] + " isn't a valid schema type, try with:");
                         for (final SchemaType type : SchemaType.values()) {
                             System.out.println("  *** " + type.name());
@@ -243,16 +245,16 @@ public class SchemaCommand extends AbstractCommand {
                         }
                     } catch (final SyncopeClientException | WebServiceException ex) {
                         if (ex.getMessage().startsWith("NotFound")) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "Schema " + parameters[0] + " doesn't exists!");
                         } else if (ex.getMessage().startsWith("DataIntegrityViolation")) {
-                            UsageMessages.printErrorMessage(
+                            Messages.printMessage(
                                     "You cannot delete schema " + parameters[0]);
                         } else {
-                            UsageMessages.printErrorMessage(ex.getMessage());
+                            Messages.printMessage(ex.getMessage());
                         }
                     } catch (final IllegalArgumentException ex) {
-                        UsageMessages.printErrorMessage(
+                        Messages.printMessage(
                                 parameters[0] + " isn't a valid schema type, try with:");
                         for (final SchemaType type : SchemaType.values()) {
                             System.out.println("  *** " + type.name());
@@ -273,6 +275,11 @@ public class SchemaCommand extends AbstractCommand {
         }
     }
 
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
+
     private enum Options {
 
         HELP("--help"),
@@ -307,5 +314,13 @@ public class SchemaCommand extends AbstractCommand {
             }
             return optionToReturn;
         }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final Options value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/commands/install/InstallCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/install/InstallCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/install/InstallCommand.java
index 35441d1..e049a28 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/install/InstallCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/install/InstallCommand.java
@@ -41,7 +41,7 @@ public class InstallCommand extends AbstractCommand {
 
     private static final Logger LOG = LoggerFactory.getLogger(LoggerCommand.class);
 
-    private static final String HELP_MESSAGE = "Usage: logger [options]\n"
+    private static final String HELP_MESSAGE = "Usage: install [options]\n"
             + "  Options:\n"
             + "    --help \n"
             + "    --setup";
@@ -265,6 +265,11 @@ public class InstallCommand extends AbstractCommand {
         }
     }
 
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
+
     private enum Options {
 
         HELP("--help"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/4133c240/client/cli/src/main/java/org/apache/syncope/client/cli/messages/Messages.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/messages/Messages.java b/client/cli/src/main/java/org/apache/syncope/client/cli/messages/Messages.java
new file mode 100644
index 0000000..9be3813
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/messages/Messages.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.messages;
+
+public final class Messages {
+
+    private static final String OPTION_COMMAND_MESSAGE_TEMPLATE = "\n - Usage: %s\n";
+
+    public static String optionCommandMessage(final String message) {
+        return String.format(OPTION_COMMAND_MESSAGE_TEMPLATE, message);
+    }
+
+    public static void printMessage(final String... messages) {
+        final StringBuilder messageBuilder = new StringBuilder("\n");
+        for (final String message : messages) {
+            messageBuilder.append(" - ").append(message).append("\n");
+        }
+        System.out.println(messageBuilder.toString());
+    }
+
+    private Messages() {
+
+    }
+}