mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
05.17.2006 461b1f6784e6cf1483dc29fdcbef14ccfe6bc849
Update the configuration and the associated code to be more consistent in the
time and size units used for various purposes. A new set of constants have
been added to allow the same units to be used throughout the code, including
providing both full and abbreviated unit names.

In addition, the ds-cfg-time-limit and ds-cfg-profile-sample-interval
attributes have been updated so that they use the integer with unit format
rather than just an integer with an implied unit.

OpenDS Issue Number: 559
14 files modified
653 ■■■■ changed files
opends/resource/config/config.ldif 22 ●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/Config.java 30 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java 33 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/TaskBackend.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/CoreConfigManager.java 90 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/PasswordPolicy.java 47 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/FIFOEntryCache.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ConfigMessages.java 13 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/PluginMessages.java 8 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java 69 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java 60 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/ServerConstants.java 241 ●●●●● patch | view | raw | blame | history
opends/resource/config/config.ldif
@@ -38,7 +38,7 @@
ds-cfg-notify-abandoned-operations: false
ds-cfg-proxied-authorization-identity-mapper-dn: cn=Exact Match,cn=Identity Mappers,cn=config
ds-cfg-size-limit: 1000
ds-cfg-time-limit: 60
ds-cfg-time-limit: 60 seconds
ds-cfg-writability-mode: enabled
ds-cfg-bind-with-dn-requires-password: true
ds-cfg-default-password-policy: cn=Default Password Policy,cn=Password Policies,cn=config
@@ -84,9 +84,9 @@
ds-cfg-backend-directory: db
ds-cfg-backend-index-entry-limit: 4000
ds-cfg-backend-subtree-delete-size-limit: 100000
ds-cfg-backend-preload-time-limit: 0 s
ds-cfg-backend-preload-time-limit: 0 seconds
ds-cfg-backend-import-temp-directory: importTmp
ds-cfg-backend-import-buffer-size: 256 MB
ds-cfg-backend-import-buffer-size: 256 megabytes
ds-cfg-backend-import-queue-size: 100
ds-cfg-backend-import-pass-size: 0
ds-cfg-backend-import-thread-count: 8
@@ -170,18 +170,18 @@
objectClass: ds-cfg-je-database
cn: JE Database
ds-cfg-database-cache-percent: 10
ds-cfg-database-cache-size: 0 MB
ds-cfg-database-cache-size: 0 megabytes
ds-cfg-database-txn-no-sync: false
ds-cfg-database-txn-write-no-sync: true
ds-cfg-database-run-cleaner: true
ds-cfg-database-cleaner-min-utilization: 75
ds-cfg-database-evictor-lru-only: true
ds-cfg-database-evictor-nodes-per-scan: 10
ds-cfg-database-log-file-max: 50 MB
ds-cfg-database-log-file-max: 50 megabytes
ds-cfg-database-logging-file-handler-on: true
ds-cfg-database-logging-level: CONFIG
ds-cfg-database-checkpointer-bytes-interval: 20 MB
ds-cfg-database-checkpointer-wakeup-interval: 30 s
ds-cfg-database-checkpointer-bytes-interval: 20 megabytes
ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
ds-cfg-database-lock-num-lock-tables: 19
dn: ds-cfg-backend-id=backup,cn=Backends,cn=config
@@ -256,7 +256,7 @@
ds-cfg-use-tcp-nodelay: true
ds-cfg-allow-tcp-reuse-address: true
ds-cfg-send-rejection-notice: true
ds-cfg-max-request-size: 5 MB
ds-cfg-max-request-size: 5 megabytes
ds-cfg-num-request-handlers: 2
ds-cfg-allow-start-tls: false
ds-cfg-use-ssl: false
@@ -962,7 +962,7 @@
ds-cfg-plugin-type: startup
ds-cfg-enable-profiling-on-startup: false
ds-cfg-profile-directory: logs
ds-cfg-profile-sample-interval: 10
ds-cfg-profile-sample-interval: 10 milliseconds
dn: cn=Root DNs,cn=config
objectClass: top
@@ -980,8 +980,8 @@
sn: Manager
userPassword: {SSHA}7SvN6HIPUPGr0YFd0NbRkoXWyWzHsOnEfUMyxg==
ds-cfg-alternate-bind-dn: cn=Directory Manager
ds-rlim-size-limit: -1
ds-rlim-time-limit: -1
ds-rlim-size-limit: 0
ds-rlim-time-limit: 0
dn: cn=Root DSE,cn=config
objectClass: top
opends/resource/schema/02-config.ldif
@@ -294,7 +294,7 @@
  NAME 'ds-cfg-profiler-state' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.85
  NAME 'ds-cfg-profile-sample-interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  NAME 'ds-cfg-profile-sample-interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.86 NAME 'ds-cfg-realm'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE
