================================================================================
Changes since v18.01
================================================================================

--------------------------------------------------------------------------------
General framework-wide changes, improvements, trends, philosophy, and goals

- Topic: Consistency in terminology with regard to represented Players discovered,
         created and/or managed by an interoperability interface.

  Within MIXR, different terms associated with interoperability discovered,
  created and/or managed players had been used.  For example, in some parts
  of the code, the term 'remote' player was used, in others, the terms 'networked',
  'interoperability' and even 'surrogate' could be found. To further confuse
  matters, the term 'ghost' is sometimes used in other simulation packages.
  The use of terms implies the same thing; a stand-in representation of
  a player being updated or managed by a different simulation (most likely executed
  on a different computer within a distributed environment).

  To improve the consistent use of terminology within MIXR, we have
  shifted all references for this kind of stand-in representation, to a 'proxy' (e.g.,
  a proxy player).  Proxies are updated and/or managed, etc., by another
  (i.e., different, often networked) simulation, that is connected via a 'network'
  interface.  This interaction is facilitated by some kind of 'interoperability'
  protocol or mechanism. In other words, this stand-in representation (that is not being
  updated or managed by this simulation) is called a proxy. We feel the term 'proxy'
  more fairly conveys what it is, as opposed to how it comes about or where it comes from.

  We especially wanted to avoid using the term 'interoperability' player (or 'IPlayer'
  as abbreviated in code), as the 'I' is often stylistically (in code) used to
  imply interface, or more specifically an interface class; in this case, to a player.

  Moving to a consistent and more specific terminology also communicates that a
  degree of uncertainty or difference (due to the inconsistency of state and/or
  representation) between locally managed representations and stand-ins might exist.
  For example, from an analysis point of view, the outcomes (or results) from
  interactions between locally managed players and proxy players (especially, if not
  time-sync'd) might be different than outcomes that do not include induced consistency
  or representation differences.

- Topic: Being explicit (String verses Identifier)

  The processing of a Extensible Description Language (EDL) configuration file is
  enabled by a language parser and code embedded within Object-based classes.  Within it,
  two important data types, the String and the Identifier are of particular interest.

  Strings are defined in the language as quoted sequences of characters (e.g.,
  "Hello, World") as is common in many computer languages.  Identifiers are a bit different,
  they are an unquoted sequence of characters (e.g., 'blue', 'localhost', etc.), in other
  words, they are a sequence of printable characters without embedded spaces.
  (Note: We use single quotes (') in the examples above to indicate a particular valid
  character sequence for an Identifier; they are not to be used in a real configuration
  file.)

  Identifiers, like most computer languages, are defined using one or more deemed
  valid characters that excludes spaces; they are most commonly used to label
  or name things such as objects and variables. They are stored as a string value,
  and used to identify (no pun intended) things.  Their value is used in several ways,
  for example, from an input file parsing perspective, the value might be used to select a
  specific behavior of interest within an object instance (e.g., the type of scan).

  Within MIXR, although not enforced, stylistically, we prefer and strive to keep
  all identifiers lower case.  We believe this improves the readability of
  configuration input files and avoids potential confusion with macros (which
  are often written in UPPER case).

  Even though both Identifiers and Strings are created and defined as a sequence
  of characters, they are distinguished by the role they play within the language.
  Under the hood, their value is stored as a string, but they serve different
  purposes in terms of semantic meaning.  Identifiers can be viewed as value types
  that have internal meaning to the application (e.g., the mode for a sensor)
  Strings can be viewed as value types that have external meaning, for example,
  a description of something not terribly relevant to the executing application,
  a filename, or even a network address for which no unique data type (think token)
  has been defined.  Identifiers play the same role as symbols within a programming
  language (e.g., x=10, 'x' is a symbol), strings are used to communicate information
  to a user (e.g, "input>").  Note: It makes no sense for identifiers to be mutable
  (e.g., it would like saying the value '5' is mutable, as '5' is a value).

  Internal to the EDL parser, Strings and Identifiers are distinguished by
  different tokens.  Within the C++ code base, they were confounded - namely,
  an Identifier was defined as a subclass to a String. So, all Identifiers
  were considered Strings, even though their use and meaning is different.

  Change:

  The previous IS-A relationship within the C++ codebase no longer exists;
  Identifiers and Strings are now entirely different types. From an
  implementation point of view, they both use a string to store a particular
  value; but they are now unrelated types. This had an impact on the code base,
  but interestingly, very little, in fact, almost no impact on the configuration
  files.  Configuration files mostly specified types completely consistent with
  the EDL specification.  It was the C++ side or Object-based classes that
  required some rework and tweaking.

  In several cases, classes that defined slots to accept an identifier-type value
  information (such as Antenna with its slot to define polarization as either
  'none', 'vertical', 'horizontal', 'slant', etc.) was in fact accepting a
  String to process the same input value.  This worked because of the previous
  IS-A relationship between the two; Identifier values were being accepted
  as a valid 'String'.

  We feel that the role of Identifiers and Strings are more easily understood
  without an IS-A relationship obfuscating it.  All classes have been updated to
  handle slot inputs more in-line with the value types they expect. Specific
  changes are listed within each library.

- Topic: Being explicit (Boolean verses Number)

  The Extensible Description Language (EDL) system is enabled by a language parser
  and code embedded within Object-based classes.  Within it, two important data
  types, Boolean and Number are of particular interest.

  Previously, within the C++ code base, the Boolean type (i.e., class) was defined
  as a subclass to Number (i.e., IS-A relationship).  This relationship allowed
  for Boolean's to be a valid substitute for any Number, even though, both
  mathematically and in many computer languages are often considered to
  be different types (e.g., C++ 'bool' vs 'int'). Note: The C programming language
  provides no primitive Boolean type, its properties has to be emulated using
  an integer.

  Much like String and Identifiers, this can lead to some confusion.  For example,
  configuration files settings for things things that are on/off, true/false, etc.
  were, unfortunately conflated with other Number representations (e.g., '5') -
  which, somewhat disturbingly 'worked' where it was used. Worked in the sense that
  numbers were being interpreted as Boolean values (e.g., true if positive), but
  misaligned with the semantics for the kind of input that was expected. (This is
  commonly referred to as "weak" typing.)

  To resolve any possible misunderstanding of input file settings, and to better
  align the documentation of classes (which often indicates a desired Boolean value)
  with code implementation, we have revised Boolean's and Number's to be
  different types (i.e., there is no longer an IS-A relationship between them).
  Number's no longer convert to Boolean's, and Boolean's don't have a Number value
  equivalent.  Such conversions are, of course, available within the C++ domain
  as explicit type conversions. (In fact, this is a general trend in programming
  languages - make the programmer "say" exactly what they want.)

- Topic: General refactoring of EDL -> C++ support classes

  The Extensible Description Language (EDL) parses character strings into
  bite size chunks called tokens.  The meaning of those tokens, and how they are
  organized defines the language.

  In the case of computer programs, this input language (i.e., EDL) is 'spoken'
  in the form of an ASCII-based file (which we call a configuration file). It is
  interpreted (i.e., translated) by reading it and building an Object tree which
  eventually is handed (returned) to the C++-based program for use.

  Just like the EDL, C++ is a language as well. The software code that connects
  (or streamlines their interaction with each other) between these languages is
  referred to as 'binding' code.  Developers might also call this code
  'wrapper' code.  The purpose of the code is to provide a way to interface these
  different languages (i.e., smooth the 'impedance mismatch' between them).  For
  EDL based inputs, this means the process of parsing and translating what is
  specified into it's C++ equivalent.  (Technically, is not translating EDL to
  C++, but serving as a useful tool to help the developer create useful classes,
  and allow a user to configure them for their own needed.

  The translation aspect of this process is supported by tokens as defined
  by the EDL scanner and C++ classes to represent that information.  The
  process of translating can be thought of a series of representational casts.
  For example, in EDL land, a string is a series of characters surrounded by
  quotes ("hello world").  This is represented by a token with a particular value,
  which will be stored in a C++-defined class called String and eventually
  be used by the C++-based code.  As another example, Boolean's in the EDL are
  represented by "true" and "false" string values as identified by the scanner
  which creates a C++ Boolean object.  Once this translation happens, the C++ code
  might convert this representation to it's own primitive 'bool' type for internal use.
  In this class the Boolean class exists to facilite this intereaction between languages
  and can be considered part of the binding code.

  We could of exclusively used C++ primitive types for many of EDL's understood
  types, such as 'int', 'double' and 'float' but we wanted to lessen the burden
  on the user by being less picky (in terms of syntax) on how a number is written.
  From an EDL language perspective, the Number 5 can be written as 5, 5., 5.0, etc...
  If we require (from the user) a more specific representation for an integer (e.g., '5')
  or a float (5.0), those classes exist.

  For example, consider a slot parameter called 'range' - in which we allow a user
  to enter (input or specify) a number.  If we used purely C++ number representations,
  the user would be forced to enter one of a number of possible variations of a number
  (e.g., 1, 1.0, 1.0f, etc).  In the C++ language, the value 1 is considered to be an
  integer, the value 1.0 is considered a double and 1.0f is a float.  In other words,
  the C++ language (by default) defines a more strict or finer resolution representations
  for a number.  EDL doesn't care, we are perfectly willing to accept 1 or 1.0
  as a reasonable value input, then we can just accept a Number.

  From this perspective, the EDL language is purposely weakened (comparied to C++) in the
  domain of numbers.  It understands integers and floating point numbers, but that's about
  it.  In other words, both of these types are considered just concrete variations of
  the more abstract concept called 'Number'.  If, for example, we want the user to specify
  the parameter 'range', an abstract Number representation is probably good enough
  for what's intended.

  Rules (or suggestions):

  Within C++ classes that process EDL parser supplied inputs, accept Number if the
  user is suppose to provide it.  Accept an Integer if you want the user to specify
  an integer - it's kind of weird to see code that is ultimately looking for a C++ 'int'
  accept and happily process, without warning or error, an input value of say, 3.4.
  Not only does that not make sense, it can lead to a input file values that are
  easily misunderstood. If the user should specify a Boolean-type input, force
  them to specify 'true' or 'false' by using the Boolean class to clearly differentiate
  and/or strengthen that type.

  All code within MIXR (including examples) that is expecting a integer type value
  ('int') to be entered, has been updated to accept Integers, not the more general
  Number type.  This disallows, the possible acceptance of commonly understood floating
  point values (e.g., 1.0, 3.4, etc) and their interpretation as integers (e.g., 1, 3).
  This improvement makes more visible the values expected (and considered
  correct) and reduces the possible misunderstanding of a configuration input.
  Note: no configuration inputs were found to be incorrect or in error after this
  change was made.

- Topic: Being explicit (Unit classes)

  Units are no longer (IS-A) Numbers; they are units (Meters != 5).  Units represents
  magnitudes of a quantity. Obviously they are related to numbers; and are often
  view as meta-data about the numeric value of interest - but, units themselves
  are not numbers. Because they relate to numbers, or a specific value, the
  unit classes within MIXR contain a value for which it is associated with.
  When parsing and reading in an EDL file, the value they are associated with
  is accessed via 'getValue()' - which returns, by default, a double precision
  number (not Number!).  Maintaining units as a distinct type provides the means
  understand the value presented in terms of its measurement.

- Topic: Being explicit (Accepting Number vs Unit as Configuration Parameters)

  At many points in the code base, quantities (with an associated numerical value)
  are needed. As an example, the EarthModel class exposes configurable parameters
  for two lengths (a & b) and a flattening (f) value. It can accept parameters
  'a' and 'b' as either a 'Length' (a unit instance) or simply as a 'Number'.  According
  to the documentation (within source code), if a number is supplied, it would be
  interpreted as a length in meters.  While this is convenient, if the value is
  specified as a number, the meaning of it is certainly not explicit within a
  configuration file.

  In other parts of the code, numbers are accepted as a valid configuration
  parameter, only to be downcast to check if, for example, an 'Angle' was specifed
  (see Gun class).  Since Angle used to be a subclass of Number, all of this worked.
  While, again, this is convenient, it can lead to not very explicit configuration
  files.

  Arguments can be made between convenience, explicitness and correctness. Convenience
  comes from allowing a person to be less verbose - if used this way, correctness is
  based on knowledge of how that input will be interpreted and used.  Explicitness
  causes configuration files to become more verbose, but reduces the possibility of them
  being incorrect, better yet helps reduce the possibility of a less knowledgable person
  from entering incorrect information.

  We have decided on being explicit and remove any ambiguity within the MIXR-base classes.
  If a number associated with a quantity is going to be used, the slot/configuration
  parameter will be defined to accept that quantity.  Classes built 'on top' of MIXR can
  define classes to accept parameters in whatever way is desired (numbers, angles,
  power, etc.) - which allows for configuration flexibility, but caution should be
  exercised if correctness is of primary importance.

- Topic: Character arrays, the String class and std::string

  Many years ago, C++ (a superset of C) did not include much support for string handling.
  In fact, the string class (std::string) was not defined until 1998. Because
  initial versions of C++ only included low-level C string functionality,
  multiple incompatible designs for string handling classes were designed.
  In retrospect, even the inventor of C++ (Bjarne Stoustrup) considers this
  one of the worse mistakes he made during development.

  Unfortunately, because of legacy code, this issue persists even today;
  multiple conventions often need to be handled within applications - MIXR is
  no different in this regard. But now, std::string has been around for over
  20 years, it's probably as good a time as any to reduce the complexity of
  the code base by using it, and try to avoid the management of strings via
  C-style character arrays as much as possible.

  MIXR, defines its own Object-based reference counted String class - it,
  along with a character-based (char*) representation has been used almost
  exclusively as the way to manage and represent strings throughout the
  code base; this is changing.

  Starting with this release, we are transitioning to using the std library
  provided 'std::string' class as much as possible. We still need to retain
  MIXR's String class because of its Object-based compatibilities that
  streamlines interactions with the EDL parser.  But for places
  within the code base where this is not an issue, we are striving to replace
  String, String* and character-based representations with 'std::string'.
  At this point in time, we consider and treat 'std::string' much like any
  other C++ primitive (int, double, bool, etc).

  Design goal:

  At the end of this transition, we would like to use std::string as much as
  possible, and only use MIXR's String class when the need to marshal it around
  as an Object-based representation. Ultimately, the String class will become an
  Object-based, reference counted wrapper for std::string (as opposed to char*,
  which is currently what it does).

  Transition approach:

  It's difficult to make the transition from MIXR Strings and char*
  representations to std::string in one step.  Here are a series of steps we
  are taking right now:

  1) We are making MIXR's String class interface look more like (i.e., mimic)
     std::string. We renamed the 'getString()' method to 'c_str()', as among C++
     developers, 'c_str' is universally understood to be a C-style string.

     Note: we corrected a basic behavior of the String class to always
     represent a valid String by always maintaining a valid C string.  Previously,
     instantiating a String instance would create a 'shell' object which would
     return a null pointer when asked for its char* representation (via getString(),
     implicit char* or const char* methods).  Now, every instance of String
     manages a valid string representation (in other words, a String really IS a
     string! This is RAII!).

     A review of the code base indicated that Strings were always initialized
     - in other words, the behavior of existing code did not rely on possible
     String instances returning null pointers when asked for its char* pointer.
     Because 'std::string' always returns a valid C string (via c_str()), even if
     it's empty (it never returns a nullptr); we felt it important to mimic this
     behavior.

  2) Eliminated the implicit conversions from String to either 'char*' or
     'const char*'. The standard library string class does not allow this, neither
     should we.  It did make a few places within code more verbose (as
     '->c_str()' was occasionally added), but arguably, it did make the code more clear.
     Also, later in this transition, it's easy to search for all those 'c_str()' method
     calls and review them as opportunities to streamline type translations or
     mismatches.

  3) Separate the concepts of a String from an Identifier - in other words, we separated
     the concept of what a string is (a data type), from how it's interpreted or used.
     Identifier is no longer a subclass of String.  This simple change causes source code
     and a few configuration files to change in a way that made them more clear.

