diff --git a/bin/tools/foamCreateCompletionCache b/bin/tools/foamCreateCompletionCache
index f6c23e30e9a25e36e1f65483813dd74500061172..8b5f419a709df5629b93dcd627b3c24537621863 100755
--- a/bin/tools/foamCreateCompletionCache
+++ b/bin/tools/foamCreateCompletionCache
@@ -3,7 +3,7 @@
 # =========                 |
 # \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
 #  \\    /   O peration     |
-#   \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+#   \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
 #    \\/     M anipulation  |
 #------------------------------------------------------------------------------
 # License
@@ -146,6 +146,7 @@ HEADER
 #   -help-man     Internal option
 #   -hostRoots    Advanced distributed run option
 #   -roots        Advanced distributed run option
+#   -debug-switch, -opt-switch, -info-switch, -lib  Advanced options
 #
 # Begin parsing after first appearance of "^[Oo]ptions:"
 # Terminate parsing on first appearance of "-help-full"
@@ -159,6 +160,8 @@ extractOptions()
         sed -ne '1,/^[Oo]ptions:/d' \
             -e 's/^ *//; /^$/d; /^[^-]/d; /^--/d; /^-help-man/d;' \
             -e '/^-hostRoots /d; /^-roots /d;' \
+            -e '/^-lib /d;' \
+            -e '/^-[a-z]*-switch /d;' \
             -e 'y/,/ /; s/=.*$/=/;' \
             -e '/^-[^ ]* </{ s/^\(-[^ ]* <\).*$/\1/; p; d }' \
             -e 's/^\(-[^ ]*\).*$/\1/; p; /^-help-full/q;' \
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index d18e3b073a24ae5943d82275ac048327ea212edc..bdeb9a1557b9b7f324630e524de8c77901f243c9 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -7,6 +7,7 @@ global/clock/clock.C
 global/clockTime/clockTime.C
 global/clockValue/clockValue.C
 global/cpuTime/cpuTimeCxx.C
+global/debug/simpleObjectRegistry.C
 global/profiling/profiling.C
 global/profiling/profilingInformation.C
 global/profiling/profilingSysInfo.C
diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
index e5d2c484a013e3965617806379ffcb589f9fbb29..d0fbd4de3653cab69aa3e02a495c6bb8d445f3db 100644
--- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
+++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
@@ -149,11 +149,11 @@ public:
 
 
         //- Construct as copy
-        ITstream(const ITstream& its)
+        ITstream(const ITstream& is)
         :
             Istream(ASCII, currentVersion),
-            tokenList(its),
-            name_(its.name_),
+            tokenList(is),
+            name_(is.name_),
             tokenIndex_(0)
         {
             setOpened();
diff --git a/src/OpenFOAM/db/Time/Time.C b/src/OpenFOAM/db/Time/Time.C
index e3e9649745d85389b21d20da3a4f9b0b2589c8da..4a38d746c48b7e0159089902b80212e59af85898 100644
--- a/src/OpenFOAM/db/Time/Time.C
+++ b/src/OpenFOAM/db/Time/Time.C
@@ -87,7 +87,6 @@ int Foam::Time::printExecutionFormat_
     Foam::debug::infoSwitch("printExecutionFormat", 0)
 );
 
-
 registerInfoSwitch
 (
     "printExecutionFormat",
diff --git a/src/OpenFOAM/db/Time/TimeIO.C b/src/OpenFOAM/db/Time/TimeIO.C
index 0683a3243abe7931cadb23a61b053f777752e7e5..13eb4ae1976b6d9ec0374024f5395ea4a1dd6e76 100644
--- a/src/OpenFOAM/db/Time/TimeIO.C
+++ b/src/OpenFOAM/db/Time/TimeIO.C
@@ -109,39 +109,7 @@ void Foam::Time::readDict()
             << "Overriding DebugSwitches according to "
             << controlDict_.name() << nl;
 
-        simpleObjectRegistry& objs = debug::debugObjects();
-
-        for (const entry& dEntry : *localDict)
-        {
-            const word& name = dEntry.keyword();
-
-            simpleObjectRegistryEntry* objPtr = objs.lookupPtr(name);
-
-            if (objPtr)
-            {
-                const List<simpleRegIOobject*>& objects = *objPtr;
-
-                DetailInfo << "    " << dEntry << nl;
-
-                if (dEntry.isDict())
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        OStringStream os(IOstream::ASCII);
-                        os  << dEntry.dict();
-                        IStringStream is(os.str());
-                        obj->readData(is);
-                    }
-                }
-                else
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        obj->readData(dEntry.stream());
-                    }
-                }
-            }
-        }
+        debug::debugObjects().setValues(*localDict, true);
     }
 
 
