////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Initializes the filter.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Suppress or enable messages by message type
/// @param[in] type     (--) Message category to suppress or allow.
/// @param[in] filterOn (--) Flag specifying whether to suppress or allow messages of this category.
/// @note This depends on TS_HS_MSG_TYPE's enumeration constants to have sequential 0-based values.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Test if the specified message type has been suppressed.
/// @param[in] type     (--) Message category of interest
/// @return true if specified message category has been suppressed.
/// @note This depends on TS_HS_MSG_TYPE's enumeration constants to have sequential 0-based values.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Set the time interval to the specified value. Does nothing if argument not
///            greater than 0.
///
/// @param[in] sec ( s) The interval of time in which we are concerned about duplicate messages.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Set the maximum message display count to the specified value. Does nothing if
///            argument not greater than 0.
///
/// @param[in] count (--) The max number of messages allowed per interval of time.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Set the maximum amount of message history to keep. Does nothing if
///            argument not greater than 0.
///
/// @param[in] size (--) The max number of messages that will be tracked at a time.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Used by the "C" wrapper version of the hsSendMsg macro when the macro is invoked
///          with severity, subsystem, and message text arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Used by the "C" wrapper version to log message that contain field specifiers. The
///          hsSendMsg macro should be used log messages which do not contain field specifiers.
///
/// @param[in] file     (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line     (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function (--) The name of the function logging the message; typically __func__ (unused).
/// @param[in] severity (--) Enumeration constant that represents the type of message.
/// @param[in] subsys   (--) The subsystem that is logging the message.
/// @param[in] mtext    (--) The message text.
///
/// @note    It is undesirable to use field specifiers since they can lead to run-time errors.
///          In C++ they can be replaced with "<<" and I/O manipulators; however, in "C" there
///          are no practical alternatives, so we continue to provide the functionality here.
///          This function is only intended to be used by the TS_hs_msg macro and that macro
///          is only intended to be used by "C" code which needs to log messages that contain
///          field specifiers. Messages which do not use field specifiers should use the
///          hsSendMsg macro.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Default constructor
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Log a health and status message to the terminate plugin. This will terminate the
///            simulation if the message type TS_HS_FATAL and the originating subsystem is in
///            the list of "is-fatal-to" subsystems.
///
/// @param[in] file      (--) name of file which initiated logging the message.
/// @param[in] line      (--) line of file which initiated logging the message.
/// @param[in] function  (--) The name of the function logging the message.
/// @param[in] type      (--) the type of message (e.g. info, warning, etc.).
/// @param[in] subsystem (--) the subsystem from which the message originated.
/// @param[in] mtext     (--) the message text.
///
/// @return  True if successful, or false on failure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Determine if a TS_HS_FATAL message should cause termination of the simulation.
///
/// @param[in] subsystem   (--) Check if the message should be fatal to this subsystem.
///
/// @return    True if the message should terminate the simulation, else false.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Turn on/off sim termination behavior for the specified subsystem.
///
/// @param[in] subsystem  (--) The relevant subsystem.
/// @param[in] fatal      (--) True means turn termination behavior "on", false means "off".
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Turn on sim termination behavior for the specified delimited list of subsystems.
///            Clears existing settings before applying new ones, if any, i.e. it replaces.
///
/// @param[in] subsystems   (--) List of delimited subsystem names.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Turn on sim termination behavior for the specified delimited list of subsystems.
///            Does not clear existing settings before applying new ones, i.e. it appends.
///
/// @param[in] subsystems  (--) A string containing a list of delimited subsystems for which
///                             logging a "fatal" message should terminate the simulation.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Non-member function which registers an subsys override string for all HS activity
///          associated with the SimObject identified by the id.
///          A vector is used to store the strings.
///          Should be called from a "default_data" or "initialization" job.
///          Both job classes are called prior to entering freeze so no special treatment for
///          check-pointing.
///
/// @param[in] id     (int)           SimObject id  - index into the vector
/// @param[in] subsys (const char *)  override string for the subsystem.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Non-member function which based on the current job looks a override string for
///          the subsystem.  If the current job provides access to the parent sim object which has
///          an integer identifier.  The identifier is used as an index into a vector of strings.
///          The string at the index is populated by tsHsRegisterSubsys. If the sim object has not
///          registered the default from the supplied std::string is returned.
///
/// @param[in] subsystem (const std::string&) default subsystem string
/// @return  subsystem string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Non-member function which produces a stack trace string for debugging purposes.
///          The string is generated using gcc's backtrace function. The application must be
///          compiled with "-g" option and linked with the "-rdynamic" option for the backtrace to
///          contain meaningful information.
///
/// @return  The stack trace string with embedded newlines between each stack frame line.
/// @see     http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
/// @see     http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Constructor that sets the message severity and subsystem, but not the message text.
///
/// @param[in] severity   (--) Enumeration constant that represents the type of message.
/// @param[in] subsys     (--) The subsystem that is logging the message.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Constructor which sets all data members, including the message text.
///
/// @param[in] severity   (--) Enumeration constant that represents the type of message.
/// @param[in] subsys     (--) The subsystem that is logging the message.
/// @param[in] mtext      (--) The message text.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Sets the message's message text. This is the part of the message which tells the
///            reader what actually happened.
///
/// @param[in] mtext   (--) The message text.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Sends a message to the message log assuming the message's message text has
///            already been set either by the ctor or a setter. While this method is public, the
///            helper macro hsSendMsg can be used instead to automatically determine the file
///            and line number.
///
/// @param[in] file      (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line      (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function  (--) Function invoking 'send'; typically __func__ macro is used.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Sends a message to the message log. While this method is public, the
///            helper macro hsSendMsg can be used instead to automatically determine the file
///            and line number.
///
/// @param[in] file      (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line      (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function  (--) Function invoking 'send'; typically __func__ macro is used.
/// @param[in] mtext     (--) The message text.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   A non-class function which sends a message to the message log. This version is
///            primarily intended for use by the hsSendMsg macro.
///
/// @param[in] file      (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line      (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function  (--) Function invoking 'send'; typically __func__ macro is used.
/// @param[in] msg       (--) A message object.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   A non-class function which sends a message to the message log. This version is
///            primarily intended for use by the hsSendMsg macro.
///
/// @param[in] file     (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line     (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function (--) The name of the function logging the message; typically __func__.
/// @param[in] severity (--) Enumeration constant that represents the type of message.
/// @param[in] subsys   (--) The subsystem that is logging the message.
/// @param[in] mtext    (--) The message text.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Default constructor.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Constructor that takes queue size and blocking flag.
///
/// @param[in] size     (--) The maximum number of messages the queue can hold before overflow occurs.
/// @param[in] blocking (--) True if user is willing to allow insertMsg to block.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Return the capacity of the queue.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Return the current size of the queue.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Initializes (or re-initializes) the queue.
///
/// @param[in] size     (--) The maximum number of messages the queue can hold before overflow occurs.
/// @param[in] blocking (--) True if user is willing to allow insertMsg to block.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Inserts a message request at the tail of the queue. If queue overflows, the oldest
///            message will be silently overwritten. A counter is kept to record how many time
///            this happens. Inserts can be blocking or not. If not blocking then messages will
///            be dropped if a lock cannot be achieved.
///
/// @param[in] file       (--) Source file name invoking 'send'; typically __FILE__ macro is used.
/// @param[in] line       (--) Line in file invoking 'send'; typically __LINE__ macro is used.
/// @param[in] function   (--) The name of the function logging the message; typically __func__.
/// @param[in] type       (--) Enumeration constant that represents the type of message.
/// @param[in] subsys     (--) The subsystem that is logging the message.
/// @param[in] mtext      (--) The message text.
/// @param[in] met        (--) The mission elapsed time.
/// @param[in] timestamp  (--) The Unix timestamp.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Removes a message request from the head of the queue and places it in node. If
///            the queue is empty, false is return and the contents of node are undefined.
///
/// @param[out] node   (--) The message request info from the head of the queue is returned in this.
///
/// @return Returns true if successful, false if queue was empty.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Allocates memory for the queue. If size is <1, a queue big enough to hold 1 message
///            will be allocated.
///
/// @param[in] size     (--) The maximum number of messages the queue can hold before overflow occurs.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Reallocates memory for the queue. Copies outstanding request from original queue to
///            resized queue. If resized queue is smaller, older request will be discarded.
///
/// @param[in] size     (--) The maximum number of messages the queue can hold before overflow occurs.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details   Make a shallow copy of a queue
/// @param[in] original     (--) The source queue to clone from.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details A utility function which returns a timestamp of the form: "_MMDDHHmm" where the letters
///          represent month, day, hour, minute, respectively.
///
/// @return  The timestamp as a std::string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Deletes all managed plugins.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Initializes all managed plugins.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Updates all managed plugins.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Shuts down all managed plugins.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Forwards the specified message to all managed plugins.
///
/// @param[in] file      (--) name of file which initiated logging the message.
/// @param[in] line      (--) line of file which initiated logging the message.
/// @param[in] function  (--) The name of the function logging the message; typically __func__.
/// @param[in] type      (--) the type of message (e.g. info, warning, etc.).
/// @param[in] subsys    (--) the subsystem from which the message originated.
/// @param[in] met       (--) the mission-elapsed time that the message was sent.
/// @param[in] timestamp (--) the unix timestamp that the message was sent.
/// @param[in] mtext     (--) the message text.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Returns a pointer to the specified plugin.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Copy constructor.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Attempts to acquire H&S configuration info from files and environment variables.
///          Initial configuration values are set by the ctor initialization list. This method
///          first attempts to load a file named HS_CONFIG_FILE_NAME from the current directory.
///          If that fails, the method attempts to load the file from location $HS_CONFIG_PATH. If
///          that fails, the default ctor values are used. In all cases values may be overridden
///          after being set by file or ctor by $USS_HS_TEXT_PATH and/or $USS_HS_SQLITE_PATH.
///
/// @return  Returns false if a configuration file exist but contains bad content, else returns
///          true.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Replaces the text plugin path and sqlite plugin path with values of environment
///          variables $USS_HS_TEXT_PATH and $USS_HS_SQLITE_PATH, respectively, provided the
///          environment variables are defined.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Loads an H&S configuration file from the specified stream.
///
/// @param[inout] file  (--) The input file.
///
/// @return  Returns true if all fields read and file's ios flag are good else returns false.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Debug method that dumps data members to the console.
////////////////////////////////////////////////////////////////////////////////////////////////////