- Topic: Being explicit (User defined enumeration data types in C++11)

  The C programming language includes the capability to define user defined
  data types using the 'enum' keyword.  For example:

  enum State {Working, Failed};
  enum Color {Red = 0, Green = 1, Blue = 2};

  While this is convenient, problematic issues surface.

  1) The defined 'types' (State and Color) are unscoped, meaning,
     Working, Failed, Red, Green and Blue are all defined within
     the same scope. As is, Working, Failed, Red, Green and Blue
     represent integers and can be freely interchanged, and easily
     used in the wrong program context.

  2) The identifiers (e.g., Green) can be used directly to set integer
     variables.  In this case, the enumeration carries a value that has
     meaning.  Unfortunately, so does Working and Failed, which is
     less than obvious.

  In C++11, finer grained control over both aspects are available to avoid
  possible confusion. Now, one would write the equivalent desired code
  as follows:

  enum class State {Working, Failed}
  enum class Color: int {Red = 0, Green = 1, Blue = 2};

  Now Working and Failed belong to the class 'State' and Red, Green and Blue
  belong to the class 'Color' - never to be confused.  Additionally, Red,
  Green and Blue will (under the hood) be stored using an integer with
  the value as defined.  The underlying values can be extracted using
  an explicit cast as the example below shows:

  // extract the value for Red
  int x = static_cast<int>(Color::Red);

  - or -

  Color color{Color::Red};          // color initialized to Red
  color = Color::Green;             // now being reassigned
  int x = static_cast<int>(color);  // underlying value extracted

  MIXR code has been revised to use these (C++11) provided capabilities.