@@ -156,39 +124,7 @@ void Foam::Time::readDict()
             << "Overriding InfoSwitches according to "
             << controlDict_.name() << nl;
 
-        simpleObjectRegistry& objs = debug::infoObjects();
-
-        for (const entry& dEntry : *localDict)
-        {
-            const word& name = dEntry.keyword();
-
-            simpleObjectRegistryEntry* objPtr = objs.lookupPtr(name);
-
-            if (objPtr)
-            {
-                const List<simpleRegIOobject*>& objects = *objPtr;
-
-                DetailInfo << "    " << dEntry << nl;
-
-                if (dEntry.isDict())
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        OStringStream os(IOstream::ASCII);
-                        os  << dEntry.dict();
-                        IStringStream is(os.str());
-                        obj->readData(is);
-                    }
-                }
-                else
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        obj->readData(dEntry.stream());
-                    }
-                }
-            }
-        }
+        debug::infoObjects().setValues(*localDict, true);
     }
 
     // OptimisationSwitches
@@ -202,39 +138,7 @@ void Foam::Time::readDict()
             << "Overriding OptimisationSwitches according to "
             << controlDict_.name() << nl;
 
-        simpleObjectRegistry& objs = debug::optimisationObjects();
-
-        for (const entry& dEntry : *localDict)
-        {
-            const word& name = dEntry.keyword();
-
-            simpleObjectRegistryEntry* objPtr = objs.lookupPtr(name);
-
-            if (objPtr)
-            {
-                DetailInfo << "    " << dEntry << nl;
-
-                const List<simpleRegIOobject*>& objects = *objPtr;
-
-                if (dEntry.isDict())
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        OStringStream os(IOstream::ASCII);
-                        os  << dEntry.dict();
-                        IStringStream is(os.str());
-                        obj->readData(is);
-                    }
-                }
-                else
-                {
-                    for (simpleRegIOobject* obj : objects)
-                    {
-                        obj->readData(dEntry.stream());
-                    }
-                }
-            }
-        }
+        debug::optimisationObjects().setValues(*localDict, true);
     }
 
 
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index 157da8b8a8c3014648f91f459c0e952078c6e44f..1240540e4bfe1abb728780ac26718c8d9bf44f40 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -35,6 +35,7 @@ License
 #include "labelList.H"
 #include "regIOobject.H"
 #include "dynamicCode.H"
+#include "simpleObjectRegistry.H"
 #include "sigFpe.H"
 #include "sigInt.H"
 #include "sigQuit.H"
@@ -80,7 +81,38 @@ Foam::argList::initValidTables::initValidTables()
     (
         "lib",
         "name",
-        "Additional library/libraries to load (can be used multiple times)",
+        "Additional library or library list to load"
+        " (can be used multiple times)",
+        true  // advanced option
+    );
+
+    argList::addOption
+    (
+        "debug-switch",
+        "name=val",
+        "Specify the value of a registered debug switch."
+        " Default is 1 if the value is omitted."
+        " (Can be used multiple times)",
+        true  // advanced option
+    );
+
+    argList::addOption
+    (
+        "info-switch",
+        "name=val",
+        "Specify the value of a registered info switch."
+        " Default is 1 if the value is omitted."
+        " (Can be used multiple times)",
+        true  // advanced option
+    );
+
+    argList::addOption
+    (
+        "opt-switch",
+        "name=val",
+        "Specify the value of a registered optimisation switch (int/bool)."
+        " Default is 1 if the value is omitted."
+        " (Can be used multiple times)",
         true  // advanced option
     );
 
@@ -815,6 +847,30 @@ Foam::argList::argList
                     // Append name(s) to libs_ for later opening
                     libs_.append(this->getList<fileName>(argi));
                 }
