diff --git a/applications/test/Enum/Test-Enum.C b/applications/test/Enum/Test-Enum.C
index 064b77d4634534976ac61a5b185491255e2d97ba..f6f4d507f920ac5527c083e2e64ced6e8f1fbf54 100644
--- a/applications/test/Enum/Test-Enum.C
+++ b/applications/test/Enum/Test-Enum.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -73,7 +73,7 @@ const Foam::Enum<int> otherNames1
 
 
 // Can use for integers as well, but not scalar etc.
-const Foam::Enum<int> otherNames2
+Foam::Enum<int> otherNames2
 ({
     { 0, "a" },
     { 2, "b" },
@@ -110,6 +110,34 @@ int main(int argc, char *argv[])
         << "    values: " << flatOutput(otherNames2.values())
         << nl << nl;
 
+    otherNames2.append
+    ({
+        { 15, "fifteen"},
+        { 16, "sixteen"}
+    });
+
+    Info<<"Other Enum (appended)" << nl
+        << "    names:  " << otherNames2 << nl
+        << "    values: " << flatOutput(otherNames2.values())
+        << nl << nl;
+
+    std::cout
+        <<"stdout: "<< otherNames2
+        << nl << nl;
+
+
+    otherNames2.clear();
+    otherNames2.append
+    ({
+        { 1, "one"},
+        { 2, "two"}
+    });
+
+    Info<<"After clear and append:" << nl
+        << otherNames2 << nl
+        << otherNames2.values() << nl
+        << nl;
+
 
     dictionary testDict;
     testDict.add("lookup1", "c");
diff --git a/src/OpenFOAM/primitives/enums/Enum.C b/src/OpenFOAM/primitives/enums/Enum.C
index 591ea9f6226e0d324cf13acb8a01356269f67990..8c8eabca77b7bc82a576df5778be31e207a8493e 100644
--- a/src/OpenFOAM/primitives/enums/Enum.C
+++ b/src/OpenFOAM/primitives/enums/Enum.C
@@ -44,7 +44,6 @@ Foam::Enum<EnumType>::Enum
     {
         keys_[i] = pair.second;
         vals_[i] = int(pair.first);
-
         ++i;
     }
 }
@@ -63,6 +62,26 @@ Foam::List<Foam::word> Foam::Enum<EnumType>::sortedToc() const
 }
 
 
+template<class EnumType>
+void Foam::Enum<EnumType>::append
+(
+    std::initializer_list<std::pair<EnumType, const char*>> list
+)
+{
+    label i = size();
+
+    keys_.resize(i + list.size());
+    vals_.resize(i + list.size());
+
+    for (const auto& pair : list)
+    {
+        keys_[i] = pair.second;
+        vals_[i] = int(pair.first);
+        ++i;
+    }
+}
+
+
 template<class EnumType>
 EnumType Foam::Enum<EnumType>::get(const word& enumName) const
 {
@@ -115,6 +134,35 @@ EnumType Foam::Enum<EnumType>::read(Istream& is) const
 }
 
 