--------------------------------------------------------------------------------

#####################################################
Infrastructure libraries
#####################################################

--------------------------------------------------------------------------------
base library (mixr_base)

- All addresses in network handler classes have been updated to use type std::string
  as opposed to char*.  Also, all of the classes for which this matters also defines a
  slot method to accept Identifiers for specific hostnames.  Strings are still used
  to specify IP addresses.

- The directory containing all the function and table classes (previously called
  'functors') has been renamed to 'relations' to more properly describe the
  commonality of the classes it contains - namely, relationships. Background: in
  mathematics, a relation is just an ordered set of relationships between sets of
  information.  A function is a logical subset and is considered to be a
  'well-behaved' relation - meaning the pairing is always one for one (i.e., given
  an 'x', we get only and exactly one 'y').  Tables also implement relations.

   -------------------
   - Color classes -
   -------------------

   Color class
      1) Operators to convert a color to either Vec3d or Vec4d are now marked explicit.
         For example:
         // this (not completely obvious)
         const base::Vec4d* p = *color;
         // becomes (i.e., more obvious)
         const base::Vec4d* p = static_cast<const base::Vec4d*>(*color);
         // or even better (shorter, and still obvious)
         const auto p = static_cast<const base::Vec4d*>(*color);
      2) This class is now abstract

   --------------------------
   - Linear Systems classes -
   --------------------------

   All the classes from the linearsystems library have been integrated into 'base' -
   the linearsystems library no longer exists.

   -------------------
   - Network classes -
   -------------------

   PosixHandler class
      1) Slot parameter 'localIpAddress' now accepts both a String for IP addresses
         (e.g., "127.0.0.1") and Identifiers for addresses specified as hostnames
         (e.g., 'localhost')
      2) Internally, 'localIpAddress' is now stored as a std::string
      3) Slot parameter 'shared' now accepts a Boolean
      4) This class is now abstract

   TcpClient class
      1) Slot parameter 'ipAddress' now accepts both a String and Identifier with
         the same functionality as PosixHandler class changes
      2) Internally, 'ipAddress' is now stored as a std::string
      3) Class now marked final

   TcpHandler class
      1) Class is now abstract

   UdpBroadcastHandler class
      1) Internally, 'networkMask' is now being stored as a std::string
      2) Class now marked final

   UdpMulticastHandler class
      1) Internally, 'multicastGroup' is now being stored as a std::string
      2) Slot parameter 'loopback' now accepts a Boolean
      3) Class now marked final

   UdpUnicastHandler class
      1) Slot parameter 'ipAddress; now accepts both a String and Identifier with
         the same functionality as PosixHandler class changes
      2) Internally, ipAddr is now being stored as a std::string
      3) Class now marked final

   -------------------
   - Numeric classes -
   -------------------

   Boolean class
      1) This class has been refactored and it now based on Object.  It is
         no longer a subclass of Number.

   Complex class
      1) This class in no longer a subclass of Number.  Even through complex
         numbers are obviously 'numbers', they are usually treated uniquely
         different in mathematics and in C++.
      2) This class is primarily used to enable the creation of complex
         values as part of a configuration specification (i.e., an EDL
         file).  With the availability of std::complex as part of the C++
         standard library, there is no longer a need to maintain our own
         unique data type.  Therefore, much of the infrastructure to do
         that has been removed.
      3) The accessor asComplex() has been added to return a reference to
         the double-valued std::complex representation (i.e., complex<double>&).
      4) The special functions listed below have been deleted as well, but
         are available within the standard library; a simple mapping is as
         follows:

             zExp()  --> std::exp(std::complex)
             zLog()  --> std::log(std::complex)
             zPow()  --> std::pow(std::complex)
             zConj() --> std::conj(std::complex)
             zInv()  --> 1.0/std::complex

   Number class
      1) Methods associated with processing of Boolean values have been removed,
         please use the Boolean class instead
      2) Deleted 'getInt64' method.  Unused, and probably returns the wrong
         result on certain machines.  If you need it, do an explicit cast of
         the value contained by Number instance to what you want:

         Number x(4.0);
         int64_t my64 = static_cast<int64_t>(x.getValue());

         MIXR's representation of a Number can be viewed as a more relaxed,
         understood representation of a number (e.g., 1, 1.0), as opposed to
         the C++ perspective of simply being an integer or a double.  In other
         words, Number is a slightly weakened (less strongly typed) version
         of a number.  It's quite useful for obtaining user-defined numerical
         values from a configuration file.

   Operator and Operator-based classes
      1) These classes, provide the capability to add, subtract, multiply
         and divide Number types (Integer and Float).  They have been slightly
         refactored by creation of an abstract 'Operator' class to provide
         the foundation for operators more generally.

   -------------------
   - Transformation classes -
   -------------------

   Transform-based classes
      1) Transform is now abstract with several 'final' concretes 'Translate',
         'Rotate' and 'Scale'
      2) Transform and subclasses are designed to follow non-virtual public
         interface pattern.  'computeMatrix()' is a private pure abstract in base
         and implemented by subclasses.
      3) Operator to return a const reference Matrixd is now marked explicit
      4) A new directory 'transformations' has been created to contain all the
         individual transformation classes

   -------------------
   - Unit classes -
   -------------------

   -- Unit classes are no longer based on Number.
   -- As these classes were being updated, it appears that a number of rate
      oriented units are unfinished and probably non-functional. At some point,
      these will be improved.
   -- All rate oriented classes (AngularVelocity, FlowRate and LinearVelocity)
      have been moved and grouped into the folder called 'rates'

   FlowRate class
      1) This class appears to be broken.

   Unit class
      1) New abstract class that serves the role of storing a double
         precision value that is managed by specific concrete unit classes.

   -------------------
   - Other classes -
   -------------------

   Component class
      1) Slot parameters 'enableTimingStats', 'printTimingStats', and
         'freeze' now accept a Boolean

   FileReader class
      1) This class has been reworked to use std::string to represent
         file and path names.

   Identifier class
      1) This class is no longer a subclass of String.  It provides a complete
         implementation to manage a std::string-based identifier.  It is
         a subclass of Object to remain compatible with EDL parsing system.
         It has also been marked as a 'final' class.
      2) Two methods are of particular importance, 'c_str()' and 'str()' which
         returns a C-based and std::string-based representation, respectively.

   LatLon class
      1) Deleted class - use Latitude or Longitude to specify the coordinate
         of interest.

   Latitude & Longitude classes
      1) These new 'single responsibility' classes replace the functionality
         of the previous LatLon class.  Before this change, instances
         of the LatLon class was used to specify either a latitude or longitude
         coordinate.  We feel is better to more 'strongly' type this aspect of
         specifying coordinates to avoid possible confusion and/or misconfiguration
         of input values, which would accept latitude (or longitude) specific
         values, when the oppose is desired.  In other words, the previous design
         relied upon the particular inputs to be set correctly to be used
         correctly - this change helps avoid configuration input mistakes.
      2) Inputs for slot 'direction' is now an identifier for both classes that
         accept valid directions { north, south } or { east, west }.

   List class
      1) Updated return types for 'sizes' to be std::size_t as opposed to 'unsigned int' - this
         keeps all the code as generic as possible for differnent architectures.

   String class
      1) Removal of 'virtual' from several methods that don't need it. String is a
         fully defined concrete class, so ideally, it should not serve as a base
         class to something else.
      2) The method 'getString' has been renamed to 'c_str' per discussion above.
      3) Removed method 'getCopyString' which allocated a new character array and
         copied the internal contents of the String object into it.  It returned
         a char* (character pointer) back to callee.  While seemingly useful, this
         method was almost never used.  As the move towards using std::string
         progresses, this method becomes less useful (std::string already provides
         this functionality).

         String x("hello");
         std::string y = x->c_str();   // properly copies the char*-based string

      4) Now that the dafif library has been reworked, and the abstract Record
         is no longer a subclass to String, this String class is now marked 'final'
         to prevent subclassing of this type.
      5) The method 'empty()' which erases the contents of the string has been renamed
         to 'clear()' to more closely match std::string interface. For the time being,
         the method 'isEmpty()' will remain - it is equivalent to the std::string
         'empty()' method.

   Table class
      1) Slot parameter 'extrapolate' now accepts a Boolean

   Timer class
      1) Slot parameter 'active' now accepts a Boolean

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
dafif library (mixr_dafif)

