From c780f75a684e337357b723443ad2503ddff4af1e Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Mon, 23 Jul 2007 08:04:48 +0000
Subject: [PATCH] This commit corresponds to the following issues: https://opends.dev.java.net/issues/show_bug.cgi?id=1340 https://opends.dev.java.net/issues/show_bug.cgi?id=1341

---
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java   |   43 
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java               |  147 +++
 opends/src/server/org/opends/server/messages/ToolMessages.java                            |   41 
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java            |  944 ++++++++++++++++++++++
 opends/src/ads/org/opends/admin/ads/ADSContext.java                                       |  160 +++
 opends/src/server/org/opends/server/tools/ToolConstants.java                              |   33 
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java            |  193 ++++
 opends/src/server/org/opends/server/messages/AdminMessages.java                           |   95 ++
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java       |  742 ++++++++++-------
 opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java              |  107 --
 opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java |    2 
 11 files changed, 2,046 insertions(+), 461 deletions(-)

diff --git a/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opends/src/ads/org/opends/admin/ads/ADSContext.java
index c100998..43ebe03 100644
--- a/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -61,6 +61,29 @@
 {
   private static final Logger LOG =
     Logger.getLogger(ADSContext.class.getName());
+
+  /**
+   * Enumeration containing the different server properties syntaxes
+   * that could be stored in the ADS.
+   */
+  public enum ServerPropertySyntax
+  {
+    /**
+     * String syntax.
+     */
+    STRING,
+
+    /**
+     * Integer syntax.
+     */
+    INTEGER,
+
+    /**
+     * Boolean syntax.
+     */
+    BOOLEAN;
+  };
+
   /**
    * Enumeration containing the different server properties that are stored in
    * the ADS.
@@ -70,80 +93,83 @@
     /**
      * The ID used to identify the server.
      */
-    ID("id"),
+    ID("id",ServerPropertySyntax.STRING),
     /**
      * The host name of the server.
      */
-    HOST_NAME("hostname"),
+    HOST_NAME("hostname",ServerPropertySyntax.STRING),
     /**
      * The LDAP port of the server.
      */
-    LDAP_PORT("ldapport"),
+    LDAP_PORT("ldapport",ServerPropertySyntax.INTEGER),
     /**
      * The JMX port of the server.
      */
-    JMX_PORT("jmxport"),
+    JMX_PORT("jmxport",ServerPropertySyntax.INTEGER),
     /**
      * The JMX secure port of the server.
      */
-    JMXS_PORT("jmxsport"),
+    JMXS_PORT("jmxsport",ServerPropertySyntax.INTEGER),
     /**
      * The LDAPS port of the server.
      */
-    LDAPS_PORT("ldapsport"),
+    LDAPS_PORT("ldapsport",ServerPropertySyntax.INTEGER),
     /**
      * The certificate used by the server.
      */
-    CERTIFICATE("certificate"),
+    CERTIFICATE("certificate",ServerPropertySyntax.STRING),
     /**
      * The path where the server is installed.
      */
-    INSTANCE_PATH("instancepath"),
+    INSTANCE_PATH("instancepath",ServerPropertySyntax.STRING),
     /**
      * The description of the server.
      */
-    DESCRIPTION("description"),
+    DESCRIPTION("description",ServerPropertySyntax.STRING),
     /**
      * The OS of the machine where the server is installed.
      */
-    HOST_OS("os"),
+    HOST_OS("os",ServerPropertySyntax.STRING),
     /**
      * Whether LDAP is enabled or not.
      */
-    LDAP_ENABLED("ldapEnabled"),
+    LDAP_ENABLED("ldapEnabled",ServerPropertySyntax.BOOLEAN),
     /**
      * Whether LDAPS is enabled or not.
      */
-    LDAPS_ENABLED("ldapsEnabled"),
+    LDAPS_ENABLED("ldapsEnabled",ServerPropertySyntax.BOOLEAN),
     /**
      * Whether StartTLS is enabled or not.
      */
-    STARTTLS_ENABLED("startTLSEnabled"),
+    STARTTLS_ENABLED("startTLSEnabled",ServerPropertySyntax.BOOLEAN),
     /**
      * Whether JMX is enabled or not.
      */
-    JMX_ENABLED("jmxEnabled"),
+    JMX_ENABLED("jmxEnabled",ServerPropertySyntax.BOOLEAN),
     /**
      * Whether JMX is enabled or not.
      */
-    JMXS_ENABLED("jmxsEnabled"),
+    JMXS_ENABLED("jmxsEnabled",ServerPropertySyntax.BOOLEAN),
     /**
      * The location of the server.
      */
-    LOCATION("location"),
+    LOCATION("location",ServerPropertySyntax.STRING),
     /**
      * The groups to which this server belongs.
      */
-    GROUPS("memberofgroups");
+    GROUPS("memberofgroups",ServerPropertySyntax.STRING);
 
     private String attrName;
+    private ServerPropertySyntax attSyntax;
+
     /**
      * Private constructor.
      * @param n the name of the attribute.
      */
-    private ServerProperty(String n)
+    private ServerProperty(String n,ServerPropertySyntax s)
     {
       attrName = n;
+      attSyntax = s ;
     }
 
     /**
@@ -154,8 +180,38 @@
     {
       return attrName;
     }
+
+    /**
+     * Returns the attribute syntax.
+     * @return the attribute syntax.
+     */
+    public ServerPropertySyntax getAttributeSyntax()
+    {
+      return attSyntax;
+    }
   };
 
+  private static HashMap<String, ServerProperty> nameToServerProperty = null;
+  /**
+   * Get a ServerProperty associated to a name.
+   * @param name The name of the property to retreive.
+   *
+   * @return The corresponding ServerProperty or null if name
+   * doesn't matech with an existing property.
+   */
+  public static ServerProperty getPropFromName(String name)
+  {
+    if (nameToServerProperty == null)
+    {
+      nameToServerProperty = new HashMap<String, ServerProperty>();
+      for (ServerProperty s : ServerProperty.values())
+      {
+        nameToServerProperty.put(s.getAttributeName(), s);
+      }
+    }
+    return nameToServerProperty.get(name);
+  }
+
   /**
    * The list of server properties that are multivalued.
    */
@@ -294,15 +350,27 @@
   /**
    * Method called to udpate the properties of a server in the ADS.
    * @param serverProperties the new properties of the server.
+   * @param newServerId The new server Identifier, or null.
    * @throws ADSContextException if the server could not be registered.
    */