+                else if (strcmp(optName, "debug-switch") == 0)
+                {
+                    // The '-debug-switch' option:
+                    // change registered debug switch
+                    DetailInfo << "DebugSwitch ";
+                    debug::debugObjects()
+                        .setNamedInt(args_[argi], 1, true);
+                }
+                else if (strcmp(optName, "info-switch") == 0)
+                {
+                    // The '-info-switch' option:
+                    // change registered info switch
+                    DetailInfo << "InfoSwitch ";
+                    debug::infoObjects()
+                        .setNamedInt(args_[argi], 1, true);
+                }
+                else if (strcmp(optName, "opt-switch") == 0)
+                {
+                    // The '-opt-switch' option:
+                    // change registered optimisation switch
+                    DetailInfo << "OptimisationSwitch ";
+                    debug::optimisationObjects()
+                        .setNamedInt(args_[argi], 1, true);
+                }
                 else
                 {
                     // Regular option:
diff --git a/src/OpenFOAM/global/debug/debug.C b/src/OpenFOAM/global/debug/debug.C
index 6e851b3f4974ba1c20694ce8c646277244f43293..da2edd5534c3584c378e9f1b5b796ecf63812670 100644
--- a/src/OpenFOAM/global/debug/debug.C
+++ b/src/OpenFOAM/global/debug/debug.C
@@ -92,7 +92,7 @@ deleteControlDictPtr deleteControlDictPtr_;
 namespace Foam
 {
 
-// Like dictionary getOrAdd (default), but circumventing
+// Like dictionary getOrAdd with LITERAL, but circumventing
 // writeOptionalEntries to avoid extremely noisy output
 template<class T>
 static inline T getOrAdd
@@ -113,6 +113,26 @@ static inline T getOrAdd
     return deflt;
 }
 
+
+// Append object to a registry
+static inline void appendNamedEntry
+(
+    simpleObjectRegistry& obr,
+    const char* name,
+    simpleRegIOobject* obj
+)
+{
+    simpleObjectRegistryEntry* ptr = obr.lookupPtr(name);
+    if (ptr)
+    {
+        ptr->append(obj);
+    }
+    else
+    {
+        obr.append(name, new simpleObjectRegistryEntry(obj));
+    }
+}
+
 } // End namespace Foam
 
 
@@ -133,19 +153,19 @@ Foam::dictionary& Foam::debug::controlDict()
         {
             fileNameList controlDictFiles = findEtcFiles("controlDict", true);
             controlDictPtr_ = new dictionary();
-            forAllReverse(controlDictFiles, cdfi)
+            forAllReverse(controlDictFiles, i)
             {
-                IFstream ifs(controlDictFiles[cdfi]);
+                IFstream is(controlDictFiles[i]);
 
-                if (!ifs.good())
+                if (!is.good())
                 {
                     SafeFatalIOErrorInFunction
                     (
-                        ifs,
+                        is,
                         "Cannot open controlDict"
                     );
                 }
-                controlDictPtr_->merge(dictionary(ifs));
+                controlDictPtr_->merge(dictionary(is));
             }
         }
     }
@@ -218,11 +238,7 @@ int Foam::debug::optimisationSwitch(const char* name, const int deflt)
 }
 
 
-float Foam::debug::floatOptimisationSwitch
-(
-    const char* name,
-    const float deflt
-)
+float Foam::debug::floatOptimisationSwitch(const char* name, const float deflt)
 {
     return getOrAdd(optimisationSwitches(), name, deflt);
 }
@@ -230,43 +246,13 @@ float Foam::debug::floatOptimisationSwitch
 
 void Foam::debug::addDebugObject(const char* name, simpleRegIOobject* obj)
 {
-    simpleObjectRegistryEntry* ptr = debugObjects().lookupPtr(name);
-    if (ptr)
-    {
-        ptr->append(obj);
-    }
-    else
-    {
-        debugObjects().append
-        (
-            name,
-            new simpleObjectRegistryEntry
-            (
-                List<simpleRegIOobject*>(1, obj)
-            )
-        );
-    }
+    appendNamedEntry(debugObjects(), name, obj);
 }
 
 
 void Foam::debug::addInfoObject(const char* name, simpleRegIOobject* obj)
 {
-    simpleObjectRegistryEntry* ptr = infoObjects().lookupPtr(name);
-    if (ptr)
-    {
-        ptr->append(obj);
-    }
-    else
-    {
-        infoObjects().append
-        (
-            name,
-            new simpleObjectRegistryEntry
-            (
-                List<simpleRegIOobject*>(1, obj)
-            )
-        );
-    }
+    appendNamedEntry(infoObjects(), name, obj);
 }
 
 