- This library has been revised and updated in a few ways.
  1) All database loader classes are now grouped within a 'loaders' directory.
  2) All record oriented classes are now grouped within a 'records' directory.
  3) All of the code has been revised to use std::string to represent strings
     throughout.
  4) The testDafif example program has also been revised to use and pass only
     std::string's to/from this library.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
recorder library (mixr_recorder)

   DataRecorder class
      1) Slot parameters 'eventName' and 'application' now accept an Identifier

   PrintSelected class
      1) Slot parameter 'timeOnly' now accepts a Boolean

   NetInput class
      1) Slot parameter 'noWait' now accepts a Boolean

   NetOutput class
      1) Slot parameter 'noWait' now accepts a Boolean

   TabPrinter class
      1) Slot parameter 'msgHdrOptn' now accepts an Identifier

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
terrain library (mixr_terrain)

   DtedFile class
      1) Slot parameter 'verifyChecksum' now accepts a Boolean

--------------------------------------------------------------------------------

#####################################################
Devices, I/O, controllers libraries
#####################################################

--------------------------------------------------------------------------------
linkage library (mixr_linkage)

   Ai2DiSwitch class
      1) Slot parameter 'inverted' now accepts a Boolean

   DiscreteInput class
      1) Slot parameter 'inverted' now accepts a Boolean

   DiscreteOutput class
      1) Slot parameter 'inverted' now accepts a Boolean