// This test has been placed at the bottom to avoid the #line directives
// affecting anything else, since cppunit uses __LINE__ to report lines numbers
// for test failures.


// Test basic message output, test the getPlugin method, test the setEnabled method.


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Required by cppunit. Called at the beginning of each testXXX method.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Test message filter set functions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Test message filter set functions when they are used to change settings dynamically
///          during run-time (as opposed to during initialization). This test simulates how
///          settings could be modified while the simulation is running via tools like trick_tv.
///
/// @notes   This test is not even close to being exhaustive. The filter is somewhat of a
///          state machine with a large amount of state information and several current settings
///          all affecting the filtering outcome. This test amounts to a "spot check" verifying
///          correct outcome given typical usage.
///
/// @note    There is no "update" function for the message filter. Changes to settings take effect
///          each time a message is logged. Message filter data structures are pruned/grown
///          each time a message is logged. Pruning is opportunistic. The entire data structure
///          is not pruned with each message; only parts of the data structure related to the
///          processing of the message are pruned. In other words, the data structure will not
///          immediately shrink to its minimum size during the processing of a single message.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Test message filter's redundancy filtering algorithm.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details Test message filter's type filtering algorithm.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details See what happens when the number of nodes added to the queue exceeds the queue's
///          capacity. What should happen is that the older nodes are dropped to make room for the
///          new nodes to be inserted.
///
/// @notes   xxx
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] numberToConvert     Floating number to convert.
/// @param[in] decimalPrecision    Decimal precision to round up to.
/// @param[in] minValue            Min value output should be limited to.
/// @param[in] maxValue            Max value output should be limited to.
///
/// @return    std::string         Converted string from float.
///
/// @details   Converts the passed in argument in to a standard library string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] numberToConvert   (--)  Integer number to convert.
/// @param[in] minValue          (--)  Minimum integer value.
/// @param[in] maxValue          (--)  Maximum integer value.
///
/// @return    std::string       (--)  Converted string from int.
///
/// @details   Converts the passed in argument in to a standard library string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] str (--) The string to parse.
/// @param[in] delimiter (--) The delimiter to parse from the string.
///
/// @returns  std::vector<std::string> (--) Vector of strings split from the given string.
///
/// @details  Splits the given string by the given delimiter and returns the result as a vector of
///           sub-strings.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] str (--) The string to trim.
///
/// @returns  std::string (--) The trimmed string.
///
/// @details  Copies the given string, trims the copy by removing characters of the set
///           ( \n\r\t\f\v) (including space) from the beginning and end, and returns the trimmed
///           copy.
///           credit: https://www.techiedelight.com/trim-string-cpp-remove-leading-trailing-spaces/
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] str (--) The string to check the ending of.
/// @param[in] end (--) The suffix to check at the end of the str string.
///
/// @returns  bool (--) True if str ends with end, otherwise false.
///
/// @details  Compares the last n characters of str with end, n being the length of end.  If end is
///           longer than str, always returns false.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this strings unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the method for float to string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the method for int to string.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the method for string split.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the method for string trim.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests the method for string ends with.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      fileName     (--)  name of text file to parse
///
/// @throw          TsParseException if unable to open file becuase it does not exist, we don't have
///                 read access, or some other unknown reason.
///
/// @details        Checks accessibility of the requested text file.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  str          (--)  string entry in a column of a config-file
/// @param[in]  subsystem    (--)  subsystem string to be used in error reporting
/// @param[in]  locationInfo (--)  optional, string to report error location
///
/// @return     newDouble  (--)  double created from value in "str"
///
/// @details  Converts a string to a double, with checks and error reporting.
///
/// @note     A string appended to a valid floating-point number, like "4.15string", will be
///           be successfully converted to 4.15. However, the warning will be issued, alerting
///           the user that a string was detected but will still assume a value of 4.15.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in,out]  v   reference to vector that will contain the separated sub-strings
/// @param[in]      s   string to split
/// @param[in]      c   character that delimits string
///
/// @details        This function splits up a string according to the delimiter character passed in
///                 (the char c argument). It stores each piece of the input string into the vector
///                 that was passed in by reference. This can be then accessed in order to pull
///                 out the desired data.
///
/// @warning        Any previous data stored in the input string vector v will be cleared.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in,out]  theIfstream  (--)  std::ifstream object to associate with a given text file
/// @param[in]      fileName     (--)  name of text file to parse
///
/// @throw          TsParseException if unable to open file becuase it does not exist, we don't have
///                 read access, or some other unknown reason.
///
/// @details        Checks accessibility of the requested text file and opens it for parsing.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in,out]  theIfstream  (--)  std::ifstream object to associate with a given text file
///
/// @details        Closes an ifstream if opened.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in,out]  linesVector  (--) reference to vector that will contain each line of parsed file
/// @param[in]      fileName     (--) name of text file to parse
/// @param[in]      maxLineWidth (--) optional; the max amount of character per line (default 50000)
/// @param[in]      removeChars  (--) optional; tells parser to ignore ANY of these characters if
///                                   if found in the file
/// @param[in]      commentChars (--) optional; tells parser to ignore text that comes after this
///                                   EXACT string (up until the start of the next line)
///
/// @throw          TsParseException if error found during file parsing.
///
/// @details        Parses a file, saving each relevant line (not blank or commented out) into
///                 the reference string vector.
///
/// @warning        Any previous data stored in the input string vector will be cleared.
////////////////////////////////////////////////////////////////////////////////////////////////////


