integer.java

/*
** Module   : integer.java
** Abstract : Progress 4GL compatible integer object
**
** Copyright (c) 2005-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- --JPRM-- ----------------------------Description----------------------------
** 001 GES 20050517   @21251 Created initial version with full support
**                           for all Progress integer processing including
**                           some functions like integer, minimum and
**                           maximum.
** 002 GES 20050607   @21443 Minor additions for function support.
** 003 GES 20050614   @21489 Added increment and decrement methods.
** 004 GES 20050621   @21533 Added an assign() method to modify this
**                           instance's state based on the result of
**                           an expression of compatible type.
** 005 SVG 20050720   @21767 Cloning support for BaseDataType added.
** 006 GES 20050822   @22192 Added Undoable interface support.
** 007 GES 20050830   @22384 Added error condition processing.
** 008 ECF 20051004   @22970 Implement hashCode() method. Required to be
**                           consistent with BaseDataType's implementation
**                           of equals() method.
** 009 GES 20060123   @24024 Implemented support for decimal and group
**                           separator overrides.
** 010 GES 20060206   @24301 Made compareTo() safe to process any object
**                           type (avoids ClassCastException).
** 011 GES 20060405   @25368 Support any NumberType in lists for min/max.
** 012 GES 20060417   @25555 Added default value generation.
** 013 GES 20060530   @26665 Fixed issue with "hh:mm" formatting where the
**                           hours could be returned with only 1 digit.
** 014 NVS 20060602   @26937 Fixed assign() method for unknown values.
** 015 GES 20060724   @28162 Added a forced assign() abstract method.
** 016 GES 20060807   @28474 Moved to externalizable interface to optimize
**                           network performance.
** 017 ECF 20060812   @28588 Added methods needed for database server-side
**                           function support.
** 018 GES 20060825   @28900 Added context local default format data.
** 019 SIY 20070405   @32825 Part of numbers conversion quirk handling.
** 020 GES 20080911   @39790 Added assign(int) and assign(double)
**                           signatures.
** 021 ECF 20090212   @41299 Implemented a faster equals(). Handles most
**                           common cases without having to invoke the
**                           superclass' implementation. Also added
**                           several assign() variants and optimized
**                           compareTo() for the common case.
** 022 SVL 20090225   @41367 Make class not final.
** 023 SVL 20090824   @43722 "force" parameter should be false by default into
**                           assign(integer).
** 024 SVL 20090908   @43845 Fixed handling of large integers.
** 025 GES 20091102   @44301 Time format string processing was incorrect when
**                           the value is a large enough negative to cross
**                           back over the DST boundary. Removed all J2SE
**                           date/time processing and duplicated the Progress
**                           result directly.
** 026 GES 20110303          Moved maximum/minimum to varargs.
** 027 OM  20121220          Added int64 support.
** 028 CA  20130123          Added c'tor which builds a new instance from a
**                           BaseDataType value, if possible. This should be
**                           used only when constructing an instance using the
**                           value returned by a DYNAMIC-FUNCTION call; 4GL
**                           does some special casting in this case, which is
**                           not implemented yet.
** 029 CS  20130124          Added conversion support for memptr related 
**                           functions task #1635
** 030 GES 20130126          Changed some constructors to handle NumberType.
** 031 GES 20130322          Fixed the BDT c'tor and modified the assign(BDT,boolean) to be the
**                           common location for the _POLY morphing. This is safe because all
**                           current usage would have generated a ClassCastException if that
**                           method was ever used with an invalid type. Now, instead of the CCE,
**                           the code will morph the value as is possible. The morphing code
**                           still needs to be implemented.
** 032 OM  20130328          Added missing runtime implementation. Changed the architecture so 
**                           that this class is derived from int64. All assignments will call 
**                           checkBounds in order to check if the new value fits inside 32 bit 
**                           bounds. Most of the duplicate code common with int64 was removed 
**                           and will be accessible through inheritance.
** 033 OM  20130710          Removed unneeded conversion from Date.
** 034 GES 20140115          Handle quirky out of bounds error message in an obscure case.
** 035 ECF 20150427          Override assign(NumberType, boolean) method to bypass the superclass'
**                           much more expensive implementation for the most common use case.
** 036 OM  20150630          Converting a DATETIME to INT is an error.
** 037 CA  20151222          Added instantiateDefaultExtent.
** 038 IAS 20160331          Fixed potential NPE
** 039 ECF 20160614          Implemented faster copy constructor.
** 040 GES 20171207          Removed explicit bypass on pending error (new silent error mode).
** 041 GES 20200520          Added 4GL enum constructor.
**     GES 20200603          The INTEGER() built-in must not set error-status:error on failures.
** 042 IAS 20201007          Added Type enum
** 043 CA  20210216          If a RETURN <expr>; in a functions returns a runtime int64 value and the function
**                           is 'return integer', then the value must be set to unknown.  For this reason,
**                           the 'isAssignDirect' protection was added in 'assign'.
** 044 AL2 20220328          Added proxy checks for BDT.
** 045 CA  20230215          'duplicate()' method returns the real type instead of BDT.
** 046 ICP 20250123          Added integer constant, static and dynamic cache support - these are immutable
**                           instances which must not 'escape' from FWD runtime, and only used via
**                           assignment or as read-only.
*/