--------------------------------------------------------------------------------

#####################################################
Graphics oriented libraries
#####################################################

--------------------------------------------------------------------------------
graphics library (mixr_graphics)

   -------------------
   - Font classes -
   -------------------

   AbstractFont class
      1) Font file name and path information not stored as an std::string. All
         subclasses that use this information (namely the loaders) have been
         adjusted -- a significant amount of code associated with managing
         null and non-null, variable length char*-based strings disappeared.

   BitmapFont class
      1) Slot parameter 'reverse' now accepts a Boolean

   -------------------
   - Readout classes -
   -------------------

   AbstractField class
      1) Slot parameter 'justification' now accepts an Identifier
      2) Slot parameter 'font' now accepts an Identifier
      3) Slot parameters 'highlight', 'underline', 'reversed', 'vertical,
         'brackets', 'linked' and 'inheritColor' now accepts a Boolean
      4) removed implicit conversion operators for both 'char*' and
         'const char*'
      5) Class renamed to 'Readout'

   NumericReadout class
      1) Slot parameter for 'blankIfZero' now accepts a Boolean

   Readout class
      1) This class is what was once named AbstractField.  It was renamed to
         'Readout' as it's the root class for all readout classes
      2) The methods line(const int) and column(const int) now returns void,
         as opposed to the very value just set

   Rotary2 class
      1) Event handler for 'onSelect' now accepts a Boolean

   -------------------
   - Other classes -
   -------------------

   Display class
      1) Slot parameters for 'normalFont' and 'orientation' now accept and correctly
         process an Identifier
      2) Slot parameters for 'antiAliasing' and 'reverseVideoBrackets' now
         accept a Boolean

   Graphic class
      1) Even handler for 'onSetVisibilityEvent' now accepts a Boolean
      2) Slot parameters 'noDisplayList', 'subcomponentsFirst', 'stipple', 'visible'
         and 'mask' now accepts a Boolean

   MapPage class
      1) Event handler for 'onUpdateCentered' now accepts a Boolean
      2) Slot parameter 'centered' now accepts a Boolean
      3) Slot parameter 'northUp' now accepts a Boolean

   Page class
      1) Slot parameter for 'subpagesFirst' and 'focusSlavedToSubpage' now
         accepts a Boolean

   Shape classes
      1) Slot parameter for 'filled' in Cirle class now accepts Boolean
      2) Slot parameter for 'connect' in Arc class now accepts Boolean
      3) Slot parameter for 'segment' in Line class now accepts Boolean
      4) Slot parameter for 'strip' in Quad class now accepts Boolean
      5) Slot parameter for 'fan' in Triangle class now accepts Boolean

   SymbolLoader class
      1) Slot parameters 'showOnlyInRange' and 'interconnect' now accept a
         Boolean

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
instruments library (mixr_instruments)

   AnalogDial class
      1) Slot parameter 'mobile' now accepts a Boolean

   AnalogGauge class
      1) Slot parameters 'outlined' and 'vertical' now accepts a Boolean

   CompassRose class
      1) Event handler 'onUpdateCentered' now accepts a Boolean

   DialArcSegment class
      1) Slot parameters 'dynamic' and 'filled' now accepts a Boolean

   GhostHorizon class
      1) Slots for parameters 'skyColor' and 'groundColor' now accept an
         Identifier

   Knob class
      1) Slot for parameter 'endless' now accepts a Boolean

   Instrument class
      1) Slot parameter 'allowComponentPass' now accepts a Boolean

   PushButton class
      1) Slot parameters 'maintained' and 'startdepressed' now accepts a Boolean

   SolenoidButton class
      1) Event handler 'onPicked' now accepts a Boolean

   SolenoidSwitch class
      1) Event handler 'selectLatch' now accepts a Boolean

   Tape class
      1) Slot for parameters 'vertical' and 'convert' now accepts a Boolean

   TickMarks class
      1) Slot parameter 'flip' now accepts a Boolean

