// #############################################################################################
    // internal methods
    // #############################################################################################
        /** ****************************************************************************************
         * Implementation of get method. No locking is performed (has to be done before
         * invoking this method)
         *
         * @param variable    The variable to get.
         * @param substitute  If \c false, automatic variable substitutions are suppressed.
         *
         * @return Zero if the variable was not found. Otherwise it returns the priority of the
         *         (first) plug-in that contained the variable.
         ******************************************************************************************/
        public int loadImpl( Variable variable, bool substitute )
        {
            variable.ClearValues();

            // search variable
            int priority= 0;
            foreach ( PluginAndPrio ppp in plugins )
                if ( ppp.plugin.Load( variable ) )
                {
                    priority= ppp.prio;
                    break;
                }

            // not found?
            if ( !substitute || priority == 0 )
                return 0;

            // substitution in all values of variable
            for ( int valueNo= 0; valueNo < variable.Size(); valueNo++ )
            {
                int searchStartIdx=  0;
                int maxReplacements = 50;
                Variable replVar= null;
                do
                {
                    AString value= variable.GetString( valueNo );

                    // search start
                    int repStart= value.IndexOf( SubstitutionVariableStart, searchStartIdx );
                    if ( repStart < 0 )
                        break;
                    searchStartIdx= repStart;
                    int varStart= repStart + SubstitutionVariableStart.Length();

                    if( replVar == null )
                        replVar= new Variable();
                    int repLen;
                    int varLen;

                    // search end in two different ways depending on setting of public field "SubstitutionVariableEnd"
                    if ( SubstitutionVariableEnd.IsEmpty() )
                    {
                        int idx=   value.IndexOfAny( SubstitutionVariableDelimiters, Inclusion.Include, varStart );
                        if ( idx < 0 )
                            idx= value.Length();

                        varLen= idx - varStart;
                        repLen= idx - repStart;
                    }
                    else
                    {
                        int idx=   value.IndexOf   ( SubstitutionVariableEnd, varStart );
                        if (idx < 0 )
                        {
                            ALIB.WARNING(   "End of substitution variable not found (while start was found). Variable name: "
                                           + variable.Fullname
                                           + " Value: \"" + value + "\"." );
                            break;
                        }

                        varLen= idx - varStart;
                        repLen= idx + SubstitutionVariableEnd.Length() - repStart;

                    }

                    // get variable name string
                    tmpReplVarCategory.Clear();
                    if ( tmpReplVarAll.Set( value, varStart, varLen ).IsEmpty() )
                    {
                        searchStartIdx+=   SubstitutionVariableStart.Length()
                                         + SubstitutionVariableEnd.Length();
                        continue;
                    }

                    // parse category from name
                    int catSeparatorIdx= tmpReplVarAll.IndexOf( '_' );
                    if (catSeparatorIdx >= 0 )
                    {
                        tmpReplVarCategory.Set( tmpReplVarAll, 0                   , catSeparatorIdx );
                        tmpReplVarName    .Set( tmpReplVarAll, catSeparatorIdx + 1                   );
                    }
                    else
                        tmpReplVarName    .Set( tmpReplVarAll );

                    if ( tmpReplVarName.IsNotEmpty() )
                    {
                        replVar.Define( tmpReplVarCategory, tmpReplVarName, variable.Delim );
                        loadImpl( replVar, false );
                    }
                    else
                        replVar.ClearValues();


                    // do the replacement (even if no variable was found)
                    if ( replVar.Size() == 1 )
                        value.ReplaceSubstring( replVar.GetString(), repStart, repLen );

                    else if ( replVar.Size() > 1 )
                    {
                        variable.ReplaceValue( valueNo, replVar );

                        // repeat replacements in current value, as current value changed
                        valueNo--;
                        break;
                    }

                    else
                        value.ReplaceSubstring( "",                 repStart, repLen );

                }
                while( --maxReplacements > 0 );

                // warn if max replacements
                if( maxReplacements <= 0 )
                    ALIB.WARNING(     "Too many substitutions in variable "
                                      + variable.Fullname
                                      + ". Probably a recursive variable definition was made. ");
            }

            return priority;
        }