@@ -495,7 +495,7 @@
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.150 NAME 'ds-cfg-time-limit'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.151 NAME 'ds-rlim-size-limit'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation
opends/src/server/org/opends/server/backends/jeb/Config.java
@@ -34,6 +34,7 @@
     MSGID_CONFIG_BACKEND_NO_DIRECTORY;
import static org.opends.server.messages.JebMessages.*;
import static org.opends.server.loggers.Error.logError;
import static org.opends.server.util.ServerConstants.*;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigConstants;
@@ -203,17 +204,28 @@
  static
  {
    memoryUnits = new HashMap<String, Double>();
    memoryUnits.put("KB", 1000D);
    memoryUnits.put("MB", 1000000D);
    memoryUnits.put("GB", 1000000000D);
    memoryUnits.put("KiB", 1024D);                 // kibibyte
    memoryUnits.put("MiB", 1024D * 1024D);         // mebibyte
    memoryUnits.put("GiB", 1024D * 1024D * 1024D); // gibibyte
    memoryUnits.put(SIZE_UNIT_BYTES_ABBR, 1D);
    memoryUnits.put(SIZE_UNIT_BYTES_FULL, 1D);
    memoryUnits.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D);
    memoryUnits.put(SIZE_UNIT_KILOBYTES_FULL, 1000D);
    memoryUnits.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D);
    memoryUnits.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D);
    memoryUnits.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D);
    memoryUnits.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D);
    memoryUnits.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D);
    memoryUnits.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D);
    memoryUnits.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024));
    memoryUnits.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024));
    memoryUnits.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024));
    memoryUnits.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024));
    timeUnits = new HashMap<String, Double>();
    timeUnits.put("ms", 1D);
    timeUnits.put("s",  1000D);
    timeUnits.put("m",  60*1000D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, (double) (60 * 1000));
    timeUnits.put(TIME_UNIT_MINUTES_FULL, (double) (60 * 1000));
  }
  /**
opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java
@@ -52,6 +52,7 @@
import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.messages.JebMessages.*;
import static org.opends.server.util.ServerConstants.*;
/**
 * This class represents a JE environment handle that can be configured by the
@@ -224,19 +225,31 @@
  static
  {
    HashMap<String, Double> memoryUnits = new HashMap<String, Double>();
    memoryUnits.put("KB", 1000D);
    memoryUnits.put("MB", 1000000D);
    memoryUnits.put("GB", 1000000000D);
    memoryUnits.put("KiB", 1024D);                 // kibibyte
    memoryUnits.put("MiB", 1024D * 1024D);         // mebibyte
    memoryUnits.put("GiB", 1024D * 1024D * 1024D); // gibibyte
    memoryUnits.put(SIZE_UNIT_BYTES_ABBR, 1D);
    memoryUnits.put(SIZE_UNIT_BYTES_FULL, 1D);
    memoryUnits.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D);
    memoryUnits.put(SIZE_UNIT_KILOBYTES_FULL, 1000D);
    memoryUnits.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D);
    memoryUnits.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D);
    memoryUnits.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D);
    memoryUnits.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D);
    memoryUnits.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D);
    memoryUnits.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D);
    memoryUnits.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024));
    memoryUnits.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024));
    memoryUnits.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024));
    memoryUnits.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024));
    // JE time intervals are expressed in microseconds.
    HashMap<String, Double> timeUnits = new HashMap<String, Double>();
    timeUnits.put("us", 1D);
    timeUnits.put("ms", 1000D);
    timeUnits.put("s",  1000000D);
    timeUnits.put("m",  60*1000000D);
    timeUnits.put(TIME_UNIT_MICROSECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_MICROSECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1000D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1000D);
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000000D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000000D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, (double) (60 * 1000000));
    timeUnits.put(TIME_UNIT_MINUTES_FULL, (double) (60 * 1000000));
    String msg;
opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -68,6 +68,7 @@
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.BackendMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -136,11 +137,16 @@
  static
  {
    timeUnits.put("seconds", 1.0);
    timeUnits.put("minutes", 60.0);
    timeUnits.put("hours", (60.0*60.0));
    timeUnits.put("days", (24.0*60.0*60.0));
    timeUnits.put("weeks", (7.0*24.0*60.0*60.0));
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D);
    timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D);
    timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7));
    timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7));
  }
@@ -1286,7 +1292,7 @@
                                                    description, false,
                                                    timeUnits, true, 0, false,
                                                    0, retentionTime,
                                                    "seconds"));
                                                    TIME_UNIT_SECONDS_FULL));
    return attrList;
  }
opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -30,6 +30,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -41,6 +42,7 @@
import org.opends.server.config.ConfigException;
import org.opends.server.config.DNConfigAttribute;
import org.opends.server.config.IntegerConfigAttribute;
import org.opends.server.config.IntegerWithUnitConfigAttribute;
import org.opends.server.config.MultiChoiceConfigAttribute;
import org.opends.server.types.AcceptRejectWarn;
import org.opends.server.types.ConfigChangeResult;
@@ -76,11 +78,35 @@
  /**
   * The set of time units that will be used for the appropriate attributes.
   */
  private static final LinkedHashMap<String,Double> timeUnits =
       new LinkedHashMap<String,Double>();
  // The DN of the associated configuration entry.
  private DN configEntryDN;
  static
  {
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D);
    timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D);
    timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7));
    timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7));
  }
  /**
   * Creates a new instance of this core config manager.
   */