@@ -276,22 +262,7 @@ void Foam::debug::addOptimisationObject
     simpleRegIOobject* obj
 )
 {
-    simpleObjectRegistryEntry* ptr = optimisationObjects().lookupPtr(name);
-    if (ptr)
-    {
-        ptr->append(obj);
-    }
-    else
-    {
-        optimisationObjects().append
-        (
-            name,
-            new simpleObjectRegistryEntry
-            (
-                List<simpleRegIOobject*>(1, obj)
-            )
-        );
-    }
+    appendNamedEntry(optimisationObjects(), name, obj);
 }
 
 
@@ -301,22 +272,7 @@ void Foam::debug::addDimensionSetObject
     simpleRegIOobject* obj
 )
 {
-    simpleObjectRegistryEntry* ptr = dimensionSetObjects().lookupPtr(name);
-    if (ptr)
-    {
-        ptr->append(obj);
-    }
-    else
-    {
-        dimensionSetObjects().append
-        (
-            name,
-            new simpleObjectRegistryEntry
-            (
-                List<simpleRegIOobject*>(1, obj)
-            )
-        );
-    }
+    appendNamedEntry(dimensionSetObjects(), name, obj);
 }
 
 
@@ -326,25 +282,7 @@ void Foam::debug::addDimensionedConstantObject
     simpleRegIOobject* obj
 )
 {
-    simpleObjectRegistryEntry* ptr = dimensionedConstantObjects().lookupPtr
-    (
-        name
-    );
-    if (ptr)
-    {
-        ptr->append(obj);
-    }
-    else
-    {
-        dimensionedConstantObjects().append
-        (
-            name,
-            new simpleObjectRegistryEntry
-            (
-                List<simpleRegIOobject*>(1, obj)
-            )
-        );
-    }
+    appendNamedEntry(dimensionedConstantObjects(), name, obj);
 }
 
 