-  public void updateServer(Map<ServerProperty, Object> serverProperties)
-  throws ADSContextException
+  public void updateServer(Map<ServerProperty, Object> serverProperties,
+      String newServerId) throws ADSContextException
   {
     LdapName dn = makeDNFromServerProperties(serverProperties);
-    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
+
     try
     {
+      if (newServerId != null)
+      {
+        HashMap<ServerProperty, Object> newServerProps =
+          new HashMap<ServerProperty, Object>(serverProperties);
+        newServerProps.put(ServerProperty.ID,newServerId);
+        LdapName newDn = makeDNFromServerProperties(newServerProps);
+        dirContext.rename(dn, newDn);
+        dn = newDn ;
+        serverProperties.put(ServerProperty.ID,newServerId);
+      }
+      BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
       dirContext.modifyAttributes(dn, InitialLdapContext.REPLACE_ATTRIBUTE,
           attrs);
     }
@@ -391,7 +459,7 @@
     {
       if (x.getError() == ADSContextException.ErrorType.ALREADY_REGISTERED)
       {
-        updateServer(serverProperties);
+        updateServer(serverProperties, null);
       }
       else
       {
@@ -950,10 +1018,10 @@
    * port.
    * @throws ADSContextException if something goes wrong.
    */
-  private static LdapName makeDNFromHostnamePort(String hostnamePort)
+  private static LdapName makeDNFromServerUniqueId(String serverUniqueId)
   throws ADSContextException
   {
-    String cnValue = Rdn.escapeValue(hostnamePort);
+    String cnValue = Rdn.escapeValue(serverUniqueId);
     return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
   }
 
@@ -991,6 +1059,12 @@
   private static LdapName makeDNFromServerProperties(
       Map<ServerProperty, Object> serverProperties) throws ADSContextException
   {
+    String serverID ;
+    if ( (serverID = getServerID(serverProperties)) != null )
+    {
+      return makeDNFromServerUniqueId(serverID);
+    }
+
     String hostname = getHostname(serverProperties);
     try
     {
@@ -1000,12 +1074,29 @@
     catch (ADSContextException ace)
     {
       ServerDescriptor s = ServerDescriptor.createStandalone(serverProperties);
-      return makeDNFromHostnamePort(s.getHostPort(true));
+      return makeDNFromServerUniqueId(s.getHostPort(true));
     }
   }
 
   /**
    * This method returns the DN of the entry that corresponds to the given
+   * server properties.
+   * @param serverProperties the server properties.
+   * @return the DN of the entry that corresponds to the given server
+   * properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public static String getServerIdFromServerProperties(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    LdapName ldapName = makeDNFromServerProperties(serverProperties);
+    String rdn = ldapName.get(ldapName.size() -1);
+    int pos = rdn.indexOf("=");
+    return rdn.substring(pos+1);
+  }
+
+  /**
+   * This method returns the DN of the entry that corresponds to the given
    * administrator properties.
    * @param adminProperties the administrator properties.
    * @return the DN of the entry that corresponds to the given administrator
@@ -1422,6 +1513,25 @@
   }
 
   /**
+   * Returns the Server ID for the given properties.
+   * @param serverProperties the server properties.
+   * @return the server ID for the given properties or null.
+   */
+  private static String getServerID(
+      Map<ServerProperty, Object> serverProperties)
+  {
+    String result = (String) serverProperties.get(ServerProperty.ID);
+    if (result != null)
+    {
+      if (result.length() == 0)
+      {
+        result = null;
+      }
+    }
+    return result;
+  }
+
+  /**
    * Returns the install path for the given properties.
    * @param serverProperties the server properties.
    * @return the install path for the given properties.
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java
index 28f3f28..13bf51f 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java
@@ -31,7 +31,12 @@
 
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+
+import javax.naming.NamingException;
+import javax.naming.ldap.InitialLdapContext;
 
 import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.ADSContextException;
@@ -41,7 +46,6 @@
 import org.opends.server.util.args.BooleanArgument;
 import org.opends.server.util.args.StringArgument;
 import org.opends.server.util.args.SubCommand;
-import org.opends.server.util.args.SubCommandArgumentParser;
 
 /**
  * This class is handling server group CLI.
@@ -49,6 +53,11 @@
 public class DsFrameworkCliAds implements DsFrameworkCliSubCommandGroup
 {
   /**
+   * The subcommand Parser.
+   */
+  DsFrameworkCliParser argParser ;
+
+  /**
    * The enumeration containing the different subCommand names.
    */
   private enum SubCommandNameEnum
@@ -118,16 +127,62 @@
   private StringArgument deleteAdsBackendNameArg;
 
   /**
+   * The subcommand list.
+   */
+  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
+
+  /**
+   * Indicates whether this subCommand should be hidden in the usage
+   * information.
+   */
+  private boolean isHidden;
+
+  /**
+   * The subcommand group name.
+   */
+  private String groupName;
+
+  /**
    * {@inheritDoc}
    */
-  public void initializeCliGroup(SubCommandArgumentParser argParser,
+  public Set<SubCommand> getSubCommands()
+  {
+    return subCommands;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isHidden()
+  {
+    return isHidden ;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String getGroupName()
+  {
+    return groupName ;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeCliGroup(DsFrameworkCliParser argParser,
       BooleanArgument verboseArg)
       throws ArgumentException
   {
+
+    isHidden = true;
+    groupName = "ads";
+    this.argParser = argParser;
+
     // Create-ads subcommand
     createAdsSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_ADS
         .toString(), MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION);
     createAdsSubCmd.setHidden(true);
+    subCommands.add(createAdsSubCmd);
 
     createAdsBackendNameArg = new StringArgument("backendName",
         OPTION_SHORT_BACKENDNAME, OPTION_LONG_BACKENDNAME, true, true,
@@ -139,6 +194,7 @@
     deleteAdsSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_ADS
         .toString(), MSGID_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION);
     deleteAdsSubCmd.setHidden(true);
+    subCommands.add(deleteAdsSubCmd);
 
     deleteAdsBackendNameArg = new StringArgument("backendName",
         OPTION_SHORT_BACKENDNAME, OPTION_LONG_BACKENDNAME, true, true,
@@ -159,29 +215,80 @@
   /**
    * {@inheritDoc}
    */
-  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
-      OutputStream outStream, OutputStream errStream)
-      throws ADSContextException
+  public ReturnCode performSubCommand(SubCommand subCmd, OutputStream outStream,
+      OutputStream errStream)
+      throws ADSContextException, ArgumentException
   {
-    //
-    // create-ads subcommand
-    if (subCmd.getName().equals(createAdsSubCmd.getName()))
+    ADSContext adsCtx = null ;
+    InitialLdapContext ctx = null ;
+
+    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
+
+    try
     {
-      String backendName = createAdsBackendNameArg.getValue();
-      adsContext.createAdminData(backendName);
-      return ReturnCode.SUCCESSFUL;
+      //
+      // create-ads subcommand
+      if (subCmd.getName().equals(createAdsSubCmd.getName()))
+      {
+        String backendName = createAdsBackendNameArg.getValue();
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        adsCtx.createAdminData(backendName);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
+      {
+        String backendName = deleteAdsBackendNameArg.getValue();
+        ADSContextHelper helper = new ADSContextHelper();
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        helper
+            .removeAdministrationSuffix(adsCtx.getDirContext(), backendName);
+        returnCode =  ReturnCode.SUCCESSFUL;
+      }
+      else
+      {
+        // Should never occurs: If we are here, it means that the code to
+        // handle to subcommand is not yet written.
+        returnCode = ReturnCode.ERROR_UNEXPECTED;
+      }
     }
-    else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
+    catch (ADSContextException e)
     {
-      String backendName = deleteAdsBackendNameArg.getValue();
-      ADSContextHelper helper = new ADSContextHelper();
-      helper.removeAdministrationSuffix(adsContext.getDirContext(),
-          backendName);
-      return ReturnCode.SUCCESSFUL;
+      if (ctx != null)
+      {
+        try
+        {
+          ctx.close();
+        }
+        catch (NamingException x)
+        {
+        }
+      }
+      throw e;
     }
 
-    // Should never occur: If we are here, it means that the code to
-    // handle to subcommand is not yet written.
-    return ReturnCode.ERROR_UNEXPECTED;
+    // Close the connection, if needed
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (NamingException x)
+      {
+      }
+    }
+
+    // return part
+    return returnCode;
   }
 }
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java
index 3db3c5c..55766c6 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java
@@ -29,12 +29,7 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 
-import javax.naming.NamingException;
-import javax.naming.ldap.InitialLdapContext;
-
-import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.ADSContextException;
-import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.server.admin.ClassLoaderProvider;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.InitializationException;
@@ -208,7 +203,12 @@
 
     if (argParser.getSubCommand() == null)
     {
-      err.println(argParser.getUsage());
+      int msgID = MSGID_ERROR_PARSING_ARGS;
+      String message = getMessage(msgID,
+          getMessage(MSGID_DSCFG_ERROR_MISSING_SUBCOMMAND));
+      err.println(wrapText(message, MAX_LINE_WIDTH));
+      err.println();
+      err.println(argParser.getHelpUsageReference());
       return ReturnCode.ERROR_PARSING_ARGS.getReturnCode();
     }
 
@@ -219,71 +219,10 @@
       return ret;
     }
 
+    // Check if we need a connection
 
-    // Get connection parameters
-    String host = argParser.getHostName() ;
-    String port = argParser.getPort() ;
-    String dn   = argParser.getBindDN() ;
-    String pwd  = argParser.getBindPassword(dn,out,err) ;
-
-    // Try to connect
-    InitialLdapContext ctx = null;
     ReturnCode returnCode = ReturnCode.SUCCESSFUL;
-    if (argParser.useSSL())
-    {
-      String ldapsUrl = "ldaps://" + host + ":" + port;
-      try
-      {
-        ctx = ConnectionUtils.createLdapsContext(ldapsUrl,
-            dn, pwd, ConnectionUtils.getDefaultLDAPTimeout(), null,
-             argParser.getTrustManager(), argParser.getKeyManager());
-      }
-      catch (NamingException e)
-      {
-        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
-        String message = getMessage(msgID, host);
 
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
-      }
-    }
-    else
-    if (argParser.startTLS())
-    {
-      String ldapUrl = "ldap://" + host + ":" + port;
-      try
-      {
-        ctx = ConnectionUtils.createStartTLSContext(ldapUrl, dn, pwd,
-            ConnectionUtils.getDefaultLDAPTimeout(), null, argParser
-                .getTrustManager(), argParser.getKeyManager(), null);
-      }
-      catch (NamingException e)
-      {
-        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
-        String message = getMessage(msgID, host);
-
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
-      }
-    }
-    else
-    {
-      String ldapUrl = "ldap://" + host + ":" + port;
-      try
-      {
-        ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
-            ConnectionUtils.getDefaultLDAPTimeout(), null);
-      }
-      catch (NamingException e)
-      {
-        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
-        String message = getMessage(msgID, host);
-
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
-      }
-    }
-    ADSContext adsContext = new ADSContext(ctx);
 
     // Should we initialize the server in client mode?
     if (initializeServer)
@@ -298,27 +237,21 @@
       }
       catch (InitializationException e)
       {
-        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
-        String message = getMessage(msgID, host);
-
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
+        err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+        return ReturnCode.ERROR_UNEXPECTED.getReturnCode();
       }
       catch (IllegalStateException e)
       {
-        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
-        String message = getMessage(msgID, host);
-
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
+        err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+        return ReturnCode.ERROR_UNEXPECTED.getReturnCode();
       }
     }
 
     // perform the subCommand
-    ADSContextException adsException = null ;
+    ADSContextException adsException = null;
     try
     {
-      returnCode = argParser.performSubCommand(adsContext, out, err);
+      returnCode = argParser.performSubCommand(out, err);
     }
     catch (ADSContextException e)
     {
@@ -330,15 +263,13 @@
         returnCode = ReturnCode.ERROR_UNEXPECTED;
       }
     }
+    catch (ArgumentException ae)
+    {
+      int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
+      String message = getMessage(msgID, ae.getMessage());
 
-    // deconnection
-    try
-    {
-      ctx.close();
-    }
-    catch (NamingException e)
-    {
-      // TODO Should we do something ?
+      err.println(wrapText(message, MAX_LINE_WIDTH));
+      return ReturnCode.CANNOT_INITIALIZE_ARGS.getReturnCode();
     }
 
     int msgID = returnCode.getMessageId();
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
index 40a7338..dd1ae80 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
@@ -27,6 +27,7 @@
 package org.opends.server.admin.client.cli;
 
 import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.messages.AdminMessages.*;
 import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.messages.ToolMessages.*;
 import static org.opends.server.tools.ToolConstants.*;
@@ -41,16 +42,22 @@
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
+import java.util.Comparator;
 import java.util.HashSet;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.naming.NamingException;
+import javax.naming.ldap.InitialLdapContext;
 import javax.net.ssl.KeyManager;
 
-import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.ADSContextException;
 import org.opends.admin.ads.util.ApplicationKeyManager;
 import org.opends.admin.ads.util.ApplicationTrustManager;
+import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.DebugLogLevel;
@@ -71,6 +78,11 @@
 public class DsFrameworkCliParser extends SubCommandArgumentParser
 {
   /**
+   * End Of Line.
+   */
+  private String EOL = System.getProperty("line.separator");
+
+  /**
    * The tracer object for the debug logger.
    */
   private static final DebugTracer TRACER = getTracer();
@@ -167,7 +179,7 @@
     Logger.getLogger(DsFrameworkCliParser.class.getName());
 
   /**
-   * The diferent CLI group.
+   * The different CLI group.
    */
   public HashSet<DsFrameworkCliSubCommandGroup> cliGroup;
 
@@ -214,14 +226,48 @@
     // ads  Group cli
     cliGroup.add(new DsFrameworkCliAds());
 
-    // Server Group cli
+    // Server-group Group cli
     cliGroup.add(new DsFrameworkCliServerGroup());
 
+    // Server Group cli
+    cliGroup.add(new DsFrameworkCliServer());
+
     // Initialization
+    Comparator<SubCommand> c = new Comparator<SubCommand>() {
+
+      public int compare(SubCommand o1, SubCommand o2) {
+        return o1.getName().compareTo(o2.getName());
+      }
+    };
+
+    SortedSet<SubCommand> allSubCommands = new TreeSet<SubCommand>(c);
+
     for (DsFrameworkCliSubCommandGroup oneCli : cliGroup)
     {
       oneCli.initializeCliGroup(this, verboseArg);
+      Set<SubCommand> oneCliSubCmds = oneCli.getSubCommands() ;
+      allSubCommands.addAll(oneCliSubCmds);
+
+      // register group help
+      String grpName = oneCli.getGroupName();
+      String option = OPTION_LONG_HELP + "-" + grpName;
+      BooleanArgument arg = new BooleanArgument(option, null, option,
+          MSGID_DSCFG_DESCRIPTION_SHOW_GROUP_USAGE, grpName);
+      addGlobalArgument(arg);
+      arg.setHidden(oneCli.isHidden());
+      TreeSet<SubCommand> subCmds = new TreeSet<SubCommand>(c);
+      subCmds.addAll(oneCliSubCmds);
+      setUsageGroupArgument(arg, subCmds);
     }
+
+    // Register the --help-all argument.
+    String option = OPTION_LONG_HELP + "-all";
+    BooleanArgument arg = new BooleanArgument(option, null, option,
+        MSGID_DSCFG_DESCRIPTION_SHOW_GROUP_USAGE_ALL);
+
+    addGlobalArgument(arg);
+    setUsageGroupArgument(arg, allSubCommands);
+
   }
 
   /**
@@ -395,7 +441,7 @@
    * @return The password stored into the specified file on by the
    *         command line argument, or prompts it if not specified.
    */
-  public String getBindPassword(String dn, PrintStream out, PrintStream err)
+  public String getBindPassword(String dn, OutputStream out, OutputStream err)
   {
     if (bindPasswordArg.isPresent())
     {
@@ -405,7 +451,7 @@
         // read the password from the stdin.
         try
         {
-          out.print(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn));
+          out.write(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn).getBytes());
           char[] pwChars = PasswordReader.readPassword();
           bindPasswordValue = new String(pwChars);
         } catch(Exception ex)
@@ -414,7 +460,14 @@
           {
             TRACER.debugCaught(DebugLogLevel.ERROR, ex);
           }
-          err.println(wrapText(ex.getMessage(), MAX_LINE_WIDTH));
+          try
+          {
+            err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes());
+            err.write(EOL.getBytes());
+          }
+          catch (IOException e)
+          {
+          }
           return null;
         }
       }
