PSZ -> USUAL results in USUAL with type string

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
using System
USING System.Runtime.InteropServices
using System.Runtime.CompilerServices
using System.Diagnostics
using XSharp.Internal
begin namespace XSharp
	/// Internal type that implements the VO Compatible USUAL type.

	/// This type has many operators and implicit converters that normally are never directly called from user code.
	///
    [StructLayout(LayoutKind.Sequential, Pack := 4)];
    [DebuggerDisplay("{Value,nq} ({_usualType})", Type := "USUAL")];
    [DebuggerTypeProxy(typeof(UsualDebugView))];
    PUBLIC STRUCTURE __Usual IMPLEMENTS IConvertible, ;
		IComparable, ;
		IComparable<__Usual>, ;
		IEquatable<__Usual>
        #region static fields
			/// <exclude />
            public static _NIL as __Usual
        #endregion

        #region private fields
            private initonly _flags    	as UsualFlags	// type, byref, width, decimals
            private initonly _valueData	as _UsualData		// for non GC data
            private initonly _refData  	as object			// for GC data
        #endregion

        #region constructors
			/// <exclude />
            static constructor
            _NIL := __Usual{}
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(u as __Usual)
            self:_flags     := u:_flags
            self:_valueData	:= u:_valueData
            self:_refData 	:= u:_refData

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(f as Float)
            self:_valueData:r8		:= f:Value
            self:_flags:usualType	:= UsualType.Float
            self:_flags:Width		:= (Sbyte) f:Digits
            self:_flags:Decimals	:= (Sbyte) f:Decimals

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(r8 as real8)
            self:_valueData:r8		:= r8
            self:_flags:usualType	:= UsualType.Float
            self:_flags:Width		:= -1
            self:_flags:Decimals	:= -1

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as logic)
            self:_flags:usualType	:= UsualType.LOGIC
            self:_valueData:l		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as Array)
            self:_flags:usualType	:= UsualType.Array
            self:_refData			:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as Date)
            self:_flags:usualType	:= UsualType.Date
            self:_valueData:d		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as System.DateTime)
            self:_flags:usualType	:= UsualType.DateTime
            self:_valueData:dt		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as long)
            self:_flags:usualType	:= UsualType.LONG
            _valueData:i			:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as int64)
            self:_flags:usualType	:= UsualType.INT64
            self:_valueData:i64		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as uint64)
            if value < Int64.MaxValue
                self:_flags:usualType	:= UsualType.INT64
                self:_valueData:i64:= (int64) value
            else
                self:_flags:usualType	:= UsualType.FLOAT
                self:_valueData:r8 := value
            endif
            return

            private constructor(d as System.Decimal)
            self:_flags:usualType  := UsualType.Decimal
            self:_refdata	:= d

            private constructor(value as System.IntPtr)
            self:_flags:usualType	:= UsualType.PTR
            self:_valueData:p		:= value
            return

            private constructor(value as PSZ)
				self:_flags:usualType	:= UsualType.STRING
				self:_refData			:= Psz2String(value)
            return
   			/// This constructor is used in code generated by the compiler when needed.
            public constructor(o as object)
            local u				as __Usual
            if o != null
                if o:GetType() == typeof(__Usual)
                    // boxed __Usual
                    u		:= (__Usual)o
                    self:_flags		:= u:_flags
                    self:_refData	:= u:_refData
                    self:_valueData	:= u:_valueData
                else
                    //  decode type from typecode
                    var vartype := o:GetType()
                    var typeCode := System.Type.GetTypeCode(vartype)
                    switch typeCode
                        case  System.TypeCode.DBNull
                            self:_flags:usualType := UsualType.Void
                            self:_refData	:= null

                        case System.TypeCode.Boolean
                            self:_flags:usualType := UsualType.LOGIC
                            self:_valueData:l := (logic)o

                        case System.TypeCode.Char
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (char)o

                        case System.TypeCode.SByte
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (SByte)o

                        case System.TypeCode.Byte
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (byte)o

                        case System.TypeCode.Int16
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (short)o

                        case System.TypeCode.UInt16
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (word)o

                        case System.TypeCode.Int32
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (long)o

                        case System.TypeCode.UInt32
                            if (dword)o  <= Int32.MaxValue
                                self:_flags:usualType := UsualType.Long
                                self:_valueData:i := (long)(dword)o
                            else
                                self:_flags:usualType := UsualType.Float
                                self:_valueData:r8:= (real8) (UInt32) o
                                self:_flags:width	:= -1
                                self:_flags:decimals := -1
                            endif
                        case System.TypeCode.Int64
                            self:_flags:usualType		:= UsualType.Int64
                            self:_valueData:i64	:= (int64)o

                        case System.TypeCode.UInt64
                            if (uint64) o  <= Int64.MaxValue
                                self:_flags:usualType	:= UsualType.Int64
                                self:_valueData:i64		:= (int64)(uint64)o
                            else
                                self:_flags:usualType := UsualType.FLOAT
                                self:_valueData:r8 := (real8)(uint64)o
                                self:_flags:width	:= -1
                                self:_flags:decimals := -1
                            endif
                        case System.TypeCode.Single
                            self:_flags:usualType		:= UsualType.Float
                            self:_valueData:r8	:= (real8)o
                            self:_flags:width	:= -1
                            self:_flags:decimals := -1

                        case System.TypeCode.Double
                            self:_flags:usualType := UsualType.Float
                            self:_valueData:r8 := (real8)o
                            self:_flags:width := -1
                            self:_flags:decimals := -1

                        case System.TypeCode.Decimal
                            self:_flags:usualType := UsualType.Decimal
                            self:_refData  := o

                        case System.TypeCode.DateTime
                            self:_flags:usualType := UsualType.DateTime
                            self:_valueData:dt := (System.DateTime) o

                        case System.TypeCode.String
                            self:_flags:usualType := UsualType.STRING
                            self:_refData  := (string)o

                        otherwise
                            IF vartype == typeof(ARRAY)
                                SELF:_flags:usualType := UsualType.Array
                                self:_refData  := o
							// CodeBlock ?
							// _CodeBlock ?
                            ELSEIF vartype == typeof(DATE)
                                SELF:_flags:usualType := UsualType.Date
                                SELF:_valueData:d :=  (DATE) o
                            ELSEIF vartype == typeof(SYMBOL)
                                SELF:_flags:usualType := UsualType.Symbol
                                SELF:_valueData:s :=   (SYMBOL) o
                            ELSEIF vartype == typeof(System.Reflection.Pointer)
                                self:_flags:usualType := UsualType.Ptr
                                self:_valueData:p	  := Intptr{System.Reflection.Pointer.UnBox(o)}
							elseif o is IFloat
								local f := (IFLoat) o as IFloat
								self:_valueData:r8		:= f:Value
								self:_flags:usualType	:= UsualType.Float
								self:_flags:Width		:= (Sbyte) f:Digits
								SELF:_flags:Decimals	:= (Sbyte) f:Decimals
							elseif o is ICodeBlock
                                SELF:_flags:usualType := UsualType.CodeBlock
                                self:_refData := o
                            ELSE
                                SELF:_flags:usualType := UsualType.Object
                                self:_refData := o
                            endif
                    end switch
                endif
            endif
            return

            private constructor(s as string)
            self:_flags:usualType	:= UsualType.STRING
            self:_refData 			:= s
            return

        //[MethodImpl(MethodImplOptions.AggressiveInlining)];
        private constructor(s as symbol)
            self:_flags:usualType	:= UsualType.SYMBOL
            self:_valueData:s       := s
            return

        //[MethodImpl(MethodImplOptions.AggressiveInlining)];
        private constructor(o as object, lIsNull as logic)
            self:_flags:usualType	:= UsualType.OBJECT
            self:_refData 			:= null
            return

        #endregion

        #region properties
			private property _isByRef		as LOGIC	get _flags:isByRef
            internal property _usualType		as UsualType get _flags:usualType

			private property _arrayValue    as array	get iif(IsArray, (array) _refData , null_array)
			private property _codeblockValue as codeblock	get iif(IsCodeBlock, (Codeblock) _refData , null_codeblock)
            private property _dateValue		as Date		get _valueData:d
            private property _dateTimeValue as DateTime get _valueData:dt
            private property _decimalValue	as System.Decimal get (System.Decimal) _refData
            private property _floatValue    as Float	get Float{ _valueData:r8, _width, _decimals}
            private property _i64Value		as int64	get _valueData:i64
            private property _intValue		as int		get _valueData:i
            private property _logicValue	as logic	get _valueData:l
            PRIVATE PROPERTY _ptrValue		AS IntPtr	GET _valueData:p
			private property _pszValue		as IntPtr	get __psz.CreatePsz(_stringValue)
            private property _r8Value		as real8	get _valueData:r8
            private property _stringValue   as string	get iif(IsString, (string) _refData , String.Empty)
            private property _symValue		as Symbol	get _valueData:s

            // properties for floats
            private property _width			as SBYTE get _flags:width
            private property _decimals		as SBYTE get _flags:decimals
			// Is .. ?
			internal property IsArray		as logic get _usualtype == UsualType.Array
			internal property IsCodeblock	as logic get _usualtype == UsualType.CodeBlock
			internal property IsDate		as logic get _usualtype == UsualType.Date
			internal property IsDateTime	as logic get _usualtype == UsualType.DateTime
			internal property IsDecimal		as logic get _usualtype == UsualType.Decimal
			internal property IsFloat		as logic get _usualtype == UsualType.Float
			internal property IsInt64		as logic get _usualtype == UsualType.Int64
			internal property IsLogic		as logic get _usualtype == UsualType.Logic
			internal property IsLong		as logic get _usualtype == UsualType.Long
			internal property IsInteger		as logic get _usualtype == UsualType.Long .or. _usualtype == UsualType.Int64
			internal property Type			as UsualType get _flags:usualType
			internal property IsNumeric as logic
				get
					switch _usualType
					case UsualType.Long
					case UsualType.Int64
					case UsualType.Float
					case UsualType.Decimal
						return true
					otherwise
						return false
					end switch
				end get
			end property
			internal property IsObject		as logic get _usualtype == UsualType.Object
			internal property IsPtr			as logic get _usualtype == UsualType.Ptr
			internal property IsSymbol		as logic get _usualtype == UsualType.Symbol
			internal property IsString		as logic get _usualtype == UsualType.String
			internal property IsByRef		as logic get _isByRef
            private property IsReferenceType as logic
                get
                    switch _usualType
                        case UsualType.Array
                        case UsualType.Object
                        case UsualType.Decimal
                        case UsualType.String
                            return true
                        otherwise
                            return false
                    end switch
                end get
            end property
  			internal property IsEmpty as logic
				get
				switch _usualType
				case UsualType.Array		; return _arrayValue == null .or. _arrayValue:Length == 0
				CASE UsualType.CodeBlock	; return _codeblockValue == null
				case UsualType.Date			; return _dateValue:IsEmpty
				case UsualType.DateTime		; return _dateTimeValue == DateTime.MinValue
				case UsualType.Decimal		; return _decimalValue == 0
				case UsualType.Float		; return _floatValue == 0.0
				case UsualType.Int64		; return _i64Value == 0
				case UsualType.Logic		; return _logicValue == false
				CASE UsualType.Long			; return _intValue == 0
				case UsualType.Object		; return _refData == null
				case UsualType.Ptr			; return _ptrValue == IntPtr.Zero
				case UsualType.String		; return EmptyString(_stringValue)
				case UsualType.Symbol		; return _symValue == 0
				case UsualType.Void			; return true
				otherwise
					Debug.Fail( "Unhandled data type in Usual:Empty()" )
				end switch
				return false
				end get
			end property

            internal property IsNil as logic
                get
                    return self:_usualType == UsualType.Void .or. ;
						(self:IsReferenceType .and. self:_refData  == null) .or. ;
						(self:_usualType == UsualType.Ptr .and. self:_ptrValue == IntPtr.Zero)

                end get
            end property

            internal property SystemType as System.Type
                get
					switch _usualType
					case UsualType.Array		; return typeof(Array)
					case UsualType.Codeblock	; return typeof(Codeblock)
					case UsualType.Date			; return typeof(Date)
					case UsualType.DateTime		; return typeof(System.DateTime)
					case UsualType.Decimal		; return typeof(System.Decimal)
					case UsualType.Float		; return typeof(Float)
					case UsualType.Int64		; return typeof(INT64)
					case UsualType.Logic		; return typeof(LOGIC)
					case UsualType.Long			; return typeof(INT)
					case UsualType.Object		; return typeof(OBJECT)
					case UsualType.Ptr			; return typeof(IntPtr)
					case UsualType.String		; return typeof(STRING)
					case UsualType.Symbol		; return typeof(SYMBOL)
					case UsualType.Void			; return typeof(USUAL)
					otherwise
						Debug.Fail( "Unhandled data type in Usual:SystemType" )
					end switch
					return null
                end get

            end property

        #endregion
        #region Properties for the Debugger
			/// <exclude />
            PROPERTY Value AS OBJECT
                GET
                    SWITCH _UsualType
                        CASE UsualType.Array		; RETURN _arrayValue
						CASE UsualType.Codeblock	; RETURN _codeblockValue
                        CASE UsualType.Date			; RETURN _dateValue
                        CASE UsualType.DateTime		; RETURN _dateTimeValue
                        CASE UsualType.Decimal		; RETURN _decimalValue
                        CASE UsualType.Float		; RETURN _floatValue
                        CASE UsualType.Int64		; RETURN _i64Value
                        CASE UsualType.Logic		; RETURN _logicValue
                        CASE UsualType.Long			; RETURN _intValue
						CASE UsualType.Object		; RETURN _refData
                        CASE UsualType.Ptr			; RETURN _ptrValue
                        CASE UsualType.String		; RETURN _stringValue
                        CASE UsualType.Symbol		; RETURN _symValue
                        CASE UsualType.Void			; RETURN "NIL"
                        OTHERWISE					; RETURN _refData
                    END SWITCH
                END GET
            END PROPERTY

        #endregion

        #region implementation IComparable<T>
		PUBLIC METHOD CompareTo(rhs AS __Usual) AS LONG
            if self:_UsualType == rhs:_UsualType
                // Compare ValueTypes
                switch _UsualType
                    case UsualType.Date		; return self:_dateValue:CompareTo(rhs:_dateValue)
                    case UsualType.DateTime	; return self:_dateTimeValue:CompareTo(rhs:_dateTimeValue)
                    case UsualType.Decimal	; return self:_decimalValue:CompareTo(rhs:_decimalValue)
                    case UsualType.Int64		; return self:_i64Value:CompareTo(rhs:_i64Value)
                    case UsualType.Logic		; return self:_logicValue:CompareTo(rhs:_logicValue)
                    case UsualType.Long		; return self:_intValue:CompareTo(rhs:_intValue)
                    case UsualType.Ptr		; return self:_ptrValue:ToInt64():CompareTo(rhs:_ptrValue:ToInt64())
                    // Uses String Comparison rules
                    // Vulcan does a case insensitive comparison ?
                    case UsualType.String		; return String.Compare( _stringValue,  rhs:_stringValue)
                    case UsualType.Symbol		; return String.Compare( (string) self:_symValue, (string) rhs:_symValue)
                    otherwise					; return 0
                end switch
            else
                // Type of LHS different from type of RHS
                switch self:_UsualType
                    case UsualType.Void
                        return -1
                    case UsualType.Date
                        // Upscale when needed to avoid overflow errors
                        switch rhs:_UsualType
                            case UsualType.DateTime	; return _dateValue:CompareTo((Date) rhs:_dateTimeValue)
                            case UsualType.Decimal	; return ((System.Decimal) (int) _dateValue):CompareTo(rhs:_decimalValue)
                            case UsualType.Float		; return ((real8) (int) _dateValue):CompareTo(rhs:_r8Value)
                            case UsualType.Int64		; return ( (int64) (int) _dateValue):CompareTo(rhs:_i64Value)
                            case UsualType.Long		; return ((int) _dateValue):CompareTo(rhs:_intValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Float
                        switch rhs:_usualType
                            case UsualType.Date		; return _r8Value:CompareTo( (real8) (int) rhs:_dateValue)
                            case UsualType.Decimal	; return _r8Value:CompareTo( (real8) rhs:_decimalValue)
                            case UsualType.Long		; return _r8Value:CompareTo( (real8) rhs:_intValue)
                            case UsualType.Int64		; return _r8Value:CompareTo( (real8) rhs:_i64Value)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Long
                        // Upscale when needed to avoid overflow errors
                        switch rhs:_usualType
                            case UsualType.Date		; return _intValue:CompareTo((int) rhs:_dateValue)
                            case UsualType.Int64		; return ((int64)_intValue):CompareTo(rhs:_i64Value)
                            case UsualType.Float		; return ((real8)_intValue):CompareTo(rhs:_r8Value)
                            case UsualType.Decimal	; return ((System.Decimal)_intValue):CompareTo(rhs:_decimalValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Int64
                        switch rhs:_usualType
                            case UsualType.Date		; return _i64Value:CompareTo((int) rhs:_dateValue)
                            case UsualType.Long		; return _i64Value:CompareTo( rhs:_intValue)
                            case UsualType.Float		; return _i64Value:CompareTo( rhs:_r8Value)
                            case UsualType.Decimal	; return _i64Value:CompareTo( rhs:_decimalValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Decimal
                        switch rhs:_usualType
                            case UsualType.Date		; return _decimalValue:CompareTo((int) rhs:_dateValue)
                            case UsualType.Long		; return _decimalValue:CompareTo(rhs:_intValue)
                            case UsualType.Float		; return _decimalValue:CompareTo(rhs:_r8Value)
                            case UsualType.Int64		; return _decimalValue:CompareTo(rhs:_i64Value)
                            otherwise
                                nop	// uses comparison by type
                        end switch
                end switch
            endif
            if rhs:_usualType == UsualType.Void
                return 1
            elseif self:_usualType > rhs:_usualType
                return 1
            elseif self:_usualType < rhs:_usualType
                return -1
            endif
            return 0

		#endregion

        #region implementation IComparable
            /// This method is needed to implement the IComparable interface.
        PUBLIC METHOD CompareTo(o AS OBJECT) AS LONG
				RETURN CompareTo((__Usual) o)
        #endregion

        #region Comparison Operators
		/// This operator is used in code generated by the compiler when needed.
        static operator >(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue > rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue > rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue > rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value > rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value > rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value > rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value > rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value > rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value > (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue > rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue > rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue > (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue >  rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue> rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue > rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue > rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue > (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.DateTime	; return lhs:_dateTimeValue > rhs:_dateTimeValue
                        case UsualType.Date		; return lhs:_dateTimeValue > (DateTime) rhs:_dateValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    nop // error below
            end switch
            throw BinaryError(">", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

			/// This operator is used in code generated by the compiler when needed.
            static operator >=(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue >= rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value >= rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value >= (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue >= (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue >=  rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue>= rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue >= rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		>= rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue >= rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		>=  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue >=  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError(">=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError(">=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
			static operator <(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue < rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue < rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue < rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value < rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value < rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value < rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value < rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value < rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value < (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue < rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue < rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue < (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue <  rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue< rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue < rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue	< rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue < (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		<  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue <  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError("<", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("<", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator <=(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue <= rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value <= rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value <= (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue <= (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue <=  rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return  lhs:_stringValue<= rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue <= rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue	<= rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue <= (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		<=  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue <=  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError("<=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("<=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)
        #endregion

		#region IEquatable<T>
		public method Equals(u as USUAL) as logic
				if u:IsNil
					return self:IsNil
				endif
				return UsualEquals(u, "Usual.Equals()")

		#endregion
        #region Operators for Equality
            public method Equals(obj as object) as logic
				if obj == null
					return self:IsNil
				endif
				return UsualEquals((USUAL) obj, "Usual.Equals()")

            public method GetHashCode() as int
				local oValue as object
				oValue := self:Value
				if oValue == NULL
					return 0
				endif
				return oValue:GetHashCode()

            /// This operator is used in code generated by the compiler when needed.
            static operator ==(lhs as __Usual, rhs as __Usual) as logic
				return lhs:UsualEquals(rhs, "==")

            /// This operator is used in code generated by the compiler when needed.
            static operator !=(lhs as __Usual, rhs as __Usual) as logic
            if lhs:_usualType == UsualType.STRING .and. rhs:_usualType == UsualType.STRING
                return ! __StringEquals(  lhs:_stringValue, rhs:_stringValue)
            else
                return ! lhs:UsualEquals(rhs, "!=")
            endif

            internal method UsualEquals( rhs as __Usual, op as string) as logic
			if rhs:IsNil
				return self:IsNil
			endif
            switch self:_usualType
                case UsualType.Object
                    if rhs:_usualType == UsualType.Object
                        return self:_refData == rhs:_refData
                    else
                        nop // error below
                    endif

                case UsualType.Void
                    return rhs:_usualType == UsualType.Void

                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_intValue == rhs:_intValue
                        case UsualType.Int64		; return (int64) self:_intValue == rhs:_i64Value	// cast lhs to int64 to avoid overflow
                        case UsualType.Float		; return (real8) self:_intValue == rhs:_r8Value // cast lhs to real8 to avoid overflow
                        case UsualType.Decimal	; return (System.Decimal) self:_intValue == rhs:_decimalValue	// cast lhs to decimal to avoid overflow
                        case UsualType.Logic		; return rhs:_logicValue == (self:_intValue <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return _i64Value == (int64) rhs:_intValue
                        case UsualType.Int64		; return _i64Value == rhs:_i64Value
                        case UsualType.Float		; return  (real8) _i64Value == rhs:_r8Value
                        case UsualType.Decimal	; return _i64Value == rhs:_decimalValue
                        case UsualType.Logic		; return rhs:_logicValue == (self:_i64Value <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_r8Value == (real8) rhs:_intValue
                        case UsualType.Int64		; return self:_r8Value == (real8) rhs:_i64Value
                        case UsualType.Float		; return self:_r8Value ==  rhs:_r8Value
                        case UsualType.Decimal	; return self:_r8Value ==  (real8) rhs:_decimalValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_decimalValue == rhs:_intValue
                        case UsualType.Int64		; return self:_decimalValue == rhs:_i64Value
                        case UsualType.Float		; return self:_decimalValue == (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return self:_decimalValue == rhs:_decimalValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.LOGIC
                    switch rhs:_usualType
                        case UsualType.LOGIC		; return self:_logicValue == rhs:_logicValue
                        case UsualType.Long		; return self:_logicValue == (rhs:_intValue <> 0)
                        case UsualType.Int64		; return self:_logicValue == (rhs:_i64Value <> 0)
                        case UsualType.Decimal	; return self:_logicValue == (rhs:_decimalValue <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.DATE
                    switch rhs:_usualType
                        case UsualType.DATE		; return self:_dateValue == rhs:_dateValue
                        case UsualType.DateTime	; return self:_dateValue == (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.DateTime	; return self:_dateTimeValue == rhs:_dateTimeValue
                        case UsualType.DATE		; return self:_dateTimeValue == (DateTime) rhs:_dateValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.STRING
                    switch rhs:_usualType
                        case UsualType.STRING		; return self:_stringValue == rhs:_stringValue
                        case UsualType.Symbol		; return self:_stringValue == rhs:_symValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.ARRAY
                    switch rhs:_usualType
                        case UsualType.ARRAY		; return self:_refData == rhs:_refData
                        otherwise
                            nop // error below
                    end switch

                case UsualType.CodeBlock
                    switch rhs:_usualType
                        case UsualType.CodeBlock	; return self:_refData == rhs:_refData
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Ptr
                    switch rhs:_usualType
                        case UsualType.Ptr		; return self:_ptrValue == rhs:_ptrValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Symbol
                    switch rhs:_usualType
                        case UsualType.Symbol		; return self:_symValue == rhs:_symValue
                        case UsualType.String		; return self:_symValue == rhs:_stringValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError(op, __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, self, rhs)

            end switch
            throw BinaryError(op, __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, self, rhs)

        #endregion

        #region Unary Operators
            /// This operator is used in code generated by the compiler when needed.
            static operator !(u as __Usual) as logic
            if u:_usualType == UsualType.LOGIC
                return !u:_logicValue
            endif
            throw UnaryError("!", u)

            /// This operator is used in code generated by the compiler when needed.
            static operator ~(u as __Usual) as __Usual
            if u:_usualType == UsualType.Long
                return ~u:_intValue
            endif
            if u:_usualType == UsualType.Int64
                return ~u:_i64Value
            endif
            throw UnaryError("~", u)

            /// This operator is used in code generated by the compiler when needed.
            static operator -(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return -u:_intValue
                case UsualType.Int64		; return -u:_i64Value
                case UsualType.Float		; return -u:_floatValue
                case UsualType.Decimal	; return -u:_decimalValue
                otherwise
                    throw UnaryError("-", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator +(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue
                case UsualType.Int64		; return u:_i64Value
                case UsualType.Float		; return u:_floatValue
                case UsualType.Decimal	; return u:_decimalValue
                otherwise
                    throw UnaryError("+", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
			static operator --(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue - 1
                case UsualType.Int64		; return u:_i64Value - 1
                case UsualType.Float		; return u:_floatValue -1
                case UsualType.Decimal	; return u:_decimalValue - 1
                otherwise
                    throw UnaryError("--", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator ++(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue + 1
                case UsualType.Int64		; return u:_i64Value + 1
                case UsualType.Float		; return u:_floatValue +1
                case UsualType.Decimal	; return u:_decimalValue + 1
                otherwise
                    throw UnaryError("++", u)
            end switch

        #endregion
        #region Numeric Operators for Add, Delete etc (also for strings)

            /// This operator is used in code generated by the compiler when needed.
            static operator +(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue + rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue + rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue + rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value + rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value + rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value + rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value + rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value + rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value + rhs:_r8Value, lhs:_width, lhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value + (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue + rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue + rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue + (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.String
                    switch rhs:_usualType
                        case UsualType.String		; return lhs:_stringValue+ rhs:_stringValue
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.ARGNOTSTRING), false, lhs, rhs)
                    end switch
                case UsualType.Date
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateValue + rhs:_intValue
                        case UsualType.Int64	; return lhs:_dateValue + rhs:_i64Value
                        CASE UsualType.Float	; RETURN lhs:_dateValue + rhs:_r8Value
						// Note We can't add dates, but we can subtract dates
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.DATE_ADD), false, lhs, rhs)
                    end switch
                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateTimeValue:Add( TimeSpan.FromDays(rhs:_intValue ))
                        case UsualType.Int64	; return lhs:_dateTimeValue:Add(TimeSpan.FromDays(rhs:_i64Value))
                        CASE UsualType.Float	; RETURN lhs:_dateTimeValue:Add(TimeSpan.FromDays(rhs:_r8Value))
						// Note We can't add dates, but we can subtract dates
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.DATE_ADD), false, lhs, rhs)
                    end switch

                otherwise
                    throw BinaryError("+", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("+", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator -(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue - rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value - rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value - rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value - rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value - rhs:_intValue ,lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value - rhs:_i64Value ,lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value - rhs:_r8Value	,lhs:_width, lhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value - (real8) rhs:_decimalValue ,lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue - (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.String
                    switch rhs:_usualType
                        case UsualType.String		; return CompilerServices.__StringSubtract(lhs, rhs)
                        otherwise					; throw BinaryError("-", __CavoStr(VOErrors.ARGNOTSTRING), false, lhs, rhs)
                    end switch
                case UsualType.Date
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_dateValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_dateValue - rhs:_r8Value
                        case UsualType.Date			; return lhs:_dateValue - rhs:_dateValue
                        case UsualType.DateTime		; return lhs:_dateValue - (Date) rhs:_dateTimeValue
                        otherwise					; throw BinaryError("+", __CavoStr(VOErrors.DATE_SUBTRACT), false, lhs, rhs)
                    end switch

                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.Long			; return lhs:_dateTimeValue:Subtract(TimeSpan{rhs:_intValue,0,0,0})
                        case UsualType.Int64		; return lhs:_dateTimeValue:Subtract( TimeSpan{(int)rhs:_i64Value,0,0,0})
                        case UsualType.Float		; return lhs:_dateTimeValue:Subtract( TimeSpan{(int)rhs:_r8Value,0,0,0})
                        case UsualType.Date			; return lhs:_dateTimeValue:Subtract((DateTime) rhs:_dateValue):Days
                        case UsualType.DateTime		; return lhs:_dateTimeValue:Subtract( rhs:_dateTimeValue):Days
                        otherwise					; throw BinaryError("+", __CavoStr(VOErrors.DATE_SUBTRACT), false, lhs, rhs)
                    end switch

                otherwise
                    throw BinaryError("-", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("-", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator /(lhs as __Usual, rhs as __Usual) as __Usual

            switch lhs:_usualType

                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long
                            local result as int
                            local remainder as int
                            result := Math.DivRem(lhs:_intValue, rhs:_intValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_intValue
                            endif
                        case UsualType.Int64
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem((int64) lhs:_intValue, rhs:_i64Value, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_i64Value
                            endif
                        case UsualType.Float
                            return Float{lhs:_intValue / rhs:_r8Value, rhs:_width, rhs:_decimals}

                        case UsualType.Decimal
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem((int64) lhs:_intValue, (int64) rhs:_decimalValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_decimalValue
                            endif
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem(lhs:_i64Value, rhs:_intValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_intValue
                            endif
                        case UsualType.Int64
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem( lhs:_i64Value, rhs:_i64Value, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_i64Value
                            endif
                        case UsualType.Float
                            RETURN FLOAT{lhs:_i64Value / rhs:_r8Value, rhs:_width, rhs:_decimals}

                        case UsualType.Decimal
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem(lhs:_i64Value, (int64) rhs:_decimalValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_decimalValue
                            endif
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value / rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value / rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value / rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value / (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue / rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue / rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue / (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue / rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("/", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("/", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator %(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue % rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue % rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_intValue % rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_intValue % rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value % rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value % rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_i64Value % rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_i64Value % rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value % rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value % rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value % rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value % (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue % rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue % rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue % (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue %  rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("%", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("%", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator *(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue * rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue * rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_intValue * rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_intValue * rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value * rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value * rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_i64Value * rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_i64Value * rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value * rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value * rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value * rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value * (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue * rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue * rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue * (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue *  rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("*", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("*", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator >>(lhs as __Usual, rhs as int) as __Usual
            // Right shift
            switch lhs:_usualType
                case UsualType.Long	; return lhs:_intValue >> rhs
                case UsualType.Int64	; return lhs:_i64Value >> rhs
                otherwise
                    throw BinaryError(">>", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator <<(lhs as __Usual, rhs as long) as __Usual
            // Left shift
            switch (lhs:_usualType)
                case UsualType.Long	; return lhs:_intValue << rhs
                case UsualType.Int64	; return lhs:_i64Value << rhs
                otherwise
                    throw BinaryError("<<", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator &(lhs as __Usual, rhs as __Usual) as __Usual
            // Bitwise And
            switch (lhs:_usualType)
                case UsualType.Long
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_intValue & rhs:_intValue
                        case UsualType.Int64		; return (int64) lhs:_intValue & rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_i64Value & (int64) rhs:_intValue
                        case UsualType.Int64	; return  lhs:_i64Value & rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                otherwise
                    throw BinaryError("&", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch
            throw BinaryError("&", __CavoStr(VOErrors.ARGNOTINTEGER), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator |(lhs as __Usual, rhs as __Usual) as __Usual
            // Bitwise or
            switch (lhs:_usualType)
                case UsualType.Long
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_intValue | rhs:_intValue
                        case UsualType.Int64		; return (int64) lhs:_intValue | rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_i64Value | (int64) rhs:_intValue
                        case UsualType.Int64		; return  lhs:_i64Value | rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                otherwise
                    throw BinaryError("|", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch
            throw BinaryError("|", __CavoStr(VOErrors.ARGNOTINTEGER), false, lhs, rhs)
        #endregion

        #region Implicit From Usual to Other Type

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Array
				switch u:_usualType
				case UsualType.Array	; return (Array) u:_refData
				case UsualType.Void	; return null
				case UsualType.Object
					if u:_refData== null
						return null
					elseif u:_refData is Array
						return (Array) u:_refData
					endif
				end switch
				throw ConversionError(ARRAY, typeof(Array), u)

            STATIC OPERATOR IMPLICIT(u AS __Usual) AS CodeBlock
				SWITCH u:_usualType
				CASE UsualType.CodeBlock
					return u:_codeblockValue
				CASE UsualType.Object
					IF u:_refData == NULL
						RETURN NULL
					ENDIF
				CASE UsualType.Void
					RETURN NULL
				END SWITCH
				throw ConversionError(CODEBLOCK, typeof(CodeBlock), u)

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as logic
            switch u:_usualType
                case UsualType.Logic		; return u:_logicValue
                case UsualType.Long		; return u:_intValue != 0
                case UsualType.Int64		; return u:_i64Value != 0
                case UsualType.Decimal	; return u:_decimalValue != 0
                case UsualType.Void		; return false
                otherwise
                    throw ConversionError(LOGIC, typeof(logic), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Date
            switch u:_usualType
                case UsualType.Date		; return u:_dateValue
                case UsualType.DateTime	; return (Date) u:_dateTimeValue
                case UsualType.Void		; return Date{0}
                otherwise
                    throw ConversionError(DATE, typeof(Date), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as DateTime
            switch u:_usualType
                case UsualType.Date		; return (DateTime) u:_dateValue
                case UsualType.DateTime	; return u:_dateTimeValue
                case UsualType.Void		; return DateTime.MinValue
                otherwise
                    throw ConversionError(DATE, typeof(Date), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as System.IntPtr
            switch u:_usualType
                CASE UsualType.Ptr		; RETURN u:_ptrValue
                case UsualType.LONG		; return (IntPtr) u:_intValue
                case UsualType.Int64		; return (IntPtr) u:_i64Value
                case UsualType.Decimal	; return (IntPtr) u:_decimalValue
                case UsualType.Void		; return IntPtr.Zero
                otherwise
                    throw ConversionError(PTR, typeof(IntPtr), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as string
            switch u:_usualType
                case UsualType.String	; return u:_stringValue
                case UsualType.Void	; return ""
                case UsualType.SYMBOL	; return (string) u:_symValue
                otherwise
                    throw ConversionError(STRING, typeof(string), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Symbol
            switch u:_usualType
                case UsualType.String	; return (Symbol) u:_stringValue
                case UsualType.Void	; return Symbol{""}
                case UsualType.SYMBOL	; return u:_symValue
                otherwise
                    throw ConversionError(SYMBOL, typeof(Symbol), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Psz
            switch u:_usualType
                case UsualType.Ptr	; return (Psz) u:_ptrValue
                case UsualType.String	; return Psz{u:_stringValue}
                case UsualType.Void	; return Null_Psz
                otherwise
                    throw ConversionError(PSZ, typeof(Psz), u)
            end switch

        #endregion
        #region Implicit Numeric Operators
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as byte
            try
                switch u:_usualType
                    case UsualType.Long		; return checked((byte) u:_intValue)
                    case UsualType.Int64		; return checked((byte) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToByte(u:_r8Value)
						else
							return checked((byte) u:_r8Value)
						endif
                    case UsualType.Logic		; return iif(u:_logicValue, 1, 0)
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToByte(u:_decimalValue )
						else
							return checked((byte) u:_decimalValue )
						endif
                    case UsualType.Void		; return  0
                    otherwise
                        throw ConversionError(BYTE, typeof(byte), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "BYTE", typeof(byte), u)
            end try
            return 0

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as short
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((short) u:_intValue)
                    case UsualType.Int64	; return checked((short) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt16(u:_r8value)
						else
							return checked((short) u:_r8Value)
						endif

                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt16(u:_decimalValue )
						else
							return checked((short) u:_decimalValue )
						endif

                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(SHORT, typeof(short), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "SHORT", typeof(short), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as long
            try
                switch u:_usualType
                    case UsualType.Long	; return u:_intValue
                    case UsualType.Int64	; return checked((long) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt32(u:_r8Value)
						else
							return  checked((long) u:_r8Value)
						endif
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt32(u:_decimalValue )
						else
							return checked((long) u:_decimalValue )
						endif
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(LONG, typeof(long), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "LONG", typeof(long), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as int64
            try
                switch u:_usualType
                    case UsualType.Long	; return u:_intValue
                    case UsualType.Int64	; return checked((int64) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt64(u:_r8Value)
						else
							return  checked((int64) u:_r8Value)
						endif
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt64(u:_decimalValue )
						else
							return checked((int64) u:_decimalValue )
						endif

                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(INT64, typeof(int64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "INT64", typeof(int64), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as System.Decimal
            try
                switch u:_usualType
                    case UsualType.Long	; return checked(u:_intValue)
                    case UsualType.Int64	; return checked(u:_i64Value)
                    case UsualType.Float	; return checked((System.Decimal) u:_r8Value)
                    case UsualType.Decimal; return checked(u:_decimalValue)
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(UsualType.DECIMAL, typeof(int64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "DECIMAL", typeof(int64), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as SByte
            try
                switch u:_usualType
                    case UsualType.Long	; return checked( (SByte) u:_intValue)
                    case UsualType.Int64	; return checked( (SByte) u:_i64Value)
                    case UsualType.Float	; return checked( (SByte) u:_r8Value)
                    case UsualType.Decimal; return checked((SByte) u:_decimalValue )
                    case UsualType.Logic	; return (SByte) iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(BYTE, typeof(SByte), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "SBYTE", typeof(SByte), u)
            end try

            // Unsigned
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as word
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((word) u:_intValue)
                    case UsualType.Int64	; return checked((word) u:_i64Value)
                    case UsualType.Float	; return checked((word) u:_r8Value)
                    case UsualType.Decimal; return checked((word) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(WORD, typeof(word), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "WORD", typeof(word), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as dword
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((dword) u:_intValue)
                    case UsualType.Int64	; return checked((dword) u:_i64Value)
                    case UsualType.Float	; return checked((dword) u:_r8Value)
                    case UsualType.Decimal; return checked((dword) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(DWORD, typeof(dword), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "DWORD", typeof(dword), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as uint64
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((uint64) u:_intValue)
                    case UsualType.Int64	; return checked((uint64) u:_i64Value)
                    case UsualType.Float	; return checked((uint64) u:_r8Value)
                    case UsualType.Decimal; return checked((uint64) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(UINT64, typeof(uint64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "UINT64", typeof(uint64), u)
            end try

            // Single, Double and FLoat
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as real4
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((real4) u:_intValue)
                    case UsualType.Int64	; return checked((real4) u:_i64Value)
                    case UsualType.Float	; return checked((real4) u:_r8Value)
                    case UsualType.Decimal; return checked((real4) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(REAL4, typeof(real4), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "REAL4", typeof(real4), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as real8
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((real8) u:_intValue)
                    case UsualType.Int64	; return checked((real8) u:_i64Value)
                    case UsualType.Float	; return checked((real8) u:_r8Value)
                    case UsualType.Decimal; return checked((real8) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(REAL8, typeof(real8), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "REAL8", typeof(real8), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Float
            try
                switch u:_usualType
                    case UsualType.Long	; return checked(Float{(real8) u:_intValue})
                    case UsualType.Int64	; return checked(Float{(real8) u:_i64Value})
                    case UsualType.Float	; return u:_floatValue
                    case UsualType.Decimal; return checked(Float{(real8) u:_decimalValue})
                    case UsualType.Logic	; return Float{iif(u:_logicValue, 1, 0)}
                    case UsualType.Void	; return Float{0}
                    otherwise
                        throw ConversionError(FLOAT, typeof(Float), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "FLOAT", typeof(Float), u)
            end try

        #endregion
        #region Implicit from Other Type to Usual

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as object) as Usual
				local result as USUAL
				if value != null .and. value:GetType() == typeof(__Usual)
					result := (Usual) value
				elseif value == null
					result := Usual{NULL, true}
				else
					result := usual{value}
				endif
				return result

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as logic) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as byte) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Array) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Date) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.DateTime) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Float) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as real8) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as short) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as long) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as int64) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as uint64) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Psz) as __Usual
				return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as symbol) as __Usual
				return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.Decimal) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.IntPtr) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as SByte) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as real4) as __Usual
            return __Usual{(real8)value }

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as string) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as word) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as dword) as __Usual
            return iif((value <= 0x7fffffff),__Usual{(long)value },__Usual{(Float)value })
        #endregion

        #region implementation IConvertable
            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToBoolean(provider as System.IFormatProvider) as logic
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToByte(provider as System.IFormatProvider) as byte
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToChar(provider as System.IFormatProvider) as char
            var o := __Usual.ToObject(self)
            if o is IConvertible
                return ((IConvertible)o):ToChar(provider)
            endif
            throw InvalidCastException{}

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDateTime(provider as System.IFormatProvider) as System.DateTime
            return (Date) self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDecimal(provider as System.IFormatProvider) as Decimal
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDouble(provider as System.IFormatProvider) as real8
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt16(provider as System.IFormatProvider) as short
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt32(provider as System.IFormatProvider) as long
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt64(provider as System.IFormatProvider) as int64
            return self
			/// <exclude />
            static method ToObject(u as __Usual) as object
            switch u:_usualType
                case UsualType.ARRAY		; return u:_arrayValue
                case UsualType.CodeBlock	; return u:_codeblockValue
                case UsualType.Date			; return u:_dateValue
                case UsualType.DateTime		; return u:_dateTimeValue
                case UsualType.Decimal		; return u:_decimalValue
                case UsualType.FLOAT		; return u:_floatValue
                case UsualType.Int64		; return u:_i64Value
                case UsualType.Long			; return u:_intValue
                case UsualType.LOGIC		; return u:_logicValue
                case UsualType.OBJECT		; return u:_refData
                case UsualType.PTR			; return u:_ptrValue
                case UsualType.STRING		; return u:_refData
                case UsualType.SYMBOL		; return u:_symValue
                case UsualType.Void		; return null
                otherwise					; return null
            end switch

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToSByte(provider as System.IFormatProvider) as SByte
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToSingle(provider as System.IFormatProvider) as real4
            return self

			/// <exclude />
			public method AsString() as string strict
				return self:ToString()

			/// <exclude />
			public method Clone() as usual
				// clone types that need cloning
				local result as usual
				switch self:_usualType
				case UsualType.Object
					result := usual{self:value}
				case UsualType.String
					result := usual { String.Copy(self:_stringValue)}
				case UsualType.Array
					result := usual { Aclone(self:_arrayValue) }
				otherwise
					result := self
				end switch
				return result

            public method ToString() as string
            local strResult as string

            switch (self:_usualType)
                case UsualType.Array		; strResult := iif (self:_refData == null, "NULL_ARRAY", self:_arrayValue:ToString())
                case UsualType.CODEBLOCK  ; strResult := iif (self:_refData == null, "NULL_CODEBLOCK", self:_codeblockValue:ToString())
                case UsualType.OBJECT		; strResult := iif (self:_refData == null, "NULL_OBJECT", self:_refData:ToString())
                case UsualType.Date		; strResult := self:_dateValue:ToString()
                case UsualType.DateTime	; strResult := self:_dateTimeValue:ToString()
                case UsualType.Decimal	; strResult := iif (self:_refData == null, "0", self:_decimalValue:ToString())
                case UsualType.Float		; strResult := self:_r8Value:ToString()
                case UsualType.Long		; strResult := self:_intValue:ToString()
                case UsualType.Int64		; strResult := self:_i64Value:ToString()
                case UsualType.LOGIC		; strResult := iif(!self:_logicValue , ".F." , ".T.")
                case UsualType.PTR		; strResult := self:_ptrValue:ToString()
                case UsualType.STRING		; strResult := iif (self:_refData == null, "NULL_STRING", self:_stringValue:ToString())
                case UsualType.Symbol		; strResult := self:_symValue:ToString()
                case UsualType.Void		; strResult := "NIL"
                otherwise					; strResult := ""
            end switch
            return strResult

            public method ToString(provider as System.IFormatProvider) as string
            return self:ToString()

            public method IConvertible.ToType(conversionType as System.Type, provider as System.IFormatProvider) as object
            if conversionType:IsPointer
                switch self:_usualType
                    case UsualType.PTR	; return _ptrValue
                    case UsualType.Long	; return (IntPtr) _intValue
                    case UsualType.Int64	; return (IntPtr) _i64Value
                    otherwise
                        throw InvalidCastException{}
                end switch
            else
                var o := __Usual:ToObject(self)
                if conversionType:IsAssignableFrom(o:GetType())
                    return o
                elseif o is IConvertible
                    return ((IConvertible) o):Totype(conversionType, provider)
                else
                    throw InvalidCastException{}
                endif
            endif

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt16(provider as System.IFormatProvider) as word
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt32(provider as System.IFormatProvider) as dword
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt64(provider as System.IFormatProvider) as uint64
            return self

           /// <exclude />
		    public method GetTypeCode() as System.TypeCode
            switch _usualType
                case UsualType.ARRAY	; return TypeCode.Object
                case UsualType.CodeBlock; return TypeCode.Object
                case UsualType.Date	; return TypeCode.Object
                case UsualType.DateTime; return TypeCode.DateTime
                case UsualType.Decimal; return TypeCode.Decimal
                case UsualType.FLOAT	; return TypeCode.Object
                case UsualType.Int64	; return TypeCode.Int64
                case UsualType.Long	; return TypeCode.Int32
                case UsualType.LOGIC	; return TypeCode.Boolean
                case UsualType.OBJECT	; return TypeCode.Object
                case UsualType.PTR	; return TypeCode.Object
                case UsualType.STRING ; return TypeCode.String
                case UsualType.SYMBOL ; return TypeCode.Object
                case UsualType.Void
                otherwise				; return TypeCode.Object
            end switch
        #endregion

        #region Error Method
           internal method ValType() as string
            switch self:_usualType
                case UsualType.Array		; return "A"
                case UsualType.CodeBlock	; return "B"
                case UsualType.Date			; return "D"
                case UsualType.DateTime		; return "D"
                case UsualType.DECIMAL		; return "N"
                case UsualType.FLOAT		; return "N"
                case UsualType.Int64		; return "N"
                case UsualType.Long			; return "N"
                case UsualType.Logic		; return "L"
                case UsualType.PTR			; return "-"
                case UsualType.String		; return "C"
				case UsualType.Object		; return "O"
                case UsualType.Symbol		; return "#"
                case UsualType.Void			; return "U"
                otherwise
					Debug.Fail( "Unhandled data type in Usual:Valtype" )
            end switch
			return "?"

            static internal method ConversionError(toTypeString as string, toType as System.Type, u as Usual) as Error
				var err			:= Error{InvalidCastException{}}
				err:GenCode		:= GenCode.EG_DataType
				err:ArgTypeReq	:= toType
				err:ArgNum		:= 1
				err:FuncSym		:= "USUAL => "+toTypeString
				err:Description := VO_Sprintf(VOErrors.USUALCONVERSIONERR, TypeString(UsualType(u)), toTypeString)
				err:Arg			:= "USUAL"
				err:Args        := <OBJECT>{u}
				return err

            static internal method ConversionError(typeNum as DWORD, toType as System.Type, u as Usual) as Error
				var err			:= Error{ InvalidCastException{} }
				err:GenCode		:= GenCode.EG_DataType
				err:ArgTypeReq	:= toType
				err:ArgNum		:= 1
				err:FuncSym		:= "USUAL => "+TypeString((DWORD) typeNum)
				err:ArgType		:= typeNum
				err:Description := VO_Sprintf(VOErrors.USUALCONVERSIONERR, TypeString(UsualType(u)), typeString(DWORD(typeNum)))
				err:Arg			:= "USUAL"
				err:Args        := <OBJECT>{u}
				return err

            static internal method OverflowError(ex as OverflowException, toTypeString as string, toType as System.Type, u as Usual) as Error
				var err			 := Error{ex}
				err:GenCode		 := GenCode.EG_NUMOVERFLOW
				err:ArgTypeReq	 := toType
				err:ArgNum		 := 1
				err:FuncSym		 := "USUAL => "+toTypeString
				err:Description  := VO_Sprintf(VOErrors.USUALOVERFLOWERR, TypeString(UsualType(u)), toTypeString)
				err:Arg			 := "USUAL"
				err:Args		 := <OBJECT>{u}
				return err

            static internal method BinaryError( cOperator as string, message as string, left as logic, lhs as Usual, rhs as Usual) as Error
				var err			 := Error{ArgumentException{}}
				err:GenCode		 := GenCode.EG_ARG
				err:ArgNum		 := iif (left, 1, 2)
				err:FuncSym		 := cOperator
				err:Description  := message
				err:Arg			 := IIF(left, "left operand" , "right operand")
				err:Args         := <OBJECT> {lhs, rhs}
				return err

            static internal method UnaryError( cOperator as string, u as Usual) as Error
				var err			 := Error{ArgumentException{}}
				err:GenCode		 := GenCode.EG_ARG
				err:ArgNum		 := 1
				err:FuncSym		 := cOperator
				err:Description  := __CavoStr(VOErrors.INVALIDARGTYPE)
				err:Arg			 := "USUAL"
				err:Args         := <OBJECT> {u}
				return err

        #endregion

		#region Special methods used by the compiler
        /// This method is used by the compiler for code that does an inexact comparison between two usuals.
		static method __InexactEquals( lhs as usual, rhs as usual ) as logic
			if lhs:IsString .and. rhs:IsString
				return __StringEquals( lhs:_stringValue, rhs:_stringValue)
			else
				return lhs:UsualEquals(rhs, "=")
			endif

        /// This method is used by the compiler for code that does an inexact comparison between a usual and a string.
		static method __InexactEquals( lhs as usual, rhs as string ) as logic
			if lhs:IsString
				return __StringEquals( lhs:_stringValue, rhs)
			else
				throw BinaryError("=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
			endif

        /// This method is used by the compiler for code that does an inexact comparison.
		static method __InexactNotEquals( lhs as usual, rhs as usual ) as logic
			// emulate VO behavior for "" and NIL
			// "" = NIL but also "" != NIL, NIL = "" and NIL != ""
			IF lhs:IsString
				if rhs:IsString
					return __StringNotEquals( lhs:_stringValue, rhs:_stringValue)
				elseif rhs:IsNil .and. lhs:_stringValue != null .and. lhs:_stringValue:Length == 0
					RETURN FALSE
				ENDIF
			endif
			if rhs:IsString .and. lhs:IsNil .and. rhs:_stringValue != null .and. rhs:_stringValue:Length == 0
				return false
			else
				return ! lhs:UsualEquals(rhs, "<>")
			endif
        /// This method is used by the compiler for code that does an inexact comparison.
		static method __InexactNotEquals( lhs as usual, rhs as string ) as logic
			if lhs:IsString
				return __StringNotEquals( lhs:_stringValue, rhs)
			else
				throw BinaryError("<>", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
			endif

		#endregion
        internal class UsualDebugView
            private _uvalue as __Usual
            public constructor (u as __Usual)
            _uvalue := u

            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] ;
            public property Value as object get _uvalue:VALUE
            public property Type  as UsualType get _uvalue:_usualType

        end class
        */
    end structure

    [StructLayout(LayoutKind.Explicit)];
    internal structure _UsualData
        // Fields
        [FieldOffset(0)] internal d as __VoDate
        [FieldOffset(0)] internal r8 as real8
        [FieldOffset(0)] internal i as long
        [FieldOffset(0)] internal i64 as int64
        [FieldOffset(0)] internal l as logic
        [FieldOffset(0)] internal p as System.IntPtr
        [FieldOffset(0)] internal s as symbol
        [FieldOffset(0)] internal dt as System.DateTime

    end structure

    internal enum UsualType as byte
        // These numbers must match with the types defined in the compiler
        // They also match with the USUAL types in VO (BaseType.h)
        member @@Void		:=0
        member @@Long		:=1
        member @@Date		:=2
        member @@Float		:=3
        // Note # 4 (FIXED) was defined but never used in VO
        member @@Array		:=5
        member @@Object		:=6
        member @@String		:=7
        member @@Logic		:=8
        member @@CodeBlock	:=9
        member @@Symbol		:=10
        // see below for missing values
        // The follow numbers are defined but never stored inside a USUAL in VO and Vulcan
        member @@Byte		:=11
        member @@ShortInt	:=12
        member @@Word		:=13
        member @@DWord		:=14
        member @@Real4		:=15
        member @@Real8		:=16
        member @@Psz		:=17
        member @@Ptr		:=18
        member @@Usual		:=19	// USUAL by Ref, not implemented in Vulcan
        member @@Int64		:=22
        member @@Uint64     :=23
        member @@Char		:=24    // not stored in a usual
        member @@Dynamic    :=25
        member @@DateTime	:=26
        member @@Decimal	:=27
        member @@Memo		:=32	// Used in RDD system in VO
        member @@Invalid    :=99
    end enum

    [StructLayout(LayoutKind.Explicit, Pack := 1)];
    internal structure UsualFlags
        [FieldOffset(0)] export usualType as UsualType
        [FieldOffset(1)] export width as Sbyte
        [FieldOffset(2)] export decimals as Sbyte
        [FieldOffset(3)] export isByRef as logic

        constructor(type as UsualType)
        usualType := type
    end structure
///
/// Determine the data type of an expression.
///
/// <param name="x"></param>
/// <returns>
/// </returns>
function UsualType(u as __Usual) as dword
	return (dword) u:Type

///
/// Access contents of an address, whether it is passed by reference or not.
///
/// <param name="u"></param>
/// <returns>
/// </returns>
function UsualVal(u as Usual) as Usual
	return u

///
/// Determine the data type of an expression.
///
/// <param name="u"></param>
/// <returns>
/// </returns>
function ValType(u as Usual) as string
	return u:ValType()

end namespace

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
using System
USING System.Runtime.InteropServices
using System.Runtime.CompilerServices
using System.Diagnostics
using XSharp.Internal
begin namespace XSharp
	/// Internal type that implements the VO Compatible USUAL type.

	/// This type has many operators and implicit converters that normally are never directly called from user code.
	///
    [StructLayout(LayoutKind.Sequential, Pack := 4)];
    [DebuggerDisplay("{Value,nq} ({_usualType})", Type := "USUAL")];
    [DebuggerTypeProxy(typeof(UsualDebugView))];
    PUBLIC STRUCTURE __Usual IMPLEMENTS IConvertible, ;
		IComparable, ;
		IComparable<__Usual>, ;
		IEquatable<__Usual>
        #region static fields
			/// <exclude />
            public static _NIL as __Usual
        #endregion

        #region private fields
            private initonly _flags    	as UsualFlags	// type, byref, width, decimals
            private initonly _valueData	as _UsualData		// for non GC data
            private initonly _refData  	as object			// for GC data
        #endregion

        #region constructors
			/// <exclude />
            static constructor
            _NIL := __Usual{}
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(u as __Usual)
            self:_flags     := u:_flags
            self:_valueData	:= u:_valueData
            self:_refData 	:= u:_refData

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(f as Float)
            self:_valueData:r8		:= f:Value
            self:_flags:usualType	:= UsualType.Float
            self:_flags:Width		:= (Sbyte) f:Digits
            self:_flags:Decimals	:= (Sbyte) f:Decimals

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(r8 as real8)
            self:_valueData:r8		:= r8
            self:_flags:usualType	:= UsualType.Float
            self:_flags:Width		:= -1
            self:_flags:Decimals	:= -1

            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as logic)
            self:_flags:usualType	:= UsualType.LOGIC
            self:_valueData:l		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as Array)
            self:_flags:usualType	:= UsualType.Array
            self:_refData			:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as Date)
            self:_flags:usualType	:= UsualType.Date
            self:_valueData:d		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as System.DateTime)
            self:_flags:usualType	:= UsualType.DateTime
            self:_valueData:dt		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as long)
            self:_flags:usualType	:= UsualType.LONG
            _valueData:i			:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as int64)
            self:_flags:usualType	:= UsualType.INT64
            self:_valueData:i64		:= value
            return

            //[MethodImpl(MethodImplOptions.AggressiveInlining)];
            private constructor(value as uint64)
            if value < Int64.MaxValue
                self:_flags:usualType	:= UsualType.INT64
                self:_valueData:i64:= (int64) value
            else
                self:_flags:usualType	:= UsualType.FLOAT
                self:_valueData:r8 := value
            endif
            return

            private constructor(d as System.Decimal)
            self:_flags:usualType  := UsualType.Decimal
            self:_refdata	:= d

            private constructor(value as System.IntPtr)
            self:_flags:usualType	:= UsualType.PTR
            self:_valueData:p		:= value
            return

            private constructor(value as PSZ)
				self:_flags:usualType	:= UsualType.PSZ
				self:_refData			:= Psz2String(value)
            return
   			/// This constructor is used in code generated by the compiler when needed.
            public constructor(o as object)
            local u				as __Usual
            if o != null
                if o:GetType() == typeof(__Usual)
                    // boxed __Usual
                    u		:= (__Usual)o
                    self:_flags		:= u:_flags
                    self:_refData	:= u:_refData
                    self:_valueData	:= u:_valueData
                else
                    //  decode type from typecode
                    var vartype := o:GetType()
                    var typeCode := System.Type.GetTypeCode(vartype)
                    switch typeCode
                        case  System.TypeCode.DBNull
                            self:_flags:usualType := UsualType.Void
                            self:_refData	:= null

                        case System.TypeCode.Boolean
                            self:_flags:usualType := UsualType.LOGIC
                            self:_valueData:l := (logic)o

                        case System.TypeCode.Char
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (char)o

                        case System.TypeCode.SByte
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (SByte)o

                        case System.TypeCode.Byte
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (byte)o

                        case System.TypeCode.Int16
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (short)o

                        case System.TypeCode.UInt16
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (word)o

                        case System.TypeCode.Int32
                            self:_flags:usualType		:= UsualType.Long
                            self:_valueData:i	:= (long)o

                        case System.TypeCode.UInt32
                            if (dword)o  <= Int32.MaxValue
                                self:_flags:usualType := UsualType.Long
                                self:_valueData:i := (long)(dword)o
                            else
                                self:_flags:usualType := UsualType.Float
                                self:_valueData:r8:= (real8) (UInt32) o
                                self:_flags:width	:= -1
                                self:_flags:decimals := -1
                            endif
                        case System.TypeCode.Int64
                            self:_flags:usualType		:= UsualType.Int64
                            self:_valueData:i64	:= (int64)o

                        case System.TypeCode.UInt64
                            if (uint64) o  <= Int64.MaxValue
                                self:_flags:usualType	:= UsualType.Int64
                                self:_valueData:i64		:= (int64)(uint64)o
                            else
                                self:_flags:usualType := UsualType.FLOAT
                                self:_valueData:r8 := (real8)(uint64)o
                                self:_flags:width	:= -1
                                self:_flags:decimals := -1
                            endif
                        case System.TypeCode.Single
                            self:_flags:usualType		:= UsualType.Float
                            self:_valueData:r8	:= (real8)o
                            self:_flags:width	:= -1
                            self:_flags:decimals := -1

                        case System.TypeCode.Double
                            self:_flags:usualType := UsualType.Float
                            self:_valueData:r8 := (real8)o
                            self:_flags:width := -1
                            self:_flags:decimals := -1

                        case System.TypeCode.Decimal
                            self:_flags:usualType := UsualType.Decimal
                            self:_refData  := o

                        case System.TypeCode.DateTime
                            self:_flags:usualType := UsualType.DateTime
                            self:_valueData:dt := (System.DateTime) o

                        case System.TypeCode.String
                            self:_flags:usualType := UsualType.STRING
                            self:_refData  := (string)o

                        otherwise
                            IF vartype == typeof(ARRAY)
                                SELF:_flags:usualType := UsualType.Array
                                self:_refData  := o
							// CodeBlock ?
							// _CodeBlock ?
                            ELSEIF vartype == typeof(DATE)
                                SELF:_flags:usualType := UsualType.Date
                                SELF:_valueData:d :=  (DATE) o
                            ELSEIF vartype == typeof(SYMBOL)
                                SELF:_flags:usualType := UsualType.Symbol
                                SELF:_valueData:s :=   (SYMBOL) o
                            ELSEIF vartype == typeof(System.Reflection.Pointer)
                                self:_flags:usualType := UsualType.Ptr
                                self:_valueData:p	  := Intptr{System.Reflection.Pointer.UnBox(o)}
							elseif o is IFloat
								local f := (IFLoat) o as IFloat
								self:_valueData:r8		:= f:Value
								self:_flags:usualType	:= UsualType.Float
								self:_flags:Width		:= (Sbyte) f:Digits
								SELF:_flags:Decimals	:= (Sbyte) f:Decimals
							elseif o is ICodeBlock
                                SELF:_flags:usualType := UsualType.CodeBlock
                                self:_refData := o
                            ELSE
                                SELF:_flags:usualType := UsualType.Object
                                self:_refData := o
                            endif
                    end switch
                endif
            endif
            return

            private constructor(s as string)
            self:_flags:usualType	:= UsualType.STRING
            self:_refData 			:= s
            return

        //[MethodImpl(MethodImplOptions.AggressiveInlining)];
        private constructor(s as symbol)
            self:_flags:usualType	:= UsualType.SYMBOL
            self:_valueData:s       := s
            return

        //[MethodImpl(MethodImplOptions.AggressiveInlining)];
        private constructor(o as object, lIsNull as logic)
            self:_flags:usualType	:= UsualType.OBJECT
            self:_refData 			:= null
            return

        #endregion

        #region properties
			private property _isByRef		as LOGIC	get _flags:isByRef
            internal property _usualType		as UsualType get _flags:usualType

			private property _arrayValue    as array	get iif(IsArray, (array) _refData , null_array)
			private property _codeblockValue as codeblock	get iif(IsCodeBlock, (Codeblock) _refData , null_codeblock)
            private property _dateValue		as Date		get _valueData:d
            private property _dateTimeValue as DateTime get _valueData:dt
            private property _decimalValue	as System.Decimal get (System.Decimal) _refData
            private property _floatValue    as Float	get Float{ _valueData:r8, _width, _decimals}
            private property _i64Value		as int64	get _valueData:i64
            private property _intValue		as int		get _valueData:i
            private property _logicValue	as logic	get _valueData:l
            PRIVATE PROPERTY _ptrValue		AS IntPtr	GET _valueData:p
			private property _pszValue		as IntPtr	get __psz.CreatePsz(_stringValue)
            private property _r8Value		as real8	get _valueData:r8
            private property _stringValue   as string	get iif(IsString, (string) _refData , String.Empty)
            private property _symValue		as Symbol	get _valueData:s

            // properties for floats
            private property _width			as SBYTE get _flags:width
            private property _decimals		as SBYTE get _flags:decimals
			// Is .. ?
			internal property IsArray		as logic get _usualtype == UsualType.Array
			internal property IsCodeblock	as logic get _usualtype == UsualType.CodeBlock
			internal property IsDate		as logic get _usualtype == UsualType.Date
			internal property IsDateTime	as logic get _usualtype == UsualType.DateTime
			internal property IsDecimal		as logic get _usualtype == UsualType.Decimal
			internal property IsFloat		as logic get _usualtype == UsualType.Float
			internal property IsInt64		as logic get _usualtype == UsualType.Int64
			internal property IsLogic		as logic get _usualtype == UsualType.Logic
			internal property IsLong		as logic get _usualtype == UsualType.Long
			internal property IsInteger		as logic get _usualtype == UsualType.Long .or. _usualtype == UsualType.Int64
			internal property Type			as UsualType get _flags:usualType
			internal property IsNumeric as logic
				get
					switch _usualType
					case UsualType.Long
					case UsualType.Int64
					case UsualType.Float
					case UsualType.Decimal
						return true
					otherwise
						return false
					end switch
				end get
			end property
			internal property IsObject		as logic get _usualtype == UsualType.Object
			internal property IsPtr			as logic get _usualtype == UsualType.Ptr
			internal property IsSymbol		as logic get _usualtype == UsualType.Symbol
			internal property IsString		as logic get _usualtype == UsualType.String
			internal property IsByRef		as logic get _isByRef
            private property IsReferenceType as logic
                get
                    switch _usualType
                        case UsualType.Array
                        case UsualType.Object
                        case UsualType.Decimal
                        case UsualType.String
                            return true
                        otherwise
                            return false
                    end switch
                end get
            end property
  			internal property IsEmpty as logic
				get
				switch _usualType
				case UsualType.Array		; return _arrayValue == null .or. _arrayValue:Length == 0
				CASE UsualType.CodeBlock	; return _codeblockValue == null
				case UsualType.Date			; return _dateValue:IsEmpty
				case UsualType.DateTime		; return _dateTimeValue == DateTime.MinValue
				case UsualType.Decimal		; return _decimalValue == 0
				case UsualType.Float		; return _floatValue == 0.0
				case UsualType.Int64		; return _i64Value == 0
				case UsualType.Logic		; return _logicValue == false
				CASE UsualType.Long			; return _intValue == 0
				case UsualType.Object		; return _refData == null
				case UsualType.Ptr			; return _ptrValue == IntPtr.Zero
				case UsualType.String		; return EmptyString(_stringValue)
				case UsualType.Symbol		; return _symValue == 0
				case UsualType.Psz			; return EmptyString( (String) _refData)
				case UsualType.Void			; return true
				otherwise
					Debug.Fail( "Unhandled data type in Usual:Empty()" )
				end switch
				return false
				end get
			end property

            internal property IsNil as logic
                get
                    return self:_usualType == UsualType.Void .or. ;
						(self:IsReferenceType .and. self:_refData  == null) .or. ;
						(self:_usualType == UsualType.Ptr .and. self:_ptrValue == IntPtr.Zero)

                end get
            end property

            internal property SystemType as System.Type
                get
					switch _usualType
					case UsualType.Array		; return typeof(Array)
					case UsualType.Codeblock	; return typeof(Codeblock)
					case UsualType.Date			; return typeof(Date)
					case UsualType.DateTime		; return typeof(System.DateTime)
					case UsualType.Decimal		; return typeof(System.Decimal)
					case UsualType.Float		; return typeof(Float)
					case UsualType.Int64		; return typeof(INT64)
					case UsualType.Logic		; return typeof(LOGIC)
					case UsualType.Long			; return typeof(INT)
					case UsualType.Object		; return typeof(OBJECT)
					case UsualType.Ptr			; return typeof(IntPtr)
					case UsualType.String		; return typeof(STRING)
					case UsualType.Symbol		; return typeof(SYMBOL)
					case UsualType.Void			; return typeof(USUAL)
					otherwise
						Debug.Fail( "Unhandled data type in Usual:SystemType" )
					end switch
					return null
                end get

            end property

        #endregion
        #region Properties for the Debugger
			/// <exclude />
            PROPERTY Value AS OBJECT
                GET
                    SWITCH _UsualType
                        CASE UsualType.Array		; RETURN _arrayValue
						CASE UsualType.Codeblock	; RETURN _codeblockValue
                        CASE UsualType.Date			; RETURN _dateValue
                        CASE UsualType.DateTime		; RETURN _dateTimeValue
                        CASE UsualType.Decimal		; RETURN _decimalValue
                        CASE UsualType.Float		; RETURN _floatValue
                        CASE UsualType.Int64		; RETURN _i64Value
                        CASE UsualType.Logic		; RETURN _logicValue
                        CASE UsualType.Long			; RETURN _intValue
						CASE UsualType.Object		; RETURN _refData
                        CASE UsualType.Ptr			; RETURN _ptrValue
                        CASE UsualType.Psz			; RETURN _pszValue
                        CASE UsualType.String		; RETURN _stringValue
                        CASE UsualType.Symbol		; RETURN _symValue
                        CASE UsualType.Void			; RETURN "NIL"
                        OTHERWISE					; RETURN _refData
                    END SWITCH
                END GET
            END PROPERTY

        #endregion

        #region implementation IComparable<T>
		PUBLIC METHOD CompareTo(rhs AS __Usual) AS LONG
            if self:_UsualType == rhs:_UsualType
                // Compare ValueTypes
                switch _UsualType
                    case UsualType.Date		; return self:_dateValue:CompareTo(rhs:_dateValue)
                    case UsualType.DateTime	; return self:_dateTimeValue:CompareTo(rhs:_dateTimeValue)
                    case UsualType.Decimal	; return self:_decimalValue:CompareTo(rhs:_decimalValue)
                    case UsualType.Int64		; return self:_i64Value:CompareTo(rhs:_i64Value)
                    case UsualType.Logic		; return self:_logicValue:CompareTo(rhs:_logicValue)
                    case UsualType.Long		; return self:_intValue:CompareTo(rhs:_intValue)
                    case UsualType.Ptr		; return self:_ptrValue:ToInt64():CompareTo(rhs:_ptrValue:ToInt64())
                    // Uses String Comparison rules
                    // Vulcan does a case insensitive comparison ?
                    case UsualType.String		; return String.Compare( _stringValue,  rhs:_stringValue)
                    case UsualType.Symbol		; return String.Compare( (string) self:_symValue, (string) rhs:_symValue)
                    otherwise					; return 0
                end switch
            else
                // Type of LHS different from type of RHS
                switch self:_UsualType
                    case UsualType.Void
                        return -1
                    case UsualType.Date
                        // Upscale when needed to avoid overflow errors
                        switch rhs:_UsualType
                            case UsualType.DateTime	; return _dateValue:CompareTo((Date) rhs:_dateTimeValue)
                            case UsualType.Decimal	; return ((System.Decimal) (int) _dateValue):CompareTo(rhs:_decimalValue)
                            case UsualType.Float		; return ((real8) (int) _dateValue):CompareTo(rhs:_r8Value)
                            case UsualType.Int64		; return ( (int64) (int) _dateValue):CompareTo(rhs:_i64Value)
                            case UsualType.Long		; return ((int) _dateValue):CompareTo(rhs:_intValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Float
                        switch rhs:_usualType
                            case UsualType.Date		; return _r8Value:CompareTo( (real8) (int) rhs:_dateValue)
                            case UsualType.Decimal	; return _r8Value:CompareTo( (real8) rhs:_decimalValue)
                            case UsualType.Long		; return _r8Value:CompareTo( (real8) rhs:_intValue)
                            case UsualType.Int64		; return _r8Value:CompareTo( (real8) rhs:_i64Value)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Long
                        // Upscale when needed to avoid overflow errors
                        switch rhs:_usualType
                            case UsualType.Date		; return _intValue:CompareTo((int) rhs:_dateValue)
                            case UsualType.Int64		; return ((int64)_intValue):CompareTo(rhs:_i64Value)
                            case UsualType.Float		; return ((real8)_intValue):CompareTo(rhs:_r8Value)
                            case UsualType.Decimal	; return ((System.Decimal)_intValue):CompareTo(rhs:_decimalValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Int64
                        switch rhs:_usualType
                            case UsualType.Date		; return _i64Value:CompareTo((int) rhs:_dateValue)
                            case UsualType.Long		; return _i64Value:CompareTo( rhs:_intValue)
                            case UsualType.Float		; return _i64Value:CompareTo( rhs:_r8Value)
                            case UsualType.Decimal	; return _i64Value:CompareTo( rhs:_decimalValue)
                            otherwise
                                nop	// uses comparison by type
                        end switch

                    case UsualType.Decimal
                        switch rhs:_usualType
                            case UsualType.Date		; return _decimalValue:CompareTo((int) rhs:_dateValue)
                            case UsualType.Long		; return _decimalValue:CompareTo(rhs:_intValue)
                            case UsualType.Float		; return _decimalValue:CompareTo(rhs:_r8Value)
                            case UsualType.Int64		; return _decimalValue:CompareTo(rhs:_i64Value)
                            otherwise
                                nop	// uses comparison by type
                        end switch
                end switch
            endif
            if rhs:_usualType == UsualType.Void
                return 1
            elseif self:_usualType > rhs:_usualType
                return 1
            elseif self:_usualType < rhs:_usualType
                return -1
            endif
            return 0

		#endregion

        #region implementation IComparable
            /// This method is needed to implement the IComparable interface.
        PUBLIC METHOD CompareTo(o AS OBJECT) AS LONG
				RETURN CompareTo((__Usual) o)
        #endregion

        #region Comparison Operators
		/// This operator is used in code generated by the compiler when needed.
        static operator >(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue > rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue > rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue > rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value > rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value > rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value > rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value > rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value > rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value > rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value > (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue > rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue > rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue > (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue >  rhs:_decimalValue
                        otherwise
                            throw BinaryError(">", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue> rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue > rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue > rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue > (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.DateTime	; return lhs:_dateTimeValue > rhs:_dateTimeValue
                        case UsualType.Date		; return lhs:_dateTimeValue > (DateTime) rhs:_dateValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    nop // error below
            end switch
            throw BinaryError(">", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

			/// This operator is used in code generated by the compiler when needed.
            static operator >=(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue >= rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value >= rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value >= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value >= (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue >= rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue >= rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue >= (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue >=  rhs:_decimalValue
                        otherwise
                            throw BinaryError(">=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue>= rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue >= rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		>= rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue >= rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		>=  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue >=  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError(">=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError(">=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
			static operator <(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue < rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue < rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue < rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value < rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value < rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value < rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value < rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value < rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value < rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value < (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue < rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue < rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue < (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue <  rhs:_decimalValue
                        otherwise
                            throw BinaryError("<", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return lhs:_stringValue< rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue < rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue	< rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue < (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		<  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue <  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError("<", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("<", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator <=(lhs as __Usual, rhs as __Usual) as logic
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue <= rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value <= rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_r8Value <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_r8Value <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_r8Value <= rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_r8Value <= (real8) rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue <= rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue <= rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue <= (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue <=  rhs:_decimalValue
                        otherwise
                            throw BinaryError("<=", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)
                    end switch

                case UsualType.String
                    if rhs:_usualType == UsualType.String
                        return  lhs:_stringValue<= rhs:_stringValue
                    else
                        nop // error below
                    endif

                case UsualType.Symbol
                    if rhs:_usualType == UsualType.Symbol
                        return lhs:_symValue <= rhs:_symValue
                    else
                        nop // error below
                    endif
                case UsualType.Date
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue	<= rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateValue <= (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                case UsualType.DateTime
                    switch (rhs:_usualType)
                        case UsualType.Date		; return lhs:_dateValue		<=  rhs:_dateValue
                        case UsualType.DateTime	; return lhs:_dateTimeValue <=  rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError("<=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("<=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, lhs, rhs)
        #endregion

		#region IEquatable<T>
		public method Equals(u as USUAL) as logic
				if u:IsNil
					return self:IsNil
				endif
				return UsualEquals(u, "Usual.Equals()")

		#endregion
        #region Operators for Equality
            public method Equals(obj as object) as logic
				if obj == null
					return self:IsNil
				endif
				return UsualEquals((USUAL) obj, "Usual.Equals()")

            public method GetHashCode() as int
				local oValue as object
				oValue := self:Value
				if oValue == NULL
					return 0
				endif
				return oValue:GetHashCode()

            /// This operator is used in code generated by the compiler when needed.
            static operator ==(lhs as __Usual, rhs as __Usual) as logic
				return lhs:UsualEquals(rhs, "==")

            /// This operator is used in code generated by the compiler when needed.
            static operator !=(lhs as __Usual, rhs as __Usual) as logic
            if lhs:_usualType == UsualType.STRING .and. rhs:_usualType == UsualType.STRING
                return ! __StringEquals(  lhs:_stringValue, rhs:_stringValue)
            else
                return ! lhs:UsualEquals(rhs, "!=")
            endif

            internal method UsualEquals( rhs as __Usual, op as string) as logic
			if rhs:IsNil
				return self:IsNil
			endif
            switch self:_usualType
                case UsualType.Object
                    if rhs:_usualType == UsualType.Object
                        return self:_refData == rhs:_refData
                    else
                        nop // error below
                    endif

                case UsualType.Void
                    return rhs:_usualType == UsualType.Void

                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_intValue == rhs:_intValue
                        case UsualType.Int64		; return (int64) self:_intValue == rhs:_i64Value	// cast lhs to int64 to avoid overflow
                        case UsualType.Float		; return (real8) self:_intValue == rhs:_r8Value // cast lhs to real8 to avoid overflow
                        case UsualType.Decimal	; return (System.Decimal) self:_intValue == rhs:_decimalValue	// cast lhs to decimal to avoid overflow
                        case UsualType.Logic		; return rhs:_logicValue == (self:_intValue <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return _i64Value == (int64) rhs:_intValue
                        case UsualType.Int64		; return _i64Value == rhs:_i64Value
                        case UsualType.Float		; return  (real8) _i64Value == rhs:_r8Value
                        case UsualType.Decimal	; return _i64Value == rhs:_decimalValue
                        case UsualType.Logic		; return rhs:_logicValue == (self:_i64Value <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_r8Value == (real8) rhs:_intValue
                        case UsualType.Int64		; return self:_r8Value == (real8) rhs:_i64Value
                        case UsualType.Float		; return self:_r8Value ==  rhs:_r8Value
                        case UsualType.Decimal	; return self:_r8Value ==  (real8) rhs:_decimalValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return self:_decimalValue == rhs:_intValue
                        case UsualType.Int64		; return self:_decimalValue == rhs:_i64Value
                        case UsualType.Float		; return self:_decimalValue == (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return self:_decimalValue == rhs:_decimalValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.LOGIC
                    switch rhs:_usualType
                        case UsualType.LOGIC		; return self:_logicValue == rhs:_logicValue
                        case UsualType.Long		; return self:_logicValue == (rhs:_intValue <> 0)
                        case UsualType.Int64		; return self:_logicValue == (rhs:_i64Value <> 0)
                        case UsualType.Decimal	; return self:_logicValue == (rhs:_decimalValue <> 0)
                        otherwise
                            nop // error below
                    end switch

                case UsualType.DATE
                    switch rhs:_usualType
                        case UsualType.DATE		; return self:_dateValue == rhs:_dateValue
                        case UsualType.DateTime	; return self:_dateValue == (Date) rhs:_dateTimeValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.DateTime	; return self:_dateTimeValue == rhs:_dateTimeValue
                        case UsualType.DATE		; return self:_dateTimeValue == (DateTime) rhs:_dateValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.STRING
                    switch rhs:_usualType
                        case UsualType.STRING		; return self:_stringValue == rhs:_stringValue
                        case UsualType.Symbol		; return self:_stringValue == rhs:_symValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.ARRAY
                    switch rhs:_usualType
                        case UsualType.ARRAY		; return self:_refData == rhs:_refData
                        otherwise
                            nop // error below
                    end switch

                case UsualType.CodeBlock
                    switch rhs:_usualType
                        case UsualType.CodeBlock	; return self:_refData == rhs:_refData
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Ptr
                    switch rhs:_usualType
                        case UsualType.Ptr		; return self:_ptrValue == rhs:_ptrValue
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Symbol
                    switch rhs:_usualType
                        case UsualType.Symbol		; return self:_symValue == rhs:_symValue
                        case UsualType.String		; return self:_symValue == rhs:_stringValue
                        otherwise
                            nop // error below
                    end switch
                otherwise
                    throw BinaryError(op, __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, self, rhs)

            end switch
            throw BinaryError(op, __CavoStr(VOErrors.ARGSINCOMPATIBLE), false, self, rhs)

        #endregion

        #region Unary Operators
            /// This operator is used in code generated by the compiler when needed.
            static operator !(u as __Usual) as logic
            if u:_usualType == UsualType.LOGIC
                return !u:_logicValue
            endif
            throw UnaryError("!", u)

            /// This operator is used in code generated by the compiler when needed.
            static operator ~(u as __Usual) as __Usual
            if u:_usualType == UsualType.Long
                return ~u:_intValue
            endif
            if u:_usualType == UsualType.Int64
                return ~u:_i64Value
            endif
            throw UnaryError("~", u)

            /// This operator is used in code generated by the compiler when needed.
            static operator -(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return -u:_intValue
                case UsualType.Int64		; return -u:_i64Value
                case UsualType.Float		; return -u:_floatValue
                case UsualType.Decimal	; return -u:_decimalValue
                otherwise
                    throw UnaryError("-", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator +(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue
                case UsualType.Int64		; return u:_i64Value
                case UsualType.Float		; return u:_floatValue
                case UsualType.Decimal	; return u:_decimalValue
                otherwise
                    throw UnaryError("+", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
			static operator --(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue - 1
                case UsualType.Int64		; return u:_i64Value - 1
                case UsualType.Float		; return u:_floatValue -1
                case UsualType.Decimal	; return u:_decimalValue - 1
                otherwise
                    throw UnaryError("--", u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator ++(u as __Usual) as __Usual
            switch u:_usualType
                case UsualType.LONG		; return u:_intValue + 1
                case UsualType.Int64		; return u:_i64Value + 1
                case UsualType.Float		; return u:_floatValue +1
                case UsualType.Decimal	; return u:_decimalValue + 1
                otherwise
                    throw UnaryError("++", u)
            end switch

        #endregion
        #region Numeric Operators for Add, Delete etc (also for strings)

            /// This operator is used in code generated by the compiler when needed.
            static operator +(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue + rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue + rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue + rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value + rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value + rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value + rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value + rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value + rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value + rhs:_r8Value, lhs:_width, lhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value + (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue + rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue + rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue + (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue + rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.String
                    switch rhs:_usualType
                        case UsualType.String		; return lhs:_stringValue+ rhs:_stringValue
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.ARGNOTSTRING), false, lhs, rhs)
                    end switch
                case UsualType.Date
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateValue + rhs:_intValue
                        case UsualType.Int64	; return lhs:_dateValue + rhs:_i64Value
                        CASE UsualType.Float	; RETURN lhs:_dateValue + rhs:_r8Value
						// Note We can't add dates, but we can subtract dates
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.DATE_ADD), false, lhs, rhs)
                    end switch
                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateTimeValue:Add( TimeSpan.FromDays(rhs:_intValue ))
                        case UsualType.Int64	; return lhs:_dateTimeValue:Add(TimeSpan.FromDays(rhs:_i64Value))
                        CASE UsualType.Float	; RETURN lhs:_dateTimeValue:Add(TimeSpan.FromDays(rhs:_r8Value))
						// Note We can't add dates, but we can subtract dates
                        otherwise
                            throw BinaryError("+", __CavoStr(VOErrors.DATE_ADD), false, lhs, rhs)
                    end switch

                otherwise
                    throw BinaryError("+", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("+", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator -(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_intValue - rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_intValue - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value - rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value - rhs:_i64Value
                        case UsualType.Float		; return lhs:_i64Value - rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_i64Value - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch
                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value - rhs:_intValue ,lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value - rhs:_i64Value ,lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value - rhs:_r8Value	,lhs:_width, lhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value - (real8) rhs:_decimalValue ,lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue - (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue - rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.String
                    switch rhs:_usualType
                        case UsualType.String		; return CompilerServices.__StringSubtract(lhs, rhs)
                        otherwise					; throw BinaryError("-", __CavoStr(VOErrors.ARGNOTSTRING), false, lhs, rhs)
                    end switch
                case UsualType.Date
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_dateValue - rhs:_intValue
                        case UsualType.Int64		; return lhs:_dateValue - rhs:_i64Value
                        case UsualType.Float		; return lhs:_dateValue - rhs:_r8Value
                        case UsualType.Date			; return lhs:_dateValue - rhs:_dateValue
                        case UsualType.DateTime		; return lhs:_dateValue - (Date) rhs:_dateTimeValue
                        otherwise					; throw BinaryError("+", __CavoStr(VOErrors.DATE_SUBTRACT), false, lhs, rhs)
                    end switch

                case UsualType.DateTime
                    switch rhs:_usualType
                        case UsualType.Long			; return lhs:_dateTimeValue:Subtract(TimeSpan{rhs:_intValue,0,0,0})
                        case UsualType.Int64		; return lhs:_dateTimeValue:Subtract( TimeSpan{(int)rhs:_i64Value,0,0,0})
                        case UsualType.Float		; return lhs:_dateTimeValue:Subtract( TimeSpan{(int)rhs:_r8Value,0,0,0})
                        case UsualType.Date			; return lhs:_dateTimeValue:Subtract((DateTime) rhs:_dateValue):Days
                        case UsualType.DateTime		; return lhs:_dateTimeValue:Subtract( rhs:_dateTimeValue):Days
                        otherwise					; throw BinaryError("+", __CavoStr(VOErrors.DATE_SUBTRACT), false, lhs, rhs)
                    end switch

                otherwise
                    throw BinaryError("-", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("-", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator /(lhs as __Usual, rhs as __Usual) as __Usual

            switch lhs:_usualType

                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long
                            local result as int
                            local remainder as int
                            result := Math.DivRem(lhs:_intValue, rhs:_intValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_intValue
                            endif
                        case UsualType.Int64
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem((int64) lhs:_intValue, rhs:_i64Value, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_i64Value
                            endif
                        case UsualType.Float
                            return Float{lhs:_intValue / rhs:_r8Value, rhs:_width, rhs:_decimals}

                        case UsualType.Decimal
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem((int64) lhs:_intValue, (int64) rhs:_decimalValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_intValue / rhs:_decimalValue
                            endif
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem(lhs:_i64Value, rhs:_intValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_intValue
                            endif
                        case UsualType.Int64
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem( lhs:_i64Value, rhs:_i64Value, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_i64Value
                            endif
                        case UsualType.Float
                            RETURN FLOAT{lhs:_i64Value / rhs:_r8Value, rhs:_width, rhs:_decimals}

                        case UsualType.Decimal
                            local result as int64
                            local remainder as int64
                            result := Math.DivRem(lhs:_i64Value, (int64) rhs:_decimalValue, out remainder)
                            if remainder == 0
                                return result
                            else
                                return lhs:_i64Value / rhs:_decimalValue
                            endif
                        otherwise
                            nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value / rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value / rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value / rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value / (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue / rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue / rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue / (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue / rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("/", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("/", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator %(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue % rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue % rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_intValue % rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_intValue % rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value % rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value % rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_i64Value % rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_i64Value % rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value % rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value % rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value % rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value % (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue % rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue % rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue % (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue %  rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("%", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("%", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator *(lhs as __Usual, rhs as __Usual) as __Usual
            switch lhs:_usualType
                case UsualType.Long
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_intValue * rhs:_intValue
                        case UsualType.Int64		; return lhs:_intValue * rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_intValue * rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_intValue * rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Int64
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_i64Value * rhs:_intValue
                        case UsualType.Int64		; return lhs:_i64Value * rhs:_i64Value
                        case UsualType.Float		; return Float{lhs:_i64Value * rhs:_r8Value, rhs:_width, rhs:_decimals}
                        case UsualType.Decimal	; return lhs:_i64Value * rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                case UsualType.Float
                    switch rhs:_usualType
                        case UsualType.Long		; return Float{lhs:_r8Value * rhs:_intValue, lhs:_width, lhs:_decimals}
                        case UsualType.Int64		; return Float{lhs:_r8Value * rhs:_i64Value, lhs:_width, lhs:_decimals}
                        case UsualType.Float		; return Float{lhs:_r8Value * rhs:_r8Value, Math.Max(lhs:_width,rhs:_width), lhs:_decimals+ rhs:_decimals}
                        case UsualType.Decimal	; return Float{lhs:_r8Value * (real8) rhs:_decimalValue, lhs:_width, lhs:_decimals}
                        otherwise					; nop // error below
                    end switch

                case UsualType.Decimal
                    switch rhs:_usualType
                        case UsualType.Long		; return lhs:_decimalValue * rhs:_intValue
                        case UsualType.Int64		; return lhs:_decimalValue * rhs:_i64Value
                        case UsualType.Float		; return lhs:_decimalValue * (System.Decimal) rhs:_r8Value
                        case UsualType.Decimal	; return lhs:_decimalValue *  rhs:_decimalValue
                        otherwise					; nop // error below
                    end switch

                otherwise
                    throw BinaryError("*", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
            end switch
            throw BinaryError("*", __CavoStr(VOErrors.ARGNOTNUMERIC), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator >>(lhs as __Usual, rhs as int) as __Usual
            // Right shift
            switch lhs:_usualType
                case UsualType.Long	; return lhs:_intValue >> rhs
                case UsualType.Int64	; return lhs:_i64Value >> rhs
                otherwise
                    throw BinaryError(">>", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator <<(lhs as __Usual, rhs as long) as __Usual
            // Left shift
            switch (lhs:_usualType)
                case UsualType.Long	; return lhs:_intValue << rhs
                case UsualType.Int64	; return lhs:_i64Value << rhs
                otherwise
                    throw BinaryError("<<", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator &(lhs as __Usual, rhs as __Usual) as __Usual
            // Bitwise And
            switch (lhs:_usualType)
                case UsualType.Long
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_intValue & rhs:_intValue
                        case UsualType.Int64		; return (int64) lhs:_intValue & rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_i64Value & (int64) rhs:_intValue
                        case UsualType.Int64	; return  lhs:_i64Value & rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                otherwise
                    throw BinaryError("&", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch
            throw BinaryError("&", __CavoStr(VOErrors.ARGNOTINTEGER), false, lhs, rhs)

            /// This operator is used in code generated by the compiler when needed.
            static operator |(lhs as __Usual, rhs as __Usual) as __Usual
            // Bitwise or
            switch (lhs:_usualType)
                case UsualType.Long
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_intValue | rhs:_intValue
                        case UsualType.Int64		; return (int64) lhs:_intValue | rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                case UsualType.Int64
                    switch (rhs:_usualType)
                        case UsualType.Long		; return lhs:_i64Value | (int64) rhs:_intValue
                        case UsualType.Int64		; return  lhs:_i64Value | rhs:_i64Value
                        otherwise					; nop // error below
                    end switch
                otherwise
                    throw BinaryError("|", __CavoStr(VOErrors.ARGNOTINTEGER), true, lhs, rhs)
            end switch
            throw BinaryError("|", __CavoStr(VOErrors.ARGNOTINTEGER), false, lhs, rhs)
        #endregion

        #region Implicit From Usual to Other Type

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Array
				switch u:_usualType
				case UsualType.Array	; return (Array) u:_refData
				case UsualType.Void	; return null
				case UsualType.Object
					if u:_refData== null
						return null
					elseif u:_refData is Array
						return (Array) u:_refData
					endif
				end switch
				throw ConversionError(ARRAY, typeof(Array), u)

            STATIC OPERATOR IMPLICIT(u AS __Usual) AS CodeBlock
				SWITCH u:_usualType
				CASE UsualType.CodeBlock
					return u:_codeblockValue
				CASE UsualType.Object
					IF u:_refData == NULL
						RETURN NULL
					ENDIF
				CASE UsualType.Void
					RETURN NULL
				END SWITCH
				throw ConversionError(CODEBLOCK, typeof(CodeBlock), u)

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as logic
            switch u:_usualType
                case UsualType.Logic		; return u:_logicValue
                case UsualType.Long		; return u:_intValue != 0
                case UsualType.Int64		; return u:_i64Value != 0
                case UsualType.Decimal	; return u:_decimalValue != 0
                case UsualType.Void		; return false
                otherwise
                    throw ConversionError(LOGIC, typeof(logic), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Date
            switch u:_usualType
                case UsualType.Date		; return u:_dateValue
                case UsualType.DateTime	; return (Date) u:_dateTimeValue
                case UsualType.Void		; return Date{0}
                otherwise
                    throw ConversionError(DATE, typeof(Date), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as DateTime
            switch u:_usualType
                case UsualType.Date		; return (DateTime) u:_dateValue
                case UsualType.DateTime	; return u:_dateTimeValue
                case UsualType.Void		; return DateTime.MinValue
                otherwise
                    throw ConversionError(DATE, typeof(Date), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as System.IntPtr
            switch u:_usualType
                CASE UsualType.Ptr		; RETURN u:_ptrValue
				case UsualType.Psz		; return u:_pszValue
                case UsualType.LONG		; return (IntPtr) u:_intValue
                case UsualType.Int64		; return (IntPtr) u:_i64Value
                case UsualType.Decimal	; return (IntPtr) u:_decimalValue
                case UsualType.Void		; return IntPtr.Zero
                otherwise
                    throw ConversionError(PTR, typeof(IntPtr), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as string
            switch u:_usualType
                case UsualType.String	; return u:_stringValue
                case UsualType.Void	; return ""
                case UsualType.SYMBOL	; return (string) u:_symValue
                otherwise
                    throw ConversionError(STRING, typeof(string), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Symbol
            switch u:_usualType
                case UsualType.String	; return (Symbol) u:_stringValue
                case UsualType.Void	; return Symbol{""}
                case UsualType.SYMBOL	; return u:_symValue
                otherwise
                    throw ConversionError(SYMBOL, typeof(Symbol), u)
            end switch

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Psz
            switch u:_usualType
                case UsualType.Ptr	; return (Psz) u:_ptrValue
                case UsualType.String	; return Psz{u:_stringValue}
                case UsualType.Void	; return Null_Psz
                otherwise
                    throw ConversionError(PSZ, typeof(Psz), u)
            end switch

        #endregion
        #region Implicit Numeric Operators
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as byte
            try
                switch u:_usualType
                    case UsualType.Long		; return checked((byte) u:_intValue)
                    case UsualType.Int64		; return checked((byte) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToByte(u:_r8Value)
						else
							return checked((byte) u:_r8Value)
						endif
                    case UsualType.Logic		; return iif(u:_logicValue, 1, 0)
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToByte(u:_decimalValue )
						else
							return checked((byte) u:_decimalValue )
						endif
                    case UsualType.Void		; return  0
                    otherwise
                        throw ConversionError(BYTE, typeof(byte), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "BYTE", typeof(byte), u)
            end try
            return 0

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as short
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((short) u:_intValue)
                    case UsualType.Int64	; return checked((short) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt16(u:_r8value)
						else
							return checked((short) u:_r8Value)
						endif

                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt16(u:_decimalValue )
						else
							return checked((short) u:_decimalValue )
						endif

                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(SHORT, typeof(short), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "SHORT", typeof(short), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as long
            try
                switch u:_usualType
                    case UsualType.Long	; return u:_intValue
                    case UsualType.Int64	; return checked((long) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt32(u:_r8Value)
						else
							return  checked((long) u:_r8Value)
						endif
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt32(u:_decimalValue )
						else
							return checked((long) u:_decimalValue )
						endif
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(LONG, typeof(long), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "LONG", typeof(long), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as int64
            try
                switch u:_usualType
                    case UsualType.Long	; return u:_intValue
                    case UsualType.Int64	; return checked((int64) u:_i64Value)
                    case UsualType.Float
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt64(u:_r8Value)
						else
							return  checked((int64) u:_r8Value)
						endif
                    case UsualType.Decimal
						if RuntimeState.CompilerOptionVO11
							return Convert.ToInt64(u:_decimalValue )
						else
							return checked((int64) u:_decimalValue )
						endif

                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(INT64, typeof(int64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "INT64", typeof(int64), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as System.Decimal
            try
                switch u:_usualType
                    case UsualType.Long	; return checked(u:_intValue)
                    case UsualType.Int64	; return checked(u:_i64Value)
                    case UsualType.Float	; return checked((System.Decimal) u:_r8Value)
                    case UsualType.Decimal; return checked(u:_decimalValue)
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(UsualType.DECIMAL, typeof(int64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "DECIMAL", typeof(int64), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as SByte
            try
                switch u:_usualType
                    case UsualType.Long	; return checked( (SByte) u:_intValue)
                    case UsualType.Int64	; return checked( (SByte) u:_i64Value)
                    case UsualType.Float	; return checked( (SByte) u:_r8Value)
                    case UsualType.Decimal; return checked((SByte) u:_decimalValue )
                    case UsualType.Logic	; return (SByte) iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(BYTE, typeof(SByte), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "SBYTE", typeof(SByte), u)
            end try

            // Unsigned
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as word
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((word) u:_intValue)
                    case UsualType.Int64	; return checked((word) u:_i64Value)
                    case UsualType.Float	; return checked((word) u:_r8Value)
                    case UsualType.Decimal; return checked((word) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(WORD, typeof(word), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "WORD", typeof(word), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as dword
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((dword) u:_intValue)
                    case UsualType.Int64	; return checked((dword) u:_i64Value)
                    case UsualType.Float	; return checked((dword) u:_r8Value)
                    case UsualType.Decimal; return checked((dword) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(DWORD, typeof(dword), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "DWORD", typeof(dword), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as uint64
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((uint64) u:_intValue)
                    case UsualType.Int64	; return checked((uint64) u:_i64Value)
                    case UsualType.Float	; return checked((uint64) u:_r8Value)
                    case UsualType.Decimal; return checked((uint64) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(UINT64, typeof(uint64), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "UINT64", typeof(uint64), u)
            end try

            // Single, Double and FLoat
            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as real4
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((real4) u:_intValue)
                    case UsualType.Int64	; return checked((real4) u:_i64Value)
                    case UsualType.Float	; return checked((real4) u:_r8Value)
                    case UsualType.Decimal; return checked((real4) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(REAL4, typeof(real4), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "REAL4", typeof(real4), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as real8
            try
                switch u:_usualType
                    case UsualType.Long	; return checked((real8) u:_intValue)
                    case UsualType.Int64	; return checked((real8) u:_i64Value)
                    case UsualType.Float	; return checked((real8) u:_r8Value)
                    case UsualType.Decimal; return checked((real8) u:_decimalValue )
                    case UsualType.Logic	; return iif(u:_logicValue, 1, 0)
                    case UsualType.Void	; return 0
                    otherwise
                        throw ConversionError(REAL8, typeof(real8), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "REAL8", typeof(real8), u)
            end try

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(u as __Usual) as Float
            try
                switch u:_usualType
                    case UsualType.Long	; return checked(Float{(real8) u:_intValue})
                    case UsualType.Int64	; return checked(Float{(real8) u:_i64Value})
                    case UsualType.Float	; return u:_floatValue
                    case UsualType.Decimal; return checked(Float{(real8) u:_decimalValue})
                    case UsualType.Logic	; return Float{iif(u:_logicValue, 1, 0)}
                    case UsualType.Void	; return Float{0}
                    otherwise
                        throw ConversionError(FLOAT, typeof(Float), u)
                end switch
            catch ex as OverflowException
                throw OverflowError(ex, "FLOAT", typeof(Float), u)
            end try

        #endregion
        #region Implicit from Other Type to Usual

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as object) as Usual
				local result as USUAL
				if value != null .and. value:GetType() == typeof(__Usual)
					result := (Usual) value
				elseif value == null
					result := Usual{NULL, true}
				else
					result := usual{value}
				endif
				return result

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as logic) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as byte) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Array) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Date) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.DateTime) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Float) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as real8) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as short) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as long) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as int64) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as uint64) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as Psz) as __Usual
				return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as symbol) as __Usual
				return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.Decimal) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as System.IntPtr) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as SByte) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as real4) as __Usual
            return __Usual{(real8)value }

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as string) as __Usual
            return __Usual{value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as word) as __Usual
            return __Usual{(int)value}

            /// This operator is used in code generated by the compiler when needed.
            static operator implicit(value as dword) as __Usual
            return iif((value <= 0x7fffffff),__Usual{(long)value },__Usual{(Float)value })
        #endregion

        #region implementation IConvertable
            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToBoolean(provider as System.IFormatProvider) as logic
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToByte(provider as System.IFormatProvider) as byte
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToChar(provider as System.IFormatProvider) as char
            var o := __Usual.ToObject(self)
            if o is IConvertible
                return ((IConvertible)o):ToChar(provider)
            endif
            throw InvalidCastException{}

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDateTime(provider as System.IFormatProvider) as System.DateTime
            return (Date) self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDecimal(provider as System.IFormatProvider) as Decimal
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToDouble(provider as System.IFormatProvider) as real8
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt16(provider as System.IFormatProvider) as short
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt32(provider as System.IFormatProvider) as long
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToInt64(provider as System.IFormatProvider) as int64
            return self
			/// <exclude />
            static method ToObject(u as __Usual) as object
            switch u:_usualType
                case UsualType.ARRAY		; return u:_arrayValue
                case UsualType.CodeBlock	; return u:_codeblockValue
                case UsualType.Date			; return u:_dateValue
                case UsualType.DateTime		; return u:_dateTimeValue
                case UsualType.Decimal		; return u:_decimalValue
                case UsualType.FLOAT		; return u:_floatValue
                case UsualType.Int64		; return u:_i64Value
                case UsualType.Long			; return u:_intValue
                case UsualType.LOGIC		; return u:_logicValue
                case UsualType.OBJECT		; return u:_refData
                case UsualType.PTR			; return u:_ptrValue
                case UsualType.STRING		; return u:_refData
                case UsualType.SYMBOL		; return u:_symValue
                case UsualType.Void		; return null
                otherwise					; return null
            end switch

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToSByte(provider as System.IFormatProvider) as SByte
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToSingle(provider as System.IFormatProvider) as real4
            return self

			/// <exclude />
			public method AsString() as string strict
				return self:ToString()

			/// <exclude />
			public method Clone() as usual
				// clone types that need cloning
				local result as usual
				switch self:_usualType
				case UsualType.Object
					result := usual{self:value}
				case UsualType.String
					result := usual { String.Copy(self:_stringValue)}
				case UsualType.Array
					result := usual { Aclone(self:_arrayValue) }
				otherwise
					result := self
				end switch
				return result

            public method ToString() as string
            local strResult as string

            switch (self:_usualType)
                case UsualType.Array		; strResult := iif (self:_refData == null, "NULL_ARRAY", self:_arrayValue:ToString())
                case UsualType.CODEBLOCK  ; strResult := iif (self:_refData == null, "NULL_CODEBLOCK", self:_codeblockValue:ToString())
                case UsualType.OBJECT		; strResult := iif (self:_refData == null, "NULL_OBJECT", self:_refData:ToString())
                case UsualType.Date		; strResult := self:_dateValue:ToString()
                case UsualType.DateTime	; strResult := self:_dateTimeValue:ToString()
                case UsualType.Decimal	; strResult := iif (self:_refData == null, "0", self:_decimalValue:ToString())
                case UsualType.Float		; strResult := self:_r8Value:ToString()
                case UsualType.Long		; strResult := self:_intValue:ToString()
                case UsualType.Int64		; strResult := self:_i64Value:ToString()
                case UsualType.LOGIC		; strResult := iif(!self:_logicValue , ".F." , ".T.")
                case UsualType.PTR		; strResult := self:_ptrValue:ToString()
                case UsualType.STRING		; strResult := iif (self:_refData == null, "NULL_STRING", self:_stringValue:ToString())
                case UsualType.Symbol		; strResult := self:_symValue:ToString()
                case UsualType.Void		; strResult := "NIL"
                otherwise					; strResult := ""
            end switch
            return strResult

            public method ToString(provider as System.IFormatProvider) as string
            return self:ToString()

            public method IConvertible.ToType(conversionType as System.Type, provider as System.IFormatProvider) as object
            if conversionType:IsPointer
                switch self:_usualType
                    case UsualType.PTR	; return _ptrValue
                    case UsualType.Long	; return (IntPtr) _intValue
                    case UsualType.Int64	; return (IntPtr) _i64Value
                    otherwise
                        throw InvalidCastException{}
                end switch
            else
                var o := __Usual:ToObject(self)
                if conversionType:IsAssignableFrom(o:GetType())
                    return o
                elseif o is IConvertible
                    return ((IConvertible) o):Totype(conversionType, provider)
                else
                    throw InvalidCastException{}
                endif
            endif

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt16(provider as System.IFormatProvider) as word
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt32(provider as System.IFormatProvider) as dword
            return self

            /// This method is needed to implement the IConvertible interface.
            public method IConvertible.ToUInt64(provider as System.IFormatProvider) as uint64
            return self

           /// <exclude />
		    public method GetTypeCode() as System.TypeCode
            switch _usualType
                case UsualType.ARRAY	; return TypeCode.Object
                case UsualType.CodeBlock; return TypeCode.Object
                case UsualType.Date	; return TypeCode.Object
                case UsualType.DateTime; return TypeCode.DateTime
                case UsualType.Decimal; return TypeCode.Decimal
                case UsualType.FLOAT	; return TypeCode.Object
                case UsualType.Int64	; return TypeCode.Int64
                case UsualType.Long	; return TypeCode.Int32
                case UsualType.LOGIC	; return TypeCode.Boolean
                case UsualType.OBJECT	; return TypeCode.Object
                case UsualType.PTR	; return TypeCode.Object
                case UsualType.STRING ; return TypeCode.String
                case UsualType.SYMBOL ; return TypeCode.Object
                case UsualType.Void
                otherwise				; return TypeCode.Object
            end switch
        #endregion

        #region Error Method
           internal method ValType() as string
            switch self:_usualType
                case UsualType.Array		; return "A"
                case UsualType.CodeBlock	; return "B"
                case UsualType.Date			; return "D"
                case UsualType.DateTime		; return "D"
                case UsualType.DECIMAL		; return "N"
                case UsualType.FLOAT		; return "N"
                case UsualType.Int64		; return "N"
                case UsualType.Long			; return "N"
                case UsualType.Logic		; return "L"
                case UsualType.PTR			; return "-"
                case UsualType.String		; return "C"
				case UsualType.Object		; return "O"
                case UsualType.Symbol		; return "#"
                case UsualType.Void			; return "U"
                otherwise
					Debug.Fail( "Unhandled data type in Usual:Valtype" )
            end switch
			return "?"

            static internal method ConversionError(toTypeString as string, toType as System.Type, u as Usual) as Error
				var err			:= Error{InvalidCastException{}}
				err:GenCode		:= GenCode.EG_DataType
				err:ArgTypeReq	:= toType
				err:ArgNum		:= 1
				err:FuncSym		:= "USUAL => "+toTypeString
				err:Description := VO_Sprintf(VOErrors.USUALCONVERSIONERR, TypeString(UsualType(u)), toTypeString)
				err:Arg			:= "USUAL"
				err:Args        := <OBJECT>{u}
				return err

            static internal method ConversionError(typeNum as DWORD, toType as System.Type, u as Usual) as Error
				var err			:= Error{ InvalidCastException{} }
				err:GenCode		:= GenCode.EG_DataType
				err:ArgTypeReq	:= toType
				err:ArgNum		:= 1
				err:FuncSym		:= "USUAL => "+TypeString((DWORD) typeNum)
				err:ArgType		:= typeNum
				err:Description := VO_Sprintf(VOErrors.USUALCONVERSIONERR, TypeString(UsualType(u)), typeString(DWORD(typeNum)))
				err:Arg			:= "USUAL"
				err:Args        := <OBJECT>{u}
				return err

            static internal method OverflowError(ex as OverflowException, toTypeString as string, toType as System.Type, u as Usual) as Error
				var err			 := Error{ex}
				err:GenCode		 := GenCode.EG_NUMOVERFLOW
				err:ArgTypeReq	 := toType
				err:ArgNum		 := 1
				err:FuncSym		 := "USUAL => "+toTypeString
				err:Description  := VO_Sprintf(VOErrors.USUALOVERFLOWERR, TypeString(UsualType(u)), toTypeString)
				err:Arg			 := "USUAL"
				err:Args		 := <OBJECT>{u}
				return err

            static internal method BinaryError( cOperator as string, message as string, left as logic, lhs as Usual, rhs as Usual) as Error
				var err			 := Error{ArgumentException{}}
				err:GenCode		 := GenCode.EG_ARG
				err:ArgNum		 := iif (left, 1, 2)
				err:FuncSym		 := cOperator
				err:Description  := message
				err:Arg			 := IIF(left, "left operand" , "right operand")
				err:Args         := <OBJECT> {lhs, rhs}
				return err

            static internal method UnaryError( cOperator as string, u as Usual) as Error
				var err			 := Error{ArgumentException{}}
				err:GenCode		 := GenCode.EG_ARG
				err:ArgNum		 := 1
				err:FuncSym		 := cOperator
				err:Description  := __CavoStr(VOErrors.INVALIDARGTYPE)
				err:Arg			 := "USUAL"
				err:Args         := <OBJECT> {u}
				return err

        #endregion

		#region Special methods used by the compiler
        /// This method is used by the compiler for code that does an inexact comparison between two usuals.
		static method __InexactEquals( lhs as usual, rhs as usual ) as logic
			if lhs:IsString .and. rhs:IsString
				return __StringEquals( lhs:_stringValue, rhs:_stringValue)
			else
				return lhs:UsualEquals(rhs, "=")
			endif

        /// This method is used by the compiler for code that does an inexact comparison between a usual and a string.
		static method __InexactEquals( lhs as usual, rhs as string ) as logic
			if lhs:IsString
				return __StringEquals( lhs:_stringValue, rhs)
			else
				throw BinaryError("=", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
			endif

        /// This method is used by the compiler for code that does an inexact comparison.
		static method __InexactNotEquals( lhs as usual, rhs as usual ) as logic
			// emulate VO behavior for "" and NIL
			// "" = NIL but also "" != NIL, NIL = "" and NIL != ""
			IF lhs:IsString
				if rhs:IsString
					return __StringNotEquals( lhs:_stringValue, rhs:_stringValue)
				elseif rhs:IsNil .and. lhs:_stringValue != null .and. lhs:_stringValue:Length == 0
					RETURN FALSE
				ENDIF
			endif
			if rhs:IsString .and. lhs:IsNil .and. rhs:_stringValue != null .and. rhs:_stringValue:Length == 0
				return false
			else
				return ! lhs:UsualEquals(rhs, "<>")
			endif
        /// This method is used by the compiler for code that does an inexact comparison.
		static method __InexactNotEquals( lhs as usual, rhs as string ) as logic
			if lhs:IsString
				return __StringNotEquals( lhs:_stringValue, rhs)
			else
				throw BinaryError("<>", __CavoStr(VOErrors.ARGSINCOMPATIBLE), true, lhs, rhs)
			endif

		#endregion
        internal class UsualDebugView
            private _uvalue as __Usual
            public constructor (u as __Usual)
            _uvalue := u

            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] ;
            public property Value as object get _uvalue:VALUE
            public property Type  as UsualType get _uvalue:_usualType

        end class
        */
    end structure

    [StructLayout(LayoutKind.Explicit)];
    internal structure _UsualData
        // Fields
        [FieldOffset(0)] internal d as __VoDate
        [FieldOffset(0)] internal r8 as real8
        [FieldOffset(0)] internal i as long
        [FieldOffset(0)] internal i64 as int64
        [FieldOffset(0)] internal l as logic
        [FieldOffset(0)] internal p as System.IntPtr
        [FieldOffset(0)] internal s as symbol
        [FieldOffset(0)] internal dt as System.DateTime

    end structure

    internal enum UsualType as byte
        // These numbers must match with the types defined in the compiler
        // They also match with the USUAL types in VO (BaseType.h)
        member @@Void		:=0
        member @@Long		:=1
        member @@Date		:=2
        member @@Float		:=3
        // Note # 4 (FIXED) was defined but never used in VO
        member @@Array		:=5
        member @@Object		:=6
        member @@String		:=7
        member @@Logic		:=8
        member @@CodeBlock	:=9
        member @@Symbol		:=10
        // see below for missing values
        // The follow numbers are defined but never stored inside a USUAL in VO and Vulcan
        member @@Byte		:=11
        member @@ShortInt	:=12
        member @@Word		:=13
        member @@DWord		:=14
        member @@Real4		:=15
        member @@Real8		:=16
        member @@Psz		:=17
        member @@Ptr		:=18
        member @@Usual		:=19	// USUAL by Ref, not implemented in Vulcan
        member @@Int64		:=22
        member @@Uint64     :=23
        member @@Char		:=24    // not stored in a usual
        member @@Dynamic    :=25
        member @@DateTime	:=26
        member @@Decimal	:=27
        member @@Memo		:=32	// Used in RDD system in VO
        member @@Invalid    :=99
    end enum

    [StructLayout(LayoutKind.Explicit, Pack := 1)];
    internal structure UsualFlags
        [FieldOffset(0)] export usualType as UsualType
        [FieldOffset(1)] export width as Sbyte
        [FieldOffset(2)] export decimals as Sbyte
        [FieldOffset(3)] export isByRef as logic

        constructor(type as UsualType)
        usualType := type
    end structure
///
/// Determine the data type of an expression.
///
/// <param name="x"></param>
/// <returns>
/// </returns>
function UsualType(u as __Usual) as dword
	return (dword) u:Type

///
/// Access contents of an address, whether it is passed by reference or not.
///
/// <param name="u"></param>
/// <returns>
/// </returns>
function UsualVal(u as Usual) as Usual
	return u

///
/// Determine the data type of an expression.
///
/// <param name="u"></param>
/// <returns>
/// </returns>
function ValType(u as Usual) as string
	return u:ValType()

end namespace