@@ -406,6 +344,10 @@ Foam::simpleObjectRegistry& Foam::debug::dimensionedConstantObjects()
 namespace Foam
 {
 
+// Write the switch names.
+//
+// Use flatOutput with -1 for the length to ensure we always have newlines,
+// even if the lists are short
 static void listSwitches
 (
     const wordList& debugSwitches,
@@ -418,48 +360,50 @@ static void listSwitches
     {
         fileNameList controlDictFiles = findEtcFiles("controlDict", true);
         dictionary controlDict;
-        forAllReverse(controlDictFiles, cdfi)
+        forAllReverse(controlDictFiles, i)
         {
-            controlDict.merge(dictionary(IFstream(controlDictFiles[cdfi])()));
+            IFstream is(controlDictFiles[i]);
+
+            controlDict.merge(dictionary(is));
         }
 
-        wordHashSet controlDictDebug
-        (
-            controlDict.subDict("DebugSwitches").toc()
-        );
+        IOobject::writeDivider(Info);
 
-        wordHashSet controlDictInfo
-        (
-            controlDict.subDict("InfoSwitches").toc()
-        );
+        // Use a HashSet to track switches that have not been set
+        wordHashSet hashed;
 
-        wordHashSet controlDictOpt
-        (
-            controlDict.subDict("OptimisationSwitches").toc()
-        );
+        // DebugSwitches
+        hashed = debugSwitches;
+        hashed.unset(controlDict.subDict("DebugSwitches").toc());
 
+        Info<< "Unset DebugSwitches"
+            << flatOutput(hashed.sortedToc(), -1) << nl;
 
-        IOobject::writeDivider(Info);
 
-        wordHashSet hashset;
-        hashset = debugSwitches;
-        hashset -= controlDictDebug;
-        Info<< "Unset DebugSwitches" << hashset.sortedToc() << nl;
+        // InfoSwitches
+        hashed = infoSwitches;
+        hashed.unset(controlDict.subDict("InfoSwitches").toc());
+
+        Info<< "Unset InfoSwitches"
+            << flatOutput(hashed.sortedToc(), -1) << nl;
+
 
-        hashset = infoSwitches;
-        hashset -= controlDictInfo;
-        Info<< "Unset InfoSwitches" << hashset.sortedToc() << nl;
+        // OptimisationSwitches
+        hashed = optSwitches;
+        hashed.unset(controlDict.subDict("OptimisationSwitches").toc());
 
-        hashset = optSwitches;
-        hashset -= controlDictOpt;
-        Info<< "Unset OptimisationSwitches" << hashset.sortedToc() << nl;
+        Info<< "Unset OptimisationSwitches"
+            << flatOutput(hashed.sortedToc(), -1) << nl;
     }
     else
     {
         IOobject::writeDivider(Info);
-        Info<< "DebugSwitches" << debugSwitches << nl
-            << "InfoSwitches" << infoSwitches << nl
-            << "OptimisationSwitches" << optSwitches << nl;
+        Info<< "DebugSwitches"
+            << flatOutput(debugSwitches, -1) << nl
+            << "InfoSwitches"
+            << flatOutput(infoSwitches, -1) << nl
+            << "OptimisationSwitches"
+            << flatOutput(optSwitches, -1) << nl;
     }
 }
 
diff --git a/src/OpenFOAM/global/debug/debug.H b/src/OpenFOAM/global/debug/debug.H
index dc3bef6d280e15ebad4f3ff99ab8b941be6d8f28..f77157c4f01bbd95c6d473f534dbf6ed3e804113 100644
--- a/src/OpenFOAM/global/debug/debug.H
+++ b/src/OpenFOAM/global/debug/debug.H
@@ -68,13 +68,13 @@ namespace debug
     //  \sa Foam::findEtcFile()
     dictionary& controlDict();
 
-    //- The DebugSwitches sub-dictionary in the central controlDict.
+    //- The DebugSwitches sub-dictionary in the central controlDict(s).
     dictionary& debugSwitches();
 
-    //- The InfoSwitches sub-dictionary in the central controlDict.
+    //- The InfoSwitches sub-dictionary in the central controlDict(s).
     dictionary& infoSwitches();
 
-    //- The OptimisationSwitches sub-dictionary in the central controlDict.
+    //- The OptimisationSwitches sub-dictionary in the central controlDict(s).
     dictionary& optimisationSwitches();
 
     //- Lookup debug switch or add default value.
@@ -114,22 +114,22 @@ namespace debug
         void addDimensionedConstantObject(const char* name, simpleRegIOobject*);
 
 
-        //- Get access to registered debug switch objects
+        //- Access to registered DebugSwitch objects
         simpleObjectRegistry& debugObjects();
 
-        //- Get access to registered info switch objects
+        //- Access to registered InfoSwitch objects
         simpleObjectRegistry& infoObjects();
 
-        //- Get access to registered optimisation switch objects
+        //- Access to registered OptimisationSwitch objects
         simpleObjectRegistry& optimisationObjects();
 
-        //- Get access to registered dimensionSets switch objects
+        //- Access to registered DimensionSets objects
         simpleObjectRegistry& dimensionSetObjects();
 
-        //- Get access to registered dimensionedConstant switch objects
+        //- Access to registered DimensionedConstants objects
         simpleObjectRegistry& dimensionedConstantObjects();
 
-        //- List registered debug switches
+        //- List registered debug/info/optimisation switches
         void listRegisteredSwitches(const bool unset);
 
 } // End namespace debug
diff --git a/src/OpenFOAM/global/debug/defineDebugSwitch.H b/src/OpenFOAM/global/debug/defineDebugSwitch.H
index 8e032424d8248b4ec29a06f6b56ab33f62c586fa..2ee7276fa549cee34194d40dc1bda9558e0d9f12 100644
--- a/src/OpenFOAM/global/debug/defineDebugSwitch.H
+++ b/src/OpenFOAM/global/debug/defineDebugSwitch.H
@@ -33,14 +33,14 @@ Description
 
 #include "simpleRegIOobject.H"
 #include "debug.H"
-#include "label.H"
+#include "label.H"  // Also for defining Foam::word etc.
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-//- Define the debug information, lookup as \a Name
+//- Define the debug information, lookup as \a name
 template<class Type>
 class RegisterDebugSwitch
 :
@@ -58,12 +58,12 @@ public:
 
     virtual ~RegisterDebugSwitch() = default;
 
-    virtual void readData(Foam::Istream& is)
+    virtual void readData(Istream& is)
     {
-        Type::debug = readLabel(is);
+        is >> Type::debug;
     }
 
-    virtual void writeData(Foam::Ostream& os) const
+    virtual void writeData(Ostream& os) const
     {
         os << Type::debug;
     }
@@ -76,7 +76,7 @@ public:
 #define registerTemplateDebugSwitchWithName(Type,Name)                         \
     template<>                                                                 \
     const Foam::RegisterDebugSwitch<Type>                                      \