@@ -430,7 +483,7 @@
       // read the password from the stdin.
       try
       {
-        out.print(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn));
+        out.write(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn).getBytes());
         char[] pwChars = PasswordReader.readPassword();
         return new String(pwChars);
       }
@@ -440,7 +493,14 @@
         {
           TRACER.debugCaught(DebugLogLevel.ERROR, ex);
         }
-        err.println(wrapText(ex.getMessage(), MAX_LINE_WIDTH));
+        try
+        {
+          err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes());
+          err.write(EOL.getBytes());
+        }
+        catch (IOException e)
+        {
+        }
         return null;
       }
     }
@@ -448,22 +508,20 @@
 
   /**
    * Handle the subcommand.
-   *
-   * @param adsContext
-   *          The context to use to perform ADS operation.
-   *
    * @param  outStream         The output stream to use for standard output.
-   *
    * @param  errStream         The output stream to use for standard error.
    *
    * @return the return code
    * @throws ADSContextException
    *           If there is a problem with when trying to perform the
    *           operation.
+   * @throws ArgumentException
+   *           If there is a problem with any of the parameters used
+   *           to execute this subcommand.
    */
-  public ReturnCode performSubCommand(ADSContext adsContext,
-      OutputStream outStream, OutputStream errStream)
-    throws ADSContextException
+  public ReturnCode performSubCommand(OutputStream outStream,
+      OutputStream errStream)
+    throws ADSContextException, ArgumentException
   {
     SubCommand subCmd = getSubCommand();
 
@@ -471,8 +529,7 @@
     {
       if (oneCli.isSubCommand(subCmd))
       {
-        return oneCli.performSubCommand(adsContext, subCmd, outStream,
-            errStream);
+        return oneCli.performSubCommand( subCmd, outStream, errStream);
       }
     }
 
@@ -767,4 +824,104 @@
     return ReturnCode.SUCCESSFUL_NOP.getReturnCode();
   }
 