@@ -507,7 +533,7 @@
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_SIZE_LIMIT;
    IntegerConfigAttribute sizeLimitStub =
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), true,
                                    false, false, true, -1, true,
                                    false, false, true, 0, true,
                                    Integer.MAX_VALUE);
    try
    {
@@ -539,14 +565,14 @@
    // Determine the default server time limit.
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT;
    IntegerConfigAttribute timeLimitStub =
         new IntegerConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID), true,
                                    false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    IntegerWithUnitConfigAttribute timeLimitStub =
         new IntegerWithUnitConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID),
                                            false, timeUnits, true, 0, true,
                                            Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute timeLimitAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute timeLimitAttr =
           (IntegerWithUnitConfigAttribute)
           configRoot.getConfigAttribute(timeLimitStub);
      if (timeLimitAttr == null)
      {
@@ -554,7 +580,8 @@
      }
      else
      {
        DirectoryServer.setTimeLimit(timeLimitAttr.activeIntValue());
        DirectoryServer.setTimeLimit(
             (int) timeLimitAttr.activeCalculatedValue());
      }
    }
    catch (Exception e)
@@ -1045,7 +1072,7 @@
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_SIZE_LIMIT;
    IntegerConfigAttribute sizeLimitStub =
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    false, false, true, 0, true,
                                    Integer.MAX_VALUE);
    try
    {
@@ -1073,18 +1100,19 @@
    // Add the server time limit.
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT;
    IntegerConfigAttribute timeLimitStub =
         new IntegerConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    IntegerWithUnitConfigAttribute timeLimitStub =
         new IntegerWithUnitConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID),
                                            false, timeUnits, true, 0, true,
                                            Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute timeLimitAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute timeLimitAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(timeLimitStub);
      if (timeLimitAttr == null)
      {
        timeLimitStub.setValue(DirectoryServer.getTimeLimit());
        timeLimitStub.setValue(DirectoryServer.getTimeLimit(),
                               TIME_UNIT_SECONDS_FULL);
        timeLimitAttr = timeLimitStub;
      }
@@ -1479,7 +1507,7 @@
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_SIZE_LIMIT;
    IntegerConfigAttribute sizeLimitStub =
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    false, false, true, 0, true,
                                    Integer.MAX_VALUE);
    try
    {
@@ -1502,14 +1530,14 @@
    // See if the entry specifies the server time limit.  If so, them make sure
    // it's valid.
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT;
    IntegerConfigAttribute timeLimitStub =
         new IntegerConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    IntegerWithUnitConfigAttribute timeLimitStub =
         new IntegerWithUnitConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID),
                                            false,timeUnits, true, 0, true,
                                            Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute timeLimitAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute timeLimitAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(timeLimitStub);
    }
    catch (Exception e)