- Within this library, various edl files have been updated to remain consistent
  with what is a String verses, what an Identifier.  Very few changes were needed,
  one of which included specifying the slot parameter 'format' for readouts
  to be quoted (e.g., "###" vs '###').

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
ui_glut library (mixr_ui_glut)

   GlutDisplay class
      1) Slot parameters 'fullScreen', 'resizeSubwindows', accumBuff' and
         'stencilBuff' now accepts a Boolean

--------------------------------------------------------------------------------

#####################################################
Image generation oriented libraries
#####################################################

--------------------------------------------------------------------------------
ig library (mixr_ig_cigi)

   CigiModel class
      1) Internally 'federateName' is now being stored as an Identifier
      2) Slot parameter 'hideOwnshipModel' now accepts a Boolean

- The move to storing a federate name as an Identifier caused related code
  to change to use this datatype.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
ig library (mixr_ig_pov)

--------------------------------------------------------------------------------

#####################################################
Map libraries
#####################################################

--------------------------------------------------------------------------------
rpf library (mixr_map_rpf)

   MapDrawer class
      1) Slot parameters 'drawGridMode' and 'showMap' now accepts a Boolean

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
vpf library (mixr_map_vpf)

--------------------------------------------------------------------------------


#####################################################
Models & general capabilities oriented libraries
#####################################################