+
+  /**
+   * Get the InitialLdapContext that has to be used for the ADS.
+   * @param  out         The output stream to use for standard output.
+   * @param  err         The output stream to use for standard error.
+   *
+   * @return The InitialLdapContext that has to be used for the ADS.
+   */
+  public InitialLdapContext getContext(OutputStream out, OutputStream err)
+  {
+    // Get connection parameters
+    String host = null ;
+    String port = null;
+    String dn   = null ;
+    String pwd  = null;
+    InitialLdapContext ctx = null;
+
+    // Get connection parameters
+    host = getHostName();
+    port = getPort();
+    dn   = getBindDN();
+    pwd  = getBindPassword(dn, out, err);
+
+    // Try to connect
+    if (useSSL())
+    {
+      String ldapsUrl = "ldaps://" + host + ":" + port;
+      try
+      {
+        ctx = ConnectionUtils.createLdapsContext(ldapsUrl, dn, pwd,
+            ConnectionUtils.getDefaultLDAPTimeout(), null,getTrustManager(),
+            getKeyManager());
+      }
+      catch (NamingException e)
+      {
+        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
+        String message = getMessage(msgID, host);
+
+        try
+        {
+          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
+          err.write(EOL.getBytes());
+        }
+        catch (IOException e1)
+        {
+        }
+        return null;
+      }
+    }
+    else if (startTLS())
+    {
+      String ldapUrl = "ldap://" + host + ":" + port;
+      try
+      {
+        ctx = ConnectionUtils.createStartTLSContext(ldapUrl, dn, pwd,
+            ConnectionUtils.getDefaultLDAPTimeout(), null, getTrustManager(),
+            getKeyManager(), null);
+      }
+      catch (NamingException e)
+      {
+        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
+        String message = getMessage(msgID, host);
+
+        try
+        {
+          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
+          err.write(EOL.getBytes());
+        }
+        catch (IOException e1)
+        {
+        }
+        return null;
+      }
+    }
+    else
+    {
+      String ldapUrl = "ldap://" + host + ":" + port;
+      try
+      {
+        ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
+            ConnectionUtils.getDefaultLDAPTimeout(), null);
+      }
+      catch (NamingException e)
+      {
+        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
+        String message = getMessage(msgID, host);
+
+        try
+        {
+          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
+          err.write(EOL.getBytes());
+        }
+        catch (IOException e1)
+        {
+        }
+        return null;
+      }
+    }
+    return ctx;
+  }
 }
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
new file mode 100644
index 0000000..ec4ab37
--- /dev/null
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
@@ -0,0 +1,944 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.cli;
+
+import static org.opends.server.messages.AdminMessages.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
+import static org.opends.server.messages.ToolMessages.*;
+import static org.opends.server.tools.ToolConstants.*;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.NamingException;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.opends.admin.ads.ADSContext;
+import org.opends.admin.ads.ADSContextException;
+import org.opends.admin.ads.ADSContext.ServerProperty;
+import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
+import org.opends.server.tools.dsconfig.ArgumentExceptionFactory;
+import org.opends.server.tools.dsconfig.Messages;
+import org.opends.server.util.args.Argument;
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.BooleanArgument;
+import org.opends.server.util.args.IntegerArgument;
+import org.opends.server.util.args.StringArgument;
+import org.opends.server.util.args.SubCommand;
+import org.opends.server.util.table.TableBuilder;
+import org.opends.server.util.table.TextTablePrinter;
+
+/**
+ * This class is handling server group CLI.
+ */
+public class DsFrameworkCliServer implements DsFrameworkCliSubCommandGroup
+{
+  // Strings used in property help.
+  private static final String KEY_PREFIX = "help-properties.";
+
+  private final static String DESCRIPTION_OPTIONS_TITLE = Messages
+      .getString(KEY_PREFIX + "description.options"); //$NON-NLS-1$
+
+  private final static String DESCRIPTION_OPTIONS_READ = Messages
+      .getString(KEY_PREFIX + "description.read"); //$NON-NLS-1$
+
+  private final static String DESCRIPTION_OPTIONS_WRITE = Messages
+      .getString(KEY_PREFIX + "description.write"); //$NON-NLS-1$
+
+  private final static String DESCRIPTION_OPTIONS_MANDATORY = Messages
+      .getString(KEY_PREFIX + "description.mandatory"); //$NON-NLS-1$
+
+  private final static String DESCRIPTION_OPTIONS_SINGLE = Messages
+      .getString(KEY_PREFIX + "description.single-valued"); //$NON-NLS-1$
+
+  /**
+   * The subcommand Parser.
+   */
+  private DsFrameworkCliParser argParser;
+
+  /**
+   * The verbose argument.
+   */
+  private BooleanArgument verboseArg;
+
+  /**
+   * The enumeration containing the different subCommand names.
+   */
+  private enum SubCommandNameEnum
+  {
+    /**
+     * The register-server subcommand.
+     */
+    REGISTER_SERVER("register-server"),
+
+    /**
+     * The unregister-server subcommand.
+     */
+    UNREGISTER_SERVER("unregister-server"),
+
+    /**
+     * The list-servers subcommand.
+     */
+    LIST_SERVERS("list-servers"),
+
+    /**
+     * The get-server-properties subcommand.
+     */
+    GET_SERVER_PROPERTIES("get-server-properties"),
+
+    /**
+     * The set-server-propertiess subcommand.
+     */
+    SET_SERVER_PROPERTIES("set-server-properties"),
+
+    /**
+     * The list-servers subcommand.
+     */
+    LIST_SERVER_PROPERTIES("list-server-properties");
+
+    // String representation of the value.
+    private final String name;
+
+    // Private constructor.
+    private SubCommandNameEnum(String name)
+    {
+      this.name = name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+      return name;
+    }
+
+    // A lookup table for resolving a unit from its name.
+    private static final List<String> nameToSubCmdName;
+    static
+    {
+      nameToSubCmdName = new ArrayList<String>();
+
+      for (SubCommandNameEnum subCmd : SubCommandNameEnum.values())
+      {
+        nameToSubCmdName.add(subCmd.toString());
+      }
+    }
+
+    public static boolean isSubCommand(String name)
+    {
+      return nameToSubCmdName.contains(name);
+    }
+  }
+
+  /**
+   * The 'register-server' subcommand.
+   */
+  private SubCommand registerServerSubCmd;
+
+  /**
+   * The 'serverID' argument of the 'register-server' subcommand.
+   */
+  private StringArgument registerServerServerIdArg;
+
+  /**
+   * The 'serverName' argument of the 'register-server' subcommand.
+   */
+  private StringArgument registerServerSetArg;
+
+  /**
+   * The 'unregister-server' subcommand.
+   */
+  private SubCommand unregisterServerSubCmd;
+
+  /**
+   * The 'serverHost' argument of the 'unregister-server' subcommand.
+   */
+  private StringArgument unregisterServerServerIDArg;
+
+  /**
+   * The 'list-server-properties' subcommand.
+   */
+  private SubCommand listServerPropertiesSubCmd;
+
+  /**
+   * The 'list-servers' subcommand.
+   */
+  private SubCommand listServersSubCmd;
+
+  /**
+   * The 'get-server-properties' subcommand.
+   */
+  private SubCommand getServerPropertiesSubCmd;
+
+  /**
+   * The 'serverID' argument of the 'get-server-properties' subcommand.
+   */
+  private StringArgument getServerPropertiesServerIdArg;
+
+  /**
+   * The 'set-server-properties' subcommand.
+   */
+  private SubCommand setServerPropertiesSubCmd;
+
+  /**
+   * The 'serverID' argument of the 'set-server-properties' subcommand.
+   */
+  private StringArgument setServerPropertiesServerIdArg;
+
+  /**
+   * The 'serverName' argument of the 'set-server-properties' subcommand.
+   */
+  private StringArgument setServerPropertiesSetArg;
+
+  /**
+   * Association between ADSContext enum and properties.
+   */
+  private HashMap<ServerProperty, Argument> serverProperties;
+
+  /**
+   * List of read-only server properties.
+   */
+  private HashSet<ServerProperty> readonlyServerProperties;
+
+  /**
+   * The subcommand list.
+   */
+  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
+
+  /**
+   * Indicates whether this subCommand should be hidden in the usage
+   * information.
+   */
+  private boolean isHidden;
+
+  /**
+   * The subcommand group name.
+   */
+  private String groupName;
+
+  /**
+   * {@inheritDoc}
+   */
+  public Set<SubCommand> getSubCommands()
+  {
+    return subCommands;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isHidden()
+  {
+    return isHidden;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String getGroupName()
+  {
+    return groupName;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeCliGroup(DsFrameworkCliParser argParser,
+      BooleanArgument verboseArg) throws ArgumentException
+  {
+    this.verboseArg = verboseArg;
+    isHidden = false;
+    groupName = "server";
+    this.argParser = argParser;
+
+    // list-server-properties subcommand
+    listServerPropertiesSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.LIST_SERVER_PROPERTIES.toString(),
+        MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION);
+    subCommands.add(listServerPropertiesSubCmd);
+
+    // register-server subcommand
+    registerServerSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.REGISTER_SERVER.toString(),
+        MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION);
+    subCommands.add(registerServerSubCmd);
+
+    registerServerServerIdArg = new StringArgument("serverID", null,
+        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
+        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
+    registerServerSubCmd.addArgument(registerServerServerIdArg);
+
+    registerServerSetArg = new StringArgument(OPTION_LONG_SET,
+        OPTION_SHORT_SET, OPTION_LONG_SET, false, true, true,
+        OPTION_VALUE_SET, null, null, MSGID_DSCFG_DESCRIPTION_PROP_VAL);
+    registerServerSubCmd.addArgument(registerServerSetArg);
+
+    // unregister-server subcommand
+    unregisterServerSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.UNREGISTER_SERVER.toString(),
+        MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION);
+    subCommands.add(unregisterServerSubCmd);
+
+    unregisterServerServerIDArg = new StringArgument("serverID", null,
+        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
+        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
+    unregisterServerSubCmd.addArgument(unregisterServerServerIDArg);
+
+    // list-servers subcommand
+    listServersSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.LIST_SERVERS.toString(),
+        MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION);
+    subCommands.add(listServersSubCmd);
+
+    // get-server-properties subcommand
+    getServerPropertiesSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.GET_SERVER_PROPERTIES.toString(),
+        MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION);
+    subCommands.add(getServerPropertiesSubCmd);
+
+    getServerPropertiesServerIdArg = new StringArgument("serverID", null,
+        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
+        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
+    getServerPropertiesServerIdArg.setMultiValued(true);
+    getServerPropertiesSubCmd.addArgument(getServerPropertiesServerIdArg);
+
+
+    // set-server-properties subcommand
+    setServerPropertiesSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.SET_SERVER_PROPERTIES.toString(),
+        MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION);
+    subCommands.add(setServerPropertiesSubCmd);
+
+    setServerPropertiesServerIdArg = new StringArgument("serverID", null,
+        OPTION_LONG_SERVERID, true, true, OPTION_VALUE_SERVERID,
+        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
+    setServerPropertiesSubCmd.addArgument(setServerPropertiesServerIdArg);
+
+    setServerPropertiesSetArg = new StringArgument(OPTION_LONG_SET,
+        OPTION_SHORT_SET, OPTION_LONG_SET, false, true, true,
+        OPTION_VALUE_SET, null, null, MSGID_DSCFG_DESCRIPTION_PROP_VAL);
+    setServerPropertiesSubCmd.addArgument(setServerPropertiesSetArg);
+
+
+    // Create association between ADSContext enum and server
+    // properties
+    // Server properties are mapped to Argument.
+    serverProperties = new HashMap<ServerProperty, Argument>();
+    readonlyServerProperties = new HashSet<ServerProperty>();
+
+    /**
+     * The ID used to identify the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.ID;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(prop.getAttributeName(), null,
+          prop.getAttributeName(), false, false, true, "", null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The host name of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.HOST_NAME;
+      String attName = prop.getAttributeName();
+      readonlyServerProperties.add(prop);
+      StringArgument arg = new StringArgument(attName, null, attName, true,
+          false, true, "", "localhost", null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The LDAP port of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.LDAP_PORT;
+      String attName = prop.getAttributeName();
+      IntegerArgument arg = new IntegerArgument(attName, null, attName, true,
+          true, true, attName, 389, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The JMX port of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.JMX_PORT;
+      String attName = prop.getAttributeName();
+      IntegerArgument arg = new IntegerArgument(attName, null, attName,
+          false, true, attName, -1);
+      arg.setMultiValued(true);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The JMX secure port of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.JMXS_PORT;
+      String attName = prop.getAttributeName();
+      IntegerArgument arg = new IntegerArgument(attName, null, attName,
+          false, true, attName, -1);
+      arg.setMultiValued(true);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The LDAPS port of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.LDAPS_PORT;
+      String attName = prop.getAttributeName();
+      IntegerArgument arg = new IntegerArgument(attName, null, attName,
+          false, true, attName, -1);
+      arg.setMultiValued(true);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The certificate used by the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.CERTIFICATE;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          false, true, attName, null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The path where the server is installed.
+     */
+    {
+      ServerProperty prop = ServerProperty.INSTANCE_PATH;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          false, true, attName, null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The description of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.DESCRIPTION;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          false, true, attName, null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The OS of the machine where the server is installed.
+     */
+    {
+      ServerProperty prop = ServerProperty.HOST_OS;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          false, true, attName, null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * Whether LDAP is enabled or not.
+     */
+    {
+      ServerProperty prop = ServerProperty.LDAP_ENABLED;
+      String attName = prop.getAttributeName();
+      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
+      arg.setDefaultValue("false");
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * Whether LDAPS is enabled or not.
+     */
+    {
+      ServerProperty prop = ServerProperty.LDAPS_ENABLED;
+      String attName = prop.getAttributeName();
+      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
+      arg.setDefaultValue("false");
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * Whether StartTLS is enabled or not.
+     */
+    {
+      ServerProperty prop = ServerProperty.STARTTLS_ENABLED;
+      String attName = prop.getAttributeName();
+      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
+      arg.setDefaultValue("false");
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * Whether JMX is enabled or not.
+     */
+    {
+      ServerProperty prop = ServerProperty.JMX_ENABLED;
+      String attName = prop.getAttributeName();
+      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
+      arg.setDefaultValue("false");
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * Whether JMXS is enabled or not.
+     */
+    {
+      ServerProperty prop = ServerProperty.JMXS_ENABLED;
+      String attName = prop.getAttributeName();
+      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
+      arg.setDefaultValue("false");
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The location of the server.
+     */
+    {
+      ServerProperty prop = ServerProperty.LOCATION;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          false, true, attName, null, null, -1);
+      serverProperties.put(prop, arg);
+    }
+
+    /**
+     * The list of groups in which the server is registered.
+     */
+    {
+      ServerProperty prop = ServerProperty.GROUPS;
+      String attName = prop.getAttributeName();
+      StringArgument arg = new StringArgument(attName, null, attName, false,
+          true, true, attName, null, null, -1);
+      arg.setHidden(true);
+      serverProperties.put(prop, arg);
+    }
+
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isSubCommand(SubCommand subCmd)
+  {
+    return SubCommandNameEnum.isSubCommand(subCmd.getName());
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public ReturnCode performSubCommand(SubCommand subCmd,
+      OutputStream outStream, OutputStream errStream)
+      throws ADSContextException, ArgumentException
+  {
+
+    ADSContext adsCtx = null;
+    InitialLdapContext ctx = null;
+    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
+
+    try
+    {
+      // -----------------------
+      // register-server subcommand
+      // -----------------------
+      if (subCmd.getName().equals(registerServerSubCmd.getName()))
+      {
+        Map<ServerProperty, Object> map =
+          mapSetOptionsToMap(registerServerSetArg);
+        if (registerServerServerIdArg.isPresent())
+        {
+          map.put(ServerProperty.ID, registerServerServerIdArg.getValue());
+        }
+        else
+        {
+          map.put(ServerProperty.ID, ADSContext
+              .getServerIdFromServerProperties(map));
+        }
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        adsCtx.registerServer(map);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      // -----------------------
+      // unregister-server subcommand
+      // -----------------------
+      if (subCmd.getName().equals(unregisterServerSubCmd.getName()))
+      {
+        Map<ServerProperty, Object> map = new HashMap<ServerProperty, Object>();
+        if (unregisterServerServerIDArg.isPresent())
+        {
+          map.put(ServerProperty.ID, unregisterServerServerIDArg.getValue());
+        }
+        else
+        {
+          map.put(ServerProperty.ID, ADSContext
+              .getServerIdFromServerProperties(map));
+        }
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        adsCtx.unregisterServer(map);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      // -----------------------
+      // list-servers subcommand
+      // -----------------------
+      if (subCmd.getName().equals(listServersSubCmd.getName()))
+      {
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        Set<Map<ServerProperty, Object>> serverList = adsCtx
+            .readServerRegistry();
+
+        PrintStream out = new PrintStream(outStream);
+        for (Map<ServerProperty, Object> server : serverList)
+        {
+          // print out server ID
+          out.println(ServerProperty.ID.getAttributeName() + ": "
+              + server.get(ServerProperty.ID));
+        }
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      // -----------------------
+      // get-server-properties subcommand
+      // -----------------------
+      if (subCmd.getName().equals(getServerPropertiesSubCmd.getName()))
+      {
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        Set<Map<ServerProperty, Object>> adsServerList = adsCtx
+            .readServerRegistry();
+
+        LinkedList<String> userServerList = getServerPropertiesServerIdArg
+            .getValues();
+        PrintStream out = new PrintStream(outStream);
+        for (Map<ServerProperty, Object> server : adsServerList)
+        {
+          String serverID = (String) server.get(ServerProperty.ID);
+          if (!userServerList.contains(serverID))
+          {
+            continue;
+          }
+          // print out server ID
+          out.println(ServerProperty.ID.getAttributeName() + ": "
+              + server.get(ServerProperty.ID));
+          for (ServerProperty sp : server.keySet())
+          {
+            if (sp.equals(ServerProperty.ID))
+            {
+              continue;
+            }
+            out.println(sp.getAttributeName() + ": " + server.get(sp));
+          }
+          out.println();
+        }
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      // -----------------------
+      // set-server-properties subcommand
+      // -----------------------
+      if (subCmd.getName().equals(setServerPropertiesSubCmd.getName()))
+      {
+        Map<ServerProperty, Object> map =
+          mapSetOptionsToMap(setServerPropertiesSetArg);
+
+        // if the ID is specify in the --set list, it may mean that
+        // the user wants to rename the serverID
+        String newServerId = (String) map.get(ServerProperty.ID) ;
+
+        // replace the serverID in the map
+        map.put(ServerProperty.ID, setServerPropertiesServerIdArg.getValue());
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx);
+        adsCtx.updateServer(map, newServerId);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      // -----------------------
+      // list-server-properties subcommand
+      // -----------------------
+      if (subCmd.getName().equals(listServerPropertiesSubCmd.getName()))
+      {
+        PrintStream out = new PrintStream(outStream);
+        out.println(DESCRIPTION_OPTIONS_TITLE);
+        out.println();
+        out.print(" r -- ");
+        out.println(DESCRIPTION_OPTIONS_READ);
+        out.print(" w -- ");
+        out.println(DESCRIPTION_OPTIONS_WRITE);
+        out.print(" m -- ");
+        out.println(DESCRIPTION_OPTIONS_MANDATORY);
+        out.print(" s -- ");
+        out.println(DESCRIPTION_OPTIONS_SINGLE);
+        out.println();
+
+        TableBuilder table = new TableBuilder();
+        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_NAME));
+        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_OPTIONS));
+        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_SYNTAX));
+        table.appendHeading(getMessage(
+            MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE));
+        for (ServerProperty serverProp : serverProperties.keySet())
+        {
+          if (serverProperties.get(serverProp).isHidden())
+          {
+            continue;
+          }
+          table.startRow();
+          table.appendCell(serverProp.getAttributeName());
+          table.appendCell(getPropertyOptionSummary(serverProperties
+              .get(serverProp)));
+          table.appendCell(serverProp.getAttributeSyntax());
+          if (serverProperties.get(serverProp).getDefaultValue() != null)
+          {
+            table.appendCell(serverProperties.get(serverProp)
+                .getDefaultValue());
+          }
+          else
+          {
+            table.appendCell("-");
+          }
+        }
+        TextTablePrinter printer = new TextTablePrinter(outStream);
+        table.print(printer);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      else
+      {
+        // Should never occurs: If we are here, it means that the code
+        // to
+        // handle to subcommand is not yet written.
+        returnCode = ReturnCode.ERROR_UNEXPECTED;
+      }
+    }
+    catch (ADSContextException e)
+    {
+      if (ctx != null)
+      {
+        try
+        {
+          ctx.close();
+        }
+        catch (NamingException x)
+        {
+        }
+      }
+      throw e;
+    }
+
+    // Close the connection, if needed
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (NamingException x)
+      {
+      }
+    }
+
+    // return part
+    return returnCode;
+  }
+
+  // Compute the options field.
+  private String getPropertyOptionSummary(Argument arg)
+  {
+    StringBuilder b = new StringBuilder();
+
+    if (readonlyServerProperties.contains(
+        ADSContext.getPropFromName(arg.getName())))
+    {
+      b.append("r-"); //$NON-NLS-1$
+    }
+    else
+    {
+      b.append("rw"); //$NON-NLS-1$
+    }
+
+    if (arg.isRequired())
+    {
+      b.append('m');
+    }
+    else
+    {
+      b.append('-');
+    }
+
+    if (arg.isMultiValued())
+    {
+      b.append('-');
+    }
+    else
+    {
+      b.append('s');
+    }
+    return b.toString();
+  }
+
+  /**
+   * Translate a Set properties a to a MAP.
+   *
+   * @param propertySetArgument
+   *          The input set argument.
+   * @return The created map.
+   * @throws ArgumentException
+   *           If error error occurs during set parsing.
+   */
+  private Map<ServerProperty, Object> mapSetOptionsToMap(
+      StringArgument propertySetArgument) throws ArgumentException
+  {
+    HashMap<ServerProperty, Object> map = new HashMap<ServerProperty, Object>();
+    for (String m : propertySetArgument.getValues())
+    {
+      // Parse the property "property:value".
+      int sep = m.indexOf(':');
+
+      if (sep < 0)
+      {
+        throw ArgumentExceptionFactory.missingSeparatorInPropertyArgument(m);
+      }
+
+      if (sep == 0)
+      {
+        throw ArgumentExceptionFactory.missingNameInPropertyArgument(m);
+      }
+
+      String propertyName = m.substring(0, sep);
+      String value = m.substring(sep + 1, m.length());
+      if (value.length() == 0)
+      {
+        throw ArgumentExceptionFactory.missingValueInPropertyArgument(m);
+      }
+
+      // Check that propName is a known prop.
+      ServerProperty serverProperty = ADSContext
+          .getPropFromName(propertyName);
+      if (serverProperty == null)
+      {
+        int msgID = MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED;
+        String message = getMessage(msgID, propertyName);
+        throw new ArgumentException(msgID, message);
+      }
+
+      // Check that propName is not hidden.
+      if (serverProperties.get(serverProperty).isHidden())
+      {
+        int msgID = MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED;
+        String message = getMessage(msgID, propertyName);
+        throw new ArgumentException(msgID, message);
+      }
+
+      // Check the property Syntax.
+      StringBuilder invalidReason = new StringBuilder();
+      Argument arg = serverProperties.get(serverProperty) ;
+      if ( ! arg.valueIsAcceptable(value, invalidReason))
+      {
+        int msgID = MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE;
+        String message = getMessage(msgID, propertyName, value);
+        throw new ArgumentException(msgID, message);
+      }
+      serverProperties.get(serverProperty).addValue(value);
+
+      // add to the map.
+      map.put(serverProperty, value);
+    }
+
+    // Check that all mandatory props are set.
+    HashSet<PropertyOption> propList;
+    for (ServerProperty s : ServerProperty.values())
+    {
+      Argument arg = serverProperties.get(s);
+      if (arg.isHidden())
+      {
+        continue;
+      }
+      if (map.containsKey(s))
+      {
+        continue ;
+      }
+      if ( ! arg.isRequired())
+      {
+        continue ;
+      }
+
+      // If we are here, it means that the argument is required
+      // but not yet is the map. Cjeck if we have a default value.
+      if (arg.getDefaultValue() == null)
+      {
+        int msgID = MSGID_CLI_ERROR_MISSING_PROPERTY;
+        String message = getMessage(msgID, s.getAttributeName());
+        throw new ArgumentException(msgID, message);
+      }
+      else
+      {
+        map.put(s, arg.getDefaultValue());
+      }
+    }
+    return map;
+  }
+}
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java
index 31fc32f..fa3873b 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java
@@ -38,6 +38,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import javax.naming.NamingException;
+import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.Rdn;
 
 
@@ -49,7 +51,6 @@
 import org.opends.server.util.args.BooleanArgument;
 import org.opends.server.util.args.StringArgument;
 import org.opends.server.util.args.SubCommand;
-import org.opends.server.util.args.SubCommandArgumentParser;
 
 /**
  * This class is handling server group CLI.
@@ -65,7 +66,7 @@
   /**
    * The subcommand Parser.
    */
-  SubCommandArgumentParser argParser ;
+  DsFrameworkCliParser argParser ;
 
   /**
    * The verbose argument.
@@ -258,6 +259,22 @@
   private HashMap<ServerGroupProperty, String> attributeDisplayName;
 
   /**
+   * The subcommand list.
+   */
+  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
+
+  /**
+   * Indicates whether this subCommand should be hidden in the usage
+   * information.
+   */
+  private boolean isHidden;
+
+  /**
+   * The subcommand group name.
+   */
+  private String groupName;
+
+  /**
    * Get the display attribute name for a given attribute.
    * @param prop The server prperty
    * @return the display attribute name for a given attribute
@@ -266,19 +283,49 @@
   {
     return attributeDisplayName.get(prop);
   }
+
   /**
    * {@inheritDoc}
    */
-  public void initializeCliGroup(SubCommandArgumentParser argParser,
+  public Set<SubCommand> getSubCommands()
+  {
+    return subCommands;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isHidden()
+  {
+    return isHidden;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String getGroupName()
+  {
+    return groupName ;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeCliGroup(DsFrameworkCliParser argParser,
       BooleanArgument verboseArg)
       throws ArgumentException
   {
     this.verboseArg = verboseArg ;
+    isHidden = false ;
+    groupName = "server-group";
+    this.argParser = argParser;
+
 
     // Create-group subcommand
     createGroupSubCmd = new SubCommand(argParser,
         SubCommandNameEnum.CREATE_GROUP.toString(),
         MSGID_ADMIN_SUBCMD_CREATE_GROUP_DESCRIPTION);
+    subCommands.add(createGroupSubCmd);
 
     createGroupDescriptionArg = new StringArgument("description",
         OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
@@ -296,6 +343,7 @@
     modifyGroupSubCmd = new SubCommand(argParser,
         SubCommandNameEnum.MODIFY_GROUP.toString(),
         MSGID_ADMIN_SUBCMD_MODIFY_GROUP_DESCRIPTION);
+    subCommands.add(modifyGroupSubCmd);
 
     modifyGroupDescriptionArg = new StringArgument("new-description",
         OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
@@ -318,6 +366,7 @@
     // delete-group
     deleteGroupSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_GROUP
         .toString(), MSGID_ADMIN_SUBCMD_DELETE_GROUP_DESCRIPTION);
+    subCommands.add(deleteGroupSubCmd);
 
     deleteGroupGroupNameArg = new StringArgument("groupName",
         OPTION_SHORT_GROUPNAME, OPTION_LONG_GROUPNAME, true, true,
@@ -328,11 +377,13 @@
     // list-groups
     listGroupSubCmd = new SubCommand(argParser, "list-groups",
         MSGID_ADMIN_SUBCMD_LIST_GROUPS_DESCRIPTION);
+    subCommands.add(listGroupSubCmd);
 
     // add-to-group
     addToGroupSubCmd = new SubCommand(argParser,
         SubCommandNameEnum.ADD_TO_GROUP.toString(),
         MSGID_ADMIN_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
+    subCommands.add(addToGroupSubCmd);
 
     addToGoupMemberNameArg = new StringArgument("memberName",
         OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -350,6 +401,7 @@
     removeFromGroupSubCmd = new SubCommand(argParser,
         SubCommandNameEnum.REMOVE_FROM_GROUP.toString(),
         MSGID_ADMIN_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
+    subCommands.add(removeFromGroupSubCmd);
 
     removeFromGoupMemberNameArg = new StringArgument("memberName",
         OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -367,6 +419,7 @@
     // list-members
     listMembersSubCmd = new SubCommand(argParser,SubCommandNameEnum.LIST_MEMBERS
         .toString(), MSGID_ADMIN_SUBCMD_LIST_MEMBERS_DESCRIPTION);
+    subCommands.add(listMembersSubCmd);
 
     listMembersGroupNameArg = new StringArgument("groupName",
         OPTION_SHORT_GROUPNAME, OPTION_LONG_GROUPNAME, true, true,
@@ -378,6 +431,7 @@
     listMembershipSubCmd = new SubCommand(argParser,
         SubCommandNameEnum.LIST_MEMBERSHIP.toString(),
         MSGID_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
+    subCommands.add(listMembershipSubCmd);
 
     listMembershipMemberNameArg = new StringArgument("memberName",
         OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -406,362 +460,454 @@
   /**
    * {@inheritDoc}
    */
-  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
-      OutputStream outStream, OutputStream errStream)
-      throws ADSContextException
+  public ReturnCode performSubCommand(SubCommand subCmd, OutputStream outStream,
+      OutputStream errStream)
+      throws ADSContextException, ArgumentException
   {
-    // -----------------------
-    // create-group subcommand
-    // -----------------------
-    if (subCmd.getName().equals(createGroupSubCmd.getName()))
+    ADSContext adsCtx = null ;
+    InitialLdapContext ctx = null ;
+
+    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
+    try
     {
-      String groupId = createGroupGroupNameArg.getValue();
-      HashMap<ServerGroupProperty, Object> serverGroupProperties =
-        new HashMap<ServerGroupProperty, Object>();
-
-      // get the GROUP_NAME
-      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
-
-      // get the Description
-      if (createGroupDescriptionArg.isPresent())
+      // -----------------------
+      // create-group subcommand
+      // -----------------------
+      if (subCmd.getName().equals(createGroupSubCmd.getName()))
       {
-        serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
-            createGroupDescriptionArg.getValue());
-      }
+        String groupId = createGroupGroupNameArg.getValue();
+        HashMap<ServerGroupProperty, Object> serverGroupProperties =
+          new HashMap<ServerGroupProperty, Object>();
 
-      // Create the group
-      adsContext.createServerGroup(serverGroupProperties);
-      return ReturnCode.SUCCESSFUL;
-    }
-    // -----------------------
-    // delete-group subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(deleteGroupSubCmd.getName()))
-    {
-      String groupId = deleteGroupGroupNameArg.getValue();
-      HashMap<ServerGroupProperty, Object> serverGroupProperties =
-        new HashMap<ServerGroupProperty, Object>();
+        // get the GROUP_NAME
+        serverGroupProperties.put(ServerGroupProperty.UID, groupId);
 
-      // get the GROUP_ID
-      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
-
-      // Delete the group
-      adsContext.deleteServerGroup(serverGroupProperties);
-      return ReturnCode.SUCCESSFUL;
-    }
-    // -----------------------
-    // list-groups subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(listGroupSubCmd.getName()))
-    {
-      Set<Map<ServerGroupProperty, Object>> result = adsContext
-          .readServerGroupRegistry();
-      StringBuffer buffer = new StringBuffer();
-
-      // if not verbose mode, print group name (1 per line)
-      if (! verboseArg.isPresent())
-      {
-        for (Map<ServerGroupProperty, Object> groupProps : result)
+        // get the Description
+        if (createGroupDescriptionArg.isPresent())
         {
-          // Get the group name
-          buffer.append(groupProps.get(ServerGroupProperty.UID));
-          buffer.append(EOL);
+          serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
+              createGroupDescriptionArg.getValue());
         }
-      }
-      else
-      {
-        // Look for the max group identifier length
-        int uidLength = 0 ;
-        for (ServerGroupProperty sgp : ServerGroupProperty.values())
+
+        // Create the group
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
         {
-          int cur = attributeDisplayName.get(sgp).toString().length();
-          if (cur > uidLength)
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+        adsCtx.createServerGroup(serverGroupProperties);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // delete-group subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(deleteGroupSubCmd.getName()))
+      {
+        String groupId = deleteGroupGroupNameArg.getValue();
+        HashMap<ServerGroupProperty, Object> serverGroupProperties =
+          new HashMap<ServerGroupProperty, Object>();
+
+        // get the GROUP_ID
+        serverGroupProperties.put(ServerGroupProperty.UID, groupId);
+
+        // Delete the group
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+        adsCtx.deleteServerGroup(serverGroupProperties);
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // list-groups subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(listGroupSubCmd.getName()))
+      {
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        Set<Map<ServerGroupProperty, Object>> result = adsCtx
+            .readServerGroupRegistry();
+        StringBuffer buffer = new StringBuffer();
+
+        // if not verbose mode, print group name (1 per line)
+        if (! verboseArg.isPresent())
+        {
+          for (Map<ServerGroupProperty, Object> groupProps : result)
           {
-            uidLength = cur;
+            // Get the group name
+            buffer.append(groupProps.get(ServerGroupProperty.UID));
+            buffer.append(EOL);
           }
         }
-        uidLength++;
-
-        for (Map<ServerGroupProperty, Object> groupProps : result)
+        else
         {
-          // Get the group name
-          buffer.append(attributeDisplayName.get(ServerGroupProperty.UID));
-          // add space
-          int curLen = attributeDisplayName.get(ServerGroupProperty.UID)
-              .length();
-          for (int i = curLen; i < uidLength; i++)
+          // Look for the max group identifier length
+          int uidLength = 0 ;
+          for (ServerGroupProperty sgp : ServerGroupProperty.values())
           {
-            buffer.append(" ");
-          }
-          buffer.append(": ");
-          buffer.append(groupProps.get(ServerGroupProperty.UID));
-          buffer.append(EOL);
-
-          // Write other props
-          for (ServerGroupProperty propName : ServerGroupProperty.values())
-          {
-            if (propName.compareTo(ServerGroupProperty.UID) == 0)
+            int cur = attributeDisplayName.get(sgp).toString().length();
+            if (cur > uidLength)
             {
-              // We have already displayed the group Id
-              continue;
+              uidLength = cur;
             }
-            buffer.append(attributeDisplayName.get(propName));
+          }
+          uidLength++;
+
+          for (Map<ServerGroupProperty, Object> groupProps : result)
+          {
+            // Get the group name
+            buffer.append(attributeDisplayName.get(ServerGroupProperty.UID));
             // add space
-            curLen = attributeDisplayName.get(propName).length();
+            int curLen = attributeDisplayName.get(ServerGroupProperty.UID)
+                .length();
             for (int i = curLen; i < uidLength; i++)
             {
               buffer.append(" ");
             }
             buffer.append(": ");
+            buffer.append(groupProps.get(ServerGroupProperty.UID));
+            buffer.append(EOL);
 
-            if (propName.compareTo(ServerGroupProperty.MEMBERS) == 0)
+            // Write other props
+            for (ServerGroupProperty propName : ServerGroupProperty.values())
             {
-              Set atts = (Set) groupProps.get(propName);
-              if (atts != null)
+              if (propName.compareTo(ServerGroupProperty.UID) == 0)
               {
-                boolean indent = false;
-                for (Object att : atts)
+                // We have already displayed the group Id
+                continue;
+              }
+              buffer.append(attributeDisplayName.get(propName));
+              // add space
+              curLen = attributeDisplayName.get(propName).length();
+              for (int i = curLen; i < uidLength; i++)
+              {
+                buffer.append(" ");
+              }
+              buffer.append(": ");
+
+              if (propName.compareTo(ServerGroupProperty.MEMBERS) == 0)
+              {
+                Set atts = (Set) groupProps.get(propName);
+                if (atts != null)
                 {
-                  if (indent)
+                  boolean indent = false;
+                  for (Object att : atts)
                   {
-                    buffer.append(EOL);
-                    for (int i = 0; i < uidLength + 2; i++)
+                    if (indent)
                     {
-                      buffer.append(" ");
+                      buffer.append(EOL);
+                      for (int i = 0; i < uidLength + 2; i++)
+                      {
+                        buffer.append(" ");
+                      }
                     }
+                    else
+                    {
+                      indent = true;
+                    }
+                    buffer.append(att.toString().substring(3));
                   }
-                  else
-                  {
-                    indent = true;
-                  }
-                  buffer.append(att.toString().substring(3));
                 }
               }
-            }
-            else
-            {
-              if (groupProps.get(propName) != null)
+              else
               {
-                buffer.append(groupProps.get(propName));
+                if (groupProps.get(propName) != null)
+                {
+                  buffer.append(groupProps.get(propName));
+                }
               }
+              buffer.append(EOL);
             }
             buffer.append(EOL);
           }
-          buffer.append(EOL);
         }
-      }
-      try
-      {
-        outStream.write(buffer.toString().getBytes());
-      }
-      catch (IOException e)
-      {
-      }
-      return ReturnCode.SUCCESSFUL;
-    }
-    // -----------------------
-    // modify-group subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(modifyGroupSubCmd.getName()))
-    {
-      String groupId = modifyGroupGroupNameArg.getValue();
-      HashMap<ServerGroupProperty, Object> serverGroupProperties =
-        new HashMap<ServerGroupProperty, Object>();
-      HashSet<ServerGroupProperty> serverGroupPropertiesToRemove =
-        new HashSet<ServerGroupProperty>();
-
-      Boolean updateRequired = false;
-      Boolean removeRequired = false;
-      // get the GROUP_ID
-      if (modifyGroupGroupIdArg.isPresent())
-      {
-        // rename the entry !
-        serverGroupProperties.put(ServerGroupProperty.UID,
-            modifyGroupGroupIdArg.getValue());
-        updateRequired = true;
-      }
-      else
-      {
-        serverGroupProperties.put(ServerGroupProperty.UID, groupId) ;
-      }
-
-
-      // get the Description
-      if (modifyGroupDescriptionArg.isPresent())
-      {
-        String newDesc = modifyGroupDescriptionArg.getValue();
-        if (newDesc.length() == 0)
+        try
         {
-          serverGroupPropertiesToRemove.add(ServerGroupProperty.DESCRIPTION);
-          removeRequired = true;
+          outStream.write(buffer.toString().getBytes());
+        }
+        catch (IOException e)
+        {
+        }
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // modify-group subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(modifyGroupSubCmd.getName()))
+      {
+        String groupId = modifyGroupGroupNameArg.getValue();
+        HashMap<ServerGroupProperty, Object> serverGroupProperties =
+          new HashMap<ServerGroupProperty, Object>();
+        HashSet<ServerGroupProperty> serverGroupPropertiesToRemove =
+          new HashSet<ServerGroupProperty>();
+
+        Boolean updateRequired = false;
+        Boolean removeRequired = false;
+        // get the GROUP_ID
+        if (modifyGroupGroupIdArg.isPresent())
+        {
+          // rename the entry !
+          serverGroupProperties.put(ServerGroupProperty.UID,
+              modifyGroupGroupIdArg.getValue());
+          updateRequired = true;
         }
         else
         {
-          serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
-              modifyGroupDescriptionArg.getValue());
-          updateRequired = true;
+          serverGroupProperties.put(ServerGroupProperty.UID, groupId) ;
         }
-      }
 
 
-      // Update the server group
-      if (updateRequired)
-      {
-        adsContext.updateServerGroup(groupId, serverGroupProperties);
-      }
-      if (removeRequired)
-      {
-        adsContext.removeServerGroupProp(groupId,
-            serverGroupPropertiesToRemove);
-      }
+        // get the Description
+        if (modifyGroupDescriptionArg.isPresent())
+        {
+          String newDesc = modifyGroupDescriptionArg.getValue();
+          if (newDesc.length() == 0)
+          {
+            serverGroupPropertiesToRemove.add(ServerGroupProperty.DESCRIPTION);
+            removeRequired = true;
+          }
+          else
+          {
+            serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
+                modifyGroupDescriptionArg.getValue());
+            updateRequired = true;
+          }
+        }
 
-      if (updateRequired || removeRequired)
+
+        // Update the server group
+        if ( ! (updateRequired || removeRequired ) )
+        {
+          returnCode = ReturnCode.SUCCESSFUL_NOP;
+        }
+
+        // We need to perform an update
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        if (updateRequired)
+        {
+          adsCtx.updateServerGroup(groupId, serverGroupProperties);
+        }
+        if (removeRequired)
+        {
+          adsCtx.removeServerGroupProp(groupId,
+              serverGroupPropertiesToRemove);
+        }
+
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // add-to-group subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(addToGroupSubCmd.getName()))
       {
+        String groupId = addToGroupGroupNameArg.getValue();
+        HashMap<ServerGroupProperty, Object> serverGroupProperties =
+          new HashMap<ServerGroupProperty, Object>();
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        // get the current member list
+        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
+        if (memberList == null)
+        {
+          memberList = new HashSet<String>();
+        }
+        String newMember = "cn="
+            + Rdn.escapeValue(addToGoupMemberNameArg.getValue());
+        if (memberList.contains(newMember))
+        {
+          returnCode = ReturnCode.ALREADY_REGISTERED;
+        }
+        memberList.add(newMember);
+        serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
+
+        // Update the server group
+        adsCtx.updateServerGroup(groupId, serverGroupProperties);
+
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // remove-from-group subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(removeFromGroupSubCmd.getName()))
+      {
+        String groupId = removeFromGroupGroupNameArg.getValue();
+        HashMap<ServerGroupProperty, Object> serverGroupProperties =
+          new HashMap<ServerGroupProperty, Object>();
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        // get the current member list
+        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
+        if (memberList == null)
+        {
+          returnCode = ReturnCode.NOT_YET_REGISTERED;
+        }
+        String memberToRemove = "cn="
+            + Rdn.escapeValue(removeFromGoupMemberNameArg.getValue());
+        if (!memberList.contains(memberToRemove))
+        {
+          returnCode = ReturnCode.NOT_YET_REGISTERED;
+        }
+
+        memberList.remove(memberToRemove);
+        serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
+
+        // Update the server group
+        adsCtx.updateServerGroup(groupId, serverGroupProperties);
+
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
+      // -----------------------
+      // list-members subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(listMembersSubCmd.getName()))
+      {
+        String groupId = listMembersGroupNameArg.getValue();
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        // get the current member list
+        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
+        if (memberList == null)
+        {
+          returnCode = ReturnCode.SUCCESSFUL;
+        }
+        StringBuffer buffer = new StringBuffer();
+        for (String member : memberList)
+        {
+          buffer.append(member.substring(3));
+          buffer.append(EOL);
+        }
+        try
+        {
+          outStream.write(buffer.toString().getBytes());
+        }
+        catch (IOException e)
+        {
+        }
+
         return ReturnCode.SUCCESSFUL;
       }
+      // -----------------------
+      // list-membership subcommand
+      // -----------------------
+      else if (subCmd.getName().equals(listMembershipSubCmd.getName()))
+      {
+
+        ctx = argParser.getContext(outStream, errStream);
+        if (ctx == null)
+        {
+          return ReturnCode.CANNOT_CONNECT_TO_ADS;
+        }
+        adsCtx = new ADSContext(ctx) ;
+
+        Set<Map<ServerGroupProperty, Object>> result = adsCtx
+            .readServerGroupRegistry();
+        String MemberId = listMembershipMemberNameArg.getValue();
+
+        StringBuffer buffer = new StringBuffer();
+        for (Map<ServerGroupProperty, Object> groupProps : result)
+        {
+          // Get the group name;
+          String groupId = groupProps.get(ServerGroupProperty.UID).toString();
+
+          // look for memeber list attribute
+          for (ServerGroupProperty propName : groupProps.keySet())
+          {
+            if (propName.compareTo(ServerGroupProperty.MEMBERS) != 0)
+            {
+              continue;
+            }
+            // Check if the member list contains the member-id
+            Set atts = (Set) groupProps.get(propName);
+            for (Object att : atts)
+            {
+              if (att.toString().substring(3).toLowerCase().equals(
+                  MemberId.toLowerCase()))
+              {
+                buffer.append(groupId);
+                buffer.append(EOL);
+                break;
+              }
+            }
+            break;
+          }
+        }
+        try
+        {
+          outStream.write(buffer.toString().getBytes());
+        }
+        catch (IOException e)
+        {
+        }
+        returnCode = ReturnCode.SUCCESSFUL;
+      }
       else
       {
-       return ReturnCode.SUCCESSFUL_NOP;
+        // Should never occurs: If we are here, it means that the code to
+        // handle to subcommand is not yet written.
+        returnCode = ReturnCode.ERROR_UNEXPECTED;
       }
     }
-    // -----------------------
-    // add-to-group subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(addToGroupSubCmd.getName()))
+    catch (ADSContextException e)
     {
-      String groupId = addToGroupGroupNameArg.getValue();
-      HashMap<ServerGroupProperty, Object> serverGroupProperties =
-        new HashMap<ServerGroupProperty, Object>();
-
-      // get the current member list
-      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
-      if (memberList == null)
-      {
-        memberList = new HashSet<String>();
-      }
-      String newMember = "cn="
-          + Rdn.escapeValue(addToGoupMemberNameArg.getValue());
-      if (memberList.contains(newMember))
-      {
-        return ReturnCode.ALREADY_REGISTERED;
-      }
-      memberList.add(newMember);
-      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
-
-      // Update the server group
-      adsContext.updateServerGroup(groupId, serverGroupProperties);
-
-      return ReturnCode.SUCCESSFUL;
+     if (ctx != null)
+     {
+       try
+       {
+         ctx.close();
+       }
+       catch (NamingException x)
+       {
+       }
+     }
+     throw e;
     }
-    // -----------------------
-    // remove-from-group subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(removeFromGroupSubCmd.getName()))
+
+    // Close the connection, if needed
+    if (ctx != null)
     {
-      String groupId = removeFromGroupGroupNameArg.getValue();
-      HashMap<ServerGroupProperty, Object> serverGroupProperties =
-        new HashMap<ServerGroupProperty, Object>();
-
-      // get the current member list
-      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
-      if (memberList == null)
-      {
-        return ReturnCode.NOT_YET_REGISTERED;
-      }
-      String memberToRemove = "cn="
-          + Rdn.escapeValue(removeFromGoupMemberNameArg.getValue());
-      if (!memberList.contains(memberToRemove))
-      {
-        return ReturnCode.NOT_YET_REGISTERED;
-      }
-
-      memberList.remove(memberToRemove);
-      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
-
-      // Update the server group
-      adsContext.updateServerGroup(groupId, serverGroupProperties);
-
-      return ReturnCode.SUCCESSFUL;
-    }
-    // -----------------------
-    // list-members subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(listMembersSubCmd.getName()))
-    {
-      String groupId = listMembersGroupNameArg.getValue();
-
-      // get the current member list
-      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
-      if (memberList == null)
-      {
-        return ReturnCode.SUCCESSFUL;
-      }
-      StringBuffer buffer = new StringBuffer();
-      for (String member : memberList)
-      {
-        buffer.append(member.substring(3));
-        buffer.append(EOL);
-      }
       try
       {
-        outStream.write(buffer.toString().getBytes());
+        ctx.close();
       }
-      catch (IOException e)
+      catch (NamingException x)
       {
       }
-
-      return ReturnCode.SUCCESSFUL;
-    }
-    // -----------------------
-    // list-membership subcommand
-    // -----------------------
-    else if (subCmd.getName().equals(listMembershipSubCmd.getName()))
-    {
-
-      Set<Map<ServerGroupProperty, Object>> result = adsContext
-          .readServerGroupRegistry();
-      String MemberId = listMembershipMemberNameArg.getValue();
-
-      StringBuffer buffer = new StringBuffer();
-      for (Map<ServerGroupProperty, Object> groupProps : result)
-      {
-        // Get the group name;
-        String groupId = groupProps.get(ServerGroupProperty.UID).toString();
-
-        // look for memeber list attribute
-        for (ServerGroupProperty propName : groupProps.keySet())
-        {
-          if (propName.compareTo(ServerGroupProperty.MEMBERS) != 0)
-          {
-            continue;
-          }
-          // Check if the member list contains the member-id
-          Set atts = (Set) groupProps.get(propName);
-          for (Object att : atts)
-          {
-            if (att.toString().substring(3).toLowerCase().equals(
-                MemberId.toLowerCase()))
-            {
-              buffer.append(groupId);
-              buffer.append(EOL);
-              break;
-            }
-          }
-          break;
-        }
-      }
-      try
-      {
-        outStream.write(buffer.toString().getBytes());
-      }
-      catch (IOException e)
-      {
-      }
-      return ReturnCode.SUCCESSFUL;
     }
 
-    // Should never occurs: If we are here, it means that the code to
-    // handle to subcommand is not yet written.
-    return ReturnCode.ERROR_UNEXPECTED;
+    // return part
+    return returnCode;
+
   }
 }
diff --git a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java
index b6a839b..c5da626 100644
--- a/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java
+++ b/opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java
@@ -27,14 +27,13 @@
  package org.opends.server.admin.client.cli;
 
 import java.io.OutputStream;
+import java.util.Set;
 
-import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.ADSContextException;
 import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
 import org.opends.server.util.args.ArgumentException;
 import org.opends.server.util.args.BooleanArgument;
 import org.opends.server.util.args.SubCommand;
-import org.opends.server.util.args.SubCommandArgumentParser;
 
 /**
  * This Interface defines method that a group of subcommand shoud implement.
@@ -53,7 +52,7 @@
    *           If there is a problem with any of the parameters used
    *           to create this argument.
    */
-  public void initializeCliGroup(SubCommandArgumentParser argParser,
+  public void initializeCliGroup(DsFrameworkCliParser argParser,
       BooleanArgument verboseArg) throws ArgumentException;
 
   /**
@@ -67,21 +66,43 @@
 
   /**
    * Handle the subcommand.
-   * @param adsContext
-   *          The context to use to perform ADS operation.
    * @param subCmd
    *          The actual subcommand with input parameter
-   *
    * @param  outStream         The output stream to use for standard output.
-   *
    * @param  errStream         The output stream to use for standard error.
-   *
    * @return the return code
    * @throws ADSContextException
    *           If there is a problem with when trying to perform the
    *           operation.
+   * @throws ArgumentException
+   *           If there is a problem with any of the parameters used
+   *           to execute this subcommand.
    */
-  public ReturnCode performSubCommand(ADSContext adsContext,
-      SubCommand subCmd, OutputStream outStream, OutputStream errStream)
-      throws ADSContextException;
+  public ReturnCode performSubCommand(SubCommand subCmd,
+      OutputStream outStream, OutputStream errStream)
+      throws ADSContextException, ArgumentException;
+
+  /**
+   * Get the subcommands list.
+   * @return the subcommand list.
+   */
+  public Set<SubCommand> getSubCommands();
+
+  /**
+   * Indicates whether this subcommand group should be hidden from the usage
+   * information.
+   *
+   * @return <CODE>true</CODE> if this subcommand group should be hidden
+   *         from the usage information, or <CODE>false</CODE> if
+   *         not.
+   */
+  public boolean isHidden();
+
+  /**
+   * Indicates subcommand group name.
+   *
+   * @return the subcommand group name
+   */
+  public String getGroupName();
+
 }
diff --git a/opends/src/server/org/opends/server/messages/AdminMessages.java b/opends/src/server/org/opends/server/messages/AdminMessages.java
index 2f300c5..7548dae 100644
--- a/opends/src/server/org/opends/server/messages/AdminMessages.java
+++ b/opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -492,6 +492,70 @@
   public static final int MSGID_ADMIN_UNABLE_TO_REGISTER_LISTENER =
     CATEGORY_MASK_ADMIN | SEVERITY_MASK_SEVERE_ERROR | 57;
 
+  /**
+   * The message ID for the message that will be used as the
+   * description for the create-group subcommand part of dsservice
+   * tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 58;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description for the create-group subcommand part of dsservice
+   * tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 59;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description of the "server-name" argument. This does take one
+   * argument.
+   */
+  public static final int MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 60;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description for the list-server-properties subcommand part of
+   * dsservice tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 61;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description for the list-servers subcommand part of dsservice
+   * tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 62;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description for the get-server-properties subcommand part of
+   * dsservice tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 63;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description for the set-server-properties subcommand part of
+   * dsservice tool. This does not take any arguments.
+   */
+  public static final int MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 64;
+
+  /**
+   * The message ID for the message that will be used as the
+   * description of the "server-host" argument. This does take one
+   * argument.
+   */
+  public static final int MSGID_ADMIN_ARG_SERVERID_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 65;
+
   // Prevent instantiation.
   private AdminMessages() {
     // Do nothing.
@@ -665,8 +729,39 @@
     registerMessage(MSGID_ADMIN_ARG_BACKENDNAME_DESCRIPTION,
         "The name of the backend in which the admin data will be stored. " +
         "This is a required argument");
+    registerMessage(MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION,
+        "Register a server into the administrative domain");
+    registerMessage(MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION,
+        "Unregister a server from the administrative domain");
+    registerMessage(MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION,
+        "The server's identifier. This is a required argument");
+    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION,
+        "Describes server properties");
+    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION,
+        "List servers that have been defined");
+    registerMessage(MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION,
+        "Shows server properties");
+    registerMessage(MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION,
+        "Modifies server properties");
     registerMessage(MSGID_ADMIN_UNABLE_TO_REGISTER_LISTENER,
         "Unable to register an add/delete listener against the entry \"%s\" " +
         "because it does not exist in the configuration");
+    registerMessage(MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION,
+        "Register a server into the administrative domain");
+    registerMessage(MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION,
+        "Unregister a server from the administrative domain");
+    registerMessage(MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION,
+        "The server's identifier. This is a required argument");
+    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION,
+        "Describes server properties");
+    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION,
+        "List servers that have been defined");
+    registerMessage(MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION,
+        "Shows server properties");
+    registerMessage(MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION,
+        "Modifies server properties");
+    registerMessage(MSGID_ADMIN_ARG_SERVERID_DESCRIPTION,
+        "The registered server's unique identifier. " +
+        "This is a required argument");
   }
 }
diff --git a/opends/src/server/org/opends/server/messages/ToolMessages.java b/opends/src/server/org/opends/server/messages/ToolMessages.java
index 22db5f0..ff884f7 100644
--- a/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -9150,6 +9150,37 @@
    */
   public static final int MSGID_CONFIGDS_PORT_ALREADY_SPECIFIED  =
     CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1211;
+  /**
+   * The message ID for the message that will be used if the user
+   * attempts to access a property which is not recognized. This takes
+   * one argument which is the name of the invalid property.
+   */
+  public static final int MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED =
+      CATEGORY_MASK_TOOLS  | SEVERITY_MASK_SEVERE_ERROR | 1212;
+
+  /**
+   * The message ID for the message that will be used if the user
+   * doesn't specify a mandatory property. This takes one argument
+   * which is the name of the missing property.
+   */
+  public static final int MSGID_CLI_ERROR_MISSING_PROPERTY =
+    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1213;
+
+  /**
+   * The message ID for the message that will be used if the user
+   * specify a wrong value of a property. This takes two arguments
+   * which is the name of the property and the wrong value.
+   */
+  public static final int MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE =
+    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1214;
+
+  /**
+   * The message ID for the message that will be used as the
+   * heading of the property default value column in tables.
+   */
+  public static final int MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE =
+    CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1215;
+
 
   /**
    * Associates a set of generic messages with the message IDs defined in this
@@ -12103,6 +12134,16 @@
                     "Password History");
     registerMessage(MSGID_PWPSTATE_INVALID_RESPONSE_OP_TYPE,
                     "Unrecognized or invalid operation type:  %s");
+
+    registerMessage(MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED,
+                    "The property \"%s\" is not a recognized property");
+    registerMessage(MSGID_CLI_ERROR_MISSING_PROPERTY,
+                    "The mandatory property \"%s\" is missing");
+    registerMessage(MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE,
+                    "The value \"%s\" specified fo the property \"%s\" is " +
+                    "invalid");
+    registerMessage(MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE,
+                    "Default value");
   }
 }
 
diff --git a/opends/src/server/org/opends/server/tools/ToolConstants.java b/opends/src/server/org/opends/server/tools/ToolConstants.java
index 4ed2409..aca9d79 100644
--- a/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -586,5 +586,38 @@
    * displayed in usage information.
    */
   public static final String OPTION_VALUE_BACKENDNAME = "{backend-name}";
+
+  /**
+   * The value for the short option serverID attributes.
+   */
+  public static final String OPTION_SHORT_SERVERID = null;
+
+  /**
+   * The value for the long option serverID
+   * attribute.
+   */
+  public static final String OPTION_LONG_SERVERID= "serverID";
+
+  /**
+   * The placeholder value of serverID that will be
+   * displayed in usage information.
+   */
+  public static final String OPTION_VALUE_SERVERID = "{serverID}";
+
+  /**
+   * The value for the short option set.
+   */
+  public static final Character OPTION_SHORT_SET = null;
+
+  /**
+  * The value for the long option set.
+  */
+ public static final String OPTION_LONG_SET = "set";
+
+ /**
+  * The placeholder value for the long option set.
+  */
+ public static final String OPTION_VALUE_SET = "{PROP:VAL}";
+
 }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java
index 00507c3..0c87cff 100755
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java
@@ -106,7 +106,7 @@
     
     try
     {
-      cli.initializeCliGroup(new SubCommandArgumentParser(null, null, false),
+      cli.initializeCliGroup(new DsFrameworkCliParser(null, null, false),
           null);
     }
     catch (ArgumentException e)

--
Gitblit v1.10.0