@@ -2044,7 +2072,7 @@
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_SIZE_LIMIT;
    IntegerConfigAttribute sizeLimitStub =
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    false, false, true, 0, true,
                                    Integer.MAX_VALUE);
    try
    {
@@ -2076,18 +2104,18 @@
    // Get the server time limit.
    int timeLimit = DEFAULT_TIME_LIMIT;
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT;
    IntegerConfigAttribute timeLimitStub =
         new IntegerConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    IntegerWithUnitConfigAttribute timeLimitStub =
         new IntegerWithUnitConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID),
                                            false, timeUnits, true, 0, true,
                                            Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute timeLimitAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute timeLimitAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(timeLimitStub);
      if (timeLimitAttr != null)
      {
        timeLimit = timeLimitAttr.pendingIntValue();
        timeLimit = (int) timeLimitAttr.pendingCalculatedValue();
      }
    }
    catch (Exception e)
opends/src/server/org/opends/server/core/PasswordPolicy.java
@@ -350,11 +350,16 @@
    // Create a list of units and values that we can use to represent time
    // periods.
    LinkedHashMap<String,Double> timeUnits = new LinkedHashMap<String,Double>();
    timeUnits.put("seconds", 1.0);
    timeUnits.put("minutes", 60.0);
    timeUnits.put("hours", (60.0*60.0));
    timeUnits.put("days", (24.0*60.0*60.0));
    timeUnits.put("weeks", (7.0*24.0*60.0*60.0));
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D);
    timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D);
    timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7));
    timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7));
    // Get the password attribute.  If specified, it must have either the
@@ -2683,11 +2688,16 @@
    // Create a list of units and values that we can use to represent time
    // periods.
    LinkedHashMap<String,Double> timeUnits = new LinkedHashMap<String,Double>();
    timeUnits.put("seconds", 1.0);
    timeUnits.put("minutes", 60.0);
    timeUnits.put("hours", (60.0*60.0));
    timeUnits.put("days", (24.0*60.0*60.0));
    timeUnits.put("weeks", (7.0*24.0*60.0*60.0));
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D);
    timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D);
    timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60));
    timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24));
    timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7));
    timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7));
    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
@@ -2822,14 +2832,16 @@
    attrList.add(new IntegerWithUnitConfigAttribute(
                          ATTR_PWPOLICY_MINIMUM_PASSWORD_AGE,
                          getMessage(msgID), false, timeUnits, true, 0, true,
                          Integer.MAX_VALUE, minimumPasswordAge, "seconds"));
                          Integer.MAX_VALUE, minimumPasswordAge,
                          TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_AGE;
    attrList.add(new IntegerWithUnitConfigAttribute(
                          ATTR_PWPOLICY_MAXIMUM_PASSWORD_AGE,
                          getMessage(msgID), false, timeUnits, true, 0, true,
                          Integer.MAX_VALUE, maximumPasswordAge, "seconds"));
                          Integer.MAX_VALUE, maximumPasswordAge,
                          TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_RESET_AGE;
@@ -2837,14 +2849,14 @@
                          ATTR_PWPOLICY_MAXIMUM_PASSWORD_RESET_AGE,
                          getMessage(msgID), false, timeUnits, true, 0, true,
                          Integer.MAX_VALUE, maximumPasswordResetAge,
                          "seconds"));
                          TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_WARNING_INTERVAL;
    attrList.add(new IntegerWithUnitConfigAttribute(
                          ATTR_PWPOLICY_WARNING_INTERVAL, getMessage(msgID),
                          false, timeUnits, true, 0, true, Integer.MAX_VALUE,
                          warningInterval, "seconds"));
                          warningInterval, TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_EXPIRE_WITHOUT_WARNING;
@@ -2881,7 +2893,7 @@
    attrList.add(new IntegerWithUnitConfigAttribute(
                          ATTR_PWPOLICY_LOCKOUT_DURATION, getMessage(msgID),
                          false, timeUnits, true, 0, true, Integer.MAX_VALUE,
                          lockoutDuration, "seconds"));
                          lockoutDuration, TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_FAILURE_EXPIRATION;
