From ff6e1ddf0bccd6a40e0673f312a33dc0a76a87a1 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Thu, 31 May 2007 08:31:45 +0000
Subject: [PATCH] Commit related to issue  https://opends.dev.java.net/issues/show_bug.cgi?id=1334

---
 opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java      |   31 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextException.java         |    2 
 /dev/null                                                                       |  323 --------
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java     |  587 ++++++++++++++++
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java            |   11 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java            |  242 ++++++
 opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java         |    6 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java             |  179 ++++
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java                  |  345 ++++-----
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java          |  334 +++++++++
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java |   85 ++
 11 files changed, 1,621 insertions(+), 524 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
index 2457510..e0089e7 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -27,11 +27,6 @@
 
 package org.opends.admin.ads;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.Set;
 import java.util.HashSet;
@@ -186,7 +181,7 @@
     /**
      * The members of the server group.
      */
-    MEMBERS("members");
+    MEMBERS("uniqueMember");
 
     private String attrName;
 
@@ -445,11 +440,80 @@
     return result;
   }
 
+  /**
+   * Returns the member list of a group of server.
+   *
+   * @param serverGroupId
+   *          The group name.
+   * @return the member list of a group of server.
+   * @throws ADSContextException
+   *           if something goes wrong.
+   */
+  public Set<String> getServerGroupMemberList(
+      String serverGroupId) throws ADSContextException
+  {
+    LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(serverGroupId) + ","
+        + getServerGroupContainerDN());
+
+    Set<String> result = new HashSet<String>() ;
+    try
+    {
+      SearchControls sc = new SearchControls();
+      sc.setSearchScope(SearchControls.OBJECT_SCOPE);
+      NamingEnumeration<SearchResult> srs = getDirContext().search(dn,
+          "(objectclass=*)", sc);
+
+      if (!srs.hasMore())
+      {
+        return result;
+      }
+      Attributes attrs = srs.next().getAttributes();
+      NamingEnumeration ne = attrs.getAll();
+      while (ne.hasMore())
+      {
+        Attribute attr = (Attribute)ne.next();
+        String attrID = attr.getID();
+
+        if (!attrID.toLowerCase().equals(
+            ServerGroupProperty.MEMBERS.getAttributeName().toLowerCase()))
+        {
+          continue;
+        }
+
+        // We have the members list
+        NamingEnumeration ae = attr.getAll();
+        while (ae.hasMore())
+        {
+          result.add((String)ae.next());
+        }
+        break;
+      }
+    }
+    catch (NameNotFoundException x)
+    {
+      result = new HashSet<String>();
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
 
   /**
-   * Returns a set containing the servers that are registered in the ADS.
-   * @return a set containing the servers that are registered in the ADS.
-   * @throws ADSContextException if something goes wrong.
+   * Returns a set containing the servers that are registered in the
+   * ADS.
+   *
+   * @return a set containing the servers that are registered in the
+   *         ADS.
+   * @throws ADSContextException
+   *           if something goes wrong.
    */
   public Set<Map<ServerProperty,Object>> readServerRegistry()
   throws ADSContextException
@@ -583,6 +647,9 @@
     LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
     BasicAttributes attrs = makeAttrsFromServerGroupProperties(
         serverGroupProperties);
+    // Add the objectclass attribute value
+    attrs.put("objectclass", "top");
+    attrs.put("objectclass", "groupOfUniqueNames");
     try
     {
       DirContext ctx = dirContext.createSubcontext(dn, attrs);
@@ -604,13 +671,16 @@
    * Updates the properties of a Server Group in the ADS.
    * @param serverGroupProperties the new properties of the server group to be
    * updated.
+   * @param groupID The group name.
    * @throws ADSContextException if somethings goes wrong.
    */
-  public void updateServerGroup(
+  public void updateServerGroup(String groupID,
       Map<ServerGroupProperty, Object> serverGroupProperties)
   throws ADSContextException
   {
-    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
+
+    LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(groupID) + "," +
+        getServerGroupContainerDN());
     BasicAttributes attrs =
       makeAttrsFromServerGroupProperties(serverGroupProperties);
     try
@@ -630,6 +700,38 @@
   }
 
   /**
+   * Updates the properties of a Server Group in the ADS.
+   * @param serverGroupProperties the new properties of the server group to be
+   * updated.
+   * @param groupID The group name.
+   * @throws ADSContextException if somethings goes wrong.
+   */
+  public void removeServerGroupProp(String groupID,
+      Set<ServerGroupProperty> serverGroupProperties)
+  throws ADSContextException
+  {
+
+    LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(groupID) + "," +
+        getServerGroupContainerDN());
+    BasicAttributes attrs =
+      makeAttrsFromServerGroupProperties(serverGroupProperties);
+    try
+    {
+      dirContext.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs);
+    }
+    catch (NameAlreadyBoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ALREADY_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
    * Deletes a Server Group in the ADS.
    * @param serverGroupProperties the properties of the server group to be
    * deleted.
@@ -762,134 +864,6 @@
     createContainerEntry(getServerGroupContainerDN());
   }
 
-  /**
-   * TODO: remove this method if we can assume that the server during setup
-   * can be started to do a number of things.
-   * NOTE: this can only be called locally.
-   * The call to this method assumes that OpenDS.jar has already been loaded.
-   * So this should not be called by the Java Web Start before being sure that
-   * this jar is loaded.
-   * @param serverProperties the properties of the servers to register.
-   * @param serverGroupProperties the properties of the server groups to
-   * register.
-   * @param administratorProperties the properties of the administrators to
-   * register.
-   * @param installPath the installation path of the server.
-   * @throws ADSContextException if something goes wrong.
-   */
-  public static void createOfflineAdminData(
-      Set<Map<ServerProperty, Object>> serverProperties,
-      Set<Map<ServerGroupProperty, Object>> serverGroupProperties,
-      Set<Map<AdministratorProperty, Object>> administratorProperties,
-      String installPath)
-  throws ADSContextException
-  {
-    // Add the administration suffix
-    createOfflineAdministrationSuffix(installPath);
-
-    // Create the DIT below the administration suffix
-    try
-    {
-      File ldifFile = File.createTempFile("ads", ".ldif");
-      ldifFile.deleteOnExit();
-
-      LinkedList<String> lines = new LinkedList<String>();
-
-      lines.add("dn: "+getAdministrationSuffixDN());
-      lines.add("objectclass: extensibleobject");
-      lines.add("aci: "+getTopContainerACI());
-      lines.add("");
-
-      lines.add("dn: "+getAdministratorContainerDN());
-      lines.add("objectclass: groupOfUniqueNames");
-      lines.add("objectclass: groupofurls");
-      lines.add("memberURL: ldap:///" + getAdministratorContainerDN() +
-      "??one?(objectclass=*)");
-      lines.add("description: Group of identities which have full access.");
-
-      lines.add("dn: "+getServerContainerDN());
-      lines.add("objectclass: extensibleobject");
-      lines.add("");
-
-      lines.add("dn: "+getServerGroupContainerDN());
-      lines.add("objectclass: extensibleobject");
-
-      for (Map<ServerProperty, Object> props : serverProperties)
-      {
-        lines.add("");
-        LdapName dn = makeDNFromServerProperties(props);
-        BasicAttributes attrs = makeAttrsFromServerProperties(props);
-        addToLines(dn, attrs, lines);
-      }
-      for (Map<ServerGroupProperty, Object> props : serverGroupProperties)
-      {
-        lines.add("");
-        LdapName dn = makeDNFromServerGroupProperties(props);
-        BasicAttributes attrs = makeAttrsFromServerGroupProperties(props);
-        addToLines(dn, attrs, lines);
-      }
-      for (Map<AdministratorProperty, Object> props : administratorProperties)
-      {
-        lines.add("");
-        LdapName dn = makeDNFromAdministratorProperties(props);
-        BasicAttributes attrs = makeAttrsFromAdministratorProperties(props);
-        addToLines(dn, attrs, lines);
-      }
-
-
-      BufferedWriter writer = new BufferedWriter(new FileWriter(ldifFile));
-      for (String line : lines)
-      {
-        writer.write(line);
-        writer.newLine();
-      }
-
-      writer.flush();
-      writer.close();
-
-      ArrayList<String> argList = new ArrayList<String>();
-      argList.add("-C");
-      argList.add(
-          org.opends.server.extensions.ConfigFileHandler.class.getName());
-
-      argList.add("-c");
-      argList.add(installPath+File.separator+"config"+File.separator+
-          "config.ldif");
-
-      argList.add("-n");
-      argList.add(getBackendName());
-      argList.add("-t");
-      argList.add(ldifFile.getAbsolutePath());
-      argList.add("-S");
-      argList.add("0");
-
-      String[] args = new String[argList.size()];
-      argList.toArray(args);
-
-      try
-      {
-
-        int result = org.opends.server.tools.ImportLDIF.mainImportLDIF(args);
-
-        if (result != 0)
-        {
-          throw new ADSContextException(
-              ADSContextException.ErrorType.ERROR_UNEXPECTED);
-        }
-      } catch (Throwable t)
-      {
-//      This should not happen
-        throw new ADSContextException(
-            ADSContextException.ErrorType.ERROR_UNEXPECTED, t);
-      }
-    }
-    catch (IOException ioe)
-    {
-//    This should not happen
-      throw new ADSContextException(
-          ADSContextException.ErrorType.ERROR_UNEXPECTED, ioe);
-    }
-  }
 
   /**
    * Removes the administration data.
@@ -1297,8 +1271,29 @@
         result.put(attr);
       }
     }
-    // Add the objectclass attribute value
-    result.put("objectclass", "extensibleobject");
+    return result;
+  }
+
+  /**
+   * Returns the attributes for some server group properties.
+   * @param serverProperties the server group properties.
+   * @return the attributes for the given server group properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static BasicAttributes makeAttrsFromServerGroupProperties(
+      Set<ServerGroupProperty> serverGroupProperties)
+  {
+    BasicAttributes result = new BasicAttributes();
+
+    // Transform 'properties' into 'attributes'
+    for (ServerGroupProperty prop: serverGroupProperties)
+    {
+      Attribute attr = makeAttrFromServerGroupProperty(prop,null);
+      if (attr != null)
+      {
+        result.put(attr);
+      }
+    }
     return result;
   }
 
@@ -1344,29 +1339,15 @@
       new HashMap<ServerGroupProperty, Object>();
     try
     {
-      NamingEnumeration ne = attrs.getAll();
-      while (ne.hasMore())
+      for (ServerGroupProperty prop : ServerGroupProperty.values())
       {
-        Attribute attr = (Attribute)ne.next();
-        String attrID = attr.getID();
+        Attribute attr = (Attribute) attrs.get(prop.getAttributeName());
+        if (attr == null)
+        {
+          continue ;
+        }
         Object value = null;
 
-        ServerGroupProperty prop = null;
-        ServerGroupProperty[] props = ServerGroupProperty.values();
-        for (int i=0; i<props.length && (prop == null); i++)
-        {
-          String v = props[i].getAttributeName();
-          if (attrID.equalsIgnoreCase(v))
-          {
-            prop = props[i];
-          }
-        }
-        if (prop == null)
-        {
-          throw new ADSContextException(
-              ADSContextException.ErrorType.ERROR_UNEXPECTED);
-        }
-
         if (attr.size() >= 1 &&
             MULTIVALUED_SERVER_GROUP_PROPERTIES.contains(prop))
         {
@@ -1769,7 +1750,9 @@
   {
     BasicAttributes attrs = new BasicAttributes();
 
-    attrs.put("objectclass", "extensibleobject");
+    attrs.put("objectclass", "top");
+    attrs.put("objectclass", "ds-cfg-branch");
+    // attrs.put("objectclass", "extensibleobject");
     createEntry(dn, attrs);
   }
 
@@ -1798,7 +1781,8 @@
   {
     BasicAttributes attrs = new BasicAttributes();
 
-    attrs.put("objectclass", "extensibleobject");
+    attrs.put("objectclass", "top");
+    attrs.put("objectclass", "ds-cfg-branch");
     attrs.put("aci", getTopContainerACI());
     createEntry(getAdministrationSuffixDN(), attrs);
   }
@@ -1851,41 +1835,6 @@
   }
 
   /**
-   * Creates the Administration Suffix when the server is down.  This can only
-   * be called locally.
-   * @param installPath the installation path of the server
-   * @throws ADSContextException if something goes wrong.
-   */
-  private static void createOfflineAdministrationSuffix(String installPath)
-  throws ADSContextException
-  {
-    // NOTE: the call to this method assumes
-    // that OpenDS.jar has already been loaded.  So this should not be called by
-    // the Java Web Start before being sure that this jar is loaded.
-    ArrayList<String> argList = new ArrayList<String>();
-    argList.add("-C");
-    argList.add(org.opends.server.extensions.ConfigFileHandler.class.getName());
-
-    argList.add("-c");
-    argList.add(installPath+File.separator+"config"+File.separator+
-        "config.ldif");
-
-    argList.add("-b");
-    argList.add(getAdministrationSuffixDN());
-
-    String[] args = new String[argList.size()];
-    argList.toArray(args);
-
-    int returnValue = org.opends.server.tools.ConfigureDS.configMain(args);
-
-    if (returnValue != 0)
-    {
-      throw new ADSContextException(
-          ADSContextException.ErrorType.ERROR_UNEXPECTED);
-    }
-  }
-
-  /**
    * Removes the administration suffix.
    * @throws ADSContextException
    */
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextException.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextException.java
index 0243f09..b1b180d 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextException.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextException.java
@@ -151,7 +151,7 @@
   {
     if (toString == null)
     {
-      toString = "ADSContextException: error type"+error+".";
+      toString = "ADSContextException: error type "+error+".";
       if (getCause() != null)
       {
         toString += "  Root cause: "+getCause().toString();
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
index a69c957..b239f6f 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
@@ -32,6 +32,7 @@
 
 import javax.naming.ldap.InitialLdapContext;
 
+import org.opends.server.admin.ManagedObjectNotFoundException;
 import org.opends.server.admin.client.ManagementContext;
 import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
 import org.opends.server.admin.client.ldap.LDAPManagementContext;
@@ -72,7 +73,15 @@
       ManagementContext mCtx = LDAPManagementContext.createFromContext(
           JNDIDirContextAdaptor.adapt(ctx));
       RootCfgClient root = mCtx.getRootConfiguration();
-      BackendCfgClient backend = root.getBackend(backendName);
+      BackendCfgClient backend = null;
+      try
+      {
+        backend = root.getBackend(backendName);
+      }
+      catch (ManagedObjectNotFoundException monfe)
+      {
+        // It does not exist.
+      }
       if (backend != null)
       {
         SortedSet<DN> suffixes = backend.getBackendBaseDN();
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java
deleted file mode 100644
index c420bb0..0000000
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * 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.admin.ads;
-
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-
-import org.opends.server.types.NullOutputStream;
-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.FileBasedArgument;
-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.args.SubCommandArgumentParser;
-
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.messages.AdminMessages.*;
-import static org.opends.server.messages.ToolMessages.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-import static org.opends.server.tools.ToolConstants.*;
-
-
-/**
- * This class provides a tool that can be used to Directory Server services.
- */
-public class DsServiceCLI
-{
-  /**
-   * The fully-qualified name of this class.
-   */
-  private static final String CLASS_NAME =
-      "org.opends.admin.ads.DsServiceCLI";
-
-
-  // The print stream to use for standard error.
-  private PrintStream err;
-
-  // The print stream to use for standard output.
-  private PrintStream out;
-
-
-
-  /**
-   * Constructor for the DsServiceCLI object.
-   *
-   * @param  out            The print stream to use for standard output.
-   * @param  err            The print stream to use for standard error.
-   */
-  public DsServiceCLI(PrintStream out, PrintStream err)
-  {
-    this.out           = out;
-    this.err           = err;
-  }
-
-  /**
-   * The main method for dsservice tool.
-   *
-   * @param  args  The command-line arguments provided to this program.
-   */
-
-  public static void main(String[] args)
-  {
-    int retCode = mainCLI(args, System.out, System.err);
-
-    if(retCode != 0)
-    {
-      System.exit(retCode);
-    }
-  }
-
-  /**
-   * Parses the provided command-line arguments and uses that information to
-   * run the dsservice tool.
-   *
-   * @param  args  The command-line arguments provided to this program.
-   *
-   * @return The error code.
-   */
-
-  public static int mainCLI(String[] args)
-  {
-    return mainCLI(args, System.out, System.err);
-  }
-
-  /**
-   * Parses the provided command-line arguments and uses that information to
-   * run the dsservice tool.
-   *
-   * @param  args              The command-line arguments provided to this
-   *                           program.
-   * @param  outStream         The output stream to use for standard output, or
-   *                           <CODE>null</CODE> if standard output is not
-   *                           needed.
-   * @param  errStream         The output stream to use for standard error, or
-   *                           <CODE>null</CODE> if standard error is not
-   *                           needed.
-   *
-   * @return The error code.
-   */
-
-  public static int mainCLI(String[] args, OutputStream outStream,
-      OutputStream errStream)
-  {
-    PrintStream out;
-    if (outStream == null)
-    {
-      out = NullOutputStream.printStream();
-    }
-    else
-    {
-      out = new PrintStream(outStream);
-    }
-
-    PrintStream err;
-    if (errStream == null)
-    {
-      err = NullOutputStream.printStream();
-    }
-    else
-    {
-      err = new PrintStream(errStream);
-    }
-
-    // Create the command-line argument parser for use with this program.
-    String toolDescription = getMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION);
-    SubCommandArgumentParser argParser = new SubCommandArgumentParser(
-        CLASS_NAME, toolDescription, false);
-
-    // GLOBAL OPTION
-    try
-    {
-      BooleanArgument showUsage = null;
-      BooleanArgument useSSL = null;
-      StringArgument hostName = null;
-      IntegerArgument port = null;
-      StringArgument bindDN = null;
-      FileBasedArgument bindPasswordFile = null;
-      BooleanArgument verbose = null;
-
-      showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP,
-          OPTION_LONG_HELP, MSGID_DESCRIPTION_SHOWUSAGE);
-      argParser.addGlobalArgument(showUsage);
-      argParser.setUsageArgument(showUsage, out);
-
-      useSSL = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL,
-          OPTION_LONG_USE_SSL, MSGID_DESCRIPTION_USE_SSL);
-      argParser.addGlobalArgument(useSSL);
-
-      hostName = new StringArgument("host", OPTION_SHORT_HOST,
-          OPTION_LONG_HOST, false, false, true, OPTION_VALUE_HOST, "localhost",
-          null, MSGID_DESCRIPTION_HOST);
-      argParser.addGlobalArgument(hostName);
-
-      port = new IntegerArgument("port", OPTION_SHORT_PORT, OPTION_LONG_PORT,
-          false, false, true, OPTION_VALUE_PORT, 389, null,
-          MSGID_DESCRIPTION_PORT);
-      argParser.addGlobalArgument(port);
-
-      bindDN = new StringArgument("bindDN", OPTION_SHORT_BINDDN,
-          OPTION_LONG_BINDDN, false, false, true, OPTION_VALUE_BINDDN,
-          "cn=Directory Manager", null, MSGID_DESCRIPTION_BINDDN);
-      argParser.addGlobalArgument(bindDN);
-
-      bindPasswordFile = new FileBasedArgument("bindPasswordFile",
-          OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_BINDPWD_FILE, false, false,
-          OPTION_VALUE_BINDPWD_FILE, null, null,
-          MSGID_DESCRIPTION_BINDPASSWORDFILE);
-      argParser.addGlobalArgument(bindPasswordFile);
-
-      verbose = new BooleanArgument("verbose", 'v', "verbose",
-          MSGID_DESCRIPTION_VERBOSE);
-      argParser.addGlobalArgument(verbose);
-    }
-    catch (ArgumentException ae)
-    {
-      int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
-      String message = getMessage(msgID, ae.getMessage());
-
-      err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
-    }
-
-    // SERVER GROUP MANAGEMENT
-    try
-    {
-      SubCommand subCmd ;
-      Argument argument;
-
-      // Create-group subcommand
-      subCmd = new SubCommand(argParser,"create-group",true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION);
-      argument = new StringArgument("description", OPTION_SHORT_DESCRIPTION,
-          OPTION_LONG_DESCRIPTION, false, false, true,
-          OPTION_VALUE_DESCRIPTION, "", null,
-          MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION);
-      subCmd.addArgument(argument);
-
-
-      // modify-group
-      subCmd = new SubCommand(argParser,"modify-group",true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION);
-      argument = new StringArgument("new-description",
-          OPTION_SHORT_DESCRIPTION,
-          OPTION_LONG_DESCRIPTION, false, false, true,
-          OPTION_VALUE_DESCRIPTION, "", null,
-          MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION);
-      subCmd.addArgument(argument);
-      argument = new StringArgument("new-groupID",
-          OPTION_SHORT_GROUPID,
-          OPTION_LONG_GROUPID, false, false, true,
-          OPTION_VALUE_GROUPID, "", null,
-          MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION);
-      subCmd.addArgument(argument);
-
-      // delete-group
-      subCmd = new SubCommand(argParser,"delete-group",true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION);
-
-      // list-groups
-      subCmd = new SubCommand(argParser,"list-groups",
-          MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION);
-
-      // add-to-group
-      subCmd = new SubCommand(argParser,"add-to-group",
-          true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
-      argument = new StringArgument("memberID",
-          OPTION_SHORT_MEMBERID,
-          OPTION_LONG_MEMBERID, false, false, true,
-          OPTION_VALUE_MEMBERID, "", null,
-          MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION);
-      subCmd.addArgument(argument);
-
-      // remove-from-group
-      subCmd = new SubCommand(argParser,"remove-from-group",
-          true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
-      argument = new StringArgument("memberID",
-          OPTION_SHORT_MEMBERID,
-          OPTION_LONG_MEMBERID, false, false, true,
-          OPTION_VALUE_MEMBERID, "", null,
-          MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION);
-      subCmd.addArgument(argument);
-
-      // list-members
-      subCmd = new SubCommand(argParser,"list-members",
-          true,1,1,
-          OPERAND_GROUPID,
-          MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION);
-
-      // list-membership
-      subCmd = new SubCommand(argParser,"list-membership",
-          true,1,1,
-          OPERAND_MEMBERID,
-          MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
-
-    } catch (ArgumentException ae)
-    {
-      int    msgID   = MSGID_CANNOT_INITIALIZE_ARGS;
-      String message = getMessage(msgID, ae.getMessage());
-
-      err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
-    }
-
-    // Parse the command-line arguments provided to this program.
-    try
-    {
-      argParser.parseArguments(args);
-    }
-    catch (ArgumentException ae)
-    {
-      int    msgID   = MSGID_ERROR_PARSING_ARGS;
-      String message = getMessage(msgID, ae.getMessage());
-
-      err.println(wrapText(message, MAX_LINE_WIDTH));
-      err.println(argParser.getUsage());
-      return 1;
-    }
-
-    // If we should just display usage information, then print it and exit.
-    if (argParser.usageOrVersionDisplayed())
-    {
-      return 0;
-    }
-    return 0;
-  }
-
-}
-
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java
new file mode 100644
index 0000000..231eed5
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java
@@ -0,0 +1,179 @@
+/*
+ * 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.admin.ads;
+
+import static org.opends.server.messages.AdminMessages.*;
+import static org.opends.server.tools.ToolConstants.*;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+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 class is handling server group CLI.
+ */
+public class DsServiceCliAds implements DsServiceCliSubCommandGroup
+{
+
+  /**
+   * The subcommand Parser.
+   */
+  SubCommandArgumentParser argParser ;
+
+  /**
+   * The verbose argument.
+   */
+  BooleanArgument verboseArg ;
+
+  /**
+   * The enumeration containing the different subCommand names.
+   */
+  private enum SubCommandNameEnum
+  {
+    /**
+     * The create-ads subcommand.
+     */
+    CREATE_ADS("create-ads"),
+
+    /**
+     * The delete-ads subcommand.
+     */
+    DELETE_ADS("delete-ads");
+
+    // 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 'create-ads' subcommand.
+   */
+  public SubCommand createAdsSubCmd;
+
+  /**
+   * The 'delete-ads' subcommand.
+   */
+  private SubCommand deleteAdsSubCmd;
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeCliGroup(SubCommandArgumentParser argParser,
+      BooleanArgument verboseArg)
+      throws ArgumentException
+  {
+    this.argParser = argParser ;
+    this.verboseArg = verboseArg ;
+
+    // Create-ads subcommand
+    createAdsSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_ADS
+        .toString(), true, 1, 1, OPERAND_BACKEND,
+        MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION);
+    createAdsSubCmd.setHidden(true);
+
+    // delete-ads
+    deleteAdsSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_ADS
+        .toString(), true, 1, 1, OPERAND_BACKEND,
+        MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION);
+    deleteAdsSubCmd.setHidden(true);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isSubCommand(SubCommand subCmd)
+  {
+      return SubCommandNameEnum.isSubCommand(subCmd.getName());
+  }
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public int performSubCommand(ADSContext adsContext, SubCommand subCmd,
+      OutputStream outStream, OutputStream errStream)
+      throws ADSContextException
+  {
+    //
+    // create-ads subcommand
+    if (subCmd.getName().equals(createAdsSubCmd.getName()))
+    {
+      String backendName = subCmd.getTrailingArguments().get(0);
+      ADSContextHelper helper = new ADSContextHelper();
+      adsContext.createAdminData();
+      helper.createAdministrationSuffix(adsContext.getDirContext(),
+          backendName);
+      return 0;
+    }
+    else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
+    {
+      String backendName = subCmd.getTrailingArguments().get(0);
+      ADSContextHelper helper = new ADSContextHelper();
+      helper.removeAdministrationSuffix(adsContext.getDirContext(),
+          backendName);
+      return 0;
+    }
+
+    // Should never occurs: If we are here, it means that the code to
+    // handle to subcommand is not yet written.
+    return 1;
+  }
+}
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java
new file mode 100644
index 0000000..8454d09
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliMain.java
@@ -0,0 +1,242 @@
+/*
+ * 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.admin.ads;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import javax.naming.NamingException;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.opends.admin.ads.util.ConnectionUtils;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.args.ArgumentException;
+
+import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.AdminMessages.*;
+import static org.opends.server.messages.ToolMessages.*;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+/**
+ * This class provides a tool that can be used to Directory Server services.
+ */
+public class DsServiceCliMain
+{
+  /**
+   * The fully-qualified name of this class.
+   */
+  private static final String CLASS_NAME =
+      "org.opends.admin.ads.DsServiceCLI";
+
+  // The print stream to use for standard error.
+  private PrintStream err;
+
+  // The print stream to use for standard output.
+  private PrintStream out;
+
+
+
+  /**
+   * Constructor for the DsServiceCLI object.
+   *
+   * @param  out            The print stream to use for standard output.
+   * @param  err            The print stream to use for standard error.
+   */
+  public DsServiceCliMain(PrintStream out, PrintStream err)
+  {
+    this.out           = out;
+    this.err           = err;
+  }
+
+  /**
+   * The main method for dsservice tool.
+   *
+   * @param  args  The command-line arguments provided to this program.
+   */
+
+  public static void main(String[] args)
+  {
+    int retCode = mainCLI(args, System.out, System.err);
+
+    if(retCode != 0)
+    {
+      System.exit(retCode);
+    }
+  }
+
+  /**
+   * Parses the provided command-line arguments and uses that information to
+   * run the dsservice tool.
+   *
+   * @param  args  The command-line arguments provided to this program.
+   *
+   * @return The error code.
+   */
+
+  public static int mainCLI(String[] args)
+  {
+    return mainCLI(args, System.out, System.err);
+  }
+
+  /**
+   * Parses the provided command-line arguments and uses that information to
+   * run the dsservice tool.
+   *
+   * @param  args              The command-line arguments provided to this
+   *                           program.
+   * @param  outStream         The output stream to use for standard output, or
+   *                           <CODE>null</CODE> if standard output is not
+   *                           needed.
+   * @param  errStream         The output stream to use for standard error, or
+   *                           <CODE>null</CODE> if standard error is not
+   *                           needed.
+   *
+   * @return The error code.
+   */
+
+  public static int mainCLI(String[] args, OutputStream outStream,
+      OutputStream errStream)
+  {
+    PrintStream out;
+    if (outStream == null)
+    {
+      out = NullOutputStream.printStream();
+    }
+    else
+    {
+      out = new PrintStream(outStream);
+    }
+
+    PrintStream err;
+    if (errStream == null)
+    {
+      err = NullOutputStream.printStream();
+    }
+    else
+    {
+      err = new PrintStream(errStream);
+    }
+
+    // Create the command-line argument parser for use with this
+    // program.
+    DsServiceCliParser argParser ;
+    try
+    {
+      String toolDescription = getMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION);
+      argParser = new DsServiceCliParser(CLASS_NAME,
+          toolDescription, false);
+      argParser.initializeParser(out);
+    }
+    catch (ArgumentException ae)
+    {
+      int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
+      String message = getMessage(msgID, ae.getMessage());
+
+      err.println(wrapText(message, MAX_LINE_WIDTH));
+      return 1;
+    }
+
+    // Parse the command-line arguments provided to this program.
+    try
+    {
+      argParser.parseArguments(args);
+    }
+    catch (ArgumentException ae)
+    {
+      int    msgID   = MSGID_ERROR_PARSING_ARGS;
+      String message = getMessage(msgID, ae.getMessage());
+
+      err.println(wrapText(message, MAX_LINE_WIDTH));
+      err.println(argParser.getUsage());
+      return 1;
+    }
+
+    // If we should just display usage information, then print it and exit.
+    if (argParser.usageOrVersionDisplayed())
+    {
+      return 0;
+    }
+
+    // Get connection parameters
+    String host = argParser.getHostName() ;
+    String port = argParser.getPort() ;
+    String dn   = argParser.getBindDN() ;
+    String pwd  = argParser.getBindPassword(dn,out,err) ;
+    if (pwd == null)
+    {
+      // TODO Should we do something?
+      return 1;
+    }
+
+    // Try to connect
+    String ldapUrl = "ldap://"+host+":"+port;
+
+   InitialLdapContext ctx = null;
+   int returnCode = 0 ;
+    try
+    {
+      ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
+          ConnectionUtils.getDefaultLDAPTimeout(), null);
+    }
+    catch (NamingException e)
+    {
+      int    msgID   = MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS;
+      String message = getMessage(msgID, host);
+
+      err.println(wrapText(message, MAX_LINE_WIDTH));
+      return 1;
+    }
+    ADSContext adsContext = new ADSContext(ctx);
+
+    DirectoryServer.bootstrapClient();
+    // perform the subCommand
+    try
+    {
+      returnCode = argParser.performSubCommand(adsContext, out, err);
+    }
+    catch (ADSContextException e)
+    {
+      // TODO Print a nice message
+      e.printStackTrace();
+      returnCode = e.error.ordinal();
+    }
+
+    // deconnection
+    try
+    {
+      ctx.close();
+    }
+    catch (NamingException e)
+    {
+      // TODO Should we do something ?
+    }
+    return returnCode;
+  }
+}
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java
new file mode 100644
index 0000000..63422c3
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliParser.java
@@ -0,0 +1,334 @@
+/*
+ * 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.admin.ads;
+
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
+import static org.opends.server.messages.ToolMessages.*;
+import static org.opends.server.tools.ToolConstants.*;
+import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH;
+import static org.opends.server.util.StaticUtils.wrapText;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.DebugLogLevel;
+import org.opends.server.util.PasswordReader;
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.BooleanArgument;
+import org.opends.server.util.args.FileBasedArgument;
+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.args.SubCommandArgumentParser;
+
+/**
+ * This class will parser CLI arguments.
+ */
+public class DsServiceCliParser extends SubCommandArgumentParser
+{
+  /**
+   * The tracer object for the debug logger.
+   */
+  private static final DebugTracer TRACER = getTracer();
+
+  /**
+   * The showUsage' global argument.
+   */
+  private BooleanArgument showUsageArg = null;
+
+  /**
+   * The 'useSSLArg' global argument.
+   */
+  private BooleanArgument useSSLArg = null;
+
+  /**
+   * The 'hostName' global argument.
+   */
+  private StringArgument hostNameArg = null;
+
+  /**
+   * The 'port' global argument.
+   */
+  private IntegerArgument portArg = null;
+
+  /**
+   * The 'binDN' global argument.
+   */
+  private StringArgument bindDnArg = null;
+
+  /**
+   * The 'bindPasswordFile' global argument.
+   */
+  private FileBasedArgument bindPasswordFileArg = null;
+
+  /**
+   * The 'verbose' global argument.
+   */
+  private BooleanArgument verboseArg = null;
+
+  /**
+   * The diferent CLI group.
+   */
+  public HashSet<DsServiceCliSubCommandGroup> cliGroup;
+
+
+
+  /**
+   * Creates a new instance of this subcommand argument parser with no
+   * arguments.
+   *
+   * @param mainClassName
+   *          The fully-qualified name of the Java class that should
+   *          be invoked to launch the program with which this
+   *          argument parser is associated.
+   * @param toolDescription
+   *          A human-readable description for the tool, which will be
+   *          included when displaying usage information.
+   * @param longArgumentsCaseSensitive
+   *          Indicates whether subcommand and long argument names
+   *          should be treated in a case-sensitive manner.
+   */
+  public DsServiceCliParser(String mainClassName, String toolDescription,
+      boolean longArgumentsCaseSensitive)
+  {
+    super(mainClassName, toolDescription, longArgumentsCaseSensitive);
+    cliGroup = new HashSet<DsServiceCliSubCommandGroup>();
+  }
+
+  /**
+   * Initialize the parser with the Gloabal options ans subcommands.
+   *
+   * @param outStream
+   *          The output stream to use for standard output, or <CODE>null</CODE>
+   *          if standard output is not needed.
+   * @throws ArgumentException
+   *           If there is a problem with any of the parameters used
+   *           to create this argument.
+   */
+  public void initializeParser(OutputStream outStream)
+      throws ArgumentException
+  {
+    // Global parameters
+    initializeGlobalOption(outStream);
+
+    // ads  Group cli
+    cliGroup.add(new DsServiceCliAds());
+
+    // Server Group cli
+    cliGroup.add(new DsServiceCliServerGroup());
+
+    // Initialization
+    for (DsServiceCliSubCommandGroup oneCli : cliGroup)
+    {
+      oneCli.initializeCliGroup(this, verboseArg);
+    }
+  }
+
+  /**
+   * Initialize Global option.
+   *
+   * @param outStream
+   *          The output stream used forn the usage.
+   * @throws ArgumentException
+   *           If there is a problem with any of the parameters used
+   *           to create this argument.
+   */
+  private void initializeGlobalOption(OutputStream outStream)
+  throws ArgumentException
+  {
+    showUsageArg = new BooleanArgument("showUsage", OPTION_SHORT_HELP,
+        OPTION_LONG_HELP, MSGID_DESCRIPTION_SHOWUSAGE);
+    addGlobalArgument(showUsageArg);
+    setUsageArgument(showUsageArg, outStream);
+
+    useSSLArg = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL,
+        OPTION_LONG_USE_SSL, MSGID_DESCRIPTION_USE_SSL);
+    addGlobalArgument(useSSLArg);
+
+    hostNameArg = new StringArgument("host", OPTION_SHORT_HOST,
+        OPTION_LONG_HOST, false, false, true, OPTION_VALUE_HOST, "localhost",
+        null, MSGID_DESCRIPTION_HOST);
+    addGlobalArgument(hostNameArg);
+
+    portArg = new IntegerArgument("port", OPTION_SHORT_PORT, OPTION_LONG_PORT,
+        false, false, true, OPTION_VALUE_PORT, 389, null,
+        MSGID_DESCRIPTION_PORT);
+    addGlobalArgument(portArg);
+
+    bindDnArg = new StringArgument("bindDN", OPTION_SHORT_BINDDN,
+        OPTION_LONG_BINDDN, false, false, true, OPTION_VALUE_BINDDN,
+        "cn=Directory Manager", null, MSGID_DESCRIPTION_BINDDN);
+    addGlobalArgument(bindDnArg);
+
+    bindPasswordFileArg = new FileBasedArgument("bindPasswordFile",
+        OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_BINDPWD_FILE, false, false,
+        OPTION_VALUE_BINDPWD_FILE, null, null,
+        MSGID_DESCRIPTION_BINDPASSWORDFILE);
+    addGlobalArgument(bindPasswordFileArg);
+
+    verboseArg = new BooleanArgument("verbose", 'v', "verbose",
+        MSGID_DESCRIPTION_VERBOSE);
+    addGlobalArgument(verboseArg);
+  }
+
+
+  /**
+   * Get the host name which has to be used for the command.
+   *
+   * @return The host name specified by the command line argument, or
+   *         the default value, if not specified.
+   */
+  public String getHostName()
+  {
+    if (hostNameArg.isPresent())
+    {
+      return hostNameArg.getValue();
+    }
+    else
+    {
+      return hostNameArg.getDefaultValue();
+    }
+
+  }
+
+  /**
+   * Get the port which has to be used for the command.
+   *
+   * @return The port specified by the command line argument, or the
+   *         default value, if not specified.
+   */
+  public String getPort()
+  {
+    if (portArg.isPresent())
+    {
+      return portArg.getValue();
+    }
+    else
+    {
+      return portArg.getDefaultValue();
+    }
+
+  }
+
+  /**
+   * Get the bindDN which has to be used for the command.
+   *
+   * @return The bindDN specified by the command line argument, or the
+   *         default value, if not specified.
+   */
+  public String getBindDN()
+  {
+    if (bindDnArg.isPresent())
+    {
+      return bindDnArg.getValue();
+    }
+    else
+    {
+      return bindDnArg.getDefaultValue();
+    }
+  }
+
+
+  /**
+   * Get the password which has to be used for the command.
+   *
+   * @param dn
+   *          The user DN for which to password could be asked.
+   * @param out
+   *          The input stream to used if we have to prompt to the
+   *          user.
+   * @param err
+   *          The error stream to used if we have to prompt to the
+   *          user.
+   * @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)
+  {
+    if (bindPasswordFileArg.isPresent())
+    {
+      return bindPasswordFileArg.getValue();
+    }
+    else
+    {
+      // read the password from the stdin.
+      try
+      {
+        out.print(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn));
+        char[] pwChars = PasswordReader.readPassword();
+        return new String(pwChars);
+      }
+      catch (Exception ex)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+        }
+        err.println(wrapText(ex.getMessage(), MAX_LINE_WIDTH));
+        return null;
+      }
+    }
+  }
+
+  /**
+   * 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.
+   */
+  public int performSubCommand(ADSContext adsContext, OutputStream outStream,
+      OutputStream errStream)
+    throws ADSContextException
+  {
+    SubCommand subCmd = getSubCommand();
+
+    for (DsServiceCliSubCommandGroup oneCli : cliGroup)
+    {
+      if (oneCli.isSubCommand(subCmd))
+      {
+        return oneCli.performSubCommand(adsContext, subCmd, outStream,
+            errStream);
+      }
+    }
+
+    // Should never occurs: If we are here, it means that the code to
+    // handle to subcommand is not yet written.
+    return 1;
+  }
+}
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java
new file mode 100644
index 0000000..1fab2e3
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliServerGroup.java
@@ -0,0 +1,587 @@
+/*
+ * 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.admin.ads;
+
+import static org.opends.server.messages.AdminMessages.*;
+import static org.opends.server.tools.ToolConstants.*;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+import org.opends.admin.ads.ADSContext.ServerGroupProperty;
+import org.opends.server.util.args.ArgumentException;
+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.
+ */
+public class DsServiceCliServerGroup implements DsServiceCliSubCommandGroup
+{
+
+  /**
+   * End Of Line.
+   */
+  private String EOL = System.getProperty("line.separator");
+
+  /**
+   * The subcommand Parser.
+   */
+  SubCommandArgumentParser argParser ;
+
+  /**
+   * The verbose argument.
+   */
+  BooleanArgument verboseArg ;
+
+  /**
+   * The enumeration containing the different subCommand names.
+   */
+  private enum SubCommandNameEnum
+  {
+    /**
+     * The create-group subcommand.
+     */
+    CREATE_GROUP("create-group"),
+
+    /**
+     * The delete-group subcommand.
+     */
+    DELETE_GROUP("delete-group"),
+
+    /**
+     * The modify-group subcommand.
+     */
+    MODIFY_GROUP("modify-group"),
+
+    /**
+     * The list-groups subcommand.
+     */
+    LIST_GROUPS("list-groups"),
+
+    /**
+     * The list-members subcommand.
+     */
+    LIST_MEMBERS("list-members"),
+
+    /**
+     * The list-membership subcommand.
+     */
+    LIST_MEMBERSHIP("list-membership"),
+
+    /**
+     * The add-to-group subcommand.
+     */
+    ADD_TO_GROUP("add-to-group"),
+
+    /**
+     * The remove-from-group subcommand.
+     */
+    REMOVE_FROM_GROUP("remove-from-group");
+
+    // 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 'create-group' subcommand.
+   */
+  public SubCommand createGoupSubCmd;
+
+  /**
+   * The 'description' argument of the 'create-group' subcommand.
+   */
+  private StringArgument createGoupDescriptionArg;
+
+  /**
+   * The 'modify-group' subcommand.
+   */
+  private SubCommand modifyGroupSubCmd;
+
+  /**
+   * The 'description' argument of the 'modify-group' subcommand.
+   */
+  private StringArgument modifyGroupDescriptionArg;
+
+  /**
+   * The 'group-id' argument of the 'modify-group' subcommand.
+   */
+  private StringArgument modifyGroupGroupIdArg;
+
+  /**
+   * The 'delete-group' subcommand.
+   */
+  private SubCommand deleteGroupSubCmd;
+
+  /**
+   * The 'list-group' subcommand.
+   */
+  private SubCommand listGroupSubCmd;
+
+  /**
+   * The 'add-to-group' subcommand.
+   */
+  private SubCommand addToGroupSubCmd;
+
+  /**
+   * The 'member-id' argument of the 'add-to-group' subcommand.
+   */
+  private StringArgument addToGoupMemberIdArg;
+
+  /**
+   * The 'remove-from-group' subcommand.
+   */
+  private SubCommand removeFromGroupSubCmd;
+
+  /**
+   * The 'member-id' argument of the 'remove-from-group' subcommand.
+   */
+  private StringArgument removeFromGoupMemberIdArg;
+
+  /**
+   * The 'list-members' subcommand.
+   */
+  private SubCommand listMembersSubCmd;
+
+  /**
+   * The 'mlist-membership' subcommand.
+   */
+  private SubCommand listMembershipSubCmd;
+
+  /**
+   * {@inheritDoc}
+   */
+  public void initializeCliGroup(SubCommandArgumentParser argParser,
+      BooleanArgument verboseArg)
+      throws ArgumentException
+  {
+    this.argParser = argParser ;
+    this.verboseArg = verboseArg ;
+
+    // Create-group subcommand
+    createGoupSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_GROUP
+        .toString(), true, 1, 1, OPERAND_GROUPID,
+        MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION);
+    createGoupDescriptionArg = new StringArgument("description",
+        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
+        true, OPTION_VALUE_DESCRIPTION, "", null,
+        MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION);
+    createGoupSubCmd.addArgument(createGoupDescriptionArg);
+
+    // modify-group
+    modifyGroupSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.MODIFY_GROUP.toString(), true, 1, 1,
+        OPERAND_GROUPID, MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION);
+    modifyGroupDescriptionArg = new StringArgument("new-description",
+        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
+        true, OPTION_VALUE_DESCRIPTION, "", null,
+        MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION);
+    modifyGroupSubCmd.addArgument(modifyGroupDescriptionArg);
+    modifyGroupGroupIdArg = new StringArgument("new-groupID",
+        OPTION_SHORT_GROUPID, OPTION_LONG_GROUPID, false, false, true,
+        OPTION_VALUE_GROUPID, "", null,
+        MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION);
+    modifyGroupSubCmd.addArgument(modifyGroupGroupIdArg);
+
+    // delete-group
+    deleteGroupSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_GROUP
+        .toString(), true, 1, 1, OPERAND_GROUPID,
+        MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION);
+
+    // list-groups
+    listGroupSubCmd = new SubCommand(argParser, "list-groups",
+        MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION);
+
+    // add-to-group
+    addToGroupSubCmd = new SubCommand(argParser, SubCommandNameEnum.ADD_TO_GROUP
+        .toString(), true, 1, 1, OPERAND_GROUPID,
+        MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
+    addToGoupMemberIdArg = new StringArgument("memberID", OPTION_SHORT_MEMBERID,
+        OPTION_LONG_MEMBERID, false, false, true, OPTION_VALUE_MEMBERID, "",
+        null, MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION);
+    addToGroupSubCmd.addArgument(addToGoupMemberIdArg);
+
+    // remove-from-group
+    removeFromGroupSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.REMOVE_FROM_GROUP.toString(), true, 1, 1,
+        OPERAND_GROUPID, MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
+    removeFromGoupMemberIdArg = new StringArgument("memberID",
+        OPTION_SHORT_MEMBERID, OPTION_LONG_MEMBERID, false, false, true,
+        OPTION_VALUE_MEMBERID, "", null,
+        MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION);
+    removeFromGroupSubCmd.addArgument(removeFromGoupMemberIdArg);
+
+    // list-members
+    listMembersSubCmd = new SubCommand(argParser,SubCommandNameEnum.LIST_MEMBERS
+        .toString(), true, 1, 1, OPERAND_GROUPID,
+        MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION);
+
+    // list-membership
+    listMembershipSubCmd = new SubCommand(argParser,
+        SubCommandNameEnum.LIST_MEMBERSHIP.toString(), true, 1, 1,
+        OPERAND_MEMBERID, MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isSubCommand(SubCommand subCmd)
+  {
+      return SubCommandNameEnum.isSubCommand(subCmd.getName());
+  }
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public int performSubCommand(ADSContext adsContext, SubCommand subCmd,
+      OutputStream outStream, OutputStream errStream)
+      throws ADSContextException
+  {
+    // -----------------------
+    // create-group subcommand
+    // -----------------------
+    if (subCmd.getName().equals(createGoupSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+      HashMap<ServerGroupProperty, Object> serverGroupProperties =
+        new HashMap<ServerGroupProperty, Object>();
+
+      // get the GROUP_ID
+      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
+
+      // get the Description
+      if (createGoupDescriptionArg.isPresent())
+      {
+        serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
+            createGoupDescriptionArg.getValue());
+      }
+
+      // Create the group
+      adsContext.createServerGroup(serverGroupProperties);
+      return 0;
+    }
+    // -----------------------
+    // delete-group subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(deleteGroupSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+      HashMap<ServerGroupProperty, Object> serverGroupProperties =
+        new HashMap<ServerGroupProperty, Object>();
+
+      // get the GROUP_ID
+      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
+
+      // Delete the group
+      adsContext.deleteServerGroup(serverGroupProperties);
+      return 0;
+    }
+    // -----------------------
+    // list-group subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(listGroupSubCmd.getName()))
+    {
+      Set<Map<ServerGroupProperty, Object>> result = adsContext
+          .readServerGroupRegistry();
+      StringBuffer buffer = new StringBuffer();
+      for (Map<ServerGroupProperty, Object> groupProps : result)
+      {
+        // Get the group name
+        buffer.append(ServerGroupProperty.UID.toString() + " ");
+        buffer.append(groupProps.get(ServerGroupProperty.UID));
+        buffer.append(EOL);
+        if (! verboseArg.isPresent())
+        {
+          continue;
+        }
+
+        // Write other props
+        for (ServerGroupProperty propName : groupProps.keySet())
+        {
+          if ( propName.compareTo(ServerGroupProperty.UID) == 0)
+          {
+            continue;
+          }
+          buffer.append("  " + propName.toString() + " ");
+          if (propName.compareTo(ServerGroupProperty.MEMBERS) == 0)
+          {
+            Set atts = (Set)groupProps.get(propName);
+            Set<String> membersToPrint = new HashSet<String>(atts.size());
+            for (Object att : atts)
+            {
+              membersToPrint.add(att.toString().substring(3));
+            }
+            buffer.append(membersToPrint);
+          }
+          else
+          {
+            buffer.append(groupProps.get(propName));
+          }
+          buffer.append(EOL);
+        }
+      }
+      try
+      {
+        outStream.write(buffer.toString().getBytes());
+      }
+      catch (IOException e)
+      {
+      }
+      return 0;
+    }
+    // -----------------------
+    // modify-group subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(modifyGroupSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+      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, groupId);
+      }
+      else
+      {
+        serverGroupProperties.put(ServerGroupProperty.UID, groupId) ;
+      }
+
+
+      // 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;
+        }
+      }
+
+
+      // Update the server group
+      if (updateRequired)
+      {
+        adsContext.updateServerGroup(groupId, serverGroupProperties);
+      }
+      if (removeRequired)
+      {
+        adsContext.removeServerGroupProp(groupId,
+            serverGroupPropertiesToRemove);
+      }
+
+      return 0;
+    }
+    // -----------------------
+    // add-to-group subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(addToGroupSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+      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>();
+      }
+      memberList.add("cn=" + addToGoupMemberIdArg.getValue());
+      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
+
+      // Update the server group
+      adsContext.updateServerGroup(groupId, serverGroupProperties);
+
+      return 0;
+    }
+    // -----------------------
+    // remove-from-group subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(removeFromGroupSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+      HashMap<ServerGroupProperty, Object> serverGroupProperties =
+        new HashMap<ServerGroupProperty, Object>();
+
+      // get the current member list
+      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
+      if (memberList == null)
+      {
+        // TODO Error message
+        return 1;
+      }
+      String memberToRemove = "cn=" + removeFromGoupMemberIdArg.getValue();
+      if (! memberList.contains(memberToRemove))
+      {
+        // TODO Error message
+        return 1;
+      }
+
+      memberList.remove(memberToRemove);
+      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
+
+      // Update the server group
+      adsContext.updateServerGroup(groupId, serverGroupProperties);
+
+      return 0;
+    }
+    // -----------------------
+    // list-members subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(listMembersSubCmd.getName()))
+    {
+      String groupId = subCmd.getTrailingArguments().get(0);
+
+      // get the current member list
+      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
+      if (memberList == null)
+      {
+        return 0;
+      }
+      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 0;
+    }
+    // -----------------------
+    // list-membership subcommand
+    // -----------------------
+    else if (subCmd.getName().equals(listMembershipSubCmd.getName()))
+    {
+
+      Set<Map<ServerGroupProperty, Object>> result = adsContext
+          .readServerGroupRegistry();
+      String MemberId = subCmd.getTrailingArguments().get(0);
+
+      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 0;
+    }
+
+    // Should never occurs: If we are here, it means that the code to
+    // handle to subcommand is not yet written.
+    return 1;
+  }
+}
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java
new file mode 100644
index 0000000..0fbfcb0
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCliSubCommandGroup.java
@@ -0,0 +1,85 @@
+/*
+ * 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.admin.ads;
+
+import java.io.OutputStream;
+
+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.
+ */
+public interface DsServiceCliSubCommandGroup
+{
+
+  /**
+   * Initialize subcommand related to server group management.
+   *
+   * @param argParser
+   *          The parser in which we should be registered.
+   * @param verboseArg
+   *          The verbose Argument.
+   * @throws ArgumentException
+   *           If there is a problem with any of the parameters used
+   *           to create this argument.
+   */
+  public abstract void initializeCliGroup(SubCommandArgumentParser argParser,
+      BooleanArgument verboseArg) throws ArgumentException;
+
+  /**
+   * Indicates if the provided suncommand is part of this group.
+   *
+   * @param subCmd
+   *          The actual subcommand with input parameter.
+   * @return True if the provided suncommand is part of this group.
+   */
+  public abstract boolean isSubCommand(SubCommand subCmd);
+
+  /**
+   * 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.
+   */
+  public abstract int performSubCommand(ADSContext adsContext,
+      SubCommand subCmd, OutputStream outStream, OutputStream errStream)
+      throws ADSContextException;
+
+}
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
index d02d70f..7f26c56 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -306,6 +306,29 @@
   public static final int MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION =
     CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 31;
 