--------------------------------------------------------------------------------
models library (mixr_models)

- All signature classes (IR and RF) are now grouped within the 'signature'
  folder.  All the classes defined in previous Signatures (.hpp/.cpp) files
  have been extracted into their own class files.

   IWeapon class
      1) Slot parameters 'released', 'failed', 'power', 'hang', 'hung', 'dummy',
         'jettisonable' now accepts a Boolean

   Antenna class
      1) Polarization enum is now an 'enum class' based integer
      2) Slot parameter 'polarization' now accepts an Identifier
      3) Slot parameter 'gainPatternDeg" and 'recycle' now accepts a Boolean

   Autopilot class
      1) Slot parameters 'navMode', 'altitudeHoldMode', 'velocityHoldMode',
         'holdHeading', 'loiterMode', 'loiterPatternCcwFlag', and
         'followTheLeadMode' now accepts a Boolean

   Bomb class
      1) Slot parameters 'noseFuze', 'midFuze' and 'tailFuze' now accepts
         a Boolean

   CollisionDetect class
      1) Slot parameter 'localOnly', 'useWorldCoordinates', and 'sendCrashEvents'
         now accepts a Boolean

   ExternalStore
      1) Slot parameter 'jettisonable' now accepts a Boolean

   Gimbal class
      1) Slot parameter 'type' now accepts an Identifier
      2) Enumerated type 'Type' is now an 'enum class'
      3) Enumerated type 'ServoMode' is now an 'enum class'
      4) 'ServoMode' type names have been shorten by removing the '_SERVO'
         postfix from each of them
      5) Slot parameters for 'terrainOcculting', 'checkHorizon', 'localPlayersOfInterest",
         'useWorldCoordinates', and 'ownHeadingOnly' now accepts a Boolean

   Gun class
      1) Filename was Guns.hpp/cpp, this was renamed to Gun.hpp/cpp

   Iff class
      1) Slot parameters 'enableMode1', 'enableMode2', 'enableMode3a', 'enableMode4',
         'whichMode4', and 'enableModeC' now accepts a Boolean

   IrSensor class
      1) Slot parameter 'sensorType' now accepts an Identifier
      2) Enumerated type 'SensorType' is now an 'enum class'
      3) Slot parameter 'trackManagerName' now accepts an Identifier
      4) The name of the track manager is now stored as a std::string

   IrSystem class
      1) Slot parameter 'seekerName' now accepts an Identifier
      2) The name of the seeker stored in this class is now a std::string
      3) Slot parameter 'disableQueries' now accepts a Boolean

   Gun class
      1) Slot parameter 'unlimited' now accepts a Boolean

   Player class
      1) The enumerated list of coordinate systems is now a class (i.e.,
         'enum class CoordSys').  Also the enumeration names have been shorted
         to eliminate the 'CS_' prefix, as it's no longer needed due to
         class specification
      2) Slot parameters 'terrainElevReq', 'interpolateTerrain', 'positionFreeze',
         'altitudeFreeze', 'attitudeFreeze', 'fuelFreeze', 'crashOverride', killOverride',
         'killRemoval'' 'enableNetOutput' and 'testBodyAxis' now accepts a Boolean
      3) Removed slot parameter for initPosition with a base::List
      4) 'useCoordSys' slot redefined to accept an Identifier { world, geod, local },
         not just any string

   RfSensor class
      1) Slot parameter 'trackManagerName' now accepts an Identifier
      2) Internally, this class now stores the track manager name as a
         std::string. Its API has been updated to set or get its name based on
         this type
      3) Slot parameter 'syncXmitWithScan' now accepts a Boolean

   RfSystem class
      1) Slot parameter 'antennaName' now accepts an Identifier
      2) Slot parameter 'disableEmissions' now accepts a Boolean
      3) Fixed bug in setSlotFrequency() in that it was dynamically casting a
         Frequency provided input value into a Frequency value.  If the cast failed
         (which is impossible), then treat the value as if it is a Number - which
         it can't be.

   Route class
      1) Slot parameters 'autoSequence' and 'wrap' now accepts a Boolean

   ScanGimbal class
      1) Enumerated type 'Side' is now an 'enum class'
      2) The anonymous enumerated list of scan modes has been replaced by a
         'enum class' that defines a ScanMode
      3) Slot parameter 'scanMode' now accepts an Identifier
      4) Slot parameter 'leftToRightScan' now accept a Boolean

   SigAzEl class
      1) Slot parameters 'swapOrder', 'inDegrees' and 'inDecibel' now accepts
         a Boolean

   TargetData class
      1) Slot parameters 'enabled', 'completed' and 'manualAssign' now accepts
         a Boolean

   TrackManager class
      1) Slot parameter 'logTrackUpdates' now accepts a Boolean

   WorldModel class
      1) Slot parameter 'gamingAreaUseEarthModel' now accepts a Boolean

