# SequenceManager.java

    /*
    ** Module   : SequenceManager.java
    ** Abstract : Static abstract class that handles sequence functions and statements from
    **            Progress / OpenEdge 10.x. The actual implementation is delegated to one of the
    **            derived classes that implements a strategy of handling the persistence of the sequences.
    **
    ** Copyright (c) 2013-2025, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ---------------------------------------Description---------------------------------------
    ** 001 OM  20121116 Created initial version.
    ** 002 OM  20130507 Switch to int64 API function for obtaining desired java type.
    ** 003 OM  20130703 Massive changes:
    **                   - Removed unneeded overloaded signatures leaving the wider form (long in
    **                      place of int and int64 for integer).
    **                   - Added support for legacy-to-sql name mapping.
    **                   - Added error checking for invalid names and values.
    **                   - getSequenceHandler() will use the P2J dialect to obtain the handler.
    ** 004 ECF 20150202 Lowercase legacy sequence names when using them as map keys.
    ** 005 ECF 20170201 Lowercase keys to sequences map.
    ** 006 ECF 20171201 Look up sequence by database alias as well as logical database name.
    **     OM  20180126 Final look up of sequences done by database schema name.
    ** 007 ECF 20200610 The sequence definitions are read from annotations of _Sequence enum.
    ** 008 SBI 20200710 Fixed resolveDynamicName on behalf of Constantin.
    ** 009 OM  20220531 Added validation. Extracted common code in worker procedures.
    **     CA  20220602 Ensure SQL sequence names are lowercased when used as keys.
    **     CA  20220831 Ensure SQL sequence name returned by resolveDynamicName is lowercased.
    **     CA  20221014 legacyMap is always populated with the legacy to SQL name of sequences - this is required
    **                  because resolveDynamicName can't assume that if an entry is missing, then the SQL name
    **                  must be lowercased (MariaDB dialect is case-sensitive!).
    **     CA  20230116 Avoid using handle.unwrap, handle.getReference or other BDT usage from within FWD runtime.
    ** 010 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus.
    ** 011 OM  20250110 Added sequence support for multi-tenant databases.
    ** 012 CA  20250321 Added overloads for DYNAMIC-CURENT-VALUE statement (dynamicSetValue).
    */

    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.persist;

    import java.lang.reflect.*;
    import java.util.*;
    import java.util.logging.Level;
    import com.goldencode.p2j.persist.dialect.*;
    import com.goldencode.p2j.persist.orm.*;
    import com.goldencode.p2j.persist.sequence.*;
    import com.goldencode.p2j.util.*;
    import com.goldencode.p2j.util.logging.*;

    /**
     * A class that manages all sequence handling functions and statements calls,
     * including static dynamic forms. It also manages a map with handlers for each database
     * and will dispatch the primitives to a dedicate handler per database.
     *
     * The runtime implementations of XXXSequenceHandlers the statement/functions leverage dialect
     * infrastructure in Hibernate if possible (if we find it is feasible to use native sequences
     * on PostgreSQL). If this is not possible, the SequenceHandlers will use any native support
     * the respective database server offer and will emulate the needed 4GL behavior in java.
     */
    public abstract class SequenceManager
    {
       /**
        * A default handler for sequences that will return unknown values.
        * It is used for sequences that are not found in db or unsupported dialects.
        */
       private static final SequenceHandler defaultHandler = new SequenceHandler("");

       /**
        * The list of all known sequences in a double hashed Map (schema x sqlName).
        * <p>
        * <i>I wonder if the first level uses the sequence names and the second
        * the database. This makes it easier to look for a sequence when the name
        * of the database is default/unknown. </i>
        */
       private static final HashMap<String, HashMap<String, Sequence>> sequences = new HashMap<>();

       /**
        * Internal data structure with all instantiated {@link SequenceHandler}s.
        * The keys are logical database names. This assures that for each database there is only one
        * <code>SequenceHandler</code> which also serves for synchronizing access to sequence
        * functionality using these database-unique objects as locks.
        */
       private static final HashMap<String, SequenceHandler> seqHandlers = new HashMap<>();

       /**
        * Mapping from 4GL-legacy names to db-oriented names used in application.
        * Each schema has its own set of mapping for sequences. This is why this member is
        * double-hashed.
        * <strong>Note:</strong>Only sequences that have mutated name will be store is this structure.
        */
       private static final HashMap<String, HashMap<String, String>> legacyMap = new HashMap<>();

       /** Constant used to activate the NEXT-VALUE mode. */
       private static final boolean NEXT = true;

       /** Constant used for obtaining the current value of the sequence. */
       private static final boolean CURRENT = false;

       /** Constant for forcing the auto-detection of tenant. */
       private static final Long AUTO_TENANT = null;

       /**
        * Maps the <code>CURRENT-VALUE(seqName)</code> function from Progress as
        * it is defined in Open Edge 10.x.
        * Returns the current value of a sequence defined in the Data
        * Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in 4GL.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName)
       {
          return getValueImpl(CURRENT, null, seqName, false, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName)</code> function from Progress as
        * it is defined in Open Edge 10.x.
        * Returns the current value of a sequence defined in the Data
        * Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in 4GL.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(CURRENT, null, seqName, false, tenant);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName)</code> function from Progress as
        * it is defined in Open Edge 10.x.
        * Returns the current value of a sequence defined in the Data
        * Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in 4GL.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName, long tenantId)
       {
          return getValueImpl(CURRENT, null, seqName, false, tenantId);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName)</code> function from
        * Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in 4GL.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If a sequence with this name exists in more than
        *          one connected database, then you must specify
        *          <code>ldbName</code>.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName, String ldbName)
       {
          return getValueImpl(CURRENT, ldbName, seqName, false, AUTO_TENANT);
       }

       /**
        * Maps the {@code CURRENT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open
        * Edge 10.x. Returns the current value of the sequence defined in 4GL.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database in which the sequence is defined.
        *          The database must be connected. You can omit this parameter if the sequence name is
        *          unambiguous. If a sequence with this name exists in more than one connected database, then you
        *          must specify {@code ldbName}.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(CURRENT, ldbName, seqName, false, tenant);
       }

       /**
        * Maps the {@code CURRENT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open
        * Edge 10.x. Returns the current value of the sequence defined in 4GL.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database in which the sequence is defined.
        *          The database must be connected. You can omit this parameter if the sequence name is
        *          unambiguous. If a sequence with this name exists in more than one connected database, then you
        *          must specify {@code ldbName}.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 currentValue(String seqName, String ldbName, long tenantId)
       {
          return getValueImpl(CURRENT, ldbName, seqName, false, tenantId);
       }

       /**
        * Maps the <code>NEXT-VALUE(seqName)</code> function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName)
       {
          return getValueImpl(NEXT, null, seqName, false, AUTO_TENANT);
       }

       /**
        * Maps the <code>NEXT-VALUE(seqName)</code> function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName, long tenantId)
       {
          return getValueImpl(NEXT, null, seqName, false, tenantId);
       }

       /**
        * Maps the {@code NEXT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. If multiple databases are connected, you can omit
        *          this parameter if you specify a sequence that is unique to
        *          one of the databases.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName, String ldbName)
       {
          return getValueImpl(NEXT, ldbName, seqName, false, AUTO_TENANT);
       }

       /**
        * Maps the {@code NEXT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. If multiple databases are connected, you can omit
        *          this parameter if you specify a sequence that is unique to
        *          one of the databases.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(NEXT, ldbName, seqName, false, tenant);
       }

       /**
        * Maps the {@code NEXT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(NEXT, null, seqName, false, tenant);
       }

       /**
        * Maps the {@code NEXT-VALUE(seqName, ldbName)} function from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. If multiple databases are connected, you can omit
        *          this parameter if you specify a sequence that is unique to
        *          one of the databases.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 nextValue(String seqName, String ldbName, long tenantId)
       {
          return getValueImpl(NEXT, ldbName, seqName, false, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(String seqName, String ldbName)
       {
          return getValueImpl(CURRENT, ldbName, seqName, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function from Progress as it is defined in
        * Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(String seqName, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(CURRENT, ldbName, seqName, true, tenant);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(String seqName, String ldbName, long tenantId)
       {
          return getValueImpl(CURRENT, ldbName, seqName, true, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to a logical name of
        *          the database in which the sequence is defined. The database must be connected.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(String seqName, character ldbName)
       {
          return getValueImpl(CURRENT, ldbName.toJavaType(), seqName, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the
        *          Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(character seqName, String ldbName)
       {
          return getValueImpl(CURRENT, ldbName, seqName.toJavaType(), true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the current value of the sequence defined in the Data Dictionary.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param ldbName
        *          A character expression that evaluates to a logical name of
        *          the database in which the sequence is defined. The database
        *          must be connected.
        *
        * @return
        *       The current value of a sequence can be one of the following:
        *       <ul>
        *          <li>The initial value specified in the Data Dictionary.
        *          <li>The last value set with either the
        *             <code>CURRENT-VALUE</code> statement or the
        *             <code>NEXT-VALUE</code> function.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicCurrentValue(character seqName, character ldbName)
       {
          return getValueImpl(CURRENT, ldbName.toJavaType(), seqName.toJavaType(), true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(String seqName, String ldbName)
       {
          return getValueImpl(NEXT, ldbName, seqName, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(String seqName, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          return getValueImpl(NEXT, ldbName, seqName, true, tenant);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(String seqName, String ldbName, long tenantId)
       {
          return getValueImpl(NEXT, ldbName, seqName, true, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to a logical name of
        *          the database in which the sequence is defined. The database
        *          must be connected.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(String seqName, character ldbName)
       {
          return getValueImpl(NEXT, ldbName.toJavaType(), seqName, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param   ldbName
        *          The logical name of the database in which the sequence is
        *          defined. The database must be connected.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(character seqName, String ldbName)
       {
          return getValueImpl(NEXT, ldbName, seqName.toJavaType(), true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-NEXT-VALUE(seqName, ldbName)</code> function
        * from Progress as it is defined in Open Edge 10.x.
        * Returns the next value of the sequence, incremented by the
        * positive or negative value defined in the Data Dictionary.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param ldbName
        *          A character expression that evaluates to a logical name of
        *          the database in which the sequence is defined. The database
        *          must be connected.
        *
        * @return
        *       The next value of a sequence can be one of the following:
        *       <ul>
        *          <li>The value obtained by incremented the current value of the
        *             sequence with its increment if the value does not cross the
        *             upper/lower limits. In the case of cycling sequences the
        *             sequence value is reset to initial value.
        *          <li>The unknown value (<code>?</code>) if the sequence has
        *             exceeded its minimum or maximum and is not cycling.
        *       </ul>
        */
       public static int64 dynamicNextValue(character seqName, character ldbName)
       {
          return getValueImpl(NEXT, ldbName.toJavaType(), seqName.toJavaType(), true, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName) = expr</code> statement from
        * Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void setValue(String seqName, NumberType newValue)
       {
          setValueImpl(null, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName) = expr</code> statement from
        * Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, NumberType newValue, long tenantId)
       {
          setValueImpl(null, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, tenantId);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName) = expr</code> statement from
        * Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          An integer expression assigned as the current value of the specified sequence. If expression is
        *          outside the boundary set by the initial value (at one end) and the lower limit or upper limit
        *          (at the other end) for the sequence, FWD returns an error, and the sequence value remains
        *          unchanged.
        */
       public static void setValue(String seqName, long newValue)
       {
          setValueImpl(null, seqName, newValue, false, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName) = expr</code> statement from
        * Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          An integer expression assigned as the current value of the specified sequence. If expression is
        *          outside the boundary set by the initial value (at one end) and the lower limit or upper limit
        *          (at the other end) for the sequence, FWD returns an error, and the sequence value remains
        *          unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, long newValue, long tenantId)
       {
          setValueImpl(null, seqName, newValue, false, tenantId);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void setValue(String seqName, long newValue, String ldbName)
       {
          setValueImpl(ldbName, seqName, newValue, false, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, long newValue, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(ldbName, seqName, newValue, false, tenant);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, long newValue, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(null, seqName, newValue, false, tenant);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, long newValue, String ldbName, long tenantId)
       {
          setValueImpl(ldbName, seqName, newValue, false, tenantId);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void setValue(String seqName, NumberType newValue, String ldbName)
       {
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, AUTO_TENANT);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, NumberType newValue, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, tenant);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, NumberType newValue, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(null, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, tenant);
       }

       /**
        * Maps the <code>CURRENT-VALUE(seqName, ldbName) = expr</code> statement
        * from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void setValue(String seqName, NumberType newValue, String ldbName, long tenantId)
       {
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), false, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, long newValue, String ldbName)
       {
          setValueImpl(ldbName, seqName, newValue, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, NumberType newValue, String ldbName)
       {
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void dynamicSetValue(String seqName, long newValue, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(ldbName, seqName, newValue, true, tenant);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void dynamicSetValue(String seqName, long newValue, String ldbName, long tenantId)
       {
          setValueImpl(ldbName, seqName, newValue, true, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, long newValue, character ldbName)
       {
          setValueImpl(ldbName.toJavaType(), seqName, newValue, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to the name of a database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void dynamicSetValue(String seqName, NumberType newValue, String ldbName, NumberType tenantId)
       {
          Long tenant = tenantId == null || tenantId.isUnknown() ? null : tenantId.longValue();
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), true, tenant);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to the name of a database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       public static void dynamicSetValue(String seqName, NumberType newValue, String ldbName, long tenantId)
       {
          setValueImpl(ldbName, seqName, newValue.isUnknown() ? null : newValue.longValue(), true, tenantId);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, NumberType newValue, character ldbName)
       {
          setValueImpl(ldbName.toJavaType(),
                       seqName,
                       newValue.isUnknown() ? null : newValue.longValue(),
                       true,
                       AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to the name of a database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(character seqName, long newValue, String ldbName)
       {
          setValueImpl(ldbName, seqName.toJavaType(), newValue, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          The legacy name of a sequence defined in the Data Dictionary.
        * @param   ldbName
        *          An identifier that specifies the logical name of the database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          An integer expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(character seqName, long newValue, character ldbName)
       {
          setValueImpl(ldbName.toJavaType(), seqName.toJavaType(), newValue, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code>
        * statement from Progress as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param   seqName
        *          A character expression that evaluates to the legacy name of a sequence defined in the Data
        *          Dictionary.
        * @param   ldbName
        *          A character expression that evaluates to the name of a database
        *          in which the sequence is defined. The database must be
        *          connected. You can omit this parameter if the sequence name is
        *          unambiguous. If more than one connected database has a sequence
        *          with given name, then you must supply <code>ldbName</code>.
        * @param   newValue
        *          A numerical expression assigned as the current value of the
        *          specified sequence. If expression is outside the boundary set
        *          by the initial value (at one end) and the lower limit or upper
        *          limit (at the other end) for the sequence, Progress returns an
        *          error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(character seqName, NumberType newValue, String ldbName)
       {
          setValueImpl(ldbName,
                       seqName.toJavaType(),
                       newValue.isUnknown() ? null : newValue.longValue(),
                       true,
                       AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(character seqName, NumberType newValue, character ldbName)
       {
          Long val = newValue.isUnknown() ? null : newValue.longValue();
          setValueImpl(ldbName.toJavaType(), seqName.toJavaType(), val, true, AUTO_TENANT);
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(BaseDataType seqName, BaseDataType newValue, BaseDataType ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(BaseDataType seqName, BaseDataType newValue, String ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, BaseDataType newValue, BaseDataType ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(BaseDataType seqName, long newValue, BaseDataType ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(BaseDataType seqName, long newValue, String ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Maps the <code>DYNAMIC-CURRENT-VALUE(seqName, ldbName) = expr</code> statement from Progress
        * as it is defined in Open Edge 10.x.
        * Resets the current value of the sequence to the one specified as parameter.
        *
        * @param seqName
        *        A character expression that evaluates to the name of a sequence defined in the Data
        *        Dictionary.
        * @param ldbName
        *        A character expression that evaluates to the name of a database in which the sequence
        *        is defined. The database must be connected. You can omit this parameter if the
        *        sequence name is unambiguous. If more than one connected database has a sequence with
        *        given name, then you must supply <code>ldbName</code>.
        * @param newValue
        *        A numerical expression assigned as the current value of the specified sequence. If
        *        expression is outside the boundary set by the initial value (at one end) and the
        *        lower limit or upper limit (at the other end) for the sequence, Progress returns an
        *        error, and the sequence value remains unchanged.
        */
       public static void dynamicSetValue(String seqName, long newValue, BaseDataType ldbName)
       {
          dynamicSetValue(new character(seqName), new int64(newValue), new character(ldbName));
       }

       /**
        * Lookups the internal data structure representing a sequence object.
        *
        * @param   dbName
        *          The logical name or alias of the database.
        * @param   name
        *          The sql name of the sequence.
        *
        * @return  The named {@code Sequence} from the database and {@code null} if something is wrong
        *          (database not connected, sequence does not exist).
        */
       public static Sequence getSequence(String dbName, String name)
       {
          Database database = ConnectionManager.get().getDatabase(dbName);
          if (database == null)
          {
             return null; // database not connected ?
          }

          String schema = DatabaseManager.getSchema(database);
          if (schema == null)
          {
             return null;   // unknown schema?
          }

          HashMap<String, Sequence> dbSeqList = sequences.get(schema);
          if (dbSeqList == null)
          {
             return null;   // schema not registered ?
          }

          return dbSeqList.get(name.toLowerCase());
       }

       /**
        * Prepare the sequences from a specified database for usage. The set of sequences is obtained from
        * {@code _Sequence enum} form from the database's location. It is possible that the enum is not created
        * at all when there are no sequences defined in the database.
        *
        * @param   database
        *          The database to be analyzed.
        * @param   schema
        *          The database's schema.
        */
       public static void prepare(Database database, String schema)
       {
          if (!database.isPrimary())
          {
             return; // no sequences for this database
          }

          Class<?> seqEnumClass;
          String sequenceEnumName =
                DmoMetadataManager.getDmoBasePackage() + "." + database.getName() + "._Sequences";
          try
          {
             seqEnumClass = Class.forName(sequenceEnumName);
          }
          catch (ClassNotFoundException e)
          {
             // the _Sequences class could not be loaded. There are no sequences defined for this database.
             return;
          }

          for (Field field : seqEnumClass.getDeclaredFields())
          {
             com.goldencode.p2j.persist.annotation.Sequence seqAnn =
                   field.getAnnotation(com.goldencode.p2j.persist.annotation.Sequence.class);
             if (seqAnn == null)
             {
                // the enums have some hidden fields
                continue;
             }

             addSequenceDefinition(schema,
                                   seqAnn.legacy(),
                                   seqAnn.name(),
                                   seqAnn.start(),
                                   seqAnn.increment(),
                                   seqAnn.minValue(),
                                   seqAnn.maxValue(),
                                   seqAnn.cycle(),
                                   seqAnn.multiTenant());
          }
       }

       /**
        * Implementation of all cases of querying the sequence values.
        *
        * @param   next
        *          If {@code NEXT}, the next value of the sequence is returned.
        *          If {@code CURRENT} the current value is returned.
        * @param   ldbName
        *          The legacy database name. In static mode, the {@code null} / {@code ?} (unknown) value will
        *          attempt to detect the database dynamically. If operation fails, unknown value is returned.
        *          In dynamic mode, this is an error and an appropriate error condition will be raised.
        * @param   seqLegacyName
        *          The sequence legacy name.
        * @param   dynamic
        *          Activates the dynamic sequence name resolution mode.
        * @param   tenantId
        *          The tenant id. If present (not null) it is checked. If not it is computed as
        *          {@code tenant-id(ldbName}).
        *
        * @return  The (new) value of the sequence, as requested.
        */
       private static int64 getValueImpl(boolean next,
                                         String ldbName,
                                         String seqLegacyName,
                                         boolean dynamic,
                                         Long tenantId)
       {
          if (ldbName == null || ldbName.trim().isEmpty())
          {
             if (dynamic)
             {
                ErrorManager.recordOrThrowError(12747);
                // You must provide a valid connected database name to dynamic sequence functions. (12747)
                return new int64();
             }

             ldbName = getDatabaseForSequence(seqLegacyName);
             if (ldbName == null)
             {
                // database could not be identified
                return new int64();
             }
          }
          else
          {
             // if an alias was used, switch to logical name
             ldbName = ConnectionManager.get().getLDBName(ldbName);
          }

          String sqlSeqName = resolveDynamicName(seqLegacyName, ldbName);
          if (sqlSeqName == null)
          {
             if (dynamic)
             {
                ErrorManager.recordOrThrowError(12748);
                // Unable to evaluate sequence name for dynamic sequence function. (12748)
                return new int64();
             }

             // is this possible? This is a compile-time error. The sequence must exist!
             ErrorManager.throwError(3588, seqLegacyName, "");
             // Sequence <sequence> not found. (3588)

             return new int64();
          }

          SequenceHandler handler = getSequenceHandler(ldbName);
          return next ? handler.getNextValue(sqlSeqName, tenantId)
                      : handler.getCurrentValue(sqlSeqName, tenantId);
       }

       /**
        * Implementation of all cases of manual update of a sequence's value.
        *
        * @param   ldbName
        *          The legacy database name. In static mode, the {@code null} / {@code ?} (unknown) value will
        *          attempt to detect the database dynamically. If operation fails, unknown value is returned.
        *          In dynamic mode, this is an error and an appropriate error condition will be raised.
        * @param   seqLegacyName
        *          The sequence legacy name.
        * @param   val
        *          The new value to be set.
        * @param   dynamic
        *          Activates the dynamic sequence name resolution mode.
        * @param   tenantId
        *          The optional tenant-id. Especially used with super-tenants. Can be specified with default (but
        *          must be 0) or regular tenants (but must be {@code tenant-id(ldbName)}). If this is invalid a
        *          specific error condition is raised.
        */
       private static void setValueImpl(String ldbName,
                                        String seqLegacyName,
                                        Long val,
                                        boolean dynamic,
                                        Long tenantId)
       {
          if (val == null)
          {
             ExternalProgramWrapper epw = (ExternalProgramWrapper) ProcedureManager.thisProcedure().getResource();
             ErrorManager.recordOrThrowError(143, epw.getFileName().toJavaType(), "");
             // ** <program-name>: Unable to evaluate field for assignment. (143)
             return;
          }

          if (ldbName == null || ldbName.trim().isEmpty())
          {
             if (dynamic)
             {
                ErrorManager.recordOrThrowError(12747);
                // You must provide a valid connected database name to dynamic sequence functions. (12747)
                return;
             }

             ldbName = getDatabaseForSequence(seqLegacyName);
             if (ldbName == null)
             {
                ErrorManager.recordOrThrowError(3133, seqLegacyName.toUpperCase(), "");
                // SYSTEM ERROR: Sequence <sequence name> not found. (3133)
                return;
             }
          }
          else
          {
             // if an alias was used, switch to logical name
             ldbName = ConnectionManager.get().getLDBName(ldbName);
          }

          String sqlSeqName = resolveDynamicName(seqLegacyName, ldbName);
          if (sqlSeqName == null)
          {
             if (dynamic)
             {
                ErrorManager.recordOrThrowError(12748);
                // Unable to evaluate sequence name for dynamic sequence function. (12748)
                return;
             }

             // is this possible?
             return;
          }

          getSequenceHandler(ldbName).setValue(sqlSeqName, val, tenantId);
       }

       /**
        * Seeks the database in which the sequence is defined. It is assumed that there should no conflicts or the
        * first found database is returned. This method is called when some (static) sequence function has been
        * called without the last parameter (ldbName).
        * As a side effect, if the database is found, it is guaranteed that the appropriate
        * {@code SequenceHandler} has been loaded.
        *
        * @param   legacyName
        *          The legacy sequence name of the sequence to lookup after.
        *
        * @return The name of the database where the sequence is defined.
        */
       private static String getDatabaseForSequence(String legacyName)
       {
          int connectedDbCount = ConnectionManager.getConnectedDbCount();
          for (int i = 0; i < connectedDbCount; i++)
          {
             String ldbName = ConnectionManager.ldbName(i + 1).toJavaType();
             SequenceHandler handler = getSequenceHandler(ldbName);

             String sqlSeqName = resolveDynamicName(legacyName, ldbName);
             if (handler != null && handler.contains(sqlSeqName))
             {
                return ldbName;
             }
          }

          return null;
       }

       /**
        * Resolve the legacy name to actual sql name of a sequence.
        *
        * @param   legacyName
        *          The name of the sequence in 4GL.
        * @param   schema
        *          The schema of the sequence.
        *
        * @return  The sql-legal name of the schema.
        */
       private static String resolveDynamicName(String legacyName, String schema)
       {
          HashMap<String, String> legSeqMap = legacyMap.get(schema.toLowerCase());
          if (legSeqMap == null)
          {
             // TODO: sql name is the same as legacy name, but lowercased - this is incorrect for case-sensitive
             //       dialects like MariaDB
             return legacyName.toLowerCase();
          }
          else
          {
             String sqlName = legSeqMap.get(legacyName.toLowerCase());
             // TODO: if null, sql name is the same as legacy name, but lowercased - this is incorrect for
             //       case-sensitive dialects like MariaDB
             return sqlName != null ? sqlName : legacyName.toLowerCase();
          }
       }

       /**
        * Factory method for obtaining a sequence object for a database.  If some
        * settings is not found in directory a default <code>SequenceHandler</code> is
        * returned by default.
        *
        * @param   ldbName
        *          The name of the database
        *
        * @return  An instance of Sequence that will to which the internal
        *          functionality will be delegated.
        */
       private static SequenceHandler getSequenceHandler(String ldbName)
       {
          synchronized (SequenceManager.class)
          {
             if (seqHandlers.containsKey(ldbName))
             {
                // sequence handler already prepared for this database
                return seqHandlers.get(ldbName);
             }

             // as the database name can be dynamically passed, check if the name is valid
             if (ConnectionManager.get().getDatabase(ldbName) == null)
             {
                ErrorManager.recordOrThrowError(3141,
                      "Database " + ldbName + " does not exist or is not open");
                return defaultHandler;
             }

             // Obtain the appropriate sequence handler using the Dialect of the database
             Persistence persistence = ConnectionManager.getPersistence(ldbName);
             Dialect dialect = persistence.getDialect();
             SequenceHandler sequenceHandler = dialect.createSequenceHandler(ldbName);
             if (sequenceHandler == null)
             {
                // This should not happen, but to be on the safe side, use the default handler:
                sequenceHandler = defaultHandler;

                CentralLogger LOG = CentralLogger.get(SequenceHandler.class);
                LOG.logp(Level.WARNING,
                         SequenceManager.class.getName(),
                         "getSequenceHandler()",
                         "Could not detect dialect for " + ldbName);
             }

             // save to internal cache for further fast access
             seqHandlers.put(ldbName, sequenceHandler);
             return sequenceHandler;
          }
       }

       /**
        * Creates the internal data structure representing a sequence object and add it to in-memory list. <p>
        * This method is only called at startup time or when the database is initializing.
        *
        * @param   schema
        *          The schema/database.
        * @param   legName
        *          The legacy name of the sequence (as it was defined in 4GL).
        * @param   sqlName
        *          The sql-legal name of the sequence.
        * @param   sesInit
        *          The initial value of the sequence.
        * @param   seqInc
        *          The increment value of the sequence.
        * @param   seqMin
        *          The minimum value of the sequence.
        * @param   seqMax
        *          The maximum value of the sequence.
        * @param   seqCycle
        *          The cycle flag of the sequence.
        * @param   mt
        *          Multi-tenant flag.
        */
       private static void addSequenceDefinition(String  schema,
                                                 String  legName,
                                                 String  sqlName,
                                                 long    sesInit,
                                                 long    seqInc,
                                                 long    seqMin,
                                                 long    seqMax,
                                                 boolean seqCycle,
                                                 boolean mt)
       {
          // first check if Sequence already exists
          Sequence sequence = getSequence(schema, sqlName);
          if (sequence != null)
          {
             return;
          }

          // sequence does not exist, create it now
          sequence = new Sequence(schema, legName, sqlName, sesInit, seqMin, seqMax, seqInc, seqCycle, mt);

          // normalize schema lookup key
          String schemaKey = schema.toLowerCase();

          // if missing, create it now
          HashMap<String, Sequence> dbSeqMap = sequences.computeIfAbsent(schemaKey, k -> new HashMap<>());

          // add the object to database list
          dbSeqMap.put(sqlName.toLowerCase(), sequence);

          // add it to legacy map only when sqlName != seqName
          // CA: always register the sequence names
          // if (!sqlName.equals(seqName))
          {
             // if missing, create it now
             HashMap<String, String> legSeqMap = legacyMap.computeIfAbsent(schemaKey, k -> new HashMap<>());

             // add the object to database list
             legSeqMap.put(legName.toLowerCase(), sqlName);
          }
       }
    }