-        Foam::RegisterDebugSwitch<Type>::registerDebugSwitch(Name)
+    Foam::RegisterDebugSwitch<Type>::registerDebugSwitch(Name)
 
 
 //- Define the debug information, lookup as \a Name
@@ -88,15 +88,14 @@ public:
     public:                                                                    \
         add##Tag##ToDebug(const char* name)                                    \
         :                                                                      \
-            ::Foam::simpleRegIOobject(Foam::debug::addDebugObject, name)       \
-        {}                                                                     \
-        virtual ~add##Tag##ToDebug()                                           \
+            ::Foam::simpleRegIOobject(::Foam::debug::addDebugObject, name)     \
         {}                                                                     \
-        virtual void readData(Foam::Istream& is)                               \
+        virtual ~add##Tag##ToDebug() = default;                                \
+        virtual void readData(::Foam::Istream& is)                             \
         {                                                                      \
-            Type::debug = readLabel(is);                                       \
+            is >> Type::debug;                                                 \
         }                                                                      \
-        virtual void writeData(Foam::Ostream& os) const                        \
+        virtual void writeData(::Foam::Ostream& os) const                      \
         {                                                                      \
             os << Type::debug;                                                 \
         }                                                                      \
@@ -105,44 +104,44 @@ public:
 
 
 //- Define the debug information, lookup as \a Name
-#define defineDebugSwitchWithName(Type, Name, DebugSwitch)                     \
-    int Type::debug(::Foam::debug::debugSwitch(Name, DebugSwitch))
+#define defineDebugSwitchWithName(Type, Name, Value)                           \
+    int Type::debug(::Foam::debug::debugSwitch(Name, Value))
 
 //- Define the debug information
-#define defineDebugSwitch(Type, DebugSwitch)                                   \
-    defineDebugSwitchWithName(Type, Type::typeName_(), DebugSwitch);           \
+#define defineDebugSwitch(Type, Value)                                         \
+    defineDebugSwitchWithName(Type, Type::typeName_(), Value);                 \
     registerDebugSwitchWithName(Type, Type, Type::typeName_())
 
 //- Define the debug information for templates, lookup as \a Name
-#define defineTemplateDebugSwitchWithName(Type, Name, DebugSwitch)             \
+#define defineTemplateDebugSwitchWithName(Type, Name, Value)                   \
     template<>                                                                 \
-    defineDebugSwitchWithName(Type, Name, DebugSwitch);                        \
+    defineDebugSwitchWithName(Type, Name, Value);                              \
     registerTemplateDebugSwitchWithName(Type, Name)
 
 //- Define the debug information for templates sub-classes, lookup as \a Name
-#define defineTemplate2DebugSwitchWithName(Type, Name, DebugSwitch)            \
+#define defineTemplate2DebugSwitchWithName(Type, Name, Value)                  \
     template<>                                                                 \
-    defineDebugSwitchWithName(Type, Name, DebugSwitch);                        \
+    defineDebugSwitchWithName(Type, Name, Value);                              \
     registerTemplateDebugSwitchWithName(Type, Name)
 
 //- Define the debug information for templates
 //  Useful with typedefs
