/** ****************************************************************************************
         * Invokes grand-parent's method and in addition, de-registers with
         * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock"
         * @param acquirer The acquirer to remove.
         * @return The new number of \e acquirers set.
         ******************************************************************************************/
        public override int   RemoveAcquirer( ThreadLock acquirer )
        {
            // d-register with ALIB lockers (if not done yet)
            if ( usesStdStreams )
            {
                ALIB.Lock.Acquire();
                    int  stdStreamLockRegistrationCounter= --this.stdStreamLockRegistrationCounter;
                ALIB.Lock.Release();

                if ( stdStreamLockRegistrationCounter == 0 )
                    ALIB.StdOutputStreamsLock.RemoveAcquirer( this );
            }

            Variable variable= new Variable();

            // export autosizes to configuration
            variable.Define( ALox.AUTO_SIZES, GetName() );
            AutoSizes.Export( variable.AddString() );
            variable.Store();

            // export "max elapsed time" to configuration
            variable.Define( ALox.MAX_ELAPSED_TIME, GetName() );
            AString destVal=  variable.Load() != 0  ?  variable.GetString()
                                                    :  variable.AddString();
            destVal._()._( MetaInfo.MaxElapsedTime.InSeconds() );
            variable.Store();

            // call parents' implementation
            return base.RemoveAcquirer( acquirer );
        }
    public void Log_WriteVerbosities()
    {
        UT_INIT();

        Log.AddDebugLogger();
        MemoryLogger memLogger= new MemoryLogger("MYLGGR");
        Log.SetVerbosity( Log.DebugLogger, Verbosity.Verbose, ALox.InternalDomains );

        Variable var= new Variable( ALox.ConfigCategoryName, Log.LOX.GetName() + "_MYLGGR_VERBOSITY",  ';' );
        Variable varBack= new Variable();

        // test writing into other variable with variable name error
        UT_PRINT( "An error message should follow (wrong variable format): " );
        var.Store(  "writeback MY_" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        Log.RemoveLogger( memLogger );

        // test writing into other variable
        var.Store(  "writeback MY_VAR" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        Log.RemoveLogger( memLogger );
        varBack.Define( "MY",  "VAR" ).Load();
        UT_PRINT(  "Variable written: " + varBack.GetString().ToString() );
        UT_TRUE( varBack.GetString().Length() > 0 );

        // test writing into other variable without cat
        var.Store(  "writeback ANON" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        Log.RemoveLogger( memLogger );
        varBack.Define( "",  "ANON" ).Load();
        UT_PRINT(  "Variable written: " + varBack.GetString().ToString() );
        UT_TRUE( varBack.GetString().Length() > 0 );

        // test writing into other variable without cat and with underscores in name
        var.Store(  "writeback _2ND_ANON" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        Log.RemoveLogger( memLogger );
        varBack.Define( "",  "2ND_ANON" ).Load();
        UT_PRINT(  "Variable written: " + varBack.GetString().ToString() );
        UT_TRUE( varBack.GetString().Length() > 0 );

        // test writing into other the variable itself
        var.Store(  "writeback" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        Log.RemoveLogger( memLogger );

        ALIB.Config.Load( var);
        UT_PRINT( "Variable written: " + var.GetString().ToString() );
        UT_TRUE( var.GetString().Length() > 0 );

       Log.RemoveDebugLogger();
    }
    // #############################################################################################
    // Reimplementing interface of grand-parent class SmartLock
    // #############################################################################################

        /** ****************************************************************************************
         * Invokes grand-parent's method and in addition, if field #usesStdStreams is set,
         * registers with
         * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock", respectively
         *
         * @param newAcquirer The acquirer to add.
         * @return The new number of \e acquirers set.
         ******************************************************************************************/
        public override int   AddAcquirer( ThreadLock newAcquirer )
        {
            // register with ALIB lockers (if not done yet)
            if ( usesStdStreams )
            {
                ALIB.Lock.Acquire();
                    int  stdStreamLockRegistrationCounter= this.stdStreamLockRegistrationCounter++;
                ALIB.Lock.Release();
                if ( stdStreamLockRegistrationCounter == 0 )
                    ALIB.StdOutputStreamsLock.AddAcquirer( this );
            }

            Variable variable= new Variable();

            // import autosizes from configuration (last session)
            if ( variable.Define( ALox.AUTO_SIZES, GetName()).Load() != 0 )
                AutoSizes.Import( variable.GetString() );

            // import "max elapsed time" from configuration (last session)
            if ( variable.Define( ALox.MAX_ELAPSED_TIME, GetName()).Load()  != 0 )
            {
                long maxInSecs= variable.GetInteger();
                Substring attrValue= new Substring();
                if ( variable.GetAttribute( "limit", attrValue ) )
                {
                    long maxMax;
                    attrValue.ConsumeLong( out maxMax );
                    if ( maxInSecs > maxMax )
                        maxInSecs= maxMax;
                }
                MetaInfo.MaxElapsedTime.FromSeconds( maxInSecs );
            }

            // Variable  <name>_FORMAT / <typeName>_FORMAT:
            ALIB.ASSERT_WARNING( ALox.FORMAT.DefaultValue == null,
                                 "Default value of variable FORMAT should be kept null" );
            if(    0 ==  variable.Define( ALox.FORMAT, GetName()     ).Load()
                && 0 ==  variable.Define( ALox.FORMAT, GetTypeName() ).Load() )
            {
                // no variable created, yet. Let's create a 'personal' one on our name
                variable.Define( ALox.FORMAT, GetName() );
                variable.AddString( MetaInfo.Format            );
                variable.AddString( MetaInfo.VerbosityError    );
                variable.AddString( MetaInfo.VerbosityWarning  );
                variable.AddString( MetaInfo.VerbosityInfo     );
                variable.AddString( MetaInfo.VerbosityVerbose  );
                variable.Store();
            }
            else
            {
                                           MetaInfo.Format          ._()._( variable.GetString(0) );
                if( variable.Size() >= 2 ) MetaInfo.VerbosityError  = variable.GetString(1).ToString();
                if( variable.Size() >= 3 ) MetaInfo.VerbosityWarning= variable.GetString(2).ToString();
                if( variable.Size() >= 4 ) MetaInfo.VerbosityInfo   = variable.GetString(3).ToString();
                if( variable.Size() >= 5 ) MetaInfo.VerbosityVerbose= variable.GetString(4).ToString();
            }
        
            // Variable  <name>_FORMAT_DATE_TIME / <typeName>_FORMAT_DATE_TIME:
            ALIB.ASSERT_WARNING( ALox.FORMAT_DATE_TIME.DefaultValue == null,
                                 "Default value of variable FORMAT_DATE_TIME should be kept null" );
            if(    0 ==  variable.Define( ALox.FORMAT_DATE_TIME, GetName()     ).Load()
                && 0 ==  variable.Define( ALox.FORMAT_DATE_TIME, GetTypeName() ).Load() )
            {
                // no variable created, yet. Let's create a 'personal' one on our name
                variable.Define( ALox.FORMAT_DATE_TIME, GetName() );
                variable.AddString( MetaInfo.DateFormat        );
                variable.AddString( MetaInfo.TimeOfDayFormat   );
                variable.AddString( MetaInfo.TimeElapsedDays   );
                variable.Store();
            }
            else
            {
                                           MetaInfo.DateFormat      = variable.GetString(0).ToString();
                if( variable.Size() >= 2 ) MetaInfo.TimeOfDayFormat = variable.GetString(1).ToString();
                if( variable.Size() >= 3 ) MetaInfo.TimeElapsedDays = variable.GetString(2).ToString();
            }
        
            // Variable  <name>FORMAT_TIME_DIFF / <typeName>FORMAT_TIME_DIFF:
            ALIB.ASSERT_WARNING( ALox.FORMAT_TIME_DIFF.DefaultValue == null,
                                 "Default value of variable FORMAT_TIME_DIFF should be kept null" );
            if(    0 ==  variable.Define( ALox.FORMAT_TIME_DIFF, GetName()     ).Load()
                && 0 ==  variable.Define( ALox.FORMAT_TIME_DIFF, GetTypeName() ).Load() )
            {
                // no variable created, yet. Let's create a 'personal' one on our name
                variable.Define( ALox.FORMAT_TIME_DIFF, GetName() );
                variable.AddInteger   ( MetaInfo.TimeDiffMinimum);
                variable.AddString( MetaInfo.TimeDiffNone   );
                variable.AddString( MetaInfo.TimeDiffNanos  );
                variable.AddString( MetaInfo.TimeDiffMicros );
                variable.AddString( MetaInfo.TimeDiffMillis );
                variable.AddString( MetaInfo.TimeDiffSecs   );
                variable.AddString( MetaInfo.TimeDiffMins   );
                variable.AddString( MetaInfo.TimeDiffHours  );
                variable.AddString( MetaInfo.TimeDiffDays   );
                variable.Store();
            }
            else
            {
                                           MetaInfo.TimeDiffMinimum= variable.GetInteger   (0);
                if( variable.Size() >= 2 ) MetaInfo.TimeDiffNone   = variable.GetString(1).ToString();
                if( variable.Size() >= 3 ) MetaInfo.TimeDiffNanos  = variable.GetString(2).ToString();
                if( variable.Size() >= 4 ) MetaInfo.TimeDiffMicros = variable.GetString(3).ToString();
                if( variable.Size() >= 5 ) MetaInfo.TimeDiffMillis = variable.GetString(4).ToString();
                if( variable.Size() >= 6 ) MetaInfo.TimeDiffSecs   = variable.GetString(5).ToString();
                if( variable.Size() >= 7 ) MetaInfo.TimeDiffMins   = variable.GetString(6).ToString();
                if( variable.Size() >= 8 ) MetaInfo.TimeDiffHours  = variable.GetString(7).ToString();
                if( variable.Size() >= 9 ) MetaInfo.TimeDiffDays   = variable.GetString(8).ToString();
            }

            // Variable  <name>FORMAT_MULTILINE / <typeName>FORMAT_MULTILINE:
            ALIB.ASSERT_WARNING( ALox.FORMAT_MULTILINE.DefaultValue == null,
                                 "Default value of variable FORMAT_MULTILINE should be kept null" );
            if(    0 ==  variable.Define( ALox.FORMAT_MULTILINE, GetName()     ).Load()
                && 0 ==  variable.Define( ALox.FORMAT_MULTILINE, GetTypeName() ).Load() )
            {
                // no variable created, yet. Let's create a 'personal' one on our name
                variable.Define( ALox.FORMAT_MULTILINE, GetName() );
                variable.AddInteger( MultiLineMsgMode );
                variable.AddString ( FmtMultiLineMsgHeadline   );
                variable.AddString ( FmtMultiLinePrefix  );
                variable.AddString ( FmtMultiLineSuffix );
                variable.Store();
            }
            else
            {
                                           MultiLineMsgMode=        (int) variable.GetInteger(0)  ;
                if( variable.Size() >= 2 ) FmtMultiLineMsgHeadline= variable.GetString(1).ToString();
                if( variable.Size() >= 3 ) FmtMultiLinePrefix     = variable.GetString(2).ToString();
                if( variable.Size() >= 4 ) FmtMultiLineSuffix     = variable.GetString(3).ToString();
                if( variable.Size() >= 5 ) { if (variable.GetString(4).Equals( "nulled" , Case.Ignore ) )
                                                MultiLineDelimiter= null;
                                             else
                                                MultiLineDelimiter= variable.GetString(4).ToString();
                                           }
                if( variable.Size() >= 6 ) MultiLineDelimiterRepl = variable.GetString(5).ToString();
            }

            // call parents' implementation
            return base.AddAcquirer( newAcquirer );
        }
    public void Log_DumpStateOnExit()
    {
        UT_INIT();

        Log.AddDebugLogger();
        MemoryLogger memLogger= new MemoryLogger();


        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        UT_TRUE( Log.DebugLogger.CntLogs == 0 );
        Log.RemoveLogger( memLogger );
        UT_TRUE( Log.DebugLogger.CntLogs == 0 );

        Variable var= new Variable( ALox.ConfigCategoryName, Log.LOX.GetName() + "_DUMP_STATE_ON_EXIT",  ',' );

        var.Store( "domain=/TEST, verbosity = e, domains, basic" );
        int cntLogs;

        var.Store( "domain=/TEST, verbosity = e, sptr, basic" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        cntLogs= Log.DebugLogger.CntLogs;
        Log.RemoveLogger( memLogger );
        UT_TRUE( Log.DebugLogger.CntLogs > cntLogs );

        var.Store( "verbosity = e, domains, basic" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        cntLogs= Log.DebugLogger.CntLogs;
        Log.RemoveLogger( memLogger );
        UT_TRUE( Log.DebugLogger.CntLogs > cntLogs );

        var.Store( "domains, loggers" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        cntLogs= Log.DebugLogger.CntLogs;
        Log.RemoveLogger( memLogger );
        UT_TRUE( Log.DebugLogger.CntLogs > cntLogs );

        var.Store( "" );
        Log.SetVerbosity( memLogger, Verbosity.Verbose );
        cntLogs= Log.DebugLogger.CntLogs;
        Log.RemoveLogger( memLogger );
        UT_TRUE( Log.DebugLogger.CntLogs == cntLogs );

        Log.RemoveDebugLogger();
    }