From 1785dd375fbacdda09a9a18ef36ad4e3e56de3b9 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Tue, 16 Jun 2009 10:48:51 +0000
Subject: [PATCH] Fix for issue 3912 (Default automatic Backup should be offered by the control panel)

---
 opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java                                                  |    2 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ScheduleType.java                          |  206 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/NoLeftInsetCategoryComboBoxRenderer.java |   71 
 opendj-sdk/opends/src/server/org/opends/server/backends/task/RecurringTask.java                                      |    2 
 opendj-sdk/opends/src/messages/messages/admin_tool.properties                                                        |  130 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ManageTasksPanel.java                             |  939 ++++++++++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java                |   19 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java                                  |   30 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java                      |    1 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/TaskTableModel.java                        |  421 +++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/TaskCellRenderer.java                    |   95 +
 opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskEntry.java                                            |   65 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java                              |   31 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/TimeDocumentFilter.java                |  198 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TaskToSchedulePanel.java                          | 1178 ++++++++++++++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java                              |    7 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java                       |  122 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java                               |   15 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java                      |   26 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java             |   58 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java                           |   61 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/NumericLimitedSizeDocumentFilter.java  |  116 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/ScheduleSummaryPanel.java              |  182 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/task/CancelTaskTask.java                             |  261 +++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java                                  |    6 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java                    |  100 +
 26 files changed, 4,281 insertions(+), 61 deletions(-)

diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
index 8e037ee..648406b 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
@@ -679,6 +679,7 @@
         desc.setAuthenticated(reader instanceof ConfigFromDirContext);
         desc.setJavaVersion(reader.getJavaVersion());
         desc.setOpenConnections(reader.getOpenConnections());
