}	// InitializeInstance

        /// <summary>
        /// Enumeate missing configuration values, if any.
        /// </summary>
        /// <returns>
        /// This method returns a message suitable for display on a console or a
        /// Windows message box. The returned message summarises the state of
        /// affairs, even when all defined values are represented in the
        /// configuration file.
        /// </returns>
        public string EnumerateMissingConfigurationValues ( )
        {
            MissingConfigSettings = MissingConfigSettings ?? UnconfiguredDLLSettings.TheOnlyInstance;
            List<UnconfiguredDLLSettings.UnconfiguredSetting> missing = MissingConfigSettings.GetMissingPropsForFile (
                System.IO.Path.GetFileName (
                    _strAssemblyLocation ) );

            if ( missing.Count > ListInfo.LIST_IS_EMPTY )
            {
                System.Text.StringBuilder sbMessages = new System.Text.StringBuilder ( MagicNumbers.CAPACITY_04KB );

                //  ------------------------------------------------------------
                //  Start with a heading.
                //  ------------------------------------------------------------

                sbMessages.AppendFormat (
                    Properties.Resources.MSG_SOME_CONFIG_SETTINGS_OMITTED ,
                    MissingConfigSettings.Count ,
                    _DllConfigSettings.Count ,
                    AssemblyLocation ,
                    Environment.NewLine );

                //  ------------------------------------------------------------
                //  List each item in turn.
                //  ------------------------------------------------------------

                for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ;
                          intJ < MissingConfigSettings.Count ;
                          intJ++ )
                {
                    sbMessages.AppendFormat (
                        Properties.Resources.MSG_ACCEPTED_DEFAULT_VALUE ,       // Format Control String: {0} of {1}: {2} = {3}{4}
                        ArrayInfo.OrdinalFromIndex ( intJ ) ,                   // Format Item 0: {0} of
                        MissingConfigSettings.Count ,                           // Format Item 1: of {1}
                        missing [ intJ ].PropName ,                             // Format Item 2: : {2}
                        missing [ intJ ].PropValue ,                            // Format Item 3: = {3}
                        Environment.NewLine );                                  // Format Item 4: newline
                }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < MissingConfigSettings.Count ; intJ++ )

                //  ------------------------------------------------------------
                //  End with a footing.
                //  ------------------------------------------------------------

                sbMessages.AppendFormat (
                    Properties.Resources.MSG_ACCEPTED_LIST_END ,
                    Environment.NewLine );

                return sbMessages.ToString ( );
            }   // TRUE (One or more settings is missing from the configuration file.) block, if ( base.MissingConfigSettings.Count > ListInfo.LIST_IS_EMPTY )
            else
            {
                return string.Format (
                    Properties.Resources.MSG_ALL_CONFIG_SETTINGS_COVERED ,
                    _DllConfigSettings.Count ,
                    AssemblyLocation );
            }   // FALSE (All configuration settings are covered by the configuration file.) block, if ( base.MissingConfigSettings.Count > ListInfo.LIST_IS_EMPTY )
        }   // public string EnumerateMissingConfigurationValues
        }   // public string GetDLLSetting


		/// <summary>
		/// Set the like named properties from the linked configuration file.
		/// </summary>
		/// <param name="pderivedType">
		/// When the derived class constructor calls this method, it must pass in a
		/// reference to its own Type property.
		/// </param>
		/// <returns>
		/// The return value is the count of properties that were set.
		/// </returns>
		/// <remarks>
		/// This can almost certainly be simplified by enumerating the settings,
		/// but either way risks a NOT FOUND exception.
		/// 
		/// This method uses some fairly tricky Reflection gymnastics to map the
		/// key names in a configuration file to property names on an object.
		/// </remarks>
		protected PropertySourceCounts SetPropertiesFromDLLConfiguration ( Type pderivedType )
		{
			const BindingFlags BASELINE_BINDING_FLAGS = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            PropertySourceCounts rutpCounts = new PropertySourceCounts ( );

            rutpCounts.Defaulted = MagicNumbers.ZERO;
            rutpCounts.SpecifiedInConfiguration = MagicNumbers.ZERO;

            string [ ] astrDefaultErrorMessageColors = DLLSettings.AllKeys;

			for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ;
					  intJ < astrDefaultErrorMessageColors.Length ;
					  intJ++ )
			{
				string strPropertyName = null;                                  // This must be visible to the catch block.

                try
                {
                    strPropertyName = astrDefaultErrorMessageColors [ intJ ];
                    string strConfigValueString = DLLSettings [ strPropertyName ].Value;
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            @"At iteration {0} in {1}: {2} = {3}" ,             // Format control string
                            new object [ ]                                      // Array of values to substitute for tokens in format control string
                            {
                                ArrayInfo.OrdinalFromIndex ( intJ ) ,           // Format Item 0: At iteration {0}
                                MethodBase.GetCurrentMethod ( ).Name ,          // Format Item 1: in {1}
                                strPropertyName ,                               // Format Item 2: : {2}
                                strConfigValueString                            // Format Item 3: = {3}
                            } ) );
                    PropertyInfo piThisProperty = this.GetType ( ).GetProperty (
                        strPropertyName ,                                       // string      name         = The string containing the name of the property to get
                        BASELINE_BINDING_FLAGS );                               // bindingAttr BindingFlags = A bitmask comprised of one or more BindingFlags that specify how the search is conducted

                    if ( piThisProperty != null )
                    {
                        piThisProperty.SetValue (
                            this ,                                                  // Object      obj          = Object to which to apply setting
                            FromString (
                                piThisProperty ,
                                strConfigValueString ) ,                            // Object      value        = Value to assign to the property to which piThisProperty refers
                            BASELINE_BINDING_FLAGS | BindingFlags.SetProperty ,     // invokeAttr  invokeAtt	= A bitwise combination of the following enumeration members that specify the invocation attribute: InvokeMethod, reateInstance, Static, GetField, SetField, GetProperty, or SetProperty. You must specify a suitable invocation attribute.
                            null ,                                                  // Binder      binder		= An object that enables the binding, coercion of argument types, invocation of members, and retrieval of MemberInfo objects through reflection. If binder is null, the default binder is used.
                            null ,                                                  // Object[]    index		= Optional index values for indexed properties. This value should be null for non-indexed properties.
                            null );                                                 // CultureInfo culture		= The culture for which the resource is to be localized. If the resource is not localized for this culture, the Parent property will be called successively in search of a match. If this value is null, the culture-specific information is obtained from the CurrentUICulture property.
                        rutpCounts.SpecifiedInConfiguration++;                      // Count properties successfully set; the final value is returned as the function value.
                    }   // TRUE (The configuration file has a value for this property.) block, if ( piThisProperty != null )
                    else
                    {
                        MissingConfigSettings = MissingConfigSettings ?? UnconfiguredDLLSettings.TheOnlyInstance;

                        MissingConfigSettings.Add (
                            Path.GetFileName ( _strAssemblyLocation ) ,
                                strPropertyName ,                               // Format Item 0: property {1} default value
                                strConfigValueString );                         // Format Item 1: default value of {2} accepted
                        rutpCounts.Defaulted++;                                 // Count properties that retained their hard coded default values.
                    }   // FALSE (A value for this property is absent from the configuration file.) block, if ( piThisProperty != null )
                }
                catch ( Exception exAllKinds )
                {	// Since the catch block is within the body of the For loop, processing advances to the next item.
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            @"{0}.{1} = {2}" ,
                            nameof ( Environment ) ,
                            nameof ( Environment.StackTrace ) ,
                            Environment.StackTrace ) );
                    if ( RecoveredConfigurationExceptions == null )
                    {   // Create as and when needed.
                        RecoveredConfigurationExceptions = new System.Collections.Generic.List<RecoveredException> ( );
                    }   // if ( RecoveredConfigurationExceptions == null )

                    RecoveredConfigurationExceptions.Add (
                       new RecoveredException (
                           string.Format (
                               Properties.Resources.ERRMSG_EXCEPTION_NOT_THROWN ,
                               SaveErrorReport (
                                   this.GetType ( ) ,
                                   strPropertyName ,
                                   exAllKinds ).Message ) ,
                           exAllKinds.Source ,
                           exAllKinds.StackTrace ,
                           exAllKinds.TargetSite.Name ) );
                    Exception exWrapped = RecoveredConfigurationExceptions [ ArrayInfo.IndexFromOrdinal ( RecoveredConfigurationExceptions.Count ) ];
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_1 ,
                            exWrapped.Message ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_2 ,
                            exWrapped.Source ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_3 ,
                            exWrapped.TargetSite != null
                                ? exWrapped.TargetSite.Name
                                : Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_4 ,
                            exWrapped.StackTrace ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );

                    //  --------------------------------------------------------
                    //  Since SaveErrorReport appends the inner exception, this
                    //  test is technically redundant, but I chose to leave it,
                    //  as a reminder that new exceptions are not necessarily
                    //  so decordated. Hence, with the test, this code is a bit
                    //  more portable.
                    //  --------------------------------------------------------

                    if ( exWrapped.InnerException != null )
                    {
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                        string.Format (
                            Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_5 ,
                            exWrapped.InnerException.Message ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_6 ,
                                exWrapped.InnerException.Source ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_7 ,
                                exWrapped.InnerException.TargetSite.Name ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst (
                            string.Format (
                                Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_8 ,
                                exWrapped.InnerException.StackTrace ?? Common.Properties.Resources.MSG_OBJECT_REFERENCE_IS_NULL ) );
                    }   // TRUE (anticipated outcome) block, if ( exWrapped.InnerException != null )
                    else
                    {
                        TraceLogger.WriteWithBothTimesLabeledLocalFirst ( Properties.Resources.TRACEMSG_EXCEPTION_NOT_THROWN_9 );
                    }   // FALSE (unanticipated outcome) block, if ( exWrapped.InnerException != null )
                }   // catch ( Exception exAllKinds )
            }   // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < astrDefaultErrorMessageColors.Length ; intJ++ )

            return rutpCounts;
		}	// SetPropertiesFromDLLConfiguration