+template<class EnumType>
+bool Foam::Enum<EnumType>::read
+(
+    Istream& is,
+    EnumType& e,
+    const bool mandatory
+) const
+{
+    const word enumName(is);
+
+    const label idx = find(enumName);
+
+    if (idx >= 0)
+    {
+        e = EnumType(vals_[idx]);
+        return true;
+    }
+
+    if (mandatory)
+    {
+        FatalIOErrorInFunction(is)
+            << enumName << " is not in enumeration: " << *this << nl
+            << exit(FatalIOError);
+    }
+
+    return false;
+}
+
+
 template<class EnumType>
 EnumType Foam::Enum<EnumType>::get
 (
diff --git a/src/OpenFOAM/primitives/enums/Enum.H b/src/OpenFOAM/primitives/enums/Enum.H
index a8c190ab3e39d81f133a8e061a0ae44b6edd5d29..7d97a89c7537af3313fa8849bea6ef981dd5996b 100644
--- a/src/OpenFOAM/primitives/enums/Enum.H
+++ b/src/OpenFOAM/primitives/enums/Enum.H
@@ -28,7 +28,8 @@ Class
 
 Description
     Enum is a wrapper around a list of names/values that represent particular
-    enumeration values. All dictionary searches use a literal (not regex).
+    enumeration (or int) values.
+    All dictionary searches use a literal (not regex).
 
 SourceFiles
     Enum.C
@@ -41,6 +42,7 @@ SourceFiles
 
 #include "wordList.H"
 #include <initializer_list>
+#include <ostream>
 #include <utility>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -73,7 +75,7 @@ public:
     //- The type of enumeration represented by the Enum
     typedef EnumType value_type;
 
-    // Normally only enum, but be generous and allow integrals as well
+    // Allow enums and integrals (should fit within an int)
     static_assert
     (
         std::is_enum<EnumType>::value || std::is_integral<EnumType>::value,
@@ -83,6 +85,9 @@ public:
 
     // Constructors
 
+        //- Construct null (empty list)
+        Enum() = default;
+
         //- Construct from a values/names list.
         //  Duplicate values are permitted (eg, for aliases).
         //  Duplicate names are permitted, but won't make much sense.
@@ -112,6 +117,19 @@ public:
         inline const List<int>& values() const;
 
 
+    // Modify
+
+        //- Clear all entries
+        inline void clear();
+
+        //- Append value/key pairs to the lists of known enumerations
+        //  Does not check for duplicate entries
+        void append
+        (
+            std::initializer_list<std::pair<EnumType, const char*>> list
+        );
+
+
     // Query
 
         //- Find the index of the given name.
@@ -197,6 +215,15 @@ public:
         //- Read a word from Istream and return the corresponding enumeration
         EnumType read(Istream& is) const;
 
+        //- Read a word from Istream, lookup named enumeration.
+        //  \return true on success. Fatal if mandatory and not found.
+        bool read
+        (
+            Istream& is,
+            EnumType& val,
+            const bool mandatory = true
+        ) const;
+
         //- Write the name representation of the enumeration to an Ostream
         //  A noop if the enumeration wasn't found.
         inline void write(const EnumType e, Ostream& os) const;
@@ -266,6 +293,10 @@ public:
 template<class EnumType>
 inline Ostream& operator<<(Ostream& os, const Enum<EnumType>& list);
 
+//- Write enumeration names, without line-breaks (ie, FlatOutput)
+template<class EnumType>
+inline std::ostream& operator<<(std::ostream& os, const Enum<EnumType>& list);
+
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/primitives/enums/EnumI.H b/src/OpenFOAM/primitives/enums/EnumI.H
index 8a637cd0168754900de8757a28d99d56b9a9f3ed..0b990bed67cdd05d9cd6a0845890d159ea315f5a 100644
--- a/src/OpenFOAM/primitives/enums/EnumI.H
+++ b/src/OpenFOAM/primitives/enums/EnumI.H
@@ -55,6 +55,14 @@ inline const Foam::List<int>& Foam::Enum<EnumType>::values() const
 }
 
 
+template<class EnumType>
+inline void Foam::Enum<EnumType>::clear()
+{
+    keys_.clear();
+    vals_.clear();
+}
+
+
 template<class EnumType>
 inline Foam::label Foam::Enum<EnumType>::find(const word& enumName) const
 {
@@ -173,10 +181,37 @@ inline EnumType Foam::Enum<EnumType>::operator()
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 template<class EnumType>
-inline Foam::Ostream& Foam::operator<<(Ostream& os, const Enum<EnumType>& list)
+inline Foam::Ostream& Foam::operator<<
+(
+    Ostream& os,
+    const Enum<EnumType>& list
+)
 {
     return list.names().writeList(os, 0);
 }
 
 
+template<class EnumType>
+inline std::ostream& Foam::operator<<
+(
+    std::ostream& os,
+    const Enum<EnumType>& list
+)
+{
+    os << '(';
+
+    unsigned i = 0;
+
+    for (const word& k : list.names())
+    {
+        if (i++) os << ' ';
+        os << k;
+    }
+
+    os << ')';
+
+    return os;
+}
+
+
 // ************************************************************************* //