-#define defineTemplateDebugSwitch(Type, DebugSwitch)                           \
-    defineTemplateDebugSwitchWithName(Type, #Type, DebugSwitch)
+#define defineTemplateDebugSwitch(Type, Value)                                 \
+    defineTemplateDebugSwitchWithName(Type, #Type, Value)
 
 //- Define the debug information directly for templates
-#define defineNamedTemplateDebugSwitch(Type, DebugSwitch)                      \
-    defineTemplateDebugSwitchWithName(Type, Type::typeName_(), DebugSwitch)
+#define defineNamedTemplateDebugSwitch(Type, Value)                            \
+    defineTemplateDebugSwitchWithName(Type, Type::typeName_(), Value)
 
 
 //- Define the debug information for templates
 //  Useful with typedefs
-#define defineTemplate2DebugSwitch(Type, DebugSwitch)                          \
-    defineTemplate2DebugSwitchWithName(Type, #Type, DebugSwitch)
+#define defineTemplate2DebugSwitch(Type, Value)                                \
+    defineTemplate2DebugSwitchWithName(Type, #Type, Value)
 
 //- Define the debug information directly for templates
-#define defineNamedTemplate2DebugSwitch(Type, DebugSwitch)                     \
-    defineTemplate2DebugSwitchWithName(Type, Type::typeName_(), DebugSwitch)
+#define defineNamedTemplate2DebugSwitch(Type, Value)                           \
+    defineTemplate2DebugSwitchWithName(Type, Type::typeName_(), Value)
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/global/debug/registerSwitch.H b/src/OpenFOAM/global/debug/registerSwitch.H
index e81bee8c79a2539be9c673316c6bb0af589b9418..f242a5d130a6eba2e06817ca01080b56d7c5b5d9 100644
--- a/src/OpenFOAM/global/debug/registerSwitch.H
+++ b/src/OpenFOAM/global/debug/registerSwitch.H
@@ -52,31 +52,32 @@ class RegisterSwitch
 :
     public simpleRegIOobject
 {
-    Type& optSwitch_;
-
 public:
 
+    //- Reference to the switch variable that has been registered
+    Type& value;
+
     RegisterSwitch
     (
         void (*registryFn)(const char* name, simpleRegIOobject*),
         const char* name,
-        Type& optSwitch
+        Type& switchVar
     )
     :
         simpleRegIOobject(registryFn, name),
-        optSwitch_(optSwitch)
+        value(switchVar)
     {}
 
     virtual ~RegisterSwitch() = default;
 
-    virtual void readData(Foam::Istream& is)
+    virtual void readData(Istream& is)
     {
-        is >> optSwitch_;
+        is >> value;
     }
 
-    virtual void writeData(Foam::Ostream& os) const
+    virtual void writeData(Ostream& os) const
     {
-        os << optSwitch_;
+        os << value;
     }
 };
 
@@ -87,14 +88,14 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#define registerOptSwitch(Name, Type, Switch)                                  \
+#define registerOptSwitch(Name, Type, SwitchVar)                               \
     static Foam::RegisterSwitch<Type> FILE_UNIQUE(_addToOpt_)                  \
-        (Foam::debug::addOptimisationObject, Name, Switch)
+    (Foam::debug::addOptimisationObject, Name, SwitchVar)
 
 
-#define registerInfoSwitch(Name, Type, Switch)                                 \
+#define registerInfoSwitch(Name, Type, SwitchVar)                              \
     static Foam::RegisterSwitch<Type> FILE_UNIQUE(_addToOpt_)                  \
-        (Foam::debug::addInfoObject, Name, Switch)
+    (Foam::debug::addInfoObject, Name, SwitchVar)
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/global/debug/simpleObjectRegistry.C b/src/OpenFOAM/global/debug/simpleObjectRegistry.C
new file mode 100644
index 0000000000000000000000000000000000000000..a3589235827c6206a967f5a6547dd84804065ce9
--- /dev/null
+++ b/src/OpenFOAM/global/debug/simpleObjectRegistry.C
@@ -0,0 +1,144 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "simpleObjectRegistry.H"
+#include "dictionary.H"
+#include "StringStream.H"
+#include "int.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::simpleObjectRegistry::setValues
+(
+    const dictionary& dict,
+    bool report
+)
+{
+    // Report enables output, but respect DetailInfo state as well.
+    // The local log variable captures this logic.
+
+    const bool log = (report && Foam::infoDetailLevel > 0);
+
+    for (const entry& dEntry : dict)
+    {
+        const word& name = dEntry.keyword();
+
+        simpleObjectRegistryEntry* objPtr = this->lookupPtr(name);
+
+        if (objPtr)
+        {
+            Log << "    " << dEntry << nl;
+
+            const List<simpleRegIOobject*>& objects = *objPtr;
+
+            if (dEntry.isDict())
+            {
+                OStringStream os(IOstream::ASCII);
+                os  << dEntry.dict();
+                IStringStream is(os.str());
+
+                // Or alternatively?
+                // ITstream is(name, dEntry.dict().tokens());
+
+                for (simpleRegIOobject* obj : objects)
+                {
+                    is.rewind();
+                    obj->readData(is);
+                }
+            }
+            else
+            {
+                for (simpleRegIOobject* obj : objects)
+                {
+                    obj->readData(dEntry.stream());
+                }
+            }
+        }
+        else
+        {
+            Log << "    " << name << " (unregistered)" << nl;
+        }
+    }
+}
+
+
+void Foam::simpleObjectRegistry::setNamedInt
+(
+    std::string name,
+    int val,
+    bool report
+)
+{
+    // Report enables output, but respect DetailInfo state as well.
+    // The local log variable captures this logic.
+
+    const bool log = (report && Foam::infoDetailLevel > 0);
+
+
+    // Handle name=value
+    const auto eq = name.find('=');
+
+    if (eq != std::string::npos)
+    {
+        int intval = 0;
+
+        if (readInt(name.substr(eq+1), intval))
+        {
+            val = intval;
+        }
+        // Could warn about bad entry
+
+        name.resize(eq);  // Truncate the name
+    }
+
+
+    simpleObjectRegistryEntry* objPtr = this->lookupPtr(name.c_str());
+
+    if (objPtr)
+    {
+        // The generic interface requires an Istream.
+        IStringStream is(std::to_string(val));
+
+        // Or alternatively?
+        // ITstream is("input", tokenList(1, token(label(val))));
+
+        Log << name.c_str() << '=' << val << nl;
+
+        const List<simpleRegIOobject*>& objects = *objPtr;
+
+        for (simpleRegIOobject* obj : objects)
+        {
+            is.rewind();
+            obj->readData(is);
+        }
+    }
+    else
+    {
+        Log << name.c_str() << " (unregistered)" << nl;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/global/debug/simpleObjectRegistry.H b/src/OpenFOAM/global/debug/simpleObjectRegistry.H
index 7259f0a35224fe46d2e716441d7fa8041d924459..a18fdeb0b00731d011c843aa0cf78d4cac3ac658 100644
--- a/src/OpenFOAM/global/debug/simpleObjectRegistry.H
+++ b/src/OpenFOAM/global/debug/simpleObjectRegistry.H
@@ -30,6 +30,7 @@ Description
     Object registry for simpleRegIOobject. Maintains ordering.
 
 SourceFiles
+    simpleObjectRegistry.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -38,12 +39,16 @@ SourceFiles
 
 #include "Dictionary.H"
 #include "simpleRegIOobject.H"
+#include <string>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
+// Forward declarations
+class dictionary;
+
 /*---------------------------------------------------------------------------*\
                    Class simpleObjectRegistryEntry Declaration
 \*---------------------------------------------------------------------------*/
@@ -55,7 +60,14 @@ class simpleObjectRegistryEntry
 {
 public:
 
-    simpleObjectRegistryEntry(const List<simpleRegIOobject*>& data)
+    //- Construct with a single object (list size == 1)
+    explicit simpleObjectRegistryEntry(simpleRegIOobject* obj)
+    :
+        List<simpleRegIOobject*>(label(1), obj)
+    {}
+
+    //- Construct with a List of objects
+    explicit simpleObjectRegistryEntry(const List<simpleRegIOobject*>& data)
     :
         List<simpleRegIOobject*>(data)
     {}
@@ -79,6 +91,17 @@ public:
         :
             Dictionary<simpleObjectRegistryEntry>(size)
         {}
+
+
+    // Member Functions
+
+        //- Set values (invoke callbacks) from dictionary entries
+        //  Reporting honours the infoDetailLevel
+        void setValues(const dictionary& dict, bool report=false);
+
+        //- Set named value, but also handle embedded name=value syntax
+        //  Reporting honours the infoDetailLevel
+        void setNamedInt(std::string name, int val, bool report=false);
 };
 
 
diff --git a/src/OpenFOAM/global/debug/simpleRegIOobject.H b/src/OpenFOAM/global/debug/simpleRegIOobject.H
index 6f4c97e51b5c0eecdae62ae2044124f090c33f59..6f609154011340acf74dd004be8cbeccbf772526 100644
--- a/src/OpenFOAM/global/debug/simpleRegIOobject.H
+++ b/src/OpenFOAM/global/debug/simpleRegIOobject.H
@@ -42,7 +42,7 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of classes
+// Forward declarations
 class Istream;
 class Ostream;
 
@@ -74,11 +74,10 @@ public:
     // Member Functions
 
         //- Read
-        virtual void readData(Istream&) = 0;
+        virtual void readData(Istream& is) = 0;
 
         //- Write
-        virtual void writeData(Ostream&) const = 0;
-
+        virtual void writeData(Ostream& os) const = 0;
 };
 
 
diff --git a/src/OpenFOAM/include/macros.H b/src/OpenFOAM/include/macros.H
index 2ce3abb78c6c3d088a58ea00dda48b2c8e188a51..4c496345e6d7cf5c2d5b61e2537fe785d505d4e5 100644
--- a/src/OpenFOAM/include/macros.H
+++ b/src/OpenFOAM/include/macros.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2016 OpenFOAM Foundation