/*
** 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.util;

import java.io.*;
import java.util.function.*;

import com.goldencode.p2j.oo.lang.*;
import com.goldencode.p2j.persist.*;
import com.goldencode.p2j.util.logging.*;

/**
 * A class that represents a Progress 4GL compatible integer object whose
 * data is mutable.  This class provides the basic wrappering of the 
 * primitive data, instantiation, type conversion, <code>unknown value</code>
 * representation and the core comparison logic.
 * <p>
 * All Progress language features related to integer/decimal data
 * types are implemented in the {@link MathOps} class (except comparison
 * logic which is in {@link CompareOps}.  All Progress integer/decimal
 * features are supported including all functionality that can be accessed
 * via operators and built-in Progress functions.
 *
 * @author    GES
 */
public class integer
extends int64
{
   /** Logger */
   private static final CentralLogger log = CentralLogger.get(integer.class);

   /** Default maximum number of cached integerConstant instances */
   private static final int DEFAULT_STATIC_CACHE_SIZE = 1024;

   /** Default size for the dynamic cache */
   private static final int DEFAULT_DYNAMIC_CACHE_SIZE = 512;

   /** Singleton and immutable for the integer UNKNOWN value. */
   public static final integerConstant UNKNOWN = new integerConstant();

   /** Cache for the singleton and immutable integer values. */
   private static integerConstant[] STATIC_CACHE;

   /** Dynamic integer cache. */
   private static volatile integerConstant[] DYNAMIC_CACHE;

   /**
    * Default constructor which creates an instance representing the <code>unknown value</code>.
    */
   public integer()
   {
   }

   /**
    * This is a special c'tor which should be used only when converting the
    * value returned by a function or method with polymorphic return type into the
    * expected type (i.e. DYNAMIC-FUNCTION()).  In such cases, the 4GL does some
    * automatic type conversion (see {@link #assign(BaseDataType)}).
    * 
    * @param    value
    *           The value to be used for this instance.
    */
   public integer(BaseDataType value)
   {
      initialize(value);
   }

   /**
    * Constructs an instance wth the given enum's value. If the value is larger than
    * {@code Integer.MAX_VALUE} or smaller than {@code Integer.MIN_VALUE} (does not fit into the 32-bit
    * representation) it cannot be represented and a warning 15747 will be raised:
    * "Value too large to fit in INTEGER".
    * <p>
    * If the parameter is {@code unknown value} the resulting instance is the {@code unknown value}.
    * <p>
    * This constructor implements the {@code INTEGER(enum)} 4GL built-in function.  Any failure will
    * generate a warning instead of an error.
    *
    * @param    enm
    *           The enum whose value to be used for this instance.
    */
   public integer(object<? extends LegacyEnum> enm)
   {
      if (enm.isUnknown())
      {
         setUnknown();
      }
      else
      {
         // although the assign will call checkBounds() downstream, it will generate an error which we don't
         // want; we force the check here so that we can cause the failure to be a warning
         long num = enm.ref()._getValue();
         
         if (!checkBounds(num, true))
         {
            return;
         }
         
         super.setValue(num);
      }
   }
   
   /**
    * Constructs an instance after casting the parameter into the internal representation of this 
    * class.  If the value is larger than <code>Integer.MAX_VALUE</code> or smaller than 
    * <code>Integer.MIN_VALUE</code> (does not fit into the 32-bit representation) it
    * cannot be represented and error 15747 will be raised: "Value too large to fit in INTEGER"
    * <p>
    * It is not possible to yield an <code>unknown value</code> from this constructor without
    * calling the method {@link #setUnknown} separately.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(long value)
   {
      super.setValue(value);
   }

   /**
    * Constructs an instance after casting the parameter into the internal
    * representation of this class.  No loss of precision will occur.
    * <p>
    * It is not possible to yield an <code>unknown value</code> from this
    * constructor without calling the method {@link #setUnknown} separate.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(int value)
   {
      super.setValue(value);
   }

   /**
    * Constructs an instance after casting the parameter into the internal
    * representation of this class.  Loss of precision may occur in this
    * conversion (all digits to the right of the decimal point will be
    * truncated).
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(double value)
   {
      super.setValue(new decimal(value));
   }

   /**
    * Constructs an instance after copying the parameter's data into the
    * internal representation of this class.
    * <p>
    * When the parameter is <code>true</code> the resulting integer value
    * will be 1. Otherwise the value is 0.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(boolean value)
   {
      super.setValue(value);
   }

   /**
    * Constructs an instance after casting the parameter into the internal representation of this
    * class. Very large and very small values that do not fit into the 32 bit representation 
    * cannot be represented.
    * <p>
    * If the parameter represents the <code>unknown value</code>, this instance will also 
    * represent the <code>unknown value</code>.
    * <p>
    * This constructor implements the {@code INTEGER(int64)} 4GL built-in function.  Any failure will
    * generate a warning instead of an error.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(int64 value)
   {
      // the value may be a proxy; make sure to unwrap and work with the real value
      if (BaseDataType.isProxy(value))
      {
         if (value.val() instanceof int64)
         {
            value = (int64) value.val();
         }
         else
         {
            initialize(value.val());
            return;
         }
      }
      // although the assign will call checkBounds() downstream, it will generate an error which we don't
      // want; we force the check here so that we can cause the failure to be a warning
      if (value != null && !value.isUnknown())
      {
         long num = value.longValue();
         
         if (!checkBounds(num, true))
         {
            return;
         }
      }
      
      assign(value);
   }
   
   /**
    * Constructs an instance after casting the parameter into the internal representation of this
    * class. No loss of precision will occur.
    * <p>
    * If the parameter represents the <code>unknown value</code>, this instance will also
    * represent the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(integer value)
   {
      super(value);
   }

   /**
    * Constructs an instance after casting the parameter into the internal representation of this
    * class. Loss of precision may occur in this conversion. All digits to the right of the 
    * decimal point will be truncated. Very large and very small values cannot be represented.
    * <p>
    * If the parameter represents the <code>unknown value</code>, this instance will also 
    * represent the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(decimal value)
   {
      assign(value);
   }

   /**
    * Constructs an instance after copying the parameter's data into the
    * internal representation of this class.
    * <p>
    * If the parameter's represents the <code>unknown value</code>, this
    * instance will also represent the <code>unknown value</code>.
    * <p>
    * When the parameter is <code>true</code> the resulting integer value
    * will be 1. Otherwise the value is 0.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(logical value)
   {
      // the value may be a proxy; make sure to unwrap and work with the real value
      if (BaseDataType.isProxy(value))
      {
         if (value.val() instanceof logical)
         {
            value = (logical) value.val();
         }
         else
         {
            initialize(value.val());
            return;
         }
      }
      super.setValue(value);
   }

   /**
    * Constructs an instance after converting the string representation
    * of a number into an integer.  Due to rounding, a loss of precision
    * may occur in this conversion (all digits to the right of the decimal
    * point will be truncated).
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(String value)
   {
      setValue(value);
   }

   /**
    * Constructs an instance after converting the string representation
    * of a number into an integer.  Due to rounding, a loss of precision
    * may occur in this conversion (all digits to the right of the decimal
    * point will be truncated).
    * <p>
    * If the parameter is <code>unknown value</code> the resulting integer is 
    * the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(character value)
   {
      // the value may be a proxy; make sure to unwrap and work with the real value
      if (BaseDataType.isProxy(value))
      {
         if (value.val() instanceof character)
         {
            value = (character) value.val();
         }
         else
         {
            initialize(value.val());
            return;
         }
      }
      if (value.isUnknown())
      {
         setUnknown();
      }
      else
      {
         setValue(value.getValue());
      }
   }

   /**
    * Constructs an instance after copying the parameter's data into the
    * internal representation of this class.
    * <p>
    * If the parameter's represents the <code>unknown value</code>, this
    * instance will also represent the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(date value)
   {
      // the value may be a proxy; make sure to unwrap and work with the real value
      if (BaseDataType.isProxy(value))
      {
         if (value.val() instanceof date)
         {
            value = (date) value.val();
         }
         else
         {
            initialize(value.val());
            return;
         }
      }
      if (value.isUnknown())
      {
         setUnknown();
      }
      else if (value instanceof datetime)
      {
         ErrorManager.recordOrShowError(
            5729, "Incompatible datatypes found during runtime conversion", false);
      }
      else
      {
         super.setValue(value.longValue());
      }
   }

   /**
    * Constructs an instance after copying the parameter's data into the
    * internal representation of this class.
    * <p>
    * If the parameter is <code>null</code>, this instance will represent
    * the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(Number value)
   {
      if (value == null)
      {
         setUnknown();
      }
      else
      {
         super.setValue(value.intValue());
      }
   }

   /**
    * Constructs an instance after copying the parameter's data into the
    * internal representation of this class.
    * <p>
    * If the parameter is <code>null</code>, this instance will represent
    * the <code>unknown value</code>.
    *
    * @param   value
    *          The value to be used for this instance.
    */
   public integer(Boolean value)
   {
      if (value == null)
      {
         setUnknown();
         return;
      }
      super.setValue(value);
   }

   /**
    * Initializes the cache using CacheManager. The default value of the cache
    * is used when there is no size available from the configuration.
    */
   public static void initializeCache()
   {
      STATIC_CACHE = CacheManager.createArrayCache(integer.class,
                                            "static-cache",
                                            DEFAULT_STATIC_CACHE_SIZE,
                                            integerConstant.class);

      for (int i = 0; i < STATIC_CACHE.length; i++)
      {
         STATIC_CACHE[i] = new integerConstant(i);
      }

      DYNAMIC_CACHE = CacheManager.createArrayCache(integer.class,
                                                    "dynamic-cache",
                                                    DEFAULT_DYNAMIC_CACHE_SIZE,
                                                    integerConstant.class);
   }

   /**
    * Returns an integerConstant instance. Uses cached instances for the first n values, where n is the
    * cache size that can be configured in directory.xml.
    *
    * @param   value
    *          The value of the integer.
    * @return  An integerConstant instance.
    */
   public static integer of(Integer value)
   {
      if (value == null)
      {
         return UNKNOWN;
      }

      if (STATIC_CACHE == null)
      {
         return new integerConstant(value);
      }
      //Check static cache
      if (value >= 0 && value < STATIC_CACHE.length)
      {
         return STATIC_CACHE[value];
      }

      if (DYNAMIC_CACHE == null)
      {
         return new integerConstant(value);
      }
      // Check dynamic cache
      int index = Math.abs(value % DYNAMIC_CACHE.length);
      synchronized (DYNAMIC_CACHE)
      {
         integerConstant cachedInstance = DYNAMIC_CACHE[index];
         if (cachedInstance != null && cachedInstance.intValue() == value)
         {
            return cachedInstance;
         }

         // Cache miss - create and replace the entry in dynamic cache
         integerConstant newInstance = new integerConstant(value);
         DYNAMIC_CACHE[index] = newInstance;
         return newInstance;
      }
   }

   /**
    * Returns an integerConstant instance. Uses cached instances for the first n values, where n is the
    * cache size that can be configured in directory.xml.
    *
    * @param   value
    *          The value of the integer.
    * @return  An integerConstant instance.
    */
   public static integer of(integer value)
   {
      if (value == null || value.isUnknown())
      {
         return UNKNOWN;
      }

      return integer.of(value.intValue());
   }

   /**
    * Get the type
    * @return type
    */
   public Type getType()
   {
      return Type.INTEGER;
   }

   /**
    * Sets the state (data and unknown value) of this instance based on the state of the passed
    * instance.
    * <p>
    * Overrides the superclass' implementatoin to optimize for the most common use case of
    * copying an <code>integer</code> from another <code>integer</code> (vs. from a
    * non-<code>integer</code> <code>NumberType</code>). In bypassing the superclass' more general
    * implementation, we avoid a significantly slower implementation which performs unnecessarily
    * (for this case) a bounds check and <code>BigDecimal</code> instantiation.
    * <p>
    * In the event <code>value</code> is not an <code>integer</code> instance, delegate to the
    * superclass' implementation.
    *
    * @param    value
    *           The instance from which to copy state.
    */
   @Override
   public void assign(NumberType value)
   {
      // the value may be a proxy; make sure to unwrap and work with the real value
      if (BaseDataType.isProxy(value))
      {
         assign(value.val());
         return;
      }
      if (!(value instanceof integer))
      {
         super.assign(value);
         return;
      }
      
      if (value.isUnknown())
      {
         setUnknown();
         return;
      }
      
      if (((integer) value).isAssignDirect() && !checkBounds(value.longValue(), false))
      {
         // convert it to unknown...
         setUnknown();
         return;
      }
      
      setValue(value.intValue());
   }

   /**
    * Hash code implementation which is consistent with {@link BaseDataType#equals}.
    *
    * @return  Hash code value for this object instance.
    */
   public int hashCode()
   {
      return super.hashCode();
   }

   /**
    * Creates a new instance of the same type that represents the <code>unknown value</code>.
    *
    * @return  An instance that represents the <code>unknown value</code>.
    */
   public BaseDataType instantiateUnknown()
   {
      return new integer();
   }

   /**
    * Creates a new instance of the same type that represents the  default initialized value.
    *
    * @return  An instance that represents the default value.
    */
   public BaseDataType instantiateDefault()
   {
      return new integer(0);
   }

   /**
    * Does the same as standard <code>clone()</code> method but returns an instance of 
    * <code>BaseDataType</code> and doesn't throw the <code>CloneNotSupportedException</code>.
    *
    * @return  A clone of this instance.
    */
   public integer duplicate()
   {
      return new integer(this);
   }

   /**
    * Sets the state (data and unknown value) of this instance based on the
    * state of the passed instance.
    *
    * @param    value
    *           The instance from which to copy state.
    */
   public void assign(Undoable value)
   {
      if (value instanceof BaseDataType)
      {
         assign((BaseDataType)value);
      }
      else
      {
         throw new RuntimeException("Assignement of " + value.getClass() + 
               " to integer not implemented.");
      }
   }

   /**
    * Replacement for the default object reading method. The latest state is read from the 
    * input source.
    * 
    * @param    in
    *           The input source from which fields will be restored.
    *
    * @throws   IOException
    *           In case of I/O errors.
    * @throws   ClassNotFoundException
    *           If payload can't be instantiated.
    */
   public void readExternal(ObjectInput in)
   throws IOException,
          ClassNotFoundException
   {
      int value       = in.readInt();
      boolean unknown = in.readBoolean();
      
      if (unknown)
      {
         setUnknown();
      }
      else
      {
         super.setValue(value);
      }
   }

   /**
    * Replacement for the default object writing method. The latest
    * state is written to the output destination.
    * 
    * @param    out
    *           The output destination to which fields will be saved.
    *
    * @throws   IOException
    *           In case of I/O errors.
    */
   public void writeExternal(ObjectOutput out)
   throws IOException
   {
      out.writeInt((int)getValue());
      out.writeBoolean(isUnknown());
   }

   /**
    * Get the default initialization for an extent variable of this type.
    * 
    * @return   See above.
    */
   @Override
   protected BaseDataType instantiateDefaultExtent()
   {
      return new integer(0);
   }

   /**
    * Checks if <code>value</code> can be assigned to this data type. This is important for
    * <code>integer</code> objects where the values must fit into 32 bit storage bounds.
    * 
    * @param   value
    *          The value
    * @param   warn
    *          {@code true} if any generated error should actually be a warning (the 
    *          {@code error-status:error} set to {@code false}.
    *
    * @return  <code>true</code> if value fits into 32 bit storage bounds.
    *
    * @throws  ErrorConditionException
    *          Thrown if the <code>value</code> do not fit within this data-type.
    */
   @Override
   protected boolean checkBounds(long value, boolean warn)
   throws ErrorConditionException
   {
      if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)
      {
         int errno = 15747;
         
         // mimic the strange quirk of how the 4GL prints the smallest int64 value
         String txt = (value == Long.MIN_VALUE) ? "-(" : String.format("%d", value);
         String msg = "Value " + txt + " too large to fit in INTEGER";
         
         if (warn)
         {
            ErrorManager.recordOrShowError(errno, msg, false, true, false);
         }
         else
         {
            ErrorManager.recordOrThrowError(errno, msg, false);
         }
         
         return false;
      }

      return true;
   }

   /**
    * An immutable integer type, used for caching singleton instances for specific values.
    */
   public static class integerConstant
   extends integer
   implements BaseDataTypeConstant
   {
      /**
       * Default constructor, creates an instance that represents the unknown value.
       */
      public integerConstant()
      {
         this.unknown = true;
      }

      /**
       * Constructs an instance with a specific value.
       *
       * @param   value
       *          The value of the integerConstant instance.
       */
      public integerConstant(int value)
      {
         this.value = value;
         this.unknown = false;
      }

      /**
       * Operation not possible.
       *
       * @throws UnsupportedOperationException
       *         This is an immutable integer instance.
       */
      @Override
      public void setUnknown()
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

      /**
       * Operation not possible.
       *
       * @throws UnsupportedOperationException
       *         This is an immutable integer instance.
       */
      @Override
      public void setValue(long value)
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

      /**
       * Operation not possible.
       *
       * @throws   UnsupportedOperationException
       *           This is an immutable integer instance.
       */
      @Override
      public void assign(NumberType value)
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

      /**
       * Operation not possible.
       *
       * @throws   UnsupportedOperationException
       *           This is an immutable integer instance.
       */
      @Override
      public void assign(Undoable value)
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

      /**
       * Operation not possible.
       *
       * @throws   UnsupportedOperationException
       *           This is an immutable integer instance.
       */
      @Override
      public void assign(Object value)
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

      /**
       * Operation not possible.
       *
       * @throws   UnsupportedOperationException
       *           This is an immutable integer instance.
       */
      @Override
      Supplier<AbstractParameter> getAssigner()
      {
         throw new UnsupportedOperationException("This is an immutable integer instance.");
      }

   }
}