- Due to changes associated with 'enum's becoming full-fledged 'enum class'es
  more specificity was added in other related classes that used those
  enumerated values.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
simulation library (mixr_simulation)

   IPlayer class
      1) Numerical player identifier (ID) was changed to be an 'int' as opposed
         to 'unsigned short'
      2) The enumerated list of modes is now a class (i.e., 'enum class Mode').
      3) Method 'isNetworkedPlayer()' renamed to 'isProxyPlayer()'
      4) String-based players name is now a std::string
      5) Slot parameter 'mode' now accepts an Identifier

   Station class
      1) Slot parameter 'ownship' now accepts an Identifier
      2) Slot parameter 'enableUpdateTimers' now accepts a Boolean

--------------------------------------------------------------------------------

#####################################################
Interoperability oriented libraries
#####################################################

--------------------------------------------------------------------------------
interop library (mixr_interop)

   NetIO class
      1) The number of input and output Nibs and entity types has changed
         from an 'unsigned int' quantity to a simple 'int'.
      2) The methods 'testOutputEntityTypes()' and 'testInputEntityTypes()'
         that did nothing are now designated abstract.  Subclasses must
         implement.
      3) Renamed the method 'createIPlayer()' to 'createProxyPlayer()'
      4) Slot parameters for 'federationName' and 'federateName' now
         accept an Identifier
      5) Slot parameters 'enableInput', 'enableOutput' and 'enableRelay'
         now accepts a Boolean

- Due to changes related to federate and federation names being typed
  as an Identifier caused other classes to also store that information
  the same way.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
dis library (mixr_interop_dis)
--------------------------------------------------------------------------------

   EmissionPduHandler class
     1) Slot parameters 'defaultIn' and 'defaultOut' now accepts a Boolean

   Nib class
     1) Renamed the method 'updateTheIPlayer()' to 'updateProxyPlayer()'

--------------------------------------------------------------------------------
hla library (mixr_interop_hla)
--------------------------------------------------------------------------------

   NetIO class
      1) Slot parameters 'regulatingTime' and 'constrainedTime' now accepts a
         Boolean

--------------------------------------------------------------------------------
rprfom library (mixr_interop_rprfom)
--------------------------------------------------------------------------------