+  /**
+   * The message ID for the message that will be used if the
+   * client CLI cannot contact the ADS. This does one take argument.
+   */
+  public static final int MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_SEVERE_ERROR | 32;
+
+  /**
+   * The message ID for the message that will be used as the description for the
+   * create-ads subcommand part of dsservice tool.
+   * This does not take any arguments.
+   */
+  public static final int MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 33;
+
+  /**
+   * The message ID for the message that will be used as the description for the
+   * delete-ads subcommand part of dsservice tool.
+   * This does not take any arguments.
+   */
+  public static final int MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION =
+    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 34;
+
   // Prevent instantiation.
   private AdminMessages() {
     // Do nothing.
@@ -427,6 +450,12 @@
         "List members of the specified group" );
     registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION,
         "List groups in which the specified server is a member" );
-
+    registerMessage(MSGID_DSSERVICE_CANNOT_CONNECT_TO_ADS,
+        "Could not connect to %s. Check that the "+
+        "server is running and that the provided credentials are valid");
+    registerMessage(MSGID_DSSERVICE_SUBCMD_CREATE_ADS_DESCRIPTION,
+        "Create a new ADS DN");
+    registerMessage(MSGID_DSSERVICE_SUBCMD_DELETE_ADS_DESCRIPTION,
+         "Delete an existing ADS DN");
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
index b42d382..cf4cd46 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -570,5 +570,11 @@
    * displayed in usage information.
    */
   public static final String OPERAND_MEMBERID = "MEMBER_ID";
+
+  /**
+   * The placeholder value of backend name that will be
+   * displayed in usage information.
+   */
+  public static final String OPERAND_BACKEND = "BACKEND_NAME";
 }
 

--
Gitblit v1.10.0