@@ -2889,7 +2901,7 @@
                          ATTR_PWPOLICY_LOCKOUT_FAILURE_EXPIRATION_INTERVAL,
                          getMessage(msgID), false, timeUnits, true, 0, true,
                          Integer.MAX_VALUE, lockoutFailureExpirationInterval,
                          "seconds"));
                          TIME_UNIT_SECONDS_FULL));
    msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_CHANGE_BY_TIME;
@@ -2942,7 +2954,8 @@
    attrList.add(new IntegerWithUnitConfigAttribute(
                          ATTR_PWPOLICY_IDLE_LOCKOUT_INTERVAL,
                          getMessage(msgID), false, timeUnits, true, 0, true,
                          Integer.MAX_VALUE,  idleLockoutInterval, "seconds"));
                          Integer.MAX_VALUE,  idleLockoutInterval,
                          TIME_UNIT_SECONDS_FULL));
    return attrList;
opends/src/server/org/opends/server/extensions/FIFOEntryCache.java
@@ -67,6 +67,7 @@
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.ExtensionsMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -159,8 +160,10 @@
  static
  {
    timeUnits.put("ms", 1.0);
    timeUnits.put("s", 1000.0);
    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000D);
  }
@@ -1544,7 +1547,7 @@
         new IntegerWithUnitConfigAttribute(ATTR_FIFOCACHE_LOCK_TIMEOUT,
                                            getMessage(msgID), false, timeUnits,
                                            true, 0, false, 0, lockTimeout,
                                            "ms");
                                            TIME_UNIT_MILLISECONDS_FULL);
    attrList.add(lockTimeoutAttr);
opends/src/server/org/opends/server/extensions/SoftReferenceEntryCache.java
@@ -64,6 +64,7 @@
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.ExtensionsMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -124,8 +125,10 @@
  static
  {
    timeUnits.put("ms", 1.0);
    timeUnits.put("s", 1000.0);
    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000D);
  }
@@ -1076,7 +1079,7 @@
         new IntegerWithUnitConfigAttribute(ATTR_SOFTREFCACHE_LOCK_TIMEOUT,
                                            getMessage(msgID), false, timeUnits,
                                            true, 0, false, 0, lockTimeout,
                                            "ms");
                                            TIME_UNIT_MILLISECONDS_FULL);
    attrList.add(lockTimeoutAttr);
opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -6459,13 +6459,12 @@
                    "the size limit to use, or -1 to indicate that no limit " +
                    "should be enforced):  %s.");
    registerMessage(MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT,
                    "Specifies the default maximum length of time in seconds " +
                    "that should be allowed when processing a search " +
                    "operation.  This may be overridden on a per-user basis " +
                    "by including the " + OP_ATTR_USER_TIME_LIMIT +
                    " operational attribute in the user's entry.  Changes to " +
                    "this configuration attribute will take effect " +
                    "immediately.");
                    "Specifies the default maximum length of time that " +
                    "should be allowed when processing a search operation.  " +
                    "This may be overridden on a per-user basis by including " +
                    "the " + OP_ATTR_USER_TIME_LIMIT + " operational " +
                    "attribute in the user's entry.  Changes to this " +
                    "configuration attribute will take effect immediately.");
    registerMessage(MSGID_CONFIG_CORE_INVALID_TIME_LIMIT,
                    "Configuration entry %s has an invalid value for " +
                    "configuration attribute " + ATTR_TIME_LIMIT +
opends/src/server/org/opends/server/messages/PluginMessages.java
@@ -839,10 +839,10 @@
                    "will not automatically be captured on startup and must " +
                    "be manually enabled.");
    registerMessage(MSGID_PLUGIN_PROFILER_DESCRIPTION_INTERVAL,
                    "Specifies the sample interval in milliseconds that " +
                    "should be used when capturing profiling information in " +
                    "the server.  Changes to this configuration attribute " +
                    "will take effect the next time the profiler is started.");
                    "Specifies the sample interval that should be used when " +
                    "capturing profiling information in the server.  Changes " +
                    "to this configuration attribute will take effect the " +
                    "next time the profiler is started.");
    registerMessage(MSGID_PLUGIN_PROFILER_CANNOT_DETERMINE_INTERVAL,
                    "An unexpected error occurred while attempting to " +
                    "determine the value of the " + ATTR_PROFILE_INTERVAL +
opends/src/server/org/opends/server/plugins/profiler/ProfilerPlugin.java
@@ -30,6 +30,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
@@ -43,7 +44,7 @@
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.IntegerConfigAttribute;
import org.opends.server.config.IntegerWithUnitConfigAttribute;
import org.opends.server.config.MultiChoiceConfigAttribute;
import org.opends.server.config.ReadOnlyConfigAttribute;
import org.opends.server.config.StringConfigAttribute;
@@ -61,6 +62,7 @@
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.PluginMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -117,6 +119,15 @@
  /**
   * The set of time units that will be used for expressing the task retention
   * time.
   */
  private static final LinkedHashMap<String,Double> timeUnits =
       new LinkedHashMap<String,Double>();
  // Indicates whether the profiler should be started automatically when the
  // Directory Server is started.
  private boolean autoStart;
@@ -139,6 +150,16 @@
  static
  {
    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1D);
    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1D);
    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000D);
    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000D);
  }
  /**
   * Creates a new instance of this Directory Server plugin.  Every plugin must
   * implement a default constructor (it is the only one that will be used to
@@ -286,17 +307,18 @@
    sampleInterval = DEFAULT_PROFILE_INTERVAL;
    msgID = MSGID_PLUGIN_PROFILER_DESCRIPTION_INTERVAL;
    IntegerConfigAttribute intervalStub =
         new IntegerConfigAttribute(ATTR_PROFILE_INTERVAL, getMessage(msgID),
                                    true, false, false, true, 1, false, 0);
    IntegerWithUnitConfigAttribute intervalStub =
         new IntegerWithUnitConfigAttribute(ATTR_PROFILE_INTERVAL,
                                            getMessage(msgID), false, timeUnits,
                                            true, 1, false, 0);
    try
    {
      IntegerConfigAttribute intervalAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute intervalAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(intervalStub);
      if (intervalAttr != null)
      {
        sampleInterval = intervalAttr.activeValue();
        sampleInterval = intervalAttr.activeCalculatedValue();
      }
    }
    catch (Exception e)
@@ -417,10 +439,11 @@
    int msgID = MSGID_PLUGIN_PROFILER_DESCRIPTION_INTERVAL;
    IntegerConfigAttribute intervalAttr =
         new IntegerConfigAttribute(ATTR_PROFILE_INTERVAL, getMessage(msgID),
                                    true,false, false, true, 1, false, 0,
                                    sampleInterval);
    IntegerWithUnitConfigAttribute intervalAttr =
         new IntegerWithUnitConfigAttribute(ATTR_PROFILE_INTERVAL,
                                            getMessage(msgID), false, timeUnits,
                                            true, 1, false, 0, sampleInterval,
                                            TIME_UNIT_MILLISECONDS_FULL);
    attrList.add(intervalAttr);
@@ -482,13 +505,14 @@
    // See if there is an acceptable value for the sample interval.
    int msgID = MSGID_PLUGIN_PROFILER_DESCRIPTION_INTERVAL;
    IntegerConfigAttribute intervalStub =
         new IntegerConfigAttribute(ATTR_PROFILE_INTERVAL, getMessage(msgID),
                                    true, false, false, true, 1, false, 0);
    IntegerWithUnitConfigAttribute intervalStub =
         new IntegerWithUnitConfigAttribute(ATTR_PROFILE_INTERVAL,
                                            getMessage(msgID), false, timeUnits,
                                            true, 1, false, 0);
    try
    {
      IntegerConfigAttribute intervalAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute intervalAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(intervalStub);
    }
    catch (Exception e)
@@ -620,17 +644,18 @@
    // Check to see if the sample interval needs to change and apply it as
    // necessary.
    int msgID = MSGID_PLUGIN_PROFILER_DESCRIPTION_INTERVAL;
    IntegerConfigAttribute intervalStub =
         new IntegerConfigAttribute(ATTR_PROFILE_INTERVAL, getMessage(msgID),
                                    true, false, false, true, 1, false, 0);
    IntegerWithUnitConfigAttribute intervalStub =
         new IntegerWithUnitConfigAttribute(ATTR_PROFILE_INTERVAL,
                                            getMessage(msgID), false, timeUnits,
                                            true, 1, false, 0);
    try
    {
      IntegerConfigAttribute intervalAttr =
           (IntegerConfigAttribute)
      IntegerWithUnitConfigAttribute intervalAttr =
           (IntegerWithUnitConfigAttribute)
           configEntry.getConfigAttribute(intervalStub);
      if (intervalAttr != null)
      {
        long newInterval = intervalAttr.pendingValue();
        long newInterval = intervalAttr.pendingCalculatedValue();
        if (newInterval != sampleInterval)
        {
          sampleInterval = newInterval;
opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -105,45 +105,6 @@
  /**
   * The unit string that will be used to designate that a value is in bytes.
   */
  public static final String UNIT_BYTES = "B";
  /**
   * The unit string that will be used to designate that a value is in
   * kilobytes.
   */
  public static final String UNIT_KILOBYTES = "KB";
  /**
   * The unit string that will be used to designate that a value is in
   * kibibytes.
   */
  public static final String UNIT_KIBIBYTES = "KiB";
  /**
   * The unit string that will be used to designate that a value is in
   * megabytes.
   */
  public static final String UNIT_MEGABYTES = "MB";
  /**
   * The unit string that will be used to designate that a value is in
   * mebibytes.
   */
  public static final String UNIT_MEBIBYTES = "MiB";
  /**
   * The hash map that holds the units that may be provided in conjunction with
   * the maximum request size.
   */