// TiXmlString copy constructor


// find a char in a string from an offset. Return TiXmlString::npos if not found


// Microsoft compiler security


// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
// "assign" optimization removes over 10% of the execution time.
//


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this math unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests that a string is cleared of quotes and preceding/trailing whitespace.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests convertToDouble() method.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests that a line is split according to a delimiting character.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests parseLines() method.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] type                  Type of fluid (from FluidType enum)
/// @param[in] phase                 Phase of fluid (from FluidPhase enum)
/// @param[in] mWeight               Molecular weight (1/mol) of the fluid
/// @param[in] criticalTemperature   Critical temperature (K) of the fluid
/// @param[in] density               Pointer to curve fit of density for the fluid
/// @param[in] viscosity             Pointer to curve fit of dynamic viscosity for the fluid
/// @param[in] specificHeat          Pointer to curve fit of specific heat for the fluid
/// @param[in] thermalConductivity   Pointer to curve fit of thermal conductivity for the fluid
/// @param[in] prandtlNumber         Pointer to curve fit of Prandtl number for the fluid
/// @param[in] adiabaticIndex        Pointer to curve fit of adiabatic index for the fluid
/// @param[in] pressure              Pointer to curve fit of pressure for the fluid
/// @param[in] temperature           Pointer to curve fit of temperature for the fluid
/// @param[in] saturationPressure    Pointer to curve fit of saturation pressure for the fluid
/// @param[in] saturationTemperature Pointer to curve fit of saturation temperature for the fluid
/// @param[in] heatOfVaporization    Pointer to curve fit of heat of vaporization for the fluid
///
/// @details  Constructs the fluid properties by specifying values for each attribute. Also serves
///           as the default constructor since a default value is specified for each argument.
////////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Predefined Fluid Properties. Initializes the array of fluid
///           properties, indexed by fluid type, specifying:
///           - Type of fluid (enumeration of chemical compositions/names)
///           - Fluid phase (enumeration of gas, liquid or solid)
///           - Molecular weight (1/mol)
///           - Critical temperature Tc (K)
///           - Curve fit for density (kg/m3) as a function of temperature and pressure
///           - Curve fit for dynamic viscosity (Pa*s) as a function of temperature and pressure
///           - Curve fit for specific heat (J/kg/K) as a function of temperature and pressure
///           - Curve fit for thermal conductivity (W/m/K) as a function of temperature and pressure
///           - Curve fit for Prandtl number -- as a function of temperature and pressure
///           - Curve fit for adiabatic index -- as a function of temperature and pressure
///           - Curve fit for pressure (kPa) as a function of temperature and density
///           - Curve fit for temperature (K) as a function of specific enthalpy and pressure
///           - Curve fit for log10 of saturation pressure (kPa) as a function of inverse of reduced
///             temperature (Tc/T)
///           - Curve fit for reduced saturation temperature as a function of saturation pressure
///           - Curve fit for latent heat of vaporization as a function of reduced temperature
///           GUNNS demands an exactly invertible specific heat curve fit of the form
///           - Cp  = a + bT (for both liquids and gases)
///           GUNNS demands an exactly invertible density curve fit
///           - rho = a P / T (for ideal gases)
///           - rho = (a + b*P) + (c + d*P)*T + (e + f*P)*T^2 (for liquids)
///           - rho = f(T,P)  (table lookup for real gases)
///           all of which have exact (isothermal) inverses between pressure and density, so
///           - rho = f(T, <P = f(T, rho)>)
///           GUNNS demands exactly invertible saturation pressure & temperature curve fits
///           - Ts = f(Ps = f(Ts)
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  type                (--)     Type of Chemical Compound
/// @param[in]  fluidType           (--)     Corresponding type of fluid
/// @param[in]  mWeight             (1/mol)  Molecular Weight of Chemical Compound
/// @param[in]  thermoCoeffHighTemp (--)     Array of Coefficients, Applicable when T>1000 K
/// @param[in]  thermoCoeffLowTemp  (--)     Array of Coefficients, Applicable when T<1000 K
///
/// @details  Default constructs this Chemical Compound with the specified arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @returns  True if the given ChemicalCompound is not equal to this one.
///
/// @details  Currently does not check the mThermoCoeffs.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Defined Chemical Compounds.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    type   Type of Chemical Reaction
///
/// @return   A pointer to the specified Chemical Reaction or null if undefined.
///
/// @details  Returns a pointer to the Chemical Reaction specified by Chemical Reaction type.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    type   Type of Solid
///
/// @return   A pointer to the properties of the specified solid or null if undefined.
///
/// @details  Returns a pointer to the properties of the solid specified by solid type.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Methane combustion model. Frees memory allocated for arrays.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      Value       (--)  value to take exp() of
///
/// @return         double      (--)  exp(value).
///
/// @details  Safely calculates exp(value). If value is low enough to cause an underflow error, this
///           method will return exp(-8) , preventing run time errors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      MoleRatios    (--)  Array of mole fractions for inlet fluids.
/// @param[in]      FluidTypes    (--)  Array of fluid types that describes inlet mixture.
/// @param[in]      NFluidTypes   (--)  Number of entries in array FluidTypes.
///
/// @throws   TsInitializationException
///
/// @details  Sets the initial mixture mole quantities to the inlet condition. This method also
///           checks if the inlet quantities are outside of this reaction's explosive limit, and
///           halts combustion if this criteria is not reached. If the inlet conditions are within
///           unstable limits, this method will call the unstable method, and halt normal
///           combustion/recombination.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Gives an initial guess for the solveEquilibrium() method. From that first guess,
///           solveEquilibrium() iterates until the correct result is met. For each subsequent call
///           to solveEquilibrium(), the previous equilibrium concentration are used as a first guess.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]          ratios      (--)  Pointer to array of mole fractions.
/// @param[in]          moles       (--)  Pointer to array of moles.
/// @param[in]          compound    (--)  Compound type
///
/// @details  If the molar amount for a compound is negative after applying the conservation of atomic
///           species constraint, this method will set the the amount to what was calculated using
///           the elemental potential equations. This prevents numerical exceptions.
///
/// @note     If this method is called on the last pass of the solveElemPotEqns method, an incorrect
///           solution will result.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in,out]      productRatios   (--)  Array of Mole Fractions from current solveEquilibrium() iteration
/// @param[in,out]      productMoles    (--)  Array of Moles from current solveEquilibrium() iteration
/// @param[in]          temp            (K)   Temperature to calculate equilibrium at
/// @param[in]          it              (--)  Current solveEquilibrium() iteration
///
/// @details  Uses the Methane-Oxygen combustion elemental potential equations to calculate the
///           equilibrium concentrations. This method calculates each elemental Lagrange constraint
///           based on the concentrations of O2, CO2, and H2O. These constraints are then used to
///           calculate the mole fractions of all other compounds. The conservation of elemental
///           composition equations are then used to recalculate the concentrations of O2, CO2, and
///           H2O. This method can easily diverge and generate non-physical results, therefore a
///           dampened iterative method is used to reach the converged solution.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This method is called when the oxidizer to fuel ratio is within the unstable range.
///           This method calculates the solution at each end of this range, then uses linear
///           interpolation to estimate the solution at the desired oxidizer ratio.
////////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////////////
/// @details
/// This private constructor builds with material properties map with the predefined materials.
///////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param  name         --     name of the material
/// @throws     TsOutOfBoundException
///
/// @details
/// Returns If the named material is present, a pointer to the material.
/// Otherwise throw a TsOutOfBoundsException.
///
/// Predefined materials are:
/// - "Aluminum 6061"
/// - "Steel 304"
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    type                 Type of this Solid (from SolidType enum)
/// @param[in]    density              Fensity of this Solid
/// @param[in]    specificHeat         Specific heat of this Solid
/// @param[in]    thermalConductivity  Thermal conductivity of this Solid
/// @param[in]    roughness            Roughness of this Solid
///
/// @details  Constructs this Solid Properties by specifying values for each attribute. Also serves
///           as the default constructor since a default value is specified for each argument.
////////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Predefined Solid Properties. Initializes the array of solid
///           properties, indexed by solid type, specifying:
///           - Type of solid (enumeration of alloy types)
///           - Density (kg/m3)
///           - Specific heat (J/kg/K)
///           - Thermal conductivity (W/m/K)
///           - Roughness (m)
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] compound          (--)            The chemical compound properties of this sorbate.
/// @param[in] blockingCompounds (--)            Optional list of chemical compound types that block the sorption of this sorbate.
/// @param[in] offgasCompounds   (--)            Optional list of chemical compound types produced when this sorbate is desorbed.
/// @param[in] tothA0            (kg*mol/kg/kPa) Toth isotherm parameter a0.
/// @param[in] tothB0            (1/kPa)         Toth isotherm parameter b0.
/// @param[in] tothE             (K)             Toth isotherm parameter E.
/// @param[in] tothT0            (--)            Toth isotherm parameter t0.
/// @param[in] tothC0            (K)             Toth isotherm parameter c0.
/// @param[in] dh                (kJ/mol)        Heat of adsorption of this sorbate in the sorbant, see note on sign convention below.
/// @param[in] km                (1/s)           Adsorption time constant.
///
/// @throws   TsInitializationException
///
/// @details  Constructs this Sorbate Properties with arguments and validates properties values.
///           Validation checks throw exception on failures.
///
/// @note     Sign convention for dh: adsorption is usually exotheric (adsorbing sorbates produces
///           waste heat) and desorption usually endothermic.  For this argument, a negative sign
///           represents exothermic, and positive is endothermic.  This matches the convention for
///           delta-enthalpy typically given for heats of reaction in literature.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that (--) Object to be copied from.
///
/// @details  Copy constructs this Sorbate Properties.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  pp          (kPa)  Partial pressure of the sorbate in the freestream.
/// @param[in]  temperature (K)    Temperature of the freestream.
///
/// @returns  double (kg*mol/m3) Equilibrium loading of the sorbate.
///
/// @details  Computes & returns the equilibrium loading of the sorbate under current conditions,
///           using the Toth isotherm equation for this sorbate in the sorbant.
///
/// @note  The caller must ensure temperature > 0.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] compound    (--) The chemical compound that interacts with this Sorbate.
/// @param[in] interaction (--) The amount of interaction with this Sorbate.
///
/// @details  Pushes a new SorbateInteractingCompounds onto mBlockingCompounds with the given
///           values.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] compound    (--) The chemical compound that interacts with this Sorbate.
/// @param[in] interaction (--) The amount of interaction with this Sorbate.
///
/// @details  Pushes a new SorbateInteractingCompounds onto mOffgasCompounds with the given values.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] type     (--)     Defined type of this sorbant.
/// @param[in] density  (kg/m3)  Density of this sorbant material.
/// @param[in] porosity (--)     Fraction of the packed sorbant enclosure volume that is voids.
/// @param[in] cp       (J/kg/K) Specific heat of this sorbant material.
///
/// @throws   TsInitializationException
///
/// @details  Constructs this Sorbant Properties with arguments and validates properties values.
///           Validation checks throw exception on failures.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] that (--) Object to be copied from.
///
/// @details  Copy constructs this Sorbant Properties.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] compound          (--)            Sorbate chemical compound type.
/// @param[in] blockingCompounds (--)            Optional list of chemical compound types that block the sorption of this sorbate.
/// @param[in] offgasCompounds   (--)            Optional list of chemical compound types produced when this sorbate is desorbed.
/// @param[in] tothA0            (kg*mol/kg/kPa) Sorbate Toth isotherm parameter a0 in this sorbant.
/// @param[in] tothB0            (1/kPa)         Sorbate Toth isotherm parameter b0 in this sorbant.
/// @param[in] tothE             (K)             Sorbate Toth isotherm parameter E in this sorbant.
/// @param[in] tothT0            (--)            Sorbate Toth isotherm parameter t0 in this sorbant.
/// @param[in] tothC0            (K)             Sorbate Toth isotherm parameter c0 in this sorbant.
/// @param[in] dh                (kJ/mol)        Heat of adsorption of the sorbate in this sorbant.
/// @param[in] km                (1/s)           Adsorption time constant.
///
/// @returns  Pointer to the newly created sorbate.
///
/// @details  Adds a sorbate with the given properties to the list of sorbates that this sorbant
///           will interact with, and returns a pointer to the new sorbate.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Defined Sorbant Properties.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  type (--) Type of Sorbant Properties
///
/// @return   A pointer to the specified Sorbant Properties or null if undefined.
///
/// @details  Returns a pointer to the Sorbant Properties specified by the Sorbant Properties type.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      nCompounds      (--)  Number of compounds.
/// @param[in]      testTempStep    (K)   Initial temperature step for solveCombustion iteration.
/// @param[in]      maxItEquil      (--)  Max iterations for solveEquilibrium().
/// @param[in]      maxItCombust    (--)  Max iterations for solveCombustion().
/// @param[in]      maxCombustLoops (--)  Number of times solveCombust will refine its temperature step.
/// @param[in]      minErrorEquil   (--)  Error minimum For solveEquilibrium().
///
/// @details  Default constructs this Combustion Model.
///
/// @note     Constructor is declared protected, and is only ever called by derived classes
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      tempGuess     (K)   Guess for final mixture temperature
/// @param[in]      press         (kPa) Mixture pressure
/// @param[in]      tempIn        (K)   Inlet mixture temperature.
/// @param[in]      molesIn       (--)  Pointer to array of inlet mole fractions.
/// @param[in]      fluidTypesIn  (--)  Pointer to array of GUNNS fluid types in inlet mixture.
/// @param[in]      nFluidtypes   (--)  Number of inlet fluids.
///
/// @throws   TsInitializationException
///
/// @details  Updates this combustion model with inlet conditions, then calculates outputs. Calling
///           this method will solve for the equilibrium conditions assuming constant pressure and
///           enthalpy, as well as the inputted inlet ratios.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  tempGuess     (K)   Guess at mixture temperature
/// @param[in]  press         (kPa) Mixture pressure
///
/// @throws   TsInitializationException
///
/// @details  Calculates solution at the given pressure, using the stored variables for all other
///            inlet conditions.
///
/// @note     tempGuess should be above a certain minimum to maintain model accuracy. This limit is
///           reaction dependent.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @throws   TsInitializationException
///
/// @details  Calls solveCombustion method, and calculates thermodynamic properties.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      error1        (--)  Error subtype.
/// @param[in]      error2        (--)  Error cause.
///
/// @throws         TsInitializationException
///
/// @details  Throws a TsInizialitationException
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      array         (--)  Pointer to array being summed
/// @param[in]      arraySize     (--)  Size of array
///
/// @return         double      (--)  Sum of input array.
///
/// @throws         TsInitializationException
///
/// @details  Calculate the sum of the inputted array.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Recalculate mole ratios based on new new mole values
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      fluidTypes    (--)  Array of fluid types in inlet mixture.
/// @param[in]      type          (--)  Fluid type we wish to know the index of.
/// @param[in]      nFluidTypes   (--)  Number of entries in array FluidTypes.
///
/// @returns        int           (--)  Index of desired fluid type.
///
/// @details  Receives an array of fluid types at the inlet, and returns the index of the desired
///           fluid type. This index is then used to determine the initial moles of that fluid.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      compound      (--)  Chemical compound to look up data for.
/// @param[in]      temp          (K)   Temperature of compound
///
/// @returns        double*       (--)  Pointer to the correct array of thermodynamic coefficients.
///
/// @details  This method provides the correct array for the calcEnth, calcEnt, and calcCp methods.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      compound      (--)  Pointer to chemical compound of interest
/// @param[in]      temp          (K)   Temperature at which to evaluate thermodynamic property
///
/// @returns        double        (--)  Gibbs Free Energy
///
/// @details  Calculates Gibbs free energy using the NASA thermodynamic coefficients for the specified
///           compound.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      Compound      (--)  Pointer to chemical compound of interest
/// @param[in]      Temp          (K)   Temperature at which to evaluate thermodynamic property
///
/// @returns        double        (kJ/mol) Enthalpy
///
/// @details  Calculates enthalpy using the NASA thermodynamic coefficients for the specified
///           compound.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      compound      (--)  Pointer to chemical compound of interest
/// @param[in]      temp          (K)   Temperature at which to evaluate thermodynamic property
/// @param[in]      partPress     (Pa)  Partial Pressure of compound
///
/// @returns        double        (kJ/mol/K) Entropy
///
/// @details  Calculates entropy using the NASA thermodynamic coefficients for the specified
///           compound.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      compound      (--)  Pointer to chemical compound of interest
/// @param[in]      temp          (K)   Temperature at which to evaluate thermodynamic property
///
/// @returns        double        (kJ/mol/K) Specific Heat
///
/// @details  Calculates specific heat using the NASA thermodynamic coefficients for the specified
///           compound.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      temp    (K)   Temperature to calculate equilibrium at
///
/// @throws         TsInitializationException
///
/// @details  Calculates and updates the equilibrium concentrations of all product compounds at the
///           given temperature. Iterations continue until the solution converges or the maximum
///           iterations are reached.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @throws         TsInitializationException
///
/// @details  Performs combust and recombination calculation. This algorithm first calculates the
///           enthalpy or entropy of the inlet mixture. The process is assumed complete when the
///           enthalpy/entropy of the products equals the enthalpy/entropy of the reactants.
///           Starting at the inlet temperature, the program steps through temperature at varying
///           intervals, calling the solveEquilibrium() function and calculating enthalpy/entropy at
///           every step. When the program overshoots, it will decrease its temperature step and
///           march in the opposite direction. If the program cannot reached the desired enthalpy/
///           entropy, the program will cease calculation and output the inlet conditions.
/////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  temp    (K)     Temperature of mixture.
///
/// @returns    double      (kJ/kg)     product
///
/// @details  Calculate the product of combustion (either enthalpy or entropy). Molecular weight is
///           also calculated, because it is needed to convert the entropy/enthalpy from kJ/mol to
///           kJ/g.
/////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Fluid Heat of Vaporization curve fit model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    a     (--) First coefficient for curve fit model.
/// @param[in]    alpha (--) Second coefficient for curve fit model.
/// @param[in]    beta  (--) Beta coefficient for curve fit model.
/// @param[in]    minX  (--) Curve fit model valid range lower limit for first variable.
/// @param[in]    maxX  (--) Curve fit model valid range upper limit for first variable.
/// @param[in]    name  (--) name for the instance.
///
/// @details  Constructs this Fluid Heat of Vaporization curve fit model taking coefficient and
///           range arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    a     (--) First coefficient for curve fit model.
/// @param[in]    alpha (--) Second coefficient for curve fit model.
/// @param[in]    beta  (--) Beta coefficient for curve fit model.
/// @param[in]    minX  (--) Curve fit model valid range lower limit for first variable.
/// @param[in]    maxX  (--) Curve fit model valid range upper limit for first variable.
/// @param[in]    name  (--) name for the instance.
///
/// @details  Initializes this Fluid Heat of Vaporization curve fit model taking coefficient, range
///           and name arguments
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  type               --      Type of Chemical Reaction
/// @param[in]  reactantMoleRatio  --      Mole ratio of reactant in Chemical Reaction
/// @param[in]  reactantType       --      Chemical compound type of reactant in Chemical Reaction
/// @param[in]  reagentMoleRatio   --      Mole ratio of reagent in Chemical Reaction
/// @param[in]  reagentType        --      Chemical compound type of reagent in Chemical Reaction
/// @param[in]  product1MoleRatio  --      Mole ratio of product 1 in Chemical Reaction
/// @param[in]  product1Type       --      Chemical compound type of product 1 in Chemical Reaction
/// @param[in]  product2MoleRatio  --      Mole ratio of product 2 in Chemical Reaction
/// @param[in]  product2Type       --      Chemical compound type of product 2 in Chemical Reaction
/// @param[in]  reactantEfficiency --      Efficiency of the reaction in removing the reactant
/// @param[in]  maxReactantRate    (kg/s)  Maximum rate the reaction can remove the reactant
///
/// @details  Default constructs this Chemical Reaction with the specified arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Defined Chemical Reactions.
///
/// @note  The LiOH reactions (LIOHH2O_SYNTHESIS & LI2CO3_FORMATION) are configured work as parallel
///        reactions in a GunnsFluidHotReactor link to model a LiOH CO2 scrubber cannister.  H2O is
///        required in the input stream to form enough of the LiOH*H2O monohydrate to then react
///        with CO2 in the input stream.  This models a realistic dependency on H2O input and lag
///        between when flow starts thru the cannister and when it ramps up its CO2 absorption.  Use
///        lower efficiencies < 0.5 in the HotReactor to increase the lag.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]      CombustFactory::CombustorType   (--)  Desired combustion model type.
///
/// @return         Combust*                        (--)  Pointer to combustion model.
///
/// @details  Creates a combustion model, and returns a pointer to that combustion model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  type   Type of Chemical Compound
///
/// @return   A pointer to the specified Chemical Compound or null if undefined.
///
/// @details  Returns a pointer to the Chemical Compound specified by Chemical Compound type.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The density (kg/m3) of this Fluid at the specified temperature and pressure
///
/// @note     rho = getDensity(t, getPressure(t,rho));
///
/// @note     If the specified temperature or pressure is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the density of this Fluid at the specified temperature and
///           pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The dynamic viscosity (Pa-s) of this Fluid at the specified temperature and pressure
///
/// @note     If the specified temperature or pressure is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the dynamic viscosity of this Fluid at the specified
///           temperature and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The specific heat (J/kg/K) of this Fluid at the specified temperature and pressure
///
/// @note     If the specified temperature or pressure is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the specific heat of this Fluid at the specified temperature and
///           pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The specific enthalpy (J/kg) of this Fluid at the specified temperature and pressure
///
/// @note     h = getSpecificEnthalpy(getTemperature(h,p),p).
///
/// @note     If the specified temperature or pressure is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the specific enthalpy of this Fluid at the specified temperature
///           and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The thermal conductivity (W/m/K) of this Fluid at the specified temperature and
///           pressure.
///
/// @note     If the specified temperature or pressure is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the thermal conductivity of this Fluid at the specified
///           temperature and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Input temperature of this Fluid
/// @param[in]    pressure     (kPa) Input pressure of this Fluid
///
/// @return   The PrandtlNumber -- of this Fluid at the specified temperature and pressure.
///
/// @note     If the specified temperature or density is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the Prandtl Number -- of this Fluid at the specified
///           temperature and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)   Temperature of this Fluid
/// @param[in]    pressure     (kPa) Pressure of this Fluid
///
/// @return   The adiabatic index (gamma) of this Fluid at the specified temperature and pressure.
///
/// @note     If the specified temperature or density is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the adiabatic index (gamma) of this Fluid at the specified
///           temperature and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    temperature  (K)     Temperature of this Fluid
/// @param[in]    density      (kg/m3) Density of this Fluid
///
/// @return   The pressure (kPa) of this Fluid at the specified temperature and density.
///
/// @note     Either p = getPressure(t, getDensity(t, p)) or p >= DBL_EPSILON.
///
/// @note     If the specified temperature or density is outside the bounds of the data, then the
///           appropriate boundary value is returned.
///
/// @details  Computes and returns the pressure of this Fluid at the specified temperature and
///           density.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    specificEnthalpy  (J/kg) Specific enthalpy of this Fluid
/// @param[in]    pressure          (kPa)  Pressure of this Fluid
///
/// @return   The temperature (K) of this Fluid at the specified specific enthalpy and pressure
///
/// @note     t = getTemperature(getSpecificEnthalpy(t, p), p)
///
/// @note     If the specified specific enthalpy or pressure is outside the bounds of the data,
///           then the appropriate boundary value is returned.
///
/// @details  Computes and returns the temperature of this Fluid at the specified specific enthalpy
///           and pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    pressure  (kPa) Pressure to evaluate saturation temperature at
///
/// @return   The saturation temperature (K) of this Fluid at the specified pressure
///
/// @note     t = getSaturationTemperature(p)
///
/// @note     If the specified pressure is outside the bounds of the data,
///           then the appropriate boundary value is returned.
///
/// @details  Computes and returns the saturation temperature of this Fluid at the specified
///           pressure.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]  type   Type of Fluid
///
/// @return   A pointer to the properties of the specified fluid or null if undefined.
///
/// @details  Returns a pointer to the properties of the fluid specified by fluid type.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Fluid Saturation Temperature curve fit model .
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    a     (--) 0th-order polynomial coefficient for curve fit model.
/// @param[in]    b     (--) 1st-order polynomial coefficient for curve fit model.
/// @param[in]    c     (--) 2nd-order polynomial coefficient for curve fit model.
/// @param[in]    minX  (--) Curve fit model valid range lower limit for first variable.
/// @param[in]    maxX  (--) Curve fit model valid range upper limit for first variable.
/// @param[in]    name  (--) name for the instance.
///
/// @throws   TsInitializationException
///
/// @note     The arguments are the coefficients of the corresponding quadratic equation.
///
/// @details  Constructs this Fluid Saturation Temperature curve fit model taking coefficient and
///           range arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in]    a     (--) 0th-order polynomial coefficient for curve fit model.
/// @param[in]    b     (--) 1st-order polynomial coefficient for curve fit model.
/// @param[in]    c     (--) 2nd-order polynomial coefficient for curve fit model.
/// @param[in]    minX  (--) Curve fit model valid range lower limit for first variable.
/// @param[in]    maxX  (--) Curve fit model valid range upper limit for first variable.
/// @param[in]    name  (--) name for the instance.
///
/// @details  Initializes this Fluid Saturation Temperature curve fit model taking coefficient,
///           range and name arguments
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Sorbant Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for properties of the defined sorbants.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for properties of the defined sorbates.  We don't do an exhaustive test of exact
///           values for all sorbates in all sorbants here.  Rather, we do an easy > 0 check, and
///           we'll test for exact values for specific sorbates in further tests below.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for custom sorbants and sorbates.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for exceptions thrown during sorbant and sorbate construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[in] tothA (kg*mol/kg/kPa) Sorbate Toth isotherm parameter a0 in this sorbant.
/// @param[in] tothB (1/kPa)         Sorbate Toth isotherm parameter b0 in this sorbant.
/// @param[in] tothE (K)             Sorbate Toth isotherm parameter E in this sorbant.
/// @param[in] tothT (--)            Sorbate Toth isotherm parameter t0 in this sorbant.
/// @param[in] tothC (K)             Sorbate Toth isotherm parameter c0 in this sorbant.
/// @param[in] pp    (kPa)           Partial pressure of the sorbate in the freestream.
/// @param[in] T     (K)             Temperature of the freestream.
///
/// @returns  double (kg*mol/m3) Toth equilibrium loading.
///
/// @details  Compute the Toth equilibrium loading for test.  Assumes all arguments are in valid ranges.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Chemical Reaction Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for consistency.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for conservation of mass (within 0.0002 mole) in chemical reactions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for reaction rate between 0.0 and 1.0.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this curve fit unit-test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Executed before each unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test Saturation Temperature curve fit.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test Heat of Vaporization curve fit.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test curve fit initialization exception on invalid range (min >= max).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test curve fit invalid range exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test curve fit invalid range bounds.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test initialization exceptions specific to Saturation Temperature curve fit.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test initialization exceptions specific to Heat of Vaporization curve fit.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Material Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