+        desc.setTaskEntries(reader.getTaskEntries());
         if (reader instanceof ConfigFromDirContext)
         {
           ConfigFromDirContext rCtx = (ConfigFromDirContext)reader;
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
index 31e756d..ad540cf 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
@@ -27,9 +27,13 @@
 
 package org.opends.guitools.controlpanel.datamodel;
 
+import static org.opends.server.util.StaticUtils.toLowerCase;
+
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
@@ -44,6 +48,17 @@
 import javax.naming.directory.SearchResult;
 
 import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.AttributeBuilder;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.AttributeValues;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.OpenDsException;
+import org.opends.server.util.LDIFReader;
 
 /**
  * This is a commodity class used to wrap the SearchResult class of JNDI.
@@ -261,4 +276,89 @@
   {
     return 23 + toString.hashCode();
   }
+
+  /**
+   * Gets the Entry object equivalent to this CustomSearchResult.
+   * The method assumes that the schema in DirectoryServer has been initialized.
+   * @return the Entry object equivalent to this CustomSearchResult.
+   * @throws OpenDsException if there is an error parsing the DN or retrieving
+   * the attributes definition and objectclasses in the schema of the server.
+   */
+  public Entry getEntry() throws OpenDsException
+  {
+    DN dn = DN.decode(this.getDN());
+    Map<ObjectClass,String> objectClasses = new HashMap<ObjectClass,String>();
+    Map<AttributeType,List<org.opends.server.types.Attribute>> userAttributes =
+      new HashMap<AttributeType,List<org.opends.server.types.Attribute>>();
+    Map<AttributeType,List<org.opends.server.types.Attribute>>
+    operationalAttributes =
+      new HashMap<AttributeType,List<org.opends.server.types.Attribute>>();
+
+    for (String wholeName : this.getAttributeNames())
+    {
+      final org.opends.server.types.Attribute attribute =
+        LDIFReader.parseAttrDescription(wholeName);
+      final String attrName = attribute.getName();
+      final String lowerName = toLowerCase(attrName);
+
+      // See if this is an objectclass or an attribute.  Then get the
+      // corresponding definition and add the value to the appropriate hash.
+      if (lowerName.equals("objectclass"))
+      {
+        for (Object value : this.getAttributeValues(attrName))
+        {
+          String ocName = value.toString().trim();
+          String lowerOCName = toLowerCase(ocName);
+
+          ObjectClass objectClass =
+            DirectoryServer.getObjectClass(lowerOCName);
+          if (objectClass == null)
+          {
+            objectClass = DirectoryServer.getDefaultObjectClass(ocName);
+          }
+
+          objectClasses.put(objectClass, ocName);
+        }
+      }
+      else
+      {
+        AttributeType attrType = DirectoryServer.getAttributeType(lowerName);
+        if (attrType == null)
+        {
+          attrType = DirectoryServer.getDefaultAttributeType(attrName);
+        }
+
+        AttributeBuilder builder = new AttributeBuilder(attribute, true);
+        for (Object value : this.getAttributeValues(attrName))
+        {
+          ByteString bs;
+          if (value instanceof byte[])
+          {
+            bs = ByteString.wrap((byte[])value);
+          }
+          else
+          {
+            bs = ByteString.valueOf(value.toString());
+          }
+          AttributeValue attributeValue =
+            AttributeValues.create(attrType, bs);
+          builder.add(attributeValue);
+        }
+        List<org.opends.server.types.Attribute> attrList =
+          new ArrayList<org.opends.server.types.Attribute>(1);
+        attrList.add(builder.toAttribute());
+
+        if (attrType.isOperational())
+        {
+          operationalAttributes.put(attrType, attrList);
+        }
+        else
+        {
+          userAttributes.put(attrType, attrList);
+        }
+      }
+    }
+
+    return new Entry(dn, objectClasses, userAttributes, operationalAttributes);
+  }
 }
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ScheduleType.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ScheduleType.java
new file mode 100644
index 0000000..060777b
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ScheduleType.java
@@ -0,0 +1,206 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.datamodel;
+
+import java.util.Date;
+
+/**
+ * The class to be used to describe the task schedule.
+ *
+ */
+public class ScheduleType
+{
+  /**
+   * The different type of schedules.
+   *
+   */
+  public enum Type
+  {
+    /**
+     * Launch now.
+     */
+    LAUNCH_NOW,
+    /**
+     * Launch later in a specific date.
+     */
+    LAUNCH_LATER,
+    /**
+     * Launch periodically.
+     */
+    LAUNCH_PERIODICALLY
+  }
+
+  private Type type;
+  private Date launchLaterDate;
+  private String cronValue;
+  private String toString;
+  private int hashCode;
+
+  private ScheduleType()
+  {
+  }
+
+  /**
+   * Returns a schedule instance that launches the task now.
+   * @return a schedule instance that launches the task now.
+   */
+  public static ScheduleType createLaunchNow()
+  {
+    ScheduleType schedule = new ScheduleType();
+    schedule.type = Type.LAUNCH_NOW;
+    schedule.toString = schedule.calculateToString();
+    schedule.hashCode = schedule.calculateHashCode();
+    return schedule;
+  }
+
+  /**
+   * Returns a schedule instance that launches the task at a given date.
+   * @param date the Date at which the task must be launched.
+   * @return a schedule instance that launches the task at a given date.
+   */
+  public static ScheduleType createLaunchLater(Date date)
+  {
+    ScheduleType schedule = new ScheduleType();
+    schedule.type = Type.LAUNCH_LATER;
+    schedule.launchLaterDate = date;
+    schedule.toString = schedule.calculateToString();
+    schedule.hashCode = schedule.calculateHashCode();
+    return schedule;
+  }
+
+  /**
+   * Returns a schedule instance that launches the task using a cron schedule.
+   * @param cron the String containing the cron schedule.
+   * @return a schedule instance that launches the task using a cron schedule.
+   */
+  public static ScheduleType createCron(String cron)
+  {
+    ScheduleType schedule = new ScheduleType();
+    schedule.type = Type.LAUNCH_PERIODICALLY;
+    schedule.cronValue = cron;
+    schedule.toString = schedule.calculateToString();
+    schedule.hashCode = schedule.calculateHashCode();
+    return schedule;
+  }
+
+  /**
+   * Returns the type of the schedule.
+   * @return the type of the schedule.
+   */
+  public Type getType()
+  {
+    return type;
+  }
+
+  /**
+   * Returns the date on which the task will be launched.
+   * @return the date on which the task will be launched.
+   */
+  public Date getLaunchLaterDate()
+  {
+    return launchLaterDate;
+  }
+
+  /**
+   * Returns the CRON String representation of the schedule.
+   * @return the CRON String representation of the schedule.
+   */
+  public String getCronValue()
+  {
+    return cronValue;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean equals(Object o)
+  {
+    boolean equals;
+    if (o != null)
+    {
+      if (o == this)
+      {
+        equals = true;
+      }
+      else
+      {
+        equals = toString().equals(o.toString());
+      }
+    }
+    else
+    {
+      equals = false;
+    }
+    return equals;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String toString()
+  {
+    return toString;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public int hashCode()
+  {
+    return hashCode;
+  }
+
+  /**
+   * Calculates the hashCode.
+   * To be called after the calculateToString is called.
+   * @return the value of the hashCode.
+   */
+  private int calculateHashCode()
+  {
+    return 32 + toString.hashCode();
+  }
+
+  private String calculateToString()
+  {
+    String toString;
+    switch (type)
+    {
+    case LAUNCH_NOW:
+      toString = "Schedule Type: Launch Now";
+      break;
+    case LAUNCH_LATER:
+      toString = "Schedule Type: Launch Later at date "+launchLaterDate;
+      break;
+    case LAUNCH_PERIODICALLY:
+      toString = "Schedule Type: periodical schedule "+cronValue;
+      break;
+      default:
+        throw new IllegalStateException("Invalid type: "+type);
+    }
+    return toString;
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
index 7f2dfbd..072aef1 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
@@ -40,6 +40,7 @@
 import org.opends.guitools.controlpanel.util.ConfigFromDirContext;
 import org.opends.guitools.controlpanel.util.Utilities;
 
+import org.opends.server.tools.tasks.TaskEntry;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.DN;
 import org.opends.server.types.ObjectClass;
@@ -79,6 +80,8 @@
 
   private CustomSearchResult workQueue;
 
+  private Set<TaskEntry> taskEntries = new HashSet<TaskEntry>();
+
   private long runningTime = -1;
 
   private boolean isAuthenticated;
@@ -289,6 +292,24 @@
   }
 
   /**
+   * Returns the task entries.
+   * @return the task entries.
+   */
+  public Set<TaskEntry> getTaskEntries()
+  {
+    return taskEntries;
+  }
+
+  /**
+   * Sets the the task entries.
+   * @param taskEntries the task entries.
+   */
+  public void setTaskEntries(Set<TaskEntry> taskEntries)
+  {
+    this.taskEntries = Collections.unmodifiableSet(taskEntries);
+  }
+
+  /**
    * {@inheritDoc}
    */
   public boolean equals(Object o)
@@ -411,6 +432,11 @@
           equals =
             desc.isWindowsServiceEnabled() == isWindowsServiceEnabled();
         }
+
+        if (equals)
+        {
+          desc.getTaskEntries().equals(getTaskEntries());
+        }
       }
     }
     else
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/TaskTableModel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/TaskTableModel.java
new file mode 100644
index 0000000..bc1b7e1
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/datamodel/TaskTableModel.java
@@ -0,0 +1,421 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.datamodel;
+
+import static org.opends.messages.AdminToolMessages.*;
+import static org.opends.messages.ToolMessages.*;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.opends.guitools.controlpanel.ui.ColorAndFontConstants;
+import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.messages.Message;
+import org.opends.quicksetup.util.Utils;
+import org.opends.server.backends.task.TaskState;
+import org.opends.server.tools.tasks.TaskEntry;
+
+/**
+ * The table used to display the tasks.
+ *
+ */
+public class TaskTableModel  extends SortableTableModel
+implements Comparator<TaskEntry>
+{
+  private static final long serialVersionUID = -351142550147124L;
+  private Set<TaskEntry> data = new HashSet<TaskEntry>();
+  private ArrayList<TaskEntry> dataSourceArray = new ArrayList<TaskEntry>();
+
+  LinkedHashSet<Message> displayedAttributes = new LinkedHashSet<Message>();
+  final LinkedHashSet<Message> defaultAttributes = new LinkedHashSet<Message>();
+  {
+    defaultAttributes.add(INFO_TASKINFO_FIELD_ID.get());
+    defaultAttributes.add(INFO_TASKINFO_FIELD_TYPE.get());
+    defaultAttributes.add(INFO_TASKINFO_FIELD_STATUS.get());
+    defaultAttributes.add(INFO_CTRL_PANEL_TASK_CANCELABLE.get());
+  }
+  LinkedHashSet<Message> allAttributes = new LinkedHashSet<Message>();
+  {
+    allAttributes.addAll(defaultAttributes);
+    allAttributes.add(INFO_TASKINFO_FIELD_SCHEDULED_START.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_ACTUAL_START.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_COMPLETION_TIME.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_DEPENDENCY.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_FAILED_DEPENDENCY_ACTION.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_NOTIFY_ON_COMPLETION.get());
+    allAttributes.add(INFO_TASKINFO_FIELD_NOTIFY_ON_ERROR.get());
+  }
+
+  private String[] columnNames = {};
+
+  /**
+   * The sort column of the table.
+   */
+  private int sortColumn = 0;
+  /**
+   * Whether the sorting is ascending or descending.
+   */
+  private boolean sortAscending = true;
+
+  /**
+   * Default constructor.
+   */
+  public TaskTableModel()
+  {
+    super();
+    setAttributes(defaultAttributes);
+  }
+
+  /**
+   * Sets the data for this table model.
+   * @param newData the data for this table model.
+   */
+  public void setData(Set<TaskEntry> newData)
+  {
+    if (!newData.equals(data))
+    {
+      data.clear();
+      data.addAll(newData);
+      updateDataArray();
+      fireTableDataChanged();
+    }
+  }
+
+  /**
+   * Updates the table model contents and sorts its contents depending on the
+   * sort options set by the user.
+   */
+  public void forceResort()
+  {
+    updateDataArray();
+    fireTableDataChanged();
+  }
+
+  /**
+   * Updates the table model contents, sorts its contents depending on the
+   * sort options set by the user and updates the column structure.
+   */
+  public void forceDataStructureChange()
+  {
+    updateDataArray();
+    fireTableStructureChanged();
+    fireTableDataChanged();
+  }
+
+  /**
+   * Updates the array data.  This includes resorting it.
+   */
+  private void updateDataArray()
+  {
+    TreeSet<TaskEntry> sortedSet = new TreeSet<TaskEntry>(this);
+    sortedSet.addAll(data);
+    dataSourceArray.clear();
+    for (TaskEntry task : sortedSet)
+    {
+      dataSourceArray.add(task);
+    }
+  }
+
+  /**
+   * Sets the operations displayed by this table model.
+   * @param attributes the attributes displayed by this table model.
+   */
+  public void setAttributes(LinkedHashSet<Message> attributes)
+  {
+    if (!allAttributes.containsAll(attributes))
+    {
+      throw new IllegalArgumentException(
+          "Some of the provided attributes are not valid.");
+    }
+    this.displayedAttributes.clear();
+    this.displayedAttributes.addAll(attributes);
+    int columnCount = attributes.size();
+    columnNames = new String[columnCount];
+    int i = 0;
+    for (Message attribute : attributes)
+    {
+      columnNames[i] = getHeader(attribute, 15);
+      i++;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Class<?> getColumnClass(int column)
+  {
+    return Message.class;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String getColumnName(int col) {
+    return columnNames[col];
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Object getValueAt(int row, int column)
+  {
+    Message value;
+    column = getFixedOrderColumn(column);
+    TaskEntry taskEntry = get(row);
+    switch (column)
+    {
+    case 0:
+      value = Message.raw(taskEntry.getId());
+      break;
+    case 1:
+      value = taskEntry.getType();
+      break;
+    case 2:
+      value = taskEntry.getState();
+      break;
+    case 3:
+      if (taskEntry.isCancelable())
+      {
+        value = INFO_CTRL_PANEL_TASK_IS_CANCELABLE.get();
+      }
+      else
+      {
+        value = INFO_CTRL_PANEL_TASK_IS_NOT_CANCELABLE.get();
+      }
+      break;
+    case 4:
+      if (TaskState.isRecurring(get(row).getTaskState()))
+      {
+        value = taskEntry.getScheduleTab();
+      } else {
+        value = taskEntry.getScheduledStartTime();
+        if (value == null || value.equals(Message.EMPTY))
+        {
+          value = INFO_TASKINFO_IMMEDIATE_EXECUTION.get();
+        }
+      }
+      break;
+    case 5:
+      value = taskEntry.getActualStartTime();
+      break;
+    case 6:
+      value = taskEntry.getCompletionTime();
+      break;
+    case 7:
+      value = getValue(taskEntry.getDependencyIds(),
+          INFO_TASKINFO_NONE_SPECIFIED.get());
+      break;
+    case 8:
+      value = taskEntry.getFailedDependencyAction();
+      if (value == null)
+      {
+        value = INFO_TASKINFO_NONE.get();
+      }
+      break;
+    case 9:
+      value = getValue(taskEntry.getCompletionNotificationEmailAddresses(),
+          INFO_TASKINFO_NONE_SPECIFIED.get());
+      break;
+    case 10:
+      value = getValue(taskEntry.getErrorNotificationEmailAddresses(),
+          INFO_TASKINFO_NONE_SPECIFIED.get());
+      break;
+    default:
+      throw new IllegalArgumentException("Invalid column: "+column);
+    }
+    return value;
+  }
+
+  /**
+   * Returns the row count.
+   * @return the row count.
+   */
+  public int getRowCount()
+  {
+    return dataSourceArray.size();
+  }
+
+  /**
+   * Returns the column count.
+   * @return the column count.
+   */
+  public int getColumnCount()
+  {
+    return columnNames.length;
+  }
+
+  /**
+   * Gets the TaskDescriptor in a given row.
+   * @param row the row.
+   * @return the TaskDescriptor in a given row.
+   */
+  public TaskEntry get(int row)
+  {
+    return dataSourceArray.get(row);
+  }
+
+  /**
+   * Returns the set of attributes ordered.
+   * @return the set of attributes ordered.
+   */
+  public LinkedHashSet<Message> getDisplayedAttributes()
+  {
+    return displayedAttributes;
+  }
+
+  /**
+   * Returns the set of attributes ordered.
+   * @return the set of attributes ordered.
+   */
+  public LinkedHashSet<Message> getAllAttributes()
+  {
+    return allAttributes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public int compare(TaskEntry desc1, TaskEntry desc2)
+  {
+    int result;
+    ArrayList<Integer> possibleResults = new ArrayList<Integer>();
+
+    possibleResults.add(desc1.getId().compareTo(desc2.getId()));
+    possibleResults.add(desc1.getType().compareTo(desc2.getType()));
+    possibleResults.add(desc1.getState().compareTo(desc2.getState()));
+    possibleResults.add(String.valueOf(desc1.isCancelable()).compareTo(
+        String.valueOf(desc2.isCancelable())));
+
+    result = possibleResults.get(getSortColumn());
+    if (result == 0)
+    {
+      for (int i : possibleResults)
+      {
+        if (i != 0)
+        {
+          result = i;
+          break;
+        }
+      }
+    }
+    if (!isSortAscending())
+    {
+      result = -result;
+    }
+    return result;
+  }
+
+  /**
+   * Returns whether the sort is ascending or descending.
+   * @return <CODE>true</CODE> if the sort is ascending and <CODE>false</CODE>
+   * otherwise.
+   */
+  public boolean isSortAscending()
+  {
+    return sortAscending;
+  }
+
+  /**
+   * Sets whether to sort ascending of descending.
+   * @param sortAscending whether to sort ascending or descending.
+   */
+  public void setSortAscending(boolean sortAscending)
+  {
+    this.sortAscending = sortAscending;
+  }
+
+  /**
+   * Returns the column index used to sort.
+   * @return the column index used to sort.
+   */
+  public int getSortColumn()
+  {
+    return sortColumn;
+  }
+
+  /**
+   * Sets the column index used to sort.
+   * @param sortColumn column index used to sort..
+   */
+  public void setSortColumn(int sortColumn)
+  {
+    this.sortColumn = sortColumn;
+  }
+
+  private int getFixedOrderColumn(int column)
+  {
+    int fixedOrderColumn = 0;
+    int i=0;
+    Message colMsg = null;
+    for (Message msg : displayedAttributes)
+    {
+      if (i == column)
+      {
+        colMsg = msg;
+        break;
+      }
+      i++;
+    }
+    for (Message msg : allAttributes)
+    {
+      if (msg.equals(colMsg))
+      {
+        break;
+      }
+      fixedOrderColumn++;
+    }
+    return fixedOrderColumn;
+  }
+
+  private Message getValue(List<String> values, Message valueIfEmpty)
+  {
+    Message msg;
+    if (values.isEmpty())
+    {
+      msg = valueIfEmpty;
+    }
+    else
+    {
+      String s = Utils.getStringFromCollection(values, "<br>");
+      if (values.size() > 1)
+      {
+        msg = Message.raw(
+            "<html>"+Utilities.applyFont(s, ColorAndFontConstants.tableFont));
+      }
+      else
+      {
+        msg = Message.raw(s);
+      }
+    }
+    return msg;
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/task/CancelTaskTask.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/task/CancelTaskTask.java
new file mode 100644
index 0000000..f236683
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/task/CancelTaskTask.java
@@ -0,0 +1,261 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.controlpanel.task;
+
+import static org.opends.messages.AdminToolMessages.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.SwingUtilities;
+
+import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
+import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
+import org.opends.guitools.controlpanel.ui.ColorAndFontConstants;
+import org.opends.guitools.controlpanel.ui.ProgressDialog;
+import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.messages.Message;
+import org.opends.server.tools.ManageTasks;
+import org.opends.server.tools.tasks.TaskEntry;
+import org.opends.server.util.cli.CommandBuilder;
+
+/**
+ * Task used to cancel tasks in server.
+ *
+ */
+public class CancelTaskTask extends Task
+{
+  private Set<String> backendSet;
+  private List<TaskEntry> tasks;
+
+  /**
+   * Constructor of the task.
+   * @param info the control panel information.
+   * @param dlg the progress dialog where the task progress will be displayed.
+   * @param tasks the tasks to be canceled.
+   */
+  public CancelTaskTask(ControlPanelInfo info, ProgressDialog dlg,
+      List<TaskEntry> tasks)
+  {
+    super(info, dlg);
+    backendSet = new HashSet<String>();
+    for (BackendDescriptor backend : info.getServerDescriptor().getBackends())
+    {
+      backendSet.add(backend.getBackendID());
+    }
+    this.tasks = new ArrayList<TaskEntry>(tasks);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Type getType()
+  {
+    // TODO: change this
+    return Type.MODIFY_ENTRY;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Set<String> getBackends()
+  {
+    return backendSet;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Message getTaskDescription()
+  {
+    return INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION.get();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean regenerateDescriptor()
+  {
+    return true;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getCommandLinePath()
+  {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected ArrayList<String> getCommandLineArguments()
+  {
+    return new ArrayList<String>();
+  }
+
+  /**
+   * Returns the command-line arguments to be used to cancel the task.
+   * @param task the task to be canceled.
+   * @return the command-line arguments to be used to cancel the task.
+   */
+  private ArrayList<String> getCommandLineArguments(TaskEntry task)
+  {
+    ArrayList<String> args = new ArrayList<String>();
+    args.add("--cancel");
+    args.add(task.getId());
+    args.addAll(getConnectionCommandLineArguments());
+    args.add(getNoPropertiesFileArgument());
+    return args;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean canLaunch(Task taskToBeLaunched,
+      Collection<Message> incompatibilityReasons)
+  {
+    boolean canLaunch = true;
+    if (!isServerRunning())
+    {
+      if (state == State.RUNNING)
+      {
+        // All the operations are incompatible if they apply to this
+        // backend for safety.  This is a short operation so the limitation
+        // has not a lot of impact.
+        Set<String> backends =
+          new TreeSet<String>(taskToBeLaunched.getBackends());
+        backends.retainAll(getBackends());
+        if (backends.size() > 0)
+        {
+          incompatibilityReasons.add(getIncompatibilityMessage(this,
+              taskToBeLaunched));
+          canLaunch = false;
+        }
+      }
+    }
+    return canLaunch;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void runTask()
+  {
+    state = State.RUNNING;
+    lastException = null;
+    try
+    {
+      final int totalNumber = tasks.size();
+      int numberCanceled = 0;
+
+      SwingUtilities.invokeLater(new Runnable()
+      {
+        public void run()
+        {
+          getProgressDialog().getProgressBar().setIndeterminate(true);
+        }
+      });
+      for (final TaskEntry task : tasks)
+      {
+        final ArrayList<String> arguments = getCommandLineArguments(task);
+
+        final boolean isFirst = numberCanceled == 0;
+        SwingUtilities.invokeLater(new Runnable()
+        {
+          public void run()
+          {
+            if (isFirst)
+            {
+              getProgressDialog().appendProgressHtml("<br><br>");
+            }
+            ArrayList<String> args = new ArrayList<String>();
+            args.add(getCommandLinePath("manage-tasks"));
+            args.addAll(getObfuscatedCommandLineArguments(arguments));
+            StringBuilder sb = new StringBuilder();
+            for (String arg : args)
+            {
+              sb.append(" "+CommandBuilder.escapeValue(arg));
+            }
+            getProgressDialog().appendProgressHtml(Utilities.applyFont(
+                INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK.get(task.getId())+
+                "<br><b>"+sb.toString()+"</b><br><br>",
+                ColorAndFontConstants.progressFont));
+          }
+        });
+
+        String[] args = new String[arguments.size()];
+
+        arguments.toArray(args);
+
+        returnCode = ManageTasks.mainTaskInfo(args, System.in,
+            outPrintStream, errorPrintStream);
+
+        if (returnCode != 0)
+        {
+          break;
+        }
+        else
+        {
+          numberCanceled ++;
+          final int fNumberCanceled = numberCanceled;
+          SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              if (fNumberCanceled == 1)
+              {
+                getProgressDialog().getProgressBar().setIndeterminate(false);
+              }
+              getProgressDialog().getProgressBar().setValue(
+                  (fNumberCanceled * 100) / totalNumber);
+            }
+          });
+        }
+      }
+      if (returnCode != 0)
+      {
+        state = State.FINISHED_WITH_ERROR;
+      }
+      else
+      {
+        state = State.FINISHED_SUCCESSFULLY;
+      }
+    }
+    catch (Throwable t)
+    {
+      lastException = t;
+      state = State.FINISHED_WITH_ERROR;
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java
index d0be1e1..7523175 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java
@@ -60,9 +60,11 @@
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.BackupDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
+import org.opends.guitools.controlpanel.datamodel.ScheduleType;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
 import org.opends.guitools.controlpanel.task.Task;
+import org.opends.guitools.controlpanel.ui.components.ScheduleSummaryPanel;
 import org.opends.guitools.controlpanel.util.BackgroundTask;
 import org.opends.guitools.controlpanel.util.Utilities;
 import org.opends.messages.Message;
@@ -100,6 +102,8 @@
 
   private boolean backupIDInitialized = false;
 
+  private ScheduleSummaryPanel schedulePanel;
+
   private static final Logger LOG =
     Logger.getLogger(BackupPanel.class.getName());
 
@@ -251,20 +255,27 @@
         INFO_CTRL_PANEL_BACKUP_OPTIONS_LABEL.get());
     add(lBackupOptions, gbc);
 
-    compressData = Utilities.createCheckBox(
-        INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get());
-    compressData.setSelected(false);
+    schedulePanel = new ScheduleSummaryPanel(
+        INFO_CTRL_PANEL_BACKUP_TASK_NAME.get().toString());
+    schedulePanel.setSchedule(ScheduleType.createLaunchNow());
 
     gbc.insets.left = 10;
     gbc.gridx = 1;
     gbc.gridwidth = 2;
+    add(schedulePanel, gbc);
+
+    compressData = Utilities.createCheckBox(
+        INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get());
+    compressData.setSelected(false);
+
+    gbc.gridy ++;
+    gbc.insets.top = 5;
     add(compressData, gbc);
 
     encryptData = Utilities.createCheckBox(
         INFO_CTRL_PANEL_ENCRYPT_DATA_LABEL.get());
 
     gbc.gridy ++;
-    gbc.insets.top = 5;
     add(encryptData, gbc);
     encryptData.setSelected(false);
     generateMessageDigest = Utilities.createCheckBox(
@@ -351,6 +362,7 @@
     setPrimaryValid(lPath);
     setPrimaryValid(lAvailableBackups);
     setPrimaryValid(lParentID);
+    setPrimaryValid(lBackupOptions);
     backupIDInitialized = false;
 
     final LinkedHashSet<Message> errors = new LinkedHashSet<Message>();
@@ -434,6 +446,8 @@
       }
     }
 
+    addScheduleErrors(getSchedule(), errors, lBackupOptions);
+
     // Check that there is not a backup with the provided ID
     final JComponent[] components =
     {
@@ -578,6 +592,11 @@
     }
   }
 
+  private ScheduleType getSchedule()
+  {
+    return schedulePanel.getSchedule();
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -586,6 +605,7 @@
     setPrimaryValid(lBackend);
     setPrimaryValid(lPath);
     setPrimaryValid(lAvailableBackups);
+    setPrimaryValid(lBackupOptions);
 
     super.cancelClicked();
   }
@@ -824,6 +844,8 @@
 
       args.addAll(getConnectionCommandLineArguments());
 
+      args.addAll(getScheduleArgs(getSchedule()));
+
       if (isServerRunning())
       {
         args.addAll(getConfigCommandLineArguments());
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java
index e8c7709..a6c4fab 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java
@@ -52,7 +52,6 @@
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
-import javax.swing.JList;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
@@ -76,7 +75,8 @@
 import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor.
  State;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
-import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer;
+import org.opends.guitools.controlpanel.ui.renderer.
+ NoLeftInsetCategoryComboBoxRenderer;
 import org.opends.guitools.controlpanel.util.Utilities;
 import org.opends.guitools.controlpanel.util.ViewPositions;
 import org.opends.messages.Message;
@@ -193,7 +193,7 @@
       }
     });
     connectionHandlers.setRenderer(
-        new CustomComboBoxCellRenderer(connectionHandlers));
+        new NoLeftInsetCategoryComboBoxRenderer(connectionHandlers));
     gbc.gridx ++;
     viewOptions.add(connectionHandlers, gbc);
     gbc.gridx ++;
@@ -313,7 +313,7 @@
           });
     for (ConnectionHandlerDescriptor ch : chs)
     {
-      if (ch.getProtocol() != ConnectionHandlerDescriptor.Protocol.LDIF)
+      if (protocolHasMonitoring(ch))
       {
         sortedChs.add(ch);
       }
@@ -355,7 +355,7 @@
     {
       MessageBuilder mb = new MessageBuilder();
       mb.append(INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(
-          server.getHostname()));
+      server.getHostname()));
       mb.append("<br><br>"+getAuthenticateHTML());
       errorDetails = mb.toMessage();
       errorTitle = INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_SUMMARY.get();
@@ -555,7 +555,7 @@
         {
           for (ConnectionHandlerDescriptor ch : server.getConnectionHandlers())
           {
-            if (ch.getProtocol() != Protocol.LDIF)
+            if (protocolHasMonitoring(ch))
             {
               cchs.add(ch);
             }
@@ -588,6 +588,14 @@
     return cchs;
   }
 
+  private boolean protocolHasMonitoring(ConnectionHandlerDescriptor ch)
+  {
+    return (ch.getProtocol() == Protocol.LDAP) ||
+    (ch.getProtocol() == Protocol.LDAPS) ||
+    (ch.getProtocol() == Protocol.LDAP_STARTTLS) ||
+    (ch.getProtocol() == Protocol.OTHER);
+  }
+
   /**
    * The specific menu bar of this panel.
    *
@@ -650,43 +658,5 @@
       return menu;
     }
   }
-
-  /**
-   *  This class is used simply to avoid an inset on the left for the
-   *  elements of the combo box.
-   *  Since this item is a CategorizedComboBoxElement of type
-   *  CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on
-   *  the left.
-   */
-  class CustomComboBoxCellRenderer extends CustomListCellRenderer
-  {
-    /**
-     * The constructor.
-     * @param combo the combo box to be rendered.
-     */
-    CustomComboBoxCellRenderer(JComboBox combo)
-    {
-      super(combo);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Component getListCellRendererComponent(JList list, Object value,
-        int index, boolean isSelected, boolean cellHasFocus)
-    {
-      Component comp = super.getListCellRendererComponent(list, value, index,
-          isSelected, cellHasFocus);
-      if (value instanceof CategorizedComboBoxElement)
-      {
-        CategorizedComboBoxElement element = (CategorizedComboBoxElement)value;
-        String name = getStringValue(element);
-        ((JLabel)comp).setText(name);
-      }
-      comp.setFont(defaultFont);
-      return comp;
-    }
-  }
 }
 
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java
index 1115fb2..1686e71 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java
@@ -54,10 +54,12 @@
 import javax.swing.event.DocumentListener;
 
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
+import org.opends.guitools.controlpanel.datamodel.ScheduleType;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
 import org.opends.guitools.controlpanel.event.BrowseActionListener;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
 import org.opends.guitools.controlpanel.task.Task;
+import org.opends.guitools.controlpanel.ui.components.ScheduleSummaryPanel;
 import org.opends.guitools.controlpanel.util.Utilities;
 import org.opends.messages.Message;
 import org.opends.server.tools.ExportLDIF;
@@ -89,6 +91,8 @@
 
   private DocumentListener documentListener;
 
+  private ScheduleSummaryPanel schedulePanel;
+
   /**
    * Default constructor.
    *
@@ -238,13 +242,21 @@
       Utilities.createPrimaryLabel(INFO_CTRL_PANEL_EXPORT_OPTIONS.get());
     add(lExportOptions, gbc);
 
-    compressData = Utilities.createCheckBox(
-        INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get());
-    compressData.setSelected(false);
+    schedulePanel = new ScheduleSummaryPanel(
+        INFO_CTRL_PANEL_EXPORT_LDIF_TITLE.get().toString());
+    schedulePanel.setSchedule(ScheduleType.createLaunchNow());
 
     gbc.insets.left = 10;
     gbc.gridx = 1;
     gbc.gridwidth = 3;
+    add(schedulePanel, gbc);
+
+    compressData = Utilities.createCheckBox(
+        INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get());
+    compressData.setSelected(false);
+
+    gbc.gridy ++;
+    gbc.insets.top = 5;
     add(compressData, gbc);
 
     encryptData = Utilities.createCheckBox(
@@ -384,6 +396,7 @@
       }
     }
 
+    addScheduleErrors(getSchedule(), errors, lExportOptions);
     if (wrapText.isSelected())
     {
       String cols = wrapColumn.getText();
@@ -391,7 +404,12 @@
       int maxValue = 1000;
       Message errMsg = ERR_CTRL_PANEL_INVALID_WRAP_COLUMN.get(minValue,
       maxValue);
+      int size1 = errors.size();
       checkIntValue(errors, cols, minValue, maxValue, errMsg);
+      if (errors.size() > size1)
+      {
+        setPrimaryInvalid(lExportOptions);
+      }
     }
 
     updateIncludeExclude(errors, backendName);
@@ -448,6 +466,11 @@
     super.cancelClicked();
   }
 
+  private ScheduleType getSchedule()
+  {
+    return schedulePanel.getSchedule();
+  }
+
   /**
    * The class that performs the export.
    *
@@ -589,6 +612,8 @@
 
       args.addAll(super.getCommandLineArguments());
 
+      args.addAll(getScheduleArgs(getSchedule()));
+
       if (isServerRunning())
       {
         args.addAll(getConfigCommandLineArguments());
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java
index b9aba61..3f9f2a3 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java
@@ -217,7 +217,8 @@
           {
             INFO_CTRL_PANEL_CATEGORY_MONITORING.get(),
             INFO_CTRL_PANEL_BROWSE_GENERAL_MONITORING.get(),
-            INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get()
+            INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get(),
+            INFO_CTRL_PANEL_MANAGE_TASKS.get()
           },
           {
             INFO_CTRL_PANEL_CATEGORY_RUNTIME_OPTIONS.get(),
@@ -251,7 +252,8 @@
           {
             INFO_CTRL_PANEL_CATEGORY_MONITORING.get(),
             INFO_CTRL_PANEL_BROWSE_GENERAL_MONITORING.get(),
-            INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get()
+            INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get(),
+            INFO_CTRL_PANEL_MANAGE_TASKS.get()
           },
           {
             INFO_CTRL_PANEL_CATEGORY_RUNTIME_OPTIONS.get(),
@@ -273,6 +275,7 @@
     classes.add(RebuildIndexPanel.class);
     classes.add(BrowseGeneralMonitoringPanel.class);
     classes.add(ConnectionHandlerMonitoringPanel.class);
+    classes.add(ManageTasksPanel.class);
     classes.add(JavaPropertiesPanel.class);
     if (Utilities.isWindows())
     {
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ManageTasksPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ManageTasksPanel.java
new file mode 100644
index 0000000..f013296
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/ManageTasksPanel.java
@@ -0,0 +1,939 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.controlpanel.ui;
+
+import static org.opends.messages.AdminToolMessages.*;
+import static org.opends.server.util.StaticUtils.toLowerCase;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
+import org.opends.guitools.controlpanel.datamodel.CustomSearchResult;
+import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
+import org.opends.guitools.controlpanel.datamodel.TaskTableModel;
+import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
+import org.opends.guitools.controlpanel.task.CancelTaskTask;
+import org.opends.guitools.controlpanel.task.Task;
+import org.opends.guitools.controlpanel.ui.renderer.TaskCellRenderer;
+import org.opends.guitools.controlpanel.util.ConfigFromFile;
+import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.messages.Message;
+import org.opends.quicksetup.util.Utils;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.tools.tasks.TaskEntry;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeBuilder;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.AttributeValues;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.OpenDsException;
+
+/**
+ * The panel displaying the list of scheduled tasks.
+ *
+ */
+public class ManageTasksPanel extends StatusGenericPanel
+{
+  private static final long serialVersionUID = -8034784684412532193L;
+
+  private JLabel lNoTasksFound;
+
+  /**
+   * Remove task button.
+   */
+  private JButton cancelTask;
+  /**
+   * The scroll that contains the list of tasks (actually is a table).
+   */
+  private JScrollPane tableScroll;
+  /**
+   * The table of tasks.
+   */
+  private JTable taskTable;
+
+  /**
+   * The model of the table.
+   */
+  private TaskTableModel tableModel;
+
+  private ManageTasksMenuBar menuBar;
+
+  private MonitoringAttributesViewPanel<Message> operationViewPanel;
+  private GenericDialog operationViewDlg;
+
+  private JPanel detailsPanel;
+  private JLabel noDetailsLabel;
+  // The panel containing all the labels and values of the details.
+  private JPanel detailsSubpanel;
+
+  private static final Logger LOG =
+    Logger.getLogger(ManageTasksPanel.class.getName());
+
+  /**
+   * Default constructor.
+   *
+   */
+  public ManageTasksPanel()
+  {
+    super();
+    createLayout();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Message getTitle()
+  {
+    return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_LIST_TITLE.get();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean requiresScroll()
+  {
+    return false;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public GenericDialog.ButtonType getButtonType()
+  {
+    return GenericDialog.ButtonType.CLOSE;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void okClicked()
+  {
+    // Nothing to do, it only contains a close button.
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public JMenuBar getMenuBar()
+  {
+    if (menuBar == null)
+    {
+      menuBar = new ManageTasksMenuBar(getInfo());
+    }
+    return menuBar;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Component getPreferredFocusComponent()
+  {
+    return taskTable;
+  }
+
+  /**
+   * Returns the selected cancelable tasks in the list.
+   * @param onlyCancelable add only the cancelable tasks.
+   * @return the selected cancelable tasks in the list.
+   */
+  private List<TaskEntry> getSelectedTasks(boolean onlyCancelable)
+  {
+    ArrayList<TaskEntry> tasks = new ArrayList<TaskEntry>();
+    int[] rows = taskTable.getSelectedRows();
+    for (int row : rows)
+    {
+      if (row != -1)
+      {
+        TaskEntry task = tableModel.get(row);
+        if (!onlyCancelable || task.isCancelable())
+        {
+          tasks.add(task);
+        }
+      }
+    }
+    return tasks;
+  }
+
+  /**
+   * Creates the components and lays them in the panel.
+   * @param gbc the grid bag constraints to be used.
+   */
+  private void createLayout()
+  {
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.anchor = GridBagConstraints.WEST;
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.gridwidth = 2;
+    addErrorPane(gbc);
+
+    gbc.weightx = 0.0;
+    gbc.gridy ++;
+    gbc.anchor = GridBagConstraints.WEST;
+    gbc.weightx = 0.0;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.gridwidth = 2;
+    gbc.insets.left = 0;
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    lNoTasksFound = Utilities.createDefaultLabel(
+        INFO_CTRL_PANEL_NO_TASKS_FOUND.get());
+    gbc.gridy ++;
+    gbc.anchor = GridBagConstraints.CENTER;
+    gbc.gridheight = 2;
+    add(lNoTasksFound, gbc);
+    lNoTasksFound.setVisible(false);
+
+    gbc.gridwidth = 1;
+    gbc.weightx = 1.0;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.insets.top = 10;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    // Done to provide a good size to the table.
+    tableModel = new TaskTableModel();
+    tableModel.setData(createDummyTaskList());
+    taskTable =
+      Utilities.createSortableTable(tableModel, new TaskCellRenderer());
+    taskTable.getSelectionModel().setSelectionMode(
+        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+    tableScroll = Utilities.createScrollPane(taskTable);
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    add(tableScroll, gbc);
+    updateTableSizes();
+
+    gbc.gridx = 1;
+    gbc.gridheight = 1;
+    gbc.anchor = GridBagConstraints.EAST;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.weightx = 0.0;
+    gbc.weighty = 0.0;
+    cancelTask = Utilities.createButton(
+        INFO_CTRL_PANEL_CANCEL_TASK_BUTTON_LABEL.get());
+    cancelTask.setOpaque(false);
+    gbc.insets.left = 10;
+    add(cancelTask, gbc);
+
+    gbc.gridy ++;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.VERTICAL;
+    add(Box.createVerticalGlue(), gbc);
+    cancelTask.addActionListener(new ActionListener()
+    {
+      /**
+       * {@inheritDoc}
+       */
+      public void actionPerformed(ActionEvent ev)
+      {
+        cancelTaskClicked();
+      }
+    });
+
+    gbc.gridy ++;
+    gbc.gridx = 0;
+    gbc.gridwidth = 2;
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.weightx = 1.0;
+    gbc.weighty = 0.7;
+    gbc.insets.left = 0;
+    createDetailsPanel();
+    add(detailsPanel, gbc);
+
+    ListSelectionListener listener = new ListSelectionListener()
+    {
+      /**
+       * {@inheritDoc}
+       */
+      public void valueChanged(ListSelectionEvent ev)
+      {
+        tableSelected();
+      }
+    };
+    taskTable.getSelectionModel().addListSelectionListener(listener);
+    listener.valueChanged(null);
+  }
+
+  /**
+   * Creates the details panel.
+   *
+   */
+  private void createDetailsPanel()
+  {
+    detailsPanel = new JPanel(new GridBagLayout());
+    detailsPanel.setOpaque(false);
+    detailsPanel.setBorder(Utilities.makeTitledBorder(
+        INFO_CTRL_PANEL_TASK_SPECIFIC_DETAILS.get()));
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 1;
+    gbc.gridy = 1;
+    gbc.anchor = GridBagConstraints.CENTER;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.weightx = 1.0;
+    gbc.weighty = 1.0;
+    noDetailsLabel =
+      Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_TASK_SELECTED.get());
+    gbc.gridwidth = 2;
+    detailsPanel.add(noDetailsLabel, gbc);
+
+    detailsSubpanel = new JPanel(new GridBagLayout());
+    detailsSubpanel.setOpaque(false);
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.BOTH;
+    detailsPanel.add(Utilities.createBorderLessScrollBar(detailsSubpanel), gbc);
+  }
+
+  /**
+   * Method called when the table is selected.
+   *
+   */
+  private void tableSelected()
+  {
+    List<TaskEntry> tasks = getSelectedTasks(true);
+    cancelTask.setEnabled(!tasks.isEmpty());
+
+    detailsSubpanel.removeAll();
+
+    tasks = getSelectedTasks(false);
+
+    boolean displayContents = false;
+    if (tasks.isEmpty())
+    {
+      noDetailsLabel.setText(INFO_CTRL_PANEL_NO_TASK_SELECTED.get().toString());
+    }
+    else if (tasks.size() > 1)
+    {
+      noDetailsLabel.setText(
+          INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED.get().toString());
+    }
+    else
+    {
+      TaskEntry taskEntry = tasks.iterator().next();
+      Map<Message,List<String>> taskSpecificAttrs =
+        taskEntry.getTaskSpecificAttributeValuePairs();
+      if (taskSpecificAttrs.isEmpty())
+      {
+        noDetailsLabel.setText(
+            INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS.get().toString());
+      }
+      else
+      {
+        displayContents = true;
+        GridBagConstraints gbc = new GridBagConstraints();
+        gbc.gridy = 1;
+        gbc.fill = GridBagConstraints.NONE;
+        gbc.anchor = GridBagConstraints.NORTHWEST;
+        gbc.insets.top = 10;
+        for (Message label : taskSpecificAttrs.keySet())
+        {
+          List<String> values = taskSpecificAttrs.get(label);
+          gbc.gridx = 0;
+          gbc.insets.left = 10;
+          gbc.insets.right = 0;
+          detailsSubpanel.add(Utilities.createPrimaryLabel(
+              INFO_CTRL_PANEL_OPERATION_NAME_AS_LABEL.get(label.toString())),
+              gbc);
+
+          gbc.gridx = 1;
+          gbc.insets.right = 10;
+
+          Message msg;
+          String s = Utils.getStringFromCollection(values, "<br>");
+          if (values.size() > 1)
+          {
+            msg = Message.raw(
+                "<html>"+Utilities.applyFont(s,
+                    ColorAndFontConstants.defaultFont));
+          }
+          else
+          {
+            msg = Message.raw(s);
+          }
+          detailsSubpanel.add(Utilities.createDefaultLabel(msg), gbc);
+
+          gbc.gridy ++;
+        }
+        gbc.gridx = 0;
+        gbc.insets = new Insets(0, 0, 0, 0);
+        detailsSubpanel.add(Box.createVerticalStrut(10), gbc);
+        gbc.gridx = 1;
+        gbc.weightx = 1.0;
+        gbc.weighty = 1.0;
+        gbc.fill = GridBagConstraints.BOTH;
+        detailsSubpanel.add(Box.createGlue(), gbc);
+      }
+    }
+    noDetailsLabel.setVisible(!displayContents);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Creates a list with task descriptors.  This is done simply to have a good
+   * initial size for the table.
+   * @return a list with bogus task descriptors.
+   */
+  private Set<TaskEntry> createRandomTasksList()
+  {
+    Set<TaskEntry> list = new HashSet<TaskEntry>();
+    Random r = new Random();
+    int numberTasks = r.nextInt(10);
+    for (int i= 0; i<numberTasks; i++)
+    {
+      CustomSearchResult csr =
+        new CustomSearchResult("cn=mytask"+i+",cn=tasks");
+      String p = "ds-task-";
+      String[] attrNames =
+      {
+          p + "id",
+          p + "class-name",
+          p + "state",
+          p + "scheduled-start-time",
+          p + "actual-start-time",
+          p + "completion-time",
+          p + "dependency-id",
+          p + "failed-dependency-action",
+          p + "log-message",
+          p + "notify-on-error",
+          p + "notify-on-completion",
+          p + "ds-recurring-task-schedule"
+      };
+      String[] values =
+      {
+          "ID",
+          "TheClassName",
+          "TheState",
+          "Schedule Start Time",
+          "Actual Start Time",
+          "Completion Time",
+          "Dependency ID",
+          "Failed Dependency Action",
+          "Log Message.                              Should be pretty long"+
+          "Log Message.                              Should be pretty long"+
+          "Log Message.                              Should be pretty long"+
+          "Log Message.                              Should be pretty long"+
+          "Log Message.                              Should be pretty long",
+          "Notify On Error",
+          "Notify On Completion",
+          "Recurring Task Schedule"
+      };
+      for (int j=0; j < attrNames.length; j++)
+      {
+        Set<Object> attrValues = new HashSet<Object>(1);
+        attrValues.add(values[j] + r.nextInt());
+        csr.set(attrNames[j], attrValues);
+      }
+      try
+      {
+        Entry entry = getEntry(csr);
+        TaskEntry task = new TaskEntry(entry);
+        list.add(task);
+      }
+      catch (Throwable t)
+      {
+        LOG.log(Level.SEVERE, "Error getting entry '"+csr.getDN()+"': "+t, t);
+      }
+    }
+    return list;
+  }
+
+  /**
+   * Creates a list with task descriptors.  This is done simply to have a good
+   * initial size for the table.
+   * @return a list with bogus task descriptors.
+   */
+  private Set<TaskEntry> createDummyTaskList()
+  {
+    Set<TaskEntry> list = new HashSet<TaskEntry>();
+    for (int i= 0; i<10; i++)
+    {
+      CustomSearchResult csr =
+        new CustomSearchResult("cn=mytask"+i+",cn=tasks");
+      String p = "ds-task-";
+      String[] attrNames =
+      {
+          p + "id",
+          p + "class-name",
+          p + "state",
+          p + "scheduled-start-time",
+          p + "actual-start-time",
+          p + "completion-time",
+          p + "dependency-id",
+          p + "failed-dependency-action",
+          p + "log-message",
+          p + "notify-on-error",
+          p + "notify-on-completion",
+          p + "ds-recurring-task-schedule"
+      };
+      String[] values =
+      {
+          "A very 29-backup - Sun Mar 29 00:00:00 MET 2009",
+          "A long task type",
+          "A very long task status",
+          "Schedule Start Time",
+          "Actual Start Time",
+          "Completion Time",
+          "Dependency ID",
+          "Failed Dependency Action",
+          "Log Message.                              Should be pretty long\n"+
+          "Log Message.                              Should be pretty long\n"+
+          "Log Message.                              Should be pretty long\n"+
+          "Log Message.                              Should be pretty long\n"+
+          "Log Message.                              Should be pretty long\n",
+          "Notify On Error",
+          "Notify On Completion",
+          "Recurring Task Schedule"
+      };
+      for (int j=0; j < attrNames.length; j++)
+      {
+        Set<Object> attrValues = new HashSet<Object>(1);
+        attrValues.add(values[j]);
+        csr.set(attrNames[j], attrValues);
+      }
+      try
+      {
+        Entry entry = getEntry(csr);
+        TaskEntry task = new TaskEntry(entry);
+        list.add(task);
+      }
+      catch (Throwable t)
+      {
+        LOG.log(Level.SEVERE, "Error getting entry '"+csr.getDN()+"': "+t, t);
+      }
+    }
+    return list;
+  }
+
+  private void cancelTaskClicked()
+  {
+    ArrayList<Message> errors = new ArrayList<Message>();
+    ProgressDialog dlg = new ProgressDialog(
+        Utilities.getParentDialog(this),
+        INFO_CTRL_PANEL_CANCEL_TASK_TITLE.get(), getInfo());
+    List<TaskEntry> tasks = getSelectedTasks(true);
+    CancelTaskTask newTask = new CancelTaskTask(getInfo(), dlg, tasks);
+    for (Task task : getInfo().getTasks())
+    {
+      task.canLaunch(newTask, errors);
+    }
+    if (errors.size() == 0)
+    {
+      boolean confirmed = displayConfirmationDialog(
+          INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(),
+          INFO_CTRL_PANEL_CANCEL_TASK_MSG.get());
+      if (confirmed)
+      {
+        launchOperation(newTask,
+            INFO_CTRL_PANEL_CANCELING_TASK_SUMMARY.get(),
+            INFO_CTRL_PANEL_CANCELING_TASK_COMPLETE.get(),
+            INFO_CTRL_PANEL_CANCELING_TASK_SUCCESSFUL.get(),
+            ERR_CTRL_PANEL_CANCELING_TASK_ERROR_SUMMARY.get(),
+            ERR_CTRL_PANEL_CANCELING_TASK_ERROR_DETAILS.get(),
+            null,
+            dlg);
+        dlg.setVisible(true);
+      }
+    }
+  }
+
+
+
+  /**
+   * Gets the Entry object equivalent to the provided CustomSearchResult.
+   * The method assumes that the schema in DirectoryServer has been initialized.
+   * @param csr the search result.
+   * @return the Entry object equivalent to the provided CustomSearchResult.
+   * @throws OpenDsException if there is an error parsing the DN or retrieving
+   * the attributes definition and objectclasses in the schema of the server.
+   * TODO: move somewhere better.
+   */
+  public static Entry getEntry(CustomSearchResult csr) throws OpenDsException
+  {
+    DN dn = DN.decode(csr.getDN());
+    Map<ObjectClass,String> objectClasses = new HashMap<ObjectClass,String>();
+    Map<AttributeType,List<Attribute>> userAttributes =
+      new HashMap<AttributeType,List<Attribute>>();
+    Map<AttributeType,List<Attribute>> operationalAttributes =
+      new HashMap<AttributeType,List<Attribute>>();
+
+    for (String wholeName : csr.getAttributeNames())
+    {
+      final Attribute attribute = parseAttrDescription(wholeName);
+      final String attrName = attribute.getName();
+      final String lowerName = toLowerCase(attrName);
+
+      // See if this is an objectclass or an attribute.  Then get the
+      // corresponding definition and add the value to the appropriate hash.
+      if (lowerName.equals("objectclass"))
+      {
+        for (Object value : csr.getAttributeValues(attrName))
+        {
+          String ocName = value.toString().trim();
+          String lowerOCName = toLowerCase(ocName);
+
+          ObjectClass objectClass =
+            DirectoryServer.getObjectClass(lowerOCName);
+          if (objectClass == null)
+          {
+            objectClass = DirectoryServer.getDefaultObjectClass(ocName);
+          }
+
+          objectClasses.put(objectClass, ocName);
+        }
+      }
+      else
+      {
+        AttributeType attrType = DirectoryServer.getAttributeType(lowerName);
+        if (attrType == null)
+        {
+          attrType = DirectoryServer.getDefaultAttributeType(attrName);
+        }
+
+        AttributeBuilder builder = new AttributeBuilder(attribute, true);
+        for (Object value : csr.getAttributeValues(attrName))
+        {
+          ByteString bs;
+          if (value instanceof byte[])
+          {
+            bs = ByteString.wrap((byte[])value);
+          }
+          else
+          {
+            bs = ByteString.valueOf(value.toString());
+          }
+          AttributeValue attributeValue =
+            AttributeValues.create(attrType, bs);
+          builder.add(attributeValue);
+        }
+        List<Attribute> attrList = new ArrayList<Attribute>(1);
+        attrList.add(builder.toAttribute());
+
+        if (attrType.isOperational())
+        {
+          operationalAttributes.put(attrType, attrList);
+        }
+        else
+        {
+          userAttributes.put(attrType, attrList);
+        }
+      }
+    }
+
+    return new Entry(dn, objectClasses, userAttributes, operationalAttributes);
+  }
+
+  /**
+   * Parse an AttributeDescription (an attribute type name and its
+   * options).
+   * TODO: make this method in LDIFReader public.
+   *
+   * @param attrDescr
+   *          The attribute description to be parsed.
+   * @return A new attribute with no values, representing the
+   *         attribute type and its options.
+   */
+  private static Attribute parseAttrDescription(String attrDescr)
+  {
+    AttributeBuilder builder;
+    int semicolonPos = attrDescr.indexOf(';');
+    if (semicolonPos > 0)
+    {
+      builder = new AttributeBuilder(attrDescr.substring(0, semicolonPos));
+      int nextPos = attrDescr.indexOf(';', semicolonPos + 1);
+      while (nextPos > 0)
+      {
+        String option = attrDescr.substring(semicolonPos + 1, nextPos);
+        if (option.length() > 0)
+        {
+          builder.setOption(option);
+          semicolonPos = nextPos;
+          nextPos = attrDescr.indexOf(';', semicolonPos + 1);
+        }
+      }
+
+      String option = attrDescr.substring(semicolonPos + 1);
+      if (option.length() > 0)
+      {
+        builder.setOption(option);
+      }
+    }
+    else
+    {
+      builder = new AttributeBuilder(attrDescr);
+    }
+
+    if(builder.getAttributeType().isBinary())
+    {
+      //resetting doesn't hurt and returns false.
+      builder.setOption("binary");
+    }
+
+    return builder.toAttribute();
+  }
+
+  /**
+   * The main method to test this panel.
+   * @param args the arguments.
+   */
+  public static void main(String[] args)
+  {
+    // This is a hack to initialize configuration
+    new ConfigFromFile();
+    final ManageTasksPanel p = new ManageTasksPanel();
+    Thread t = new Thread(new Runnable()
+    {
+      public void run()
+      {
+        try
+        {
+          // To let the dialog to be displayed
+          Thread.sleep(5000);
+        }
+        catch (Throwable t)
+        {
+          t.printStackTrace();
+        }
+        while (p.isVisible())
+        {
+          try
+          {
+            SwingUtilities.invokeLater(new Runnable(){
+              public void run()
+              {
+                Set<TaskEntry> tasks = p.createRandomTasksList();
+                p.tableModel.setData(tasks);
+                boolean visible = p.tableModel.getRowCount() > 0;
+                if (visible)
+                {
+                  p.updateTableSizes();
+                }
+                p.tableModel.fireTableDataChanged();
+                p.lNoTasksFound.setVisible(!visible);
+                p.tableScroll.setVisible(visible);
+                p.cancelTask.setVisible(visible);
+              }
+            });
+            Thread.sleep(5000);
+          }
+          catch (Exception ex)
+          {
+            ex.printStackTrace();
+          }
+        }
+      }
+    });
+    t.start();
+
+
+    SwingUtilities.invokeLater(new Runnable(){
+      public void run()
+      {
+        GenericDialog dlg = new GenericDialog(new JFrame(), p);
+        dlg.setModal(true);
+        dlg.pack();
+        dlg.setVisible(true);
+      }
+    });
+    t = null;
+  }
+
+  /**
+   * Displays a dialog allowing the user to select which operations to display.
+   *
+   */
+  private void operationViewClicked()
+  {
+    if (operationViewDlg == null)
+    {
+      operationViewPanel = MonitoringAttributesViewPanel.createMessageInstance(
+          tableModel.getAllAttributes());
+      operationViewDlg = new GenericDialog(Utilities.getFrame(this),
+          operationViewPanel);
+      Utilities.centerGoldenMean(operationViewDlg,
+          Utilities.getParentDialog(this));
+      operationViewDlg.setModal(true);
+    }
+    operationViewPanel.setSelectedAttributes(
+        tableModel.getDisplayedAttributes());
+    operationViewDlg.setVisible(true);
+    if (!operationViewPanel.isCancelled())
+    {
+      LinkedHashSet<Message> displayedAttributes =
+        operationViewPanel.getAttributes();
+      setAttributesToDisplay(displayedAttributes);
+      updateTableSizes();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void configurationChanged(ConfigurationChangeEvent ev)
+  {
+    updateErrorPaneIfServerRunningAndAuthRequired(ev.getNewDescriptor(),
+        INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_REQUIRES_SERVER_RUNNING.get(),
+        INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_AUTHENTICATION.get());
+    ServerDescriptor server = ev.getNewDescriptor();
+    final Set<TaskEntry> tasks = server.getTaskEntries();
+    boolean changed = tableModel.getRowCount() != tasks.size();
+    if (!changed)
+    {
+      for (int i=0; i<tableModel.getRowCount(); i++)
+      {
+        if (!tasks.contains(tableModel.get(i)))
+        {
+          changed = true;
+          break;
+        }
+      }
+    }
+    if (changed)
+    {
+      SwingUtilities.invokeLater(new Runnable()
+      {
+        /**
+         * {@inheritDoc}
+         */
+        public void run()
+        {
+          tableModel.setData(tasks);
+          boolean visible = tableModel.getRowCount() > 0;
+          if (visible)
+          {
+            updateTableSizes();
+          }
+          tableModel.fireTableDataChanged();
+          lNoTasksFound.setVisible(!visible &&
+              !errorPane.isVisible());
+          tableScroll.setVisible(visible);
+          cancelTask.setVisible(visible);
+        }
+      });
+    }
+  }
+
+  private void updateTableSizes()
+  {
+    Utilities.updateTableSizes(taskTable, 8);
+    Utilities.updateScrollMode(tableScroll, taskTable);
+  }
+
+  private void setAttributesToDisplay(LinkedHashSet<Message> attributes)
+  {
+    tableModel.setAttributes(attributes);
+    tableModel.forceDataStructureChange();
+  }
+
+  /**
+   * The specific menu bar of this panel.
+   *
+   */
+  class ManageTasksMenuBar extends MainMenuBar
+  {
+    private static final long serialVersionUID = 5051878116443370L;
+
+    /**
+     * structor.
+     * @param info the control panel info.
+     */
+    public ManageTasksMenuBar(ControlPanelInfo info)
+    {
+      super(info);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addMenus()
+    {
+      add(createViewMenuBar());
+      add(createHelpMenuBar());
+    }
+
+    /**
+     * Creates the view menu bar.
+     * @return the view menu bar.
+     */
+    @Override
+    protected JMenu createViewMenuBar()
+    {
+      JMenu menu = Utilities.createMenu(
+          INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU.get(),
+          INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU_DESCRIPTION.get());
+      menu.setMnemonic(KeyEvent.VK_V);
+      final JMenuItem viewOperations = Utilities.createMenuItem(
+          INFO_CTRL_PANEL_OPERATIONS_VIEW.get());
+      menu.add(viewOperations);
+      viewOperations.addActionListener(new ActionListener()
+      {
+        public void actionPerformed(ActionEvent ev)
+        {
+          operationViewClicked();
+        }
+      });
+      return menu;
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java
index c92272b..6cba7f8 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java
@@ -91,7 +91,8 @@
   * Creates an instance of this panel that uses MonitoringAttributes as
   * attributes.
   * @param attributes the list of possible attributes.
-  * @return an instance of this panel that uses String as attributes.
+  * @return an instance of this panel that uses MonitoringAttributes as
+  * attributes.
   */
  public static MonitoringAttributesViewPanel<MonitoringAttributes>
  createMonitoringAttributesInstance(
@@ -101,6 +102,18 @@
  }
 
  /**
+  * Creates an instance of this panel that uses Message as
+  * attributes.
+  * @param attributes the list of possible attributes.
+  * @return an instance of this panel that uses Message as attributes.
+  */
+ public static MonitoringAttributesViewPanel<Message>
+ createMessageInstance(LinkedHashSet<Message> attributes)
+ {
+   return new MonitoringAttributesViewPanel<Message>(attributes);
+ }
+
+ /**
   * {@inheritDoc}
   */
  @Override
@@ -354,6 +367,10 @@
    {
      m = ((MonitoringAttributes)operation).getMessage();
    }
+   else if (operation instanceof Message)
+   {
+     m = (Message)operation;
+   }
    else
    {
      m = Message.raw(operation.toString());
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
index e763fb3..0104171 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -42,8 +42,11 @@
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -77,6 +80,7 @@
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
 import org.opends.guitools.controlpanel.datamodel.CustomSearchResult;
 import org.opends.guitools.controlpanel.datamodel.MonitoringAttributes;
+import org.opends.guitools.controlpanel.datamodel.ScheduleType;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
 import org.opends.guitools.controlpanel.event.*;
 import org.opends.guitools.controlpanel.task.RebuildIndexTask;
@@ -147,6 +151,9 @@
   private boolean sizeSet = false;
   private boolean focusSet = false;
 
+  private static DateFormat taskDateFormat =
+    new SimpleDateFormat("yyyyMMddHHmmss");
+
   /**
    * Returns the title that will be used as title of the dialog.
    * @return the title that will be used as title of the dialog.
@@ -2183,4 +2190,58 @@
     return INFO_CTRL_PANEL_OPERATION_NAME_AS_LABEL.get(
         attr.getMessage().toString());
   }
+
+  /**
+   * Returns the command-line arguments associated with the provided schedule.
+   * @param schedule the schedule.
+   * @return the command-line arguments associated with the provided schedule.
+   */
+  protected List<String> getScheduleArgs(ScheduleType schedule)
+  {
+    List<String> args = new ArrayList<String>(2);
+    switch (schedule.getType())
+    {
+    case LAUNCH_LATER:
+      args.add("--start");
+      args.add(getStartTimeForTask(schedule.getLaunchLaterDate()));
+      break;
+    case LAUNCH_PERIODICALLY:
+      args.add("--recurringTask");
+      args.add(schedule.getCronValue());
+      break;
+    }
+    return args;
+  }
+
+  /**
+   * Checks whether the server is running or not and depending on the schedule
+   * updates the list of errors with the errors found.
+   * @param schedule the schedule.
+   * @param errors the list of errors.
+   * @param label the label to be marked as invalid if errors where encountered.
+   */
+  protected void addScheduleErrors(ScheduleType schedule,
+      Collection<Message> errors, JLabel label)
+  {
+    if (!isServerRunning())
+    {
+      ScheduleType.Type type = schedule.getType();
+      if (type == ScheduleType.Type.LAUNCH_LATER)
+      {
+        errors.add(ERR_CTRL_PANEL_LAUNCH_LATER_REQUIRES_SERVER_RUNNING.get());
+        setPrimaryInvalid(label);
+      }
+      else if (type == ScheduleType.Type.LAUNCH_PERIODICALLY)
+      {
+        errors.add(
+            ERR_CTRL_PANEL_LAUNCH_SCHEDULE_REQUIRES_SERVER_RUNNING.get());
+        setPrimaryInvalid(label);
+      }
+    }
+  }
+
+  private String getStartTimeForTask(Date date)
+  {
+    return taskDateFormat.format(date);
+  }
 }
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TaskToSchedulePanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TaskToSchedulePanel.java
new file mode 100644
index 0000000..d4cccab
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/TaskToSchedulePanel.java
@@ -0,0 +1,1178 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.controlpanel.ui;
+
+import static org.opends.messages.AdminToolMessages.*;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import javax.swing.Box;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.text.PlainDocument;
+
+import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
+import org.opends.guitools.controlpanel.datamodel.ScheduleType;
+import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
+import org.opends.guitools.controlpanel.ui.components.
+ NumericLimitedSizeDocumentFilter;
+import org.opends.guitools.controlpanel.ui.components.TimeDocumentFilter;
+import org.opends.guitools.controlpanel.ui.renderer.
+ NoLeftInsetCategoryComboBoxRenderer;
+import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.messages.Message;
+import org.opends.server.backends.task.RecurringTask;
+
+/**
+ * The panel that allows the user to specify when a task will be launched.
+ *
+ */
+public class TaskToSchedulePanel extends StatusGenericPanel
+{
+  private static final long serialVersionUID = 6855081932432566784L;
+
+  private String taskName;
+
+  private JComboBox scheduleType;
+
+  private JTextField time;
+  private JTextField day;
+  private JComboBox month;
+  private JComboBox year;
+
+  private JLabel lTime;
+  private JLabel lDay;
+  private JLabel lMonth;
+  private JLabel lYear;
+
+  private JLabel lDailyTime;
+  private JTextField dailyTime;
+
+  private JLabel lWeeklyTime;
+  private JLabel lWeeklyDays;
+  private JTextField weeklyTime;
+  private JCheckBox sunday, monday, tuesday, wednesday, thursday, friday,
+  saturday;
+  {
+    sunday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUNDAY.get());
+    monday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONDAY.get());
+    tuesday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TUESDAY.get());
+    wednesday =
+      Utilities.createCheckBox(
+          INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEDNESDAY.get());
+    thursday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_THURSDAY.get());
+    friday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_FRIDAY.get());
+    saturday =
+      Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SATURDAY.get());
+  }
+
+  JCheckBox[] weekDays =
+  {
+      sunday, monday, tuesday, wednesday, thursday, friday, saturday
+  };
+
+  private JLabel lMonthlyTime;
+  private JLabel lMonthlyDays;
+  private JTextField monthlyTime;
+  private JCheckBox[] monthDays = new JCheckBox[31];
+
+  private JLabel lCronMinute;
+  private JLabel lCronHour;
+  private JLabel lCronWeekDay;
+  private JLabel lCronMonthDay;
+  private JLabel lCronMonth;
+
+  private JTextField cronMinute;
+  private JTextField cronHour;
+  private JTextField cronWeekDay;
+  private JTextField cronMonthDay;
+  private JTextField cronMonth;
+
+  private Component launchLaterPanel;
+  private Component dailyPanel;
+  private Component weeklyPanel;
+  private Component monthlyPanel;
+  private Component cronPanel;
+
+  private Message LAUNCH_NOW = INFO_CTRL_PANEL_LAUNCH_NOW.get();
+  private Message LAUNCH_LATER = INFO_CTRL_PANEL_LAUNCH_LATER.get();
+  private Message LAUNCH_DAILY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAILY.get();
+  private Message LAUNCH_WEEKLY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEEKLY.get();
+  private Message LAUNCH_MONTHLY =
+    INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTHLY.get();
+  private Message CRON = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON.get();
+
+  private ScheduleType schedule;
+
+  /**
+   * Default constructor.
+   * @param taskName the name of the task to be scheduled.
+   */
+  public TaskToSchedulePanel(String taskName)
+  {
+    super();
+    this.taskName = taskName;
+    createLayout();
+  }
+
+  /**
+   * Creates the layout of the panel (but the contents are not populated here).
+   */
+  private void createLayout()
+  {
+    GridBagConstraints gbc = new GridBagConstraints();
+    JEditorPane explanation = Utilities.makeHtmlPane(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUMMARY.get(taskName).toString(),
+        ColorAndFontConstants.defaultFont);
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.gridwidth = 1;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    add(explanation, gbc);
+    gbc.gridy ++;
+    gbc.insets.top = 10;
+    scheduleType = Utilities.createComboBox();
+    scheduleType.setModel(new DefaultComboBoxModel());
+
+    ArrayList<Object> newElements = new ArrayList<Object>();
+    newElements.add(new CategorizedComboBoxElement(LAUNCH_NOW,
+        CategorizedComboBoxElement.Type.REGULAR));
+    newElements.add(COMBO_SEPARATOR);
+    newElements.add(new CategorizedComboBoxElement(LAUNCH_LATER,
+        CategorizedComboBoxElement.Type.REGULAR));
+    newElements.add(COMBO_SEPARATOR);
+    newElements.add(new CategorizedComboBoxElement(LAUNCH_DAILY,
+        CategorizedComboBoxElement.Type.REGULAR));
+    newElements.add(new CategorizedComboBoxElement(LAUNCH_WEEKLY,
+        CategorizedComboBoxElement.Type.REGULAR));
+    newElements.add(new CategorizedComboBoxElement(LAUNCH_MONTHLY,
+        CategorizedComboBoxElement.Type.REGULAR));
+    newElements.add(new CategorizedComboBoxElement(CRON,
+        CategorizedComboBoxElement.Type.REGULAR));
+    updateComboBoxModel(newElements,
+        (DefaultComboBoxModel)scheduleType.getModel());
+    scheduleType.setRenderer(
+        new NoLeftInsetCategoryComboBoxRenderer(scheduleType));
+    scheduleType.addItemListener(new IgnoreItemListener(scheduleType));
+
+    gbc.weightx = 0.0;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.NONE;
+    add(scheduleType, gbc);
+
+    launchLaterPanel = createLaunchLaterPanel();
+    dailyPanel = createDailyPanel();
+    weeklyPanel = createWeeklyPanel();
+    monthlyPanel = createMonthlyPanel();
+    cronPanel = createCronPanel();
+
+    scheduleType.addItemListener(new ItemListener()
+    {
+      public void itemStateChanged(ItemEvent ev)
+      {
+        Object element = scheduleType.getSelectedItem();
+        boolean launchLaterVisible = false;
+        boolean launchDailyVisible = false;
+        boolean launchWeeklyVisible = false;
+        boolean launchMonthlyVisible = false;
+        boolean cronVisible = false;
+        if (element != null)
+        {
+          if (element instanceof CategorizedComboBoxElement)
+          {
+            element = ((CategorizedComboBoxElement)element).getValue();
+          }
+          launchLaterVisible = element == LAUNCH_LATER;
+          launchDailyVisible = element == LAUNCH_DAILY;
+          launchWeeklyVisible = element == LAUNCH_WEEKLY;
+          launchMonthlyVisible = element == LAUNCH_MONTHLY;
+          cronVisible = element == CRON;
+        }
+        launchLaterPanel.setVisible(launchLaterVisible);
+        dailyPanel.setVisible(launchDailyVisible);
+        weeklyPanel.setVisible(launchWeeklyVisible);
+        monthlyPanel.setVisible(launchMonthlyVisible);
+        cronPanel.setVisible(cronVisible);
+      }
+    });
+    launchLaterPanel.setVisible(false);
+    dailyPanel.setVisible(false);
+    weeklyPanel.setVisible(false);
+    monthlyPanel.setVisible(false);
+    cronPanel.setVisible(false);
+
+    int width = 0;
+    int height = 0;
+    Component[] comps =
+    {launchLaterPanel, dailyPanel, weeklyPanel, monthlyPanel, cronPanel};
+    for (Component comp : comps)
+    {
+      width = Math.max(width, comp.getPreferredSize().width);
+      height = Math.max(height, comp.getPreferredSize().height);
+    }
+
+    gbc.gridy ++;
+    gbc.gridwidth = 1;
+    gbc.gridx = 0;
+    gbc.weightx = 0.0;
+    gbc.insets.left = 30;
+    add(launchLaterPanel, gbc);
+    add(dailyPanel, gbc);
+    add(weeklyPanel, gbc);
+    add(monthlyPanel, gbc);
+    add(cronPanel, gbc);
+    add(Box.createRigidArea(new Dimension(width, height)), gbc);
+    gbc.gridy ++;
+    gbc.gridx = 0;
+    gbc.fill = GridBagConstraints.VERTICAL;
+    gbc.weighty = 1.0;
+    add(Box.createVerticalGlue(), gbc);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void toBeDisplayed(boolean visible)
+  {
+    // Reset the schedule
+    if (visible)
+    {
+      schedule = null;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Message getTitle()
+  {
+    return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TITLE.get(taskName);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void okClicked()
+  {
+    schedule = null;
+    ArrayList<Message> errorMessages = new ArrayList<Message>();
+
+    updateErrorMessages(errorMessages);
+
+    if (errorMessages.size() > 0)
+    {
+      displayErrorDialog(errorMessages);
+    }
+    else
+    {
+      schedule = createSchedule();
+      Utilities.getParentDialog(this).setVisible(false);
+    }
+  }
+
+  /**
+   * Checks the validity of the provided information and updates the provided
+   * collection of messages with the errors that have been found.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateErrorMessages(Collection<Message> errorMessages)
+  {
+    Object type =
+      ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue();
+    if (type == LAUNCH_LATER)
+    {
+      updateLaunchLaterErrorMessages(errorMessages);
+    }
+    else if (type == LAUNCH_DAILY)
+    {
+      updateLaunchDailyErrorMessages(errorMessages);
+    }
+    else if (type == LAUNCH_WEEKLY)
+    {
+      updateLaunchWeeklyErrorMessages(errorMessages);
+    }
+    else if (type == LAUNCH_MONTHLY)
+    {
+      updateLaunchMonthlyErrorMessages(errorMessages);
+    }
+    else if (type == CRON)
+    {
+      updateCronErrorMessages(errorMessages);
+    }
+  }
+
+  /**
+   * Checks the validity of the launch later information and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateLaunchLaterErrorMessages(Collection<Message> errorMessages)
+  {
+    setPrimaryValid(lTime);
+    setPrimaryValid(lDay);
+    setPrimaryValid(lMonth);
+    setPrimaryValid(lYear);
+
+    int previousErrorNumber = errorMessages.size();
+
+    int y = Integer.parseInt(year.getSelectedItem().toString());
+    int d = -1;
+    int m = month.getSelectedIndex();
+    int[] h = {-1};
+    int[] min = {-1};
+    checkTime(time, lTime, h, min, errorMessages);
+    try
+    {
+      d = Integer.parseInt(day.getText().trim());
+      if ((d < 0) || (d > 31))
+      {
+        errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get());
+        setPrimaryInvalid(lDay);
+      }
+    }
+    catch (Exception ex)
+    {
+      errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get());
+      setPrimaryInvalid(lDay);
+    }
+
+    if (errorMessages.size() == previousErrorNumber)
+    {
+      GregorianCalendar calendar = new GregorianCalendar(y, m, d, h[0], min[0]);
+      Date date = calendar.getTime();
+      // Check that the actual date's month date corresponds to a valid day
+      // (for instance if user specifies 30th of February, the resulting date
+      // is 2nd (or 1st depending of the year) of Mars.
+      if (calendar.get(Calendar.MONTH) != m)
+      {
+        errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY_IN_MONTH.get(d,
+            month.getSelectedItem().toString()));
+        setPrimaryInvalid(lDay);
+        setPrimaryInvalid(lMonth);
+      }
+      else if (date.before(new Date()))
+      {
+        errorMessages.add(ERR_CTRL_PANEL_DATE_ALREADY_PASSED.get());
+        setPrimaryInvalid(lTime);
+        setPrimaryInvalid(lDay);
+        setPrimaryInvalid(lMonth);
+        setPrimaryInvalid(lYear);
+      }
+    }
+  }
+
+  /**
+   * Checks the validity of the launch daily information and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateLaunchDailyErrorMessages(Collection<Message> errorMessages)
+  {
+    setPrimaryValid(lDailyTime);
+
+    int[] h = {-1};
+    int[] min = {-1};
+    checkTime(dailyTime, lDailyTime, h, min, errorMessages);
+  }
+
+  /**
+   * Checks the validity of the launch weekly information and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateLaunchWeeklyErrorMessages(
+      Collection<Message> errorMessages)
+  {
+    setPrimaryValid(lWeeklyTime);
+    setPrimaryValid(lWeeklyDays);
+
+    int[] h = {-1};
+    int[] min = {-1};
+    checkTime(weeklyTime, lWeeklyTime, h, min, errorMessages);
+
+    boolean oneSelected = false;
+    for (JCheckBox cb : weekDays)
+    {
+      if (cb.isSelected())
+      {
+        oneSelected = true;
+        break;
+      }
+    }
+    if (!oneSelected)
+    {
+      errorMessages.add(ERR_CTRL_PANEL_NO_WEEK_DAY_SELECTED.get());
+      setPrimaryInvalid(lWeeklyDays);
+    }
+  }
+
+  /**
+   * Checks the validity of the launch monthly information and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateLaunchMonthlyErrorMessages(
+      Collection<Message> errorMessages)
+  {
+    setPrimaryValid(lMonthlyTime);
+    setPrimaryValid(lMonthlyDays);
+
+    int[] h = {-1};
+    int[] min = {-1};
+    checkTime(monthlyTime, lMonthlyTime, h, min, errorMessages);
+
+    boolean oneSelected = false;
+    for (JCheckBox cb : monthDays)
+    {
+      if (cb.isSelected())
+      {
+        oneSelected = true;
+        break;
+      }
+    }
+    if (!oneSelected)
+    {
+      errorMessages.add(ERR_CTRL_PANEL_NO_MONTH_DAY_SELECTED.get());
+      setPrimaryInvalid(lMonthlyDays);
+    }
+  }
+
+  /**
+   * Checks the validity of the cron schedule information and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateCronErrorMessages(Collection<Message> errorMessages)
+  {
+    setPrimaryValid(lCronMinute);
+    setPrimaryValid(lCronHour);
+    setPrimaryValid(lCronMonthDay);
+    setPrimaryValid(lCronMonth);
+    setPrimaryValid(lCronWeekDay);
+
+    String minute = cronMinute.getText().trim();
+    String hour = cronHour.getText().trim();
+    String monthDay = cronMonthDay.getText().trim();
+    String month = cronMonth.getText().trim();
+    String weekDay = cronWeekDay.getText().trim();
+
+    updateCronErrorMessages(minute, lCronMinute,
+        ERR_CTRL_PANEL_NO_CRON_MINUTE_PROVIDED.get(),
+        ERR_CTRL_PANEL_NOT_VALID_CRON_MINUTE_PROVIDED.get(),
+        0, 59,
+        errorMessages);
+    updateCronErrorMessages(hour, lCronHour,
+        ERR_CTRL_PANEL_NO_CRON_HOUR_PROVIDED.get(),
+        ERR_CTRL_PANEL_NOT_VALID_CRON_HOUR_PROVIDED.get(),
+        0, 23,
+        errorMessages);
+    updateCronErrorMessages(weekDay, lCronWeekDay,
+        ERR_CTRL_PANEL_NO_CRON_WEEK_DAY_PROVIDED.get(),
+        ERR_CTRL_PANEL_NOT_VALID_CRON_WEEK_DAY_PROVIDED.get(),
+        0, 6,
+        errorMessages);
+    updateCronErrorMessages(monthDay, lCronMonthDay,
+        ERR_CTRL_PANEL_NO_CRON_MONTH_DAY_PROVIDED.get(),
+        ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_DAY_PROVIDED.get(),
+        1, 31,
+        errorMessages);
+    updateCronErrorMessages(month, lCronMonth,
+        ERR_CTRL_PANEL_NO_CRON_MONTH_PROVIDED.get(),
+        ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_PROVIDED.get(),
+        1, 12,
+        errorMessages);
+  }
+
+  /**
+   * Checks the validity of the cron schedule information tab and updates
+   * the provided collection of messages with the errors that have been found.
+   * The associated labels are also updated.
+   * @param value the value of the cron schedule tab.
+   * @param label the label associated with the cron schedule tab.
+   * @param errorIfEmpty the message to be displayed if the value tab is empty.
+   * @param contentError the message to be displayed if the value tab is not
+   * valid.
+   * @param minValue the minimum value accepted.
+   * @param maxValue the maximum value accepted.
+   * @param errorMessages the collection of messages to be updated.
+   */
+  private void updateCronErrorMessages(String value, JLabel label,
+      Message errorIfEmpty, Message contentError, int minValue, int maxValue,
+      Collection<Message> errorMessages)
+  {
+    if (value.length() == 0)
+    {
+      errorMessages.add(errorIfEmpty);
+      setPrimaryInvalid(label);
+    }
+    else
+    {
+      try
+      {
+        RecurringTask.parseTaskTabField(value, minValue, maxValue);
+      }
+      catch (Exception ex)
+      {
+        errorMessages.add(contentError);
+        setPrimaryInvalid(label);
+      }
+    }
+  }
+
+  /**
+   * Returns the schedule type corresponding to the input provided by user.
+   * This method assumes that all the date provided by the user has been
+   * validated.
+   * @return the schedule type corresponding to the input provided by user.
+   */
+  private ScheduleType createSchedule()
+  {
+    ScheduleType schedule;
+    Object type =
+      ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue();
+    if (type == LAUNCH_NOW)
+    {
+      schedule = ScheduleType.createLaunchNow();
+    }
+    else if (type == LAUNCH_LATER)
+    {
+      int y = Integer.parseInt(year.getSelectedItem().toString());
+      int d = Integer.parseInt(day.getText().trim());
+      int m = month.getSelectedIndex();
+      String sTime = time.getText().trim();
+      int index = sTime.indexOf(':');
+      int h = Integer.parseInt(sTime.substring(0, index).trim());
+      int min = Integer.parseInt(sTime.substring(index+1).trim());
+      GregorianCalendar calendar = new GregorianCalendar(y, m, d, h, min);
+      schedule = ScheduleType.createLaunchLater(calendar.getTime());
+    }
+    else if (type == LAUNCH_DAILY)
+    {
+      String sTime = dailyTime.getText().trim();
+      int index = sTime.indexOf(':');
+      int h = Integer.parseInt(sTime.substring(0, index).trim());
+      int m = Integer.parseInt(sTime.substring(index+1).trim());
+      String cron = m+" "+h+" * * *";
+      schedule = ScheduleType.createCron(cron);
+    }
+    else if (type == LAUNCH_WEEKLY)
+    {
+      String sTime = weeklyTime.getText().trim();
+      int index = sTime.indexOf(':');
+      int h = Integer.parseInt(sTime.substring(0, index).trim());
+      int m = Integer.parseInt(sTime.substring(index+1).trim());
+      StringBuilder sb = new StringBuilder();
+      sb.append(m+" "+h+" * * ");
+
+      boolean oneDayAdded = false;
+      for (int i=0; i<weekDays.length; i++)
+      {
+        if (weekDays[i].isSelected())
+        {
+          if (oneDayAdded)
+          {
+            sb.append(',');
+          }
+          sb.append(i);
+          oneDayAdded = true;
+        }
+      }
+      schedule = ScheduleType.createCron(sb.toString());
+    }
+    else if (type == LAUNCH_MONTHLY)
+    {
+      String sTime = monthlyTime.getText().trim();
+      int index = sTime.indexOf(':');
+      int h = Integer.parseInt(sTime.substring(0, index).trim());
+      int m = Integer.parseInt(sTime.substring(index+1).trim());
+      StringBuilder sb = new StringBuilder();
+      sb.append(m+" "+h+" ");
+      boolean oneDayAdded = false;
+      for (int i=0; i<monthDays.length; i++)
+      {
+        if (monthDays[i].isSelected())
+        {
+          if (oneDayAdded)
+          {
+            sb.append(',');
+          }
+          sb.append(i+1);
+          oneDayAdded = true;
+        }
+      }
+      sb.append(" * *");
+      schedule = ScheduleType.createCron(sb.toString());
+    }
+    else if (type == CRON)
+    {
+      String cron = cronMinute.getText().trim() + " "+
+      cronHour.getText().trim() + " "+
+      cronMonthDay.getText().trim() + " "+
+      cronMonth.getText().trim() + " "+
+      cronWeekDay.getText().trim();
+      schedule = ScheduleType.createCron(cron);
+    }
+    else
+    {
+      throw new IllegalStateException("Unknown schedule type: "+type);
+    }
+    return schedule;
+  }
+
+  /**
+   * Convenience method to retrieve the time specified by the user.
+   * @param time the text field where the user specifies time.
+   * @param lTime the label associated with the text field.
+   * @param h an integer array of size 1 where the value of the hour specified
+   * by the user will be set.
+   * @param m an integer array of size 1 where the value of the minute specified
+   * by the user will be set.
+   * @param errorMessages the collection of error messages that will be updated
+   * with the encountered problems.
+   */
+  private void checkTime(JTextField time, JLabel lTime, int[] h, int[] m,
+      Collection<Message> errorMessages)
+  {
+    String sTime = time.getText().trim();
+    int index = sTime.indexOf(':');
+    try
+    {
+      h[0] = Integer.parseInt(sTime.substring(0, index).trim());
+      m[0] = Integer.parseInt(sTime.substring(index+1).trim());
+      if (h[0] < 0 || h[0] > 23)
+      {
+        errorMessages.add(ERR_CTRL_PANEL_INVALID_HOUR.get());
+        setPrimaryInvalid(lTime);
+      }
+      if (m[0] < 0 || m[0] > 59)
+      {
+        errorMessages.add(ERR_CTRL_PANEL_INVALID_MINUTE.get());
+        setPrimaryInvalid(lTime);
+      }
+    }
+    catch (Exception ex)
+    {
+      errorMessages.add(ERR_CTRL_PANEL_INVALID_TIME.get());
+      setPrimaryInvalid(lTime);
+    }
+  }
+
+  /**
+   * Tells whether the user chose to close the dialog discarding the provided
+   * input.
+   * @return <CODE>true</CODE> if the user chose to close the dialog discarding
+   * the provided input and <CODE>false</CODE> otherwise.
+   */
+  public boolean isCancelled()
+  {
+    return schedule == null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void configurationChanged(ConfigurationChangeEvent ev)
+  {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Component getPreferredFocusComponent()
+  {
+    return scheduleType;
+  }
+
+  /**
+   * Returns the schedule provided by the user.
+   * @return the schedule provided by the user.
+   */
+  public ScheduleType getSchedule()
+  {
+    return schedule;
+  }
+
+  private Component createLaunchLaterPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+    Calendar calendar = Calendar.getInstance();
+
+    int currentYear = calendar.get(Calendar.YEAR);
+    int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
+    int currentMinute = calendar.get(Calendar.MINUTE);
+    int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
+    int currentMonth = calendar.get(Calendar.MONTH);
+
+    time = Utilities.createShortTextField();
+    PlainDocument plainTextDocument = new PlainDocument();
+    time.setDocument(plainTextDocument);
+    String sHour = currentHour >= 10 ?
+        String.valueOf(currentHour) : "0"+currentHour;
+    String sMinute = currentMinute >= 10 ?
+        String.valueOf(currentMinute) : "0"+currentMinute;
+    time.setText(sHour+":"+sMinute);
+    plainTextDocument.setDocumentFilter(new TimeDocumentFilter(time));
+
+
+    day = Utilities.createShortTextField();
+    day.setColumns(4);
+    plainTextDocument = new PlainDocument();
+    day.setDocument(plainTextDocument);
+    day.setText(String.valueOf(currentDay));
+    plainTextDocument.setDocumentFilter(
+        new NumericLimitedSizeDocumentFilter(day, 2));
+    month = Utilities.createComboBox();
+    year = Utilities.createComboBox();
+
+    int[][] maxMin =
+    {
+        {currentYear, currentYear + 5}
+    };
+
+    JComboBox[] numericBoxes =
+    {
+        year
+    };
+
+    int[] currentValues =
+    {
+        currentYear
+    };
+
+    for (int i=0; i<maxMin.length; i++)
+    {
+      int min = maxMin[i][0];
+      int max = maxMin[i][1];
+
+      DefaultComboBoxModel model = new DefaultComboBoxModel();
+
+      int selectedIndex = 0;
+
+      int index = 0;
+      for (int j=min; j<=max; j++)
+      {
+        String s;
+        if (j < 10)
+        {
+          s = "0"+j;
+        }
+        else
+        {
+          s = String.valueOf(j);
+        }
+        model.addElement(s);
+
+        if (j == currentValues[i])
+        {
+          selectedIndex= index;
+        }
+        index++;
+      }
+
+      numericBoxes[i].setModel(model);
+
+      if (selectedIndex != 0)
+      {
+        numericBoxes[i].setSelectedIndex(selectedIndex);
+      }
+    }
+
+    DefaultComboBoxModel model = new DefaultComboBoxModel();
+    month.setModel(model);
+
+    Message[] monthMessages =
+    {
+        INFO_CTRL_PANEL_JANUARY.get(),
+        INFO_CTRL_PANEL_FEBRUARY.get(),
+        INFO_CTRL_PANEL_MARS.get(),
+        INFO_CTRL_PANEL_APRIL.get(),
+        INFO_CTRL_PANEL_MAY.get(),
+        INFO_CTRL_PANEL_JUNE.get(),
+        INFO_CTRL_PANEL_JULY.get(),
+        INFO_CTRL_PANEL_AUGUST.get(),
+        INFO_CTRL_PANEL_SEPTEMBER.get(),
+        INFO_CTRL_PANEL_OCTOBER.get(),
+        INFO_CTRL_PANEL_NOVEMBER.get(),
+        INFO_CTRL_PANEL_DECEMBER.get(),
+    };
+    for (Message msg : monthMessages)
+    {
+      model.addElement(msg.toString());
+    }
+
+    month.setSelectedIndex(currentMonth);
+
+    lTime = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get());
+    lDay = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAY.get());
+    lMonth = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTH.get());
+    lYear = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_YEAR.get());
+
+    gbc.gridy = 0;
+
+    JLabel[] labels = {lTime, lDay, lMonth, lYear};
+    Component[] comps = {time, day, month, year};
+
+    gbc.gridwidth = 1;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+
+    for (int i=0; i<labels.length; i++)
+    {
+      gbc.gridx = 0;
+      gbc.weightx = 0.0;
+
+      panel.add(labels[i], gbc);
+      gbc.gridx = 1;
+      gbc.insets.left = 10;
+      panel.add(comps[i], gbc);
+      gbc.gridx = 2;
+      gbc.weightx = 1.0;
+      gbc.insets.left = 0;
+      panel.add(Box.createHorizontalGlue(), gbc);
+
+      gbc.insets.top = 10;
+      gbc.gridy ++;
+    }
+
+    gbc.insets.top = 0;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.VERTICAL;
+    panel.add(Box.createVerticalGlue(), gbc);
+
+    return panel;
+  }
+
+  private Component createDailyPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.weightx = 0.0;
+
+    lDailyTime =
+      Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get());
+
+    dailyTime = Utilities.createShortTextField();
+    PlainDocument plainTextDocument = new PlainDocument();
+    dailyTime.setDocument(plainTextDocument);
+    dailyTime.setColumns(4);
+    dailyTime.setText("00:00");
+    plainTextDocument.setDocumentFilter(new TimeDocumentFilter(dailyTime));
+
+    panel.add(lDailyTime, gbc);
+    gbc.gridx = 1;
+    gbc.insets.left = 10;
+    gbc.fill = GridBagConstraints.NONE;
+    panel.add(dailyTime, gbc);
+    gbc.gridx = 2;
+    gbc.weightx = 1.0;
+    gbc.insets.left = 0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    panel.add(Box.createHorizontalGlue(), gbc);
+
+    return panel;
+  }
+
+  private Component createWeeklyPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.weightx = 0.0;
+
+    lWeeklyTime =
+      Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get());
+
+    weeklyTime = Utilities.createShortTextField();
+    PlainDocument plainTextDocument = new PlainDocument();
+    weeklyTime.setDocument(plainTextDocument);
+    weeklyTime.setColumns(4);
+    weeklyTime.setText("00:00");
+    plainTextDocument.setDocumentFilter(new TimeDocumentFilter(weeklyTime));
+
+    lWeeklyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get());
+    for (JCheckBox cb : weekDays)
+    {
+      cb.setFont(ColorAndFontConstants.inlineHelpFont);
+    }
+    sunday.setSelected(true);
+    wednesday.setSelected(true);
+
+    gbc.anchor = GridBagConstraints.WEST;
+    panel.add(lWeeklyTime, gbc);
+    gbc.gridx = 1;
+    gbc.insets.left = 10;
+    gbc.gridwidth = weekDays.length;
+    gbc.fill = GridBagConstraints.NONE;
+    panel.add(weeklyTime, gbc);
+    gbc.gridx = 2;
+    gbc.weightx = 1.0;
+    gbc.insets.left = 0;
+    gbc.gridwidth = 1;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    panel.add(Box.createHorizontalGlue(), gbc);
+
+    gbc.gridx = 0;
+    gbc.gridy ++;
+    gbc.insets.top = 10;
+    gbc.weightx = 1.0;
+    panel.add(lWeeklyDays, gbc);
+    gbc.insets.left = 10;
+    gbc.gridwidth = 1;
+    for (JCheckBox cb : weekDays)
+    {
+      gbc.gridx ++;
+      panel.add(cb, gbc);
+    }
+    gbc.weightx = 1.0;
+    gbc.insets.left = 0;
+    gbc.gridwidth = 1;
+    gbc.gridx ++;
+    panel.add(Box.createHorizontalGlue(), gbc);
+
+    return panel;
+  }
+
+  private Component createMonthlyPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.weightx = 0.0;
+
+    lMonthlyTime =
+      Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get());
+
+    monthlyTime = Utilities.createShortTextField();
+    PlainDocument plainTextDocument = new PlainDocument();
+    monthlyTime.setDocument(plainTextDocument);
+    monthlyTime.setColumns(4);
+    monthlyTime.setText("00:00");
+    plainTextDocument.setDocumentFilter(new TimeDocumentFilter(monthlyTime));
+
+    lMonthlyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get());
+
+    gbc.anchor = GridBagConstraints.WEST;
+    panel.add(lMonthlyTime, gbc);
+    gbc.gridx = 1;
+    gbc.insets.left = 10;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.gridwidth = 7;
+    panel.add(monthlyTime, gbc);
+    gbc.gridx = 2;
+    gbc.weightx = 1.0;
+    gbc.insets.left = 0;
+    gbc.gridwidth = 1;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    panel.add(Box.createHorizontalGlue(), gbc);
+
+    gbc.gridx = 0;
+    gbc.gridy ++;
+    gbc.insets.top = 10;
+    gbc.weightx = 1.0;
+    gbc.gridwidth = 1;
+    panel.add(lMonthlyDays, gbc);
+    gbc.insets.left = 10;
+    gbc.gridwidth = 1;
+    for (int i=0 ; i<monthDays.length; i++)
+    {
+      monthDays[i] = Utilities.createCheckBox(Message.raw(String.valueOf(i+1)));
+      monthDays[i].setFont(ColorAndFontConstants.inlineHelpFont);
+      int x = i % 7;
+      if (x == 0 && i != 0)
+      {
+        gbc.gridy ++;
+        gbc.insets.top = 5;
+      }
+      if (x != 0)
+      {
+        gbc.insets.left = 5;
+      }
+      else
+      {
+        gbc.insets.left = 10;
+      }
+      gbc.gridx = x + 1;
+      panel.add(monthDays[i], gbc);
+    }
+    monthDays[0].setSelected(true);
+    gbc.weightx = 1.0;
+    gbc.insets.left = 0;
+    gbc.gridwidth = 1;
+    gbc.gridx ++;
+    panel.add(Box.createHorizontalGlue(), gbc);
+
+    return panel;
+  }
+
+  private Component createCronPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+    GridBagConstraints gbc = new GridBagConstraints();
+
+    JEditorPane explanation = Utilities.makeHtmlPane(
+        INFO_CTRL_PANEL_CRON_HELP.get().toString(),
+        ColorAndFontConstants.inlineHelpFont);
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.gridwidth = 2;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    panel.add(explanation, gbc);
+    gbc.gridy ++;
+    gbc.insets.top = 10;
+
+    gbc.gridwidth = 1;
+    lCronMinute = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MINUTE.get());
+    lCronHour = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_HOUR.get());
+    lCronWeekDay = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_WEEK_DAY.get());
+    lCronMonthDay = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH_DAY.get());
+    lCronMonth = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH.get());
+
+    cronMinute = Utilities.createShortTextField();
+    cronMinute.setText("*");
+
+    cronHour = Utilities.createShortTextField();
+    cronHour.setText("*");
+
+    cronWeekDay = Utilities.createShortTextField();
+    cronWeekDay.setText("*");
+
+    cronMonthDay = Utilities.createShortTextField();
+    cronMonthDay.setText("*");
+
+    cronMonth = Utilities.createShortTextField();
+    cronMonth.setText("*");
+
+    JLabel[] labels = {lCronMinute, lCronHour, lCronWeekDay, lCronMonthDay,
+        lCronMonth};
+    Component[] comps = {cronMinute, cronHour, cronWeekDay, cronMonthDay,
+        cronMonth};
+    Message[] help =
+    {
+      INFO_CTRL_PANEL_CRON_MINUTE_HELP.get(),
+      INFO_CTRL_PANEL_CRON_HOUR_HELP.get(),
+      INFO_CTRL_PANEL_CRON_WEEK_DAY_HELP.get(),
+      INFO_CTRL_PANEL_CRON_MONTH_DAY_HELP.get(),
+      INFO_CTRL_PANEL_CRON_MONTH_HELP.get(),
+    };
+
+    gbc.gridwidth = 1;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+
+    for (int i=0; i<labels.length; i++)
+    {
+      gbc.gridx = 0;
+      gbc.weightx = 0.0;
+
+      gbc.insets.left = 0;
+      panel.add(labels[i], gbc);
+      gbc.gridx = 1;
+      gbc.insets.left = 10;
+      panel.add(comps[i], gbc);
+      gbc.gridx = 2;
+      gbc.weightx = 1.0;
+      gbc.insets.left = 0;
+      panel.add(Box.createHorizontalGlue(), gbc);
+      if (help[i] != null)
+      {
+        gbc.insets.top = 3;
+        gbc.insets.left = 10;
+        gbc.gridy ++;
+        gbc.gridx = 1;
+        panel.add(Utilities.createInlineHelpLabel(help[i]), gbc);
+      }
+
+      gbc.insets.top = 10;
+      gbc.gridy ++;
+    }
+
+    gbc.insets.top = 0;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.VERTICAL;
+    panel.add(Box.createVerticalGlue(), gbc);
+
+    return panel;
+  }
+
+  /**
+   * The main method to test this panel.
+   * @param args the arguments.
+   */
+  public static void main(String[] args)
+  {
+    while (true)
+    {
+      TaskToSchedulePanel p = new TaskToSchedulePanel("TEST TASK");
+      GenericDialog dlg = new GenericDialog(new JFrame(), p);
+      dlg.setModal(true);
+      dlg.setVisible(true);
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/NumericLimitedSizeDocumentFilter.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/NumericLimitedSizeDocumentFilter.java
new file mode 100644
index 0000000..0111c84
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/NumericLimitedSizeDocumentFilter.java
@@ -0,0 +1,116 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.ui.components;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DocumentFilter;
+import javax.swing.text.JTextComponent;
+
+/**
+ * Document filter used to update properly a text component displaying a
+ * numeric field with a limited size.
+ */
+public class NumericLimitedSizeDocumentFilter extends DocumentFilter
+{
+  private JTextComponent tf;
+  private int maxSize;
+
+  /**
+   * Constructor.
+   * @param tf the text component associated with the document.
+   * @param maxSize the maximum size.
+   */
+  public NumericLimitedSizeDocumentFilter(JTextComponent tf, int maxSize)
+  {
+    this.tf = tf;
+    this.maxSize = maxSize;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void insertString(DocumentFilter.FilterBypass fb, int offset,
+      String text, AttributeSet attr)
+  throws BadLocationException
+  {
+    int previousLength = fb.getDocument().getLength();
+    String newText = text.replaceAll("[^0-9]", "");
+    if (newText.length() > maxSize)
+    {
+      newText = newText.substring(0, maxSize);
+    }
+    if (newText.length() + previousLength > maxSize)
+    {
+      if (offset + newText.length() > maxSize)
+      {
+        int newOffset = offset + newText.length() - maxSize;
+        fb.remove(0, newOffset);
+        fb.insertString(newOffset, newText, attr);
+      }
+      else
+      {
+        fb.insertString(offset, newText, attr);
+        fb.remove(maxSize, newText.length() + previousLength - maxSize);
+      }
+    }
+    else
+    {
+      fb.insertString(offset, newText, attr);
+    }
+    updateCaretPosition(fb);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void replace(DocumentFilter.FilterBypass fb, int offset,
+      int length, String text, AttributeSet attr)
+  throws BadLocationException
+  {
+    if (length > 0)
+    {
+      fb.remove(offset, length);
+    }
+
+    insertString(fb, offset, text, attr);
+  }
+
+  private void updateCaretPosition(DocumentFilter.FilterBypass fb)
+  throws BadLocationException
+  {
+    int totalLength = fb.getDocument().getLength();
+
+    int caretPosition = tf.getCaretPosition();
+
+    if ((totalLength >= maxSize) &&
+        (caretPosition == fb.getDocument().getLength()))
+    {
+      tf.setCaretPosition(0);
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/ScheduleSummaryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/ScheduleSummaryPanel.java
new file mode 100644
index 0000000..b5116c1
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/ScheduleSummaryPanel.java
@@ -0,0 +1,182 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.ui.components;
+
+import static org.opends.messages.AdminToolMessages.*;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.DateFormat;
+import java.util.Date;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.opends.guitools.controlpanel.datamodel.ScheduleType;
+import org.opends.guitools.controlpanel.ui.GenericDialog;
+import org.opends.guitools.controlpanel.ui.TaskToSchedulePanel;
+import org.opends.guitools.controlpanel.util.Utilities;
+
+/**
+ * A class used as component displaying the string representation of a schedule
+ * and the possibility of updating it clicking a button.
+ */
+public class ScheduleSummaryPanel extends JPanel
+{
+  private static final long serialVersionUID = 3111141404599060028L;
+  private ScheduleType schedule = ScheduleType.createLaunchNow();
+  private JLabel label;
+  private JButton change;
+  private TaskToSchedulePanel schedulePanel;
+  private GenericDialog scheduleDlg;
+  private String taskName;
+  private DateFormat formatter =
+    DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
+
+  /**
+   * Default constructor.
+   * @param taskName the name of the task to be scheduled.
+   */
+  public ScheduleSummaryPanel(String taskName)
+  {
+    super(new GridBagLayout());
+    setOpaque(false);
+    this.taskName = taskName;
+    createLayout();
+  }
+
+  /**
+   * Returns the schedule represented by this panel.
+   * @return the schedule represented by this panel.
+   */
+  public ScheduleType getSchedule()
+  {
+    return schedule;
+  }
+
+  /**
+   * Sets the schedule represented by this panel.
+   * @param schedule the schedule represented by this panel.
+   */
+  public void setSchedule(ScheduleType schedule)
+  {
+    this.schedule = schedule;
+    updateLabel(schedule);
+  }
+
+  /**
+   * Returns whether the change button is enabled or not.
+   * @return <CODE>true</CODE> if the change button is enabled and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean isChangeEnabled()
+  {
+    return change.isEnabled();
+  }
+
+  /**
+   * Sets the enable state of the change button.
+   * @param enable whether the change button must be enabled or not.
+   */
+  public void setChangeEnabled(boolean enable)
+  {
+    change.setEnabled(enable);
+  }
+
+  private void createLayout()
+  {
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    label = Utilities.createDefaultLabel();
+    change = Utilities.createButton(INFO_CTRL_PANEL_CHANGE_SCHEDULE.get());
+    change.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        changeButtonClicked();
+      }
+    });
+    updateLabel(schedule);
+
+    gbc.fill = GridBagConstraints.NONE;
+    add(label, gbc);
+    gbc.gridx ++;
+    gbc.insets.left = 10;
+    add(change, gbc);
+    gbc.gridx ++;
+    gbc.weightx = 1.0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.insets.left = 0;
+    add(Box.createHorizontalGlue(), gbc);
+  }
+
+  private void updateLabel(ScheduleType schedule)
+  {
+    ScheduleType.Type type = schedule.getType();
+    if (type == ScheduleType.Type.LAUNCH_NOW)
+    {
+      label.setText(INFO_CTRL_PANEL_LAUNCH_NOW_SUMMARY.get().toString());
+    }
+    else if (type == ScheduleType.Type.LAUNCH_LATER)
+    {
+      Date date = schedule.getLaunchLaterDate();
+      String sDate = formatter.format(date);
+      label.setText(INFO_CTRL_PANEL_LAUNCH_LATER_SUMMARY.get(sDate).toString());
+    }
+    else if (type == ScheduleType.Type.LAUNCH_PERIODICALLY)
+    {
+      String cron = schedule.getCronValue();
+      label.setText(
+          INFO_CTRL_PANEL_LAUNCH_PERIODICALLY_SUMMARY.get(cron).toString());
+    }
+    else
+    {
+      throw new IllegalStateException("Unknown schedule type: "+type);
+    }
+  }
+
+  private void changeButtonClicked()
+  {
+    if (schedulePanel == null)
+    {
+      schedulePanel = new TaskToSchedulePanel(taskName);
+      scheduleDlg = new GenericDialog(Utilities.getFrame(this), schedulePanel);
+      Utilities.centerGoldenMean(scheduleDlg, Utilities.getParentDialog(this));
+      scheduleDlg.setModal(true);
+    }
+    scheduleDlg.setVisible(true);
+    if (!schedulePanel.isCancelled())
+    {
+      setSchedule(schedulePanel.getSchedule());
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/TimeDocumentFilter.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/TimeDocumentFilter.java
new file mode 100644
index 0000000..3481373
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/components/TimeDocumentFilter.java
@@ -0,0 +1,198 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.ui.components;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DocumentFilter;
+import javax.swing.text.JTextComponent;
+
+/**
+ * Document filter used to update properly a text component displaying a
+ * time.
+ */
+public class TimeDocumentFilter extends DocumentFilter
+{
+  private JTextComponent tf;
+
+  /**
+   * Constructor.
+   * @param tf the text component associated with the document.
+   */
+  public TimeDocumentFilter(JTextComponent tf)
+  {
+    this.tf = tf;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void insertString(DocumentFilter.FilterBypass fb, int offset,
+      String text, AttributeSet attr)
+  throws BadLocationException
+  {
+    int previousLength = fb.getDocument().getLength();
+    fb.insertString(offset, text.replaceAll("[^0-9]", ""), attr);
+    trimPosition(fb, text, offset, previousLength);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void remove(DocumentFilter.FilterBypass fb, int offset,
+      int length)
+  throws BadLocationException
+  {
+    String text = fb.getDocument().getText(offset, length);
+    int index = text.indexOf(":");
+    if (index == -1)
+    {
+      fb.remove(offset, length);
+    }
+    else
+    {
+      // index value is relative to offset
+      if (index > 0)
+      {
+        fb.remove(offset, index);
+      }
+      if (index < length - 1)
+      {
+        fb.remove(offset + index + 1, length - index -1);
+      }
+    }
+    updateCaretPosition(fb);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void replace(DocumentFilter.FilterBypass fb, int offset,
+      int length, String text, AttributeSet attr)
+  throws BadLocationException
+  {
+    int previousLength = fb.getDocument().getLength();
+
+    String t = fb.getDocument().getText(offset, length);
+    int index = t.indexOf(":");
+    fb.replace(offset, length, text.replaceAll("[^0-9]", ""), attr);
+    if (index != -1)
+    {
+      if (fb.getDocument().getLength() >= 2)
+      {
+        fb.insertString(2, ":", attr);
+      }
+      else
+      {
+        fb.insertString(fb.getDocument().getLength(), ":", attr);
+      }
+    }
+
+    trimPosition(fb, text, offset, previousLength);
+  }
+
+  private void trimPosition(DocumentFilter.FilterBypass fb, String newText,
+      int offset, int previousLength)
+  throws BadLocationException
+  {
+    String allText =
+      fb.getDocument().getText(0, fb.getDocument().getLength());
+    int index = allText.indexOf(':');
+    if ((index != -1) && (newText.length() == 1))
+    {
+      int minuteLength = allText.length() - index - 1;
+      int hourLength = index;
+
+      if ((minuteLength > 2) || (hourLength > 2))
+      {
+        if (offset < previousLength)
+        {
+          fb.remove(offset + 1, 1);
+        }
+        else
+        {
+          fb.remove(previousLength, 1);
+        }
+      }
+    }
+    updateCaretPosition(fb);
+  }
+
+  private void updateCaretPosition(DocumentFilter.FilterBypass fb)
+  throws BadLocationException
+  {
+    String allText =
+      fb.getDocument().getText(0, fb.getDocument().getLength());
+    int index = allText.indexOf(':');
+    if (index != -1)
+    {
+      int minuteLength = allText.length() - index - 1;
+      int hourLength = index;
+      int caretPosition = tf.getCaretPosition();
+
+      if ((minuteLength >= 2) &&
+          (caretPosition == allText.length()))
+      {
+        tf.setCaretPosition(0);
+      }
+      else if (hourLength == caretPosition)
+      {
+        if (hourLength >= 2)
+        {
+          tf.setCaretPosition(3);
+        }
+        else if (hourLength == 1)
+        {
+          char c = allText.charAt(0);
+          if (c != '0' && c != '1' && c != '2')
+          {
+            tf.setCaretPosition(2);
+          }
+        }
+      }
+      else if (hourLength + 1 == caretPosition)
+      {
+        if (hourLength == 1)
+        {
+          char c = allText.charAt(0);
+          if (c == '0' || c == '1' || c == '2')
+          {
+            tf.setCaretPosition(caretPosition - 1);
+          }
+        }
+        else if (hourLength == 0)
+        {
+          tf.setCaretPosition(caretPosition - 1);
+        }
+      }
+    }
+    if (allText.length() == 1)
+    {
+      tf.setCaretPosition(0);
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/NoLeftInsetCategoryComboBoxRenderer.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/NoLeftInsetCategoryComboBoxRenderer.java
new file mode 100644
index 0000000..bca6a96
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/NoLeftInsetCategoryComboBoxRenderer.java
@@ -0,0 +1,71 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.guitools.controlpanel.ui.renderer;
+
+import java.awt.Component;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+
+import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
+/**
+ *  This class is used simply to avoid an inset on the left for the
+ *  elements of the combo box.
+ *  Since this item is a CategorizedComboBoxElement of type
+ *  CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on
+ *  the left.
+ */
+public class NoLeftInsetCategoryComboBoxRenderer extends CustomListCellRenderer
+{
+  /**
+   * The constructor.
+   * @param combo the combo box to be rendered.
+   */
+  public NoLeftInsetCategoryComboBoxRenderer(JComboBox combo)
+  {
+    super(combo);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Component getListCellRendererComponent(JList list, Object value,
+      int index, boolean isSelected, boolean cellHasFocus)
+  {
+    Component comp = super.getListCellRendererComponent(list, value, index,
+        isSelected, cellHasFocus);
+    if (value instanceof CategorizedComboBoxElement)
+    {
+      CategorizedComboBoxElement element = (CategorizedComboBoxElement)value;
+      String name = getStringValue(element);
+      ((JLabel)comp).setText(name);
+    }
+    comp.setFont(defaultFont);
+    return comp;
+  }
+}
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/TaskCellRenderer.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/TaskCellRenderer.java
new file mode 100644
index 0000000..5575f51
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/TaskCellRenderer.java
@@ -0,0 +1,95 @@
+/*
+ * 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
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.controlpanel.ui.renderer;
+
+import java.awt.Component;
+
+import javax.swing.BorderFactory;
+import javax.swing.JTable;
+import javax.swing.border.Border;
+import javax.swing.table.DefaultTableCellRenderer;
+
+import org.opends.guitools.controlpanel.ui.ColorAndFontConstants;
+
+/**
+ * Class used to render the task tables.
+ */
+public class TaskCellRenderer extends DefaultTableCellRenderer
+{
+  private static final long serialVersionUID = -84332267021523835L;
+  /**
+   * The border of the first column.
+   * TODO: modify CustomCellRenderer to make this public.
+   */
+  protected final static Border column0Border =
+    BorderFactory.createCompoundBorder(
+      BorderFactory.createMatteBorder(0, 1, 0, 0,
+          ColorAndFontConstants.gridColor),
+          BorderFactory.createEmptyBorder(4, 4, 4, 4));
+  /**
+   * The default border.
+   */
+  public final static Border defaultBorder = CustomCellRenderer.defaultBorder;
+
+  /**
+   * Default constructor.
+   */
+  public TaskCellRenderer()
+  {
+    setFont(ColorAndFontConstants.tableFont);
+    setOpaque(true);
+    setBackground(ColorAndFontConstants.treeBackground);
+    setForeground(ColorAndFontConstants.treeForeground);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Component getTableCellRendererComponent(JTable table, Object value,
+      boolean isSelected, boolean hasFocus, int row, int column) {
+    super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+        row, column);
+
+    if (hasFocus)
+    {
+      setBorder(
+          CustomCellRenderer.getDefaultFocusBorder(table, value, isSelected,
+              row, column));
+    }
+    else if (column == 0)
+    {
+      setBorder(column0Border);
+    }
+    else
+    {
+      setBorder(defaultBorder);
+    }
+    return this;
+  }
+}
+
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java
index 7f6e720..9782bf1 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java
@@ -33,6 +33,7 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -67,7 +68,9 @@
 import org.opends.server.admin.client.ldap.LDAPManagementContext;
 import org.opends.server.admin.std.client.*;
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType;
+import org.opends.server.config.ConfigConstants;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.tools.tasks.TaskEntry;
 import org.opends.server.types.DN;
 import org.opends.server.types.OpenDsException;
 import org.opends.server.util.ServerConstants;
@@ -238,6 +241,7 @@
       new HashSet<ConnectionHandlerDescriptor>();
     Set<BackendDescriptor> bs = new HashSet<BackendDescriptor>();
     Set<DN> as = new HashSet<DN>();
+    Set<TaskEntry> ts = new HashSet<TaskEntry>();
 
     rootMonitor = null;
     jvmMemoryUsage = null;
@@ -528,11 +532,23 @@
     }
     catch (Throwable t)
     {
-      LOG.log(Level.WARNING, "Error reading configuration: "+t, t);
+      LOG.log(Level.WARNING, "Error reading monitoring: "+t, t);
       OnlineUpdateException oupe = new OnlineUpdateException(
           ERR_READING_CONFIG_LDAP.get(t.toString()), t);
       ex.add(oupe);
     }
+    try
+    {
+      updateTaskInformation(ctx, ex, ts);
+    }
+    catch (Throwable t)
+    {
+      LOG.log(Level.WARNING, "Error reading task information: "+t, t);
+      OnlineUpdateException oupe = new OnlineUpdateException(
+          ERR_READING_CONFIG_LDAP.get(t.toString()), t);
+      ex.add(oupe);
+    }
+    taskEntries = Collections.unmodifiableSet(ts);
     for (ConnectionHandlerDescriptor ch : getConnectionHandlers())
     {
       ch.setMonitoringEntries(getMonitoringEntries(ch));
@@ -762,6 +778,33 @@
     }
   }
 
+  /**
+   * Takes the provided search result and updates the task information
+   * accordingly.
+   * @param sr the search result.
+   * @param searchBaseDN the base search.
+   * @param taskEntries the collection of TaskEntries to be updated.
+   * @throws NamingException if there is an error retrieving the values of the
+   * search result.
+   */
+  protected void handleTaskSearchResult(SearchResult sr, String searchBaseDN,
+      Collection<TaskEntry> taskEntries)
+  throws NamingException
+  {
+    CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN);
+    try
+    {
+      if (isTaskEntry(csr))
+      {
+        taskEntries.add(new TaskEntry(csr.getEntry()));
+      }
+    }
+    catch (OpenDsException ode)
+    {
+      exceptions.add(ode);
+    }
+  }
+
   private void updateMonitorInformation(InitialLdapContext ctx,
       List<OpenDsException> ex)
   {
@@ -796,6 +839,37 @@
     }
   }
 
+  private void updateTaskInformation(InitialLdapContext ctx,
+      List<OpenDsException> ex, Collection<TaskEntry> ts)
+  {
+    // Read monitoring information: since it is computed, it is faster
+    // to get everything in just one request.
+    SearchControls ctls = new SearchControls();
+    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+    ctls.setReturningAttributes(
+        getMonitoringAttributes());
+    String filter = "(objectclass=ds-task)";
+
+    try
+    {
+      LdapName jndiName = new LdapName(ConfigConstants.DN_TASK_ROOT);
+
+      NamingEnumeration taskEntries = ctx.search(jndiName, filter, ctls);
+
+      while (taskEntries.hasMore())
+      {
+        SearchResult sr = (SearchResult)taskEntries.next();
+        handleTaskSearchResult(sr, ConfigConstants.DN_TASK_ROOT, ts);
+      }
+    }
+    catch (NamingException ne)
+    {
+      OnlineUpdateException oue = new OnlineUpdateException(
+          ERR_READING_CONFIG_LDAP.get(ne.getMessage().toString()), ne);
+      ex.add(oue);
+    }
+  }
+
   private ConnectionHandlerDescriptor getConnectionHandler(
       ConnectionHandlerCfgClient connHandler, String name)
   throws OpenDsException
@@ -962,6 +1036,24 @@
     return isConnectionHandler;
   }
 
+  private boolean isTaskEntry(CustomSearchResult csr) throws OpenDsException
+  {
+    boolean isTaskEntry = false;
+    Set<Object> vs = csr.getAttributeValues("objectclass");
+    if ((vs != null) && !vs.isEmpty())
+    {
+      for (Object oc : vs)
+      {
+        if (oc.toString().equalsIgnoreCase("ds-task"))
+        {
+          isTaskEntry = true;
+          break;
+        }
+      }
+    }
+    return isTaskEntry;
+  }
+
   /**
    * Commodity method to get the string representation to be used in the
    * hash maps as key.
@@ -977,11 +1069,33 @@
       ConnectionHandlerDescriptor ch)
   {
     Set<CustomSearchResult> monitorEntries = new HashSet<CustomSearchResult>();
-    for (String key : hmConnectionHandlersMonitor.keySet())
+    if (ch.getState() == ConnectionHandlerDescriptor.State.ENABLED)
     {
-      if (key.indexOf(getKey(ch.getName())) != -1)
+      for (String key : hmConnectionHandlersMonitor.keySet())
       {
-        monitorEntries.add(hmConnectionHandlersMonitor.get(key));
+        // The name of the connection handler does not appear necessarily in the
+        // key (which is based on the DN of the monitoring entry).  In general
+        // the DN contains the String specified in
+        // LDAPConnectionHandler.DEFAULT_FRIENDLY_NAME, so we have to check that
+        // this connection handler is the right one.
+        // See org.opends.server.protocols.ldap.LDAPConnectionHandler to see
+        // how the DN of the monitoring entry is generated.
+        if (key.indexOf(getKey("port "+ch.getPort())) != -1)
+        {
+          boolean hasAllAddresses = true;
+          for (InetAddress a : ch.getAddresses())
+          {
+            if (key.indexOf(getKey(a.getHostAddress())) == -1)
+            {
+              hasAllAddresses = false;
+              break;
+            }
+          }
+          if (hasAllAddresses)
+          {
+            monitorEntries.add(hmConnectionHandlersMonitor.get(key));
+          }
+        }
       }
     }
 
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java
index cd7c495..869ae93 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java
@@ -46,6 +46,7 @@
 import org.opends.server.admin.std.meta.AdministrationConnectorCfgDefn;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.tools.tasks.TaskEntry;
 import org.opends.server.types.DN;
 import org.opends.server.types.DirectoryEnvironmentConfig;
 import org.opends.server.types.DirectoryException;
@@ -166,6 +167,11 @@
   protected Schema schema;
 
   /**
+   * The task entries.
+   **/
+  protected Set<TaskEntry> taskEntries = Collections.emptySet();
+
+  /**
    * Returns the Administrative User DNs found in the config.ldif.  The set
    * must be unmodifiable (the inheriting classes must take care of this).
    * @return the Administrative User DNs found in the config.ldif.
@@ -280,6 +286,15 @@
   }
 
   /**
+   * Returns the task entries.
+   * @return the task entries.
+   */
+  public Set<TaskEntry> getTaskEntries()
+  {
+    return taskEntries;
+  }
+
+  /**
    * Reads the schema from the files.
    * @throws ConfigException if an error occurs reading the schema.
    * @throws InitializationException if an error occurs initializing
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java
index 4ad5131..4618842 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java
@@ -993,6 +993,12 @@
     }
     JEditorPane pane2 = makeHtmlPane(wrappedText, font);
     pane.setPreferredSize(pane2.getPreferredSize());
+    JFrame frame = getFrame(pane);
+    if ((frame != null) && frame.isVisible())
+    {
+      frame.getRootPane().revalidate();
+      frame.getRootPane().repaint();
+    }
   }
 
   /**
diff --git a/opendj-sdk/opends/src/messages/messages/admin_tool.properties b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
index 85abcc2..91dadeb 100644
--- a/opendj-sdk/opends/src/messages/messages/admin_tool.properties
+++ b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -1325,6 +1325,7 @@
 MILD_ERR_CTRL_PANEL_RUN_BACKUP_ERROR_SUMMARY=Error during Backup
 MILD_ERR_CTRL_PANEL_RUN_BACKUP_ERROR_DETAILS=An error occurred during the \
  backup.  Error code: %d.
+INFO_CTRL_PANEL_BACKUP_TASK_NAME=Backup
 
 INFO_CTRL_PANEL_OTHER_BASE_DN_TITLE=Other Base DN
 MILD_ERR_CTRL_PANEL_NO_BASE_DN_PROVIDED=You must provide a base DN.
@@ -2551,3 +2552,132 @@
 SEVERE_ERR_VERSION_IN_REMOTE_SERVER_NOT_FOUND=Could not find version \
  information in the remote server.  The remote LDAP server does not seem to be \
  manageable remotely by the control panel.
+
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TITLE='%s' Task Schedule
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUMMARY=Specify when the task '%s' will be \
+ launched.
+INFO_CTRL_PANEL_LAUNCH_NOW=Launch Now
+INFO_CTRL_PANEL_LAUNCH_LATER=Launch Later
+INFO_CTRL_PANEL_DAYS=Days:
+INFO_CTRL_PANEL_JANUARY=January
+INFO_CTRL_PANEL_FEBRUARY=February
+INFO_CTRL_PANEL_MARS=Mars
+INFO_CTRL_PANEL_APRIL=April
+INFO_CTRL_PANEL_MAY=May
+INFO_CTRL_PANEL_JUNE=June
+INFO_CTRL_PANEL_JULY=July
+INFO_CTRL_PANEL_AUGUST=August
+INFO_CTRL_PANEL_SEPTEMBER=September
+INFO_CTRL_PANEL_OCTOBER=October
+INFO_CTRL_PANEL_NOVEMBER=November
+INFO_CTRL_PANEL_DECEMBER=December
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME=Time:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAY=Day:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTH=Month:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_YEAR=Year:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAILY=Launch Periodically using a Daily \
+ Schedule
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEEKLY=Launch Periodically using a Weekly \
+ Schedule
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTHLY=Launch Periodically using a Monthly \
+ Schedule
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUNDAY=Sun
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONDAY=Mon
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TUESDAY=Tue
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEDNESDAY=Wed
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_THURSDAY=Thu
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_FRIDAY=Fri
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SATURDAY=Sat
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON=Launch Periodically using a CRON \
+ Schedule
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MINUTE=Minute:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_HOUR=Hour:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_WEEK_DAY=Day of Week:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH_DAY=Day of Month:
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH=Month:
+INFO_CTRL_PANEL_CRON_MINUTE_HELP=Valid values from 0 to 59
+INFO_CTRL_PANEL_CRON_HOUR_HELP=Valid values from 0 to 23
+INFO_CTRL_PANEL_CRON_WEEK_DAY_HELP=Valid values from 0 to 6 (0 is Sunday, \
+ 1 is Monday...)
+INFO_CTRL_PANEL_CRON_MONTH_DAY_HELP=From 1 to 31
+INFO_CTRL_PANEL_CRON_MONTH_HELP=Valid values from 1 to 12 (1 is January, \
+ 2 is February...)
+#
+# Note that the following property contains line breaks in HTML format (<br>).
+#
+INFO_CTRL_PANEL_CRON_HELP=Use ',' to separate values. For example: \
+ '1,4,5'.<br>Use '-' to indicate intervals.  For example '1-5'.\<br>Use '*' to \
+ indicate any value.
+SEVERE_ERR_CTRL_PANEL_INVALID_HOUR=The provided hour value is not valid.
+SEVERE_ERR_CTRL_PANEL_INVALID_MINUTE=The provided minute value is not valid.
+SEVERE_ERR_CTRL_PANEL_INVALID_DAY=The provided day value is not valid.
+SEVERE_ERR_CTRL_PANEL_INVALID_TIME=The provided time value is not valid.
+SEVERE_ERR_CTRL_PANEL_INVALID_DAY_IN_MONTH=The day '%d' does not exist in \
+ %s.
+SEVERE_ERR_CTRL_PANEL_NO_WEEK_DAY_SELECTED=You must select at least one \
+ day of the week.
+SEVERE_ERR_CTRL_PANEL_NO_MONTH_DAY_SELECTED=You must select at least one \
+ day of the month.
+SEVERE_ERR_CTRL_PANEL_DATE_ALREADY_PASSED=The provided date already passed.
+SEVERE_ERR_CTRL_PANEL_NO_CRON_MINUTE_PROVIDED=No minute provided.  Use '*' \
+ to indicate any value.
+SEVERE_ERR_CTRL_PANEL_NO_CRON_HOUR_PROVIDED=No hour provided.  Use '*' \
+ to indicate any value.
+SEVERE_ERR_CTRL_PANEL_NO_CRON_MONTH_DAY_PROVIDED=No day of month \
+ provided.  Use '*' to indicate any value.
+SEVERE_ERR_CTRL_PANEL_NO_CRON_MONTH_PROVIDED=No month provided.  Use '*' \
+ to indicate any value.
+SEVERE_ERR_CTRL_PANEL_NO_CRON_WEEK_DAY_PROVIDED=No day of week provided.  \
+ Use '*' to indicate any value.
+SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MINUTE_PROVIDED=The minute value \
+ provided is not valid.
+SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_HOUR_PROVIDED=The hour value \
+ provided is not valid.
+SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_DAY_PROVIDED=The day of month \
+ value provided is not valid.
+SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_PROVIDED=The month value \
+ provided is not valid.
+SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_WEEK_DAY_PROVIDED=The day of week \
+ value provided is not valid.
+
+INFO_CTRL_PANEL_TASK_TO_SCHEDULE_LIST_TITLE=Scheduled Tasks
+INFO_CTRL_PANEL_NO_TASKS_FOUND=- No Tasks Found -
+INFO_CTRL_PANEL_CANCEL_TASK_BUTTON_LABEL=Cancel Task
+INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_REQUIRES_SERVER_RUNNING=To see the \
+ list of scheduled tasks the server must be running and you must provide \
+ authentication.
+INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_AUTHENTICATION=To see the list of \
+ scheduled tasks you must provide authentication.
+INFO_CTRL_PANEL_CANCEL_TASK_MSG=Are you sure you want to cancel the \
+ selected tasks?
+INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION=Cancel Selected Tasks.
+INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK=Equivalent command-line to \
+ cancel task '%s':
+INFO_CTRL_PANEL_TASK_CANCELABLE=Is Cancelable
+INFO_CTRL_PANEL_CANCELING_TASK_SUMMARY=Canceling Tasks...
+INFO_CTRL_PANEL_CANCELING_TASK_COMPLETE=The tasks were successfully \
+ canceled.
+INFO_CTRL_PANEL_CANCELING_TASK_SUCCESSFUL=The tasks were successfully \
+ canceled.
+MILD_ERR_CTRL_PANEL_CANCELING_TASK_ERROR_SUMMARY=Error canceling task
+MILD_ERR_CTRL_PANEL_CANCELING_TASK_ERROR_DETAILS=An error occurred \
+ canceling the selected tasks.
+INFO_CTRL_PANEL_CANCEL_TASK_TITLE=Cancel Tasks
+INFO_CTRL_PANEL_TASK_IS_CANCELABLE=Cancelable
+INFO_CTRL_PANEL_TASK_IS_NOT_CANCELABLE=Not Cancelable
+INFO_CTRL_PANEL_MANAGE_TASKS=Manage Tasks
+INFO_CTRL_PANEL_CHANGE_SCHEDULE=Change...
+INFO_CTRL_PANEL_LAUNCH_NOW_SUMMARY=Launch now
+INFO_CTRL_PANEL_LAUNCH_LATER_SUMMARY=Launch on %s
+INFO_CTRL_PANEL_LAUNCH_PERIODICALLY_SUMMARY=Launch periodically with CRON \
+ schedule '%s'
+
+MILD_ERR_CTRL_PANEL_LAUNCH_LATER_REQUIRES_SERVER_RUNNING=To be able to launch \
+ tasks on a future date, the server must be running.
+MILD_ERR_CTRL_PANEL_LAUNCH_SCHEDULE_REQUIRES_SERVER_RUNNING=To be able to \
+ launch tasks periodically, the server must be running.
+
+INFO_CTRL_PANEL_TASK_SPECIFIC_DETAILS=Task Specific Details
+INFO_CTRL_PANEL_NO_TASK_SELECTED=-No Task Selected-
+INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED=-Multiple Tasks Selected-
+INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS=-No Task Specific Details-
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/RecurringTask.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/RecurringTask.java
index 5c7a893..1554835 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/RecurringTask.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/RecurringTask.java
@@ -521,7 +521,7 @@
    *         the schedule field.
    * @throws IllegalArgumentException if tab field is invalid.
    */
-  private boolean[] parseTaskTabField(String tabField,
+  public static boolean[] parseTaskTabField(String tabField,
     int minValue, int maxValue) throws IllegalArgumentException
   {
     boolean[] valueList = new boolean[maxValue + 1];
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskEntry.java b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskEntry.java
index 279e541..ca1f636 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskEntry.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskEntry.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008 Sun Microsystems, Inc.
+ *      Copyright 2008-2009 Sun Microsystems, Inc.
  */
 
 package org.opends.server.tools.tasks;
@@ -66,6 +66,7 @@
   private static Map<String, Message> mapAttrToDisplayName =
           new HashMap<String, Message>();
 
+  private int hashCode;
 
   // These attributes associated with the ds-task object
   // class are all handled explicitly below in the constructor
@@ -154,6 +155,68 @@
         }
       }
     }
+    hashCode += id.hashCode();
+    hashCode += className.hashCode();
+    hashCode += state.hashCode();
+    hashCode += schedStart.hashCode();
+    hashCode += actStart.hashCode();
+    hashCode += compTime.hashCode();
+    hashCode += depends.hashCode();
+    hashCode += depFailAct.hashCode();
+    hashCode += logs.hashCode();
+    hashCode += notifyErr.hashCode();
+    hashCode += notifyComp.hashCode();
+    hashCode += schedTab.hashCode();
+    hashCode += taskSpecificAttrValues.hashCode();
+  }
+
+  /**
+   * Retrieves a hash code for this task entry.
+   *
+   * @return  The hash code for this task entry.
+   */
+  @Override()
+  public int hashCode()
+  {
+    return hashCode;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override()
+  public boolean equals(Object o)
+  {
+    if (this == o)
+    {
+      return true;
+    }
+
+    if (o == null)
+    {
+      return false;
+    }
+
+    if (! (o instanceof TaskEntry))
+    {
+      return false;
+    }
+
+    TaskEntry e = (TaskEntry) o;
+
+    return e.id.equals(id) &&
+    e.className.equals(className) &&
+    e.state.equals(state) &&
+    e.schedStart.equals(schedStart) &&
+    e.actStart.equals(actStart) &&
+    e.compTime.equals(compTime) &&
+    e.depends.equals(depends) &&
+    e.depFailAct.equals(depFailAct) &&
+    e.logs.equals(logs) &&
+    e.notifyErr.equals(notifyErr) &&
+    e.notifyComp.equals(notifyComp) &&
+    e.schedTab.equals(schedTab) &&
+    e.taskSpecificAttrValues.equals(taskSpecificAttrValues);
   }
 
   /**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
index 3c9a1fb..bf16869 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/LDIFReader.java
@@ -1235,7 +1235,7 @@
    * @return A new attribute with no values, representing the
    *         attribute type and its options.
    */
-  private static Attribute parseAttrDescription(String attrDescr)
+  public static Attribute parseAttrDescription(String attrDescr)
   {
     AttributeBuilder builder;
     int semicolonPos = attrDescr.indexOf(';');

--
Gitblit v1.10.0