@@ -152,11 +113,20 @@
  static
  {
    SIZE_UNITS.put(UNIT_BYTES, 1.0);
    SIZE_UNITS.put(UNIT_KILOBYTES, 1000.0);
    SIZE_UNITS.put(UNIT_KIBIBYTES, 1024.0);
    SIZE_UNITS.put(UNIT_MEGABYTES, 1000000.0);
    SIZE_UNITS.put(UNIT_MEBIBYTES, 1048576.0);
    SIZE_UNITS.put(SIZE_UNIT_BYTES_ABBR, 1D);
    SIZE_UNITS.put(SIZE_UNIT_BYTES_FULL, 1D);
    SIZE_UNITS.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D);
    SIZE_UNITS.put(SIZE_UNIT_KILOBYTES_FULL, 1000D);
    SIZE_UNITS.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D);
    SIZE_UNITS.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D);
    SIZE_UNITS.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D);
    SIZE_UNITS.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D);
    SIZE_UNITS.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D);
    SIZE_UNITS.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D);
    SIZE_UNITS.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024));
    SIZE_UNITS.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024));
    SIZE_UNITS.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024));
    SIZE_UNITS.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024));
  }
@@ -1821,7 +1791,7 @@
                                                       true,
                                                       MAX_REQUEST_SIZE_LIMIT,
                                                       maxRequestSize,
                                                       UNIT_BYTES));
                                                       SIZE_UNIT_BYTES_FULL));
    msgID = MSGID_LDAP_CONNHANDLER_DESCRIPTION_USE_SSL;