/// @brief check minimum values


////////////////////////////////////////////////////////////////////////////////////////////
/// @details
/// This is a test method for steel304.
////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////
/// @details
/// This is a test method for Aluminum_60601.
////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Fluid Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for default construction without exceptions.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for consistency between density and pressure..
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for consistency between specific enthalpy and temperature.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for a return value of zero within valid range of input.  All fluid properties
///           should be positive across the entire input range.  For now, we test the min & max
///           range points, which suffices for linear fits.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test invalid range bounds.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_HE_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_XE_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_N2_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_O2_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_CH4_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_H2_REAL_GAS
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test table look-ups for GUNNS_WATER_PVT
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Tests reversibility of the saturation curve.  Ts = f(Ps = f(Ts)).
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Chemical Compound Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test that the default values are set correctly.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test ensures that none of the possible input conditions will result in any exceptions.
///           The temperature bounds were determined by the limits on the fluid properties class.
///           The pressure bounds were based on the expected operating conditions for this class
///           (it was determined unlikely that this class would be used for reactions at a chamber
///           pressure above 3,000 psi or below 1 atm.
///
/// @note     WARNING! This test takes a very long time. Consider commenting it out of the test suite
///           if you don't want to wait.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test's the model's update method using last past mole fractions as inlet conditions.
///           This test checks inlet conditions at a variety of pressures and temperatures.
///
/// @note     WARNING! This test takes a very long time. Consider commenting it out of the test suite
///           if you don't want to wait.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test ensure that all get methods work correctly, and return the correct value.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test ensure that all set methods work correctly, and return the correct value.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test tries all possible non-physical input types, and ensures that initialization
///           errors are thrown in each case.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test tries updating the combustion model with fluid config data that lacks the
///           required fluid types (CH4 and O2), and ensures that initialization error are thrown.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test ensures that the combustion factory can correctly produce all possible model
///           types.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  This test validates the model. It calculates the solution to all possible inlet conditions,
///           and generates a text file of these results. This text file can then be compared to the
///           output generated from a tool such as STANJAM or Cantera. The effect of Helium at the
///           was not included in this test, since many of the validation tools used for this model
///           cannot correctly handle the presence of Helium.
///
/// @note     WARNING! This test takes a very long time. Consider commenting it out of the test suite
///           if you don't want to wait.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Default constructs this Solid Properties model unit test.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for Solid Properties model default construction.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for Solid Properties model construction with arguments.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for Solid Properties model accessors.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for Defined Solid Properties model.
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @details  Test for chemical compound properties consistency with fluid properties..
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
/// @param[out] Distributed2WayBusNotification (--) Reference to the caller's message object to copy the message into.
///
/// @returns  unsigned int (--) Number of notifications remaining in the queue.
///
/// @details  Set the caller's supplied notification object equal to the tail of the queue and pops
///           that message off of the queue, reducing the queue size by one.  If the queue size is
///           already zero, then returns an empty message.
////////////////////////////////////////////////////////////////////////////////////////////////////