opends/src/server/org/opends/server/util/ServerConstants.java
@@ -1672,5 +1672,246 @@
   * the schema file from which the schema element was loaded.
   */
  public static final String SCHEMA_PROPERTY_FILENAME = "X-SCHEMA-FILE";
  /**
   * The abbreviated unit that should be used for a size specified in bytes.
   */
  public static final String SIZE_UNIT_BYTES_ABBR = "b";
  /**
   * The full unit that should be used for a size specified in bytes.
   */
  public static final String SIZE_UNIT_BYTES_FULL = "bytes";
  /**
   * The abbreviated unit that should be used for a size specified in kilobytes.
   */
  public static final String SIZE_UNIT_KILOBYTES_ABBR = "kb";
  /**
   * The full unit that should be used for a size specified in kilobytes.
   */
  public static final String SIZE_UNIT_KILOBYTES_FULL = "kilobytes";
  /**
   * The abbreviated unit that should be used for a size specified in kibibytes.
   */
  public static final String SIZE_UNIT_KIBIBYTES_ABBR = "kib";
  /**
   * The full unit that should be used for a size specified in kibibytes.
   */
  public static final String SIZE_UNIT_KIBIBYTES_FULL = "kibibytes";
  /**
   * The abbreviated unit that should be used for a size specified in megabytes.
   */
  public static final String SIZE_UNIT_MEGABYTES_ABBR = "mb";
  /**
   * The full unit that should be used for a size specified in megabytes.
   */
  public static final String SIZE_UNIT_MEGABYTES_FULL = "megabytes";
  /**
   * The abbreviated unit that should be used for a size specified in mebibytes.
   */
  public static final String SIZE_UNIT_MEBIBYTES_ABBR = "mib";
  /**
   * The full unit that should be used for a size specified in mebibytes.
   */
  public static final String SIZE_UNIT_MEBIBYTES_FULL = "mebibytes";
  /**
   * The abbreviated unit that should be used for a size specified in gigabytes.
   */
  public static final String SIZE_UNIT_GIGABYTES_ABBR = "gb";
  /**
   * The full unit that should be used for a size specified in gigabytes.
   */
  public static final String SIZE_UNIT_GIGABYTES_FULL = "gigabytes";
  /**
   * The abbreviated unit that should be used for a size specified in gibibytes.
   */
  public static final String SIZE_UNIT_GIBIBYTES_ABBR = "gib";
  /**
   * The full unit that should be used for a size specified in gibibytes.
   */
  public static final String SIZE_UNIT_GIBIBYTES_FULL = "gibibytes";
  /**
   * The abbreviated unit that should be used for a size specified in terabytes.
   */
  public static final String SIZE_UNIT_TERABYTES_ABBR = "tb";
  /**
   * The full unit that should be used for a size specified in terabytes.
   */
  public static final String SIZE_UNIT_TERABYTES_FULL = "terabytes";
  /**
   * The abbreviated unit that should be used for a size specified in tebibytes.
   */
  public static final String SIZE_UNIT_TEBIBYTES_ABBR = "tib";
  /**
   * The full unit that should be used for a size specified in tebibytes.
   */
  public static final String SIZE_UNIT_TEBIBYTES_FULL = "tebibytes";
  /**
   * The abbreviated unit that should be used for a time specified in
   * nanoseconds.
   */
  public static final String TIME_UNIT_NANOSECONDS_ABBR = "ns";
  /**
   * The full unit that should be used for a time specified in nanoseconds.
   */
  public static final String TIME_UNIT_NANOSECONDS_FULL = "nanoseconds";
  /**
   * The abbreviated unit that should be used for a time specified in
   * microseconds.
   */
  public static final String TIME_UNIT_MICROSECONDS_ABBR = "us";
  /**
   * The full unit that should be used for a time specified in microseconds.
   */
  public static final String TIME_UNIT_MICROSECONDS_FULL = "microseconds";
  /**
   * The abbreviated unit that should be used for a time specified in
   * milliseconds.
   */
  public static final String TIME_UNIT_MILLISECONDS_ABBR = "ms";
  /**
   * The full unit that should be used for a time specified in milliseconds.
   */
  public static final String TIME_UNIT_MILLISECONDS_FULL = "milliseconds";
  /**
   * The abbreviated unit that should be used for a time specified in seconds.
   */
  public static final String TIME_UNIT_SECONDS_ABBR = "s";
  /**
   * The full unit that should be used for a time specified in seconds.
   */
  public static final String TIME_UNIT_SECONDS_FULL = "seconds";
  /**
   * The abbreviated unit that should be used for a time specified in minutes.
   */
  public static final String TIME_UNIT_MINUTES_ABBR = "m";
  /**
   * The full unit that should be used for a time specified in minutes.
   */
  public static final String TIME_UNIT_MINUTES_FULL = "minutes";
  /**
   * The abbreviated unit that should be used for a time specified in hours.
   */
  public static final String TIME_UNIT_HOURS_ABBR = "h";
  /**
   * The full unit that should be used for a time specified in hours.
   */
  public static final String TIME_UNIT_HOURS_FULL = "hours";
  /**
   * The abbreviated unit that should be used for a time specified in days.
   */
  public static final String TIME_UNIT_DAYS_ABBR = "d";
  /**
   * The full unit that should be used for a time specified in days.
   */
  public static final String TIME_UNIT_DAYS_FULL = "days";
  /**
   * The abbreviated unit that should be used for a time specified in weeks.
   */
  public static final String TIME_UNIT_WEEKS_ABBR = "w";
  /**
   * The full unit that should be used for a time specified in weeks.
   */
  public static final String TIME_UNIT_WEEKS_FULL = "weeks";
}