diff --git a/applications/test/dictionary/testSubkeyword b/applications/test/dictionary/testSubkeyword
new file mode 100644
index 0000000000000000000000000000000000000000..f8ee14850114e03cb7256b61966628fdd6f43980
--- /dev/null
+++ b/applications/test/dictionary/testSubkeyword
@@ -0,0 +1,53 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  plus                                  |
+|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      testDict;
+    note        "test with foamDictionary -expand";
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// #inputMode  overwrite
+
+key1 val1;
+
+subdict
+{
+    key1 a;
+    key2 b;
+}
+
+update
+{
+    key1 val1b;
+    key2 val2;
+
+    subdict
+    {
+        key2 $key1;
+        key3 val3;
+        key2b ${..key2};
+        key3b $^key1;
+    }
+}
+
+
+$update
+
+// Can a leading '^' or  ':' as anchor for scoping
+key3 $^subdict.key1;
+key3 ${^update.subdict.key3};
+key4 ${:update.subdict...subdict.key1};
+
+// This is currently not working
+#remove update.key1
+// #remove update
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
index 2b7ab51888cf65e035a4f71c7450c9c4328119e6..c20a9655780968ec46788d4a6850eff433777dd0 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
@@ -288,6 +288,9 @@ Foam::vtkPVFoam::vtkPVFoam
         fullCasePath = cwd();
     }
 
+    // The name of the executable, unless already present in the environment
+    setEnv("FOAM_EXECUTABLE", "paraview", false);
+
     // Set the case as an environment variable - some BCs might use this
     if (fullCasePath.name().find("processor", 0) == 0)
     {
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C
index e64f031dec7ac2e5d126f93c8e2403f1db7f6520..39c60bb7380df4a11f67d1b48a7f2f7fd6dfadd3 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C
@@ -206,6 +206,9 @@ Foam::vtkPVblockMesh::vtkPVblockMesh
         fullCasePath = cwd();
     }
 
+    // The name of the executable, unless already present in the environment
+    setEnv("FOAM_EXECUTABLE", "paraview", false);
+
     // Set the case as an environment variable - some BCs might use this
     if (fullCasePath.name().find("processor", 0) == 0)
     {
diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C
index ea449f50e6dc5911a018b6e8df161300cbc45303..08c702fee3baeb78724778afae6314da0d863ecd 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.C
+++ b/src/OpenFOAM/db/dictionary/dictionary.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,114 +60,101 @@ const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
         // Non-scoped lookup
         return lookupEntryPtr(keyword, recursive, patternMatch);
     }
-    else
+    else if (dotPos == 0)
     {
-        if (dotPos == 0)
-        {
-            // Starting with a '.'. Go up for every 2nd '.' found
-
-            const dictionary* dictPtr = this;
+        // Starting with a '.' -> go up for every further '.' found
+        ++dotPos;
 
-            string::size_type begVar = dotPos + 1;
-            string::const_iterator iter = keyword.begin() + begVar;
-            string::size_type endVar = begVar;
-            while (iter != keyword.end() && *iter == '.')
+        const dictionary* dictPtr = this;
+        for
+        (
+            string::const_iterator it = keyword.begin()+1;
+            it != keyword.end() && *it == '.';
+            ++dotPos, ++it
+        )
+        {
+            // Go to parent
+            if (&dictPtr->parent_ != &dictionary::null)
             {
-                ++iter;
-                ++endVar;
-
-                // Go to parent
-                if (&dictPtr->parent_ == &dictionary::null)
-                {
-                    FatalIOErrorInFunction
-                    (
-                        *this
-                    )   << "No parent of current dictionary"
-                        << " when searching for "
-                        << keyword.substr(begVar, keyword.size()-begVar)
-                        << exit(FatalIOError);
-                }
                 dictPtr = &dictPtr->parent_;
             }
+            else
+            {
+                FatalIOErrorInFunction
+                (
+                    *this
+                )   << "No parent of current dictionary when searching for "
+                    << keyword.substr(1)
+                    << exit(FatalIOError);
 
-            return dictPtr->lookupScopedSubEntryPtr
-            (
-                keyword.substr(endVar),
-                false,
-                patternMatch
-            );
+                return nullptr;
+            }
         }
-        else
-        {
-            // Extract the first word
-            word firstWord = keyword.substr(0, dotPos);
 
-            const entry* entPtr = lookupScopedSubEntryPtr
-            (
-                firstWord,
-                false,          //recursive
-                patternMatch
-            );
+        return dictPtr->lookupScopedSubEntryPtr
+        (
+            keyword.substr(dotPos),
+            false,
+            patternMatch
+        );
+    }
+    else
+    {
+        // The first word
+        const entry* entPtr = lookupScopedSubEntryPtr
+        (
+            keyword.substr(0, dotPos),
+            false,
+            patternMatch
+        );
+
+        if (!entPtr)
+        {
+            // Fall back to finding key with '.' so e.g. if keyword is
+            // a.b.c.d it would try
+            // a.b, a.b.c, a.b.c.d
 
-            if (!entPtr)
+            while (true)
             {
-                // Fall back to finding key with '.' so e.g. if keyword is
-                // a.b.c.d it would try
-                // a.b, a.b.c, a.b.c.d
+                dotPos = keyword.find('.', dotPos+1);
 
-                string::size_type nextDotPos = keyword.find
+                entPtr = lookupEntryPtr
                 (
-                    '.',
-                    dotPos+1
+                    keyword.substr(0, dotPos),
+                    false,
+                    patternMatch
                 );
 
-                while (true)
+                if (dotPos == string::npos)
+                {
+                    // Parsed the whole word. Return entry or null.
+                    return entPtr;
+                }
+
+                if (entPtr && entPtr->isDict())
                 {
-                    const entry* subEntPtr = lookupEntryPtr
+                    return entPtr->dict().lookupScopedSubEntryPtr
                     (
-                        keyword.substr(0, nextDotPos),
-                        false,  //recursive,
+                        keyword.substr(dotPos),
+                        false,
                         patternMatch
                     );
-                    if (nextDotPos == string::npos)
-                    {
-                        // Parsed the whole word. Return entry or null.
-                        return subEntPtr;
-                    }
-
-                    if (subEntPtr && subEntPtr->isDict())
-                    {
-                        return subEntPtr->dict().lookupScopedSubEntryPtr
-                        (
-                            keyword.substr
-                            (
-                                nextDotPos,
-                                keyword.size()-nextDotPos
-                            ),
-                            false,
-                            patternMatch
-                        );
-                    }
-
-                    nextDotPos = keyword.find('.', nextDotPos+1);
                 }
             }
+        }
 
-            if (entPtr->isDict())
-            {
-                return entPtr->dict().lookupScopedSubEntryPtr
-                (
-                    keyword.substr(dotPos, keyword.size()-dotPos),
-                    false,
-                    patternMatch
-                );
-            }
-            else
-            {
-                return nullptr;
-            }
+        if (entPtr->isDict())
+        {
+            return entPtr->dict().lookupScopedSubEntryPtr
+            (
+                keyword.substr(dotPos),
+                false,
+                patternMatch
+            );
         }
     }
+
+    return nullptr;
 }
 
 
@@ -588,7 +575,7 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
     bool patternMatch
 ) const
 {
-    if (keyword[0] == ':')
+    if (keyword[0] == ':' || keyword[0] == '^')
     {
         // Go up to top level
         const dictionary* dictPtr = this;
@@ -597,10 +584,9 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
             dictPtr = &dictPtr->parent_;
         }
 
-        // At top. Recurse to find entries
         return dictPtr->lookupScopedSubEntryPtr
         (
-            keyword.substr(1, keyword.size()-1),
+            keyword.substr(1),
             false,
             patternMatch
         );
@@ -617,9 +603,13 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
 }
 
 
-bool Foam::dictionary::substituteScopedKeyword(const word& keyword)
+bool Foam::dictionary::substituteScopedKeyword
+(
+    const word& keyword,
+    bool mergeEntry
+)
 {
-    word varName = keyword(1, keyword.size()-1);
+    const word varName = keyword(1, keyword.size()-1);
 
     // Lookup the variable name in the given dictionary
     const entry* ePtr = lookupScopedEntryPtr(varName, true, true);
@@ -631,7 +621,7 @@ bool Foam::dictionary::substituteScopedKeyword(const word& keyword)
 
         forAllConstIter(IDLList<entry>, addDict, iter)
         {
-            add(iter());
+            add(iter(), mergeEntry);
         }
 
         return true;
@@ -1034,7 +1024,6 @@ bool Foam::dictionary::changeKeyword
             IDLList<entry>::replace(iter2(), iter());
             delete iter2();
             hashedEntries_.erase(iter2);
-
         }
         else
         {
diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H
index 6f03c6babcaf9152fc7b5db5ebfc3043ea28a2b0..a2031ede037c13586c28d658af516bfd43488f62 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.H
+++ b/src/OpenFOAM/db/dictionary/dictionary.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,26 +25,57 @@ Class
     Foam::dictionary
 
 Description
-    A list of keyword definitions, which are a keyword followed by any number
-    of values (e.g. words and numbers). The keywords can represent patterns
-    which are matched using Posix regular expressions. The general order for
-    searching is as follows:
-    - exact match
-    - pattern match (in reverse order)
-    - optional recursion into the enclosing (parent) dictionaries
-
-    The dictionary class is the base class for IOdictionary.
-    It also serves as a bootstrap dictionary for the objectRegistry data
-    dictionaries since, unlike the IOdictionary class, it does not use an
-    objectRegistry itself to work.
-
-    To add - a merge() member function with a non-const dictionary parameter?
-    This would avoid unnecessary cloning in the add(entry*, bool) method.
+    A list of keyword definitions, which are a keyword followed by a number
+    of values (eg, words and numbers) or by a sub-dictionary.
+    Since the dictionary format is used extensively throughout OpenFOAM for
+    input/output files, there are many examples of its use.
+
+    Dictionary keywords are a plain word or a pattern (regular expression).
+    The general order for searching is as follows:
+      - exact match
+      - pattern match (in reverse order)
+      - optional recursion into the enclosing (parent) dictionaries
+
+    The dictionary class is the base class for IOdictionary and also serves
+    as a bootstrap dictionary for the objectRegistry data dictionaries.
+
+Note
+    Within dictionaries, entries can be referenced by using the '$' syntax
+    familiar from shell programming. A '.' separator is used when referencing
+    sub-dictionary entries. Leading '.' prefixes can be used to specify
+    an entry from a parent directory. A leading ':' or '^' prefix specifies
+    starting from the top-level entry. For example,
+
+    \verbatim
+    key1        val1;
+    key2        $key1;   // use key1 value from current scope
+    key3        $.key1;  // use key1 value from current scope
+
+    subdict1
+    {
+        key1        val1b;
+        key2        $..key1; // use key1 value from parent
+        subdict2
+        {
+            key2        val2;
+            key3        $...key1; // use key1 value from grandparent
+        }
+    }
+
+    key4        $^subdict1.subdict2.key3;  // lookup with absolute scoping
+    \endverbatim
+
+    It is also possible to use the '${}' syntax for clarity.
 
 SourceFiles
     dictionary.C
     dictionaryIO.C
 
+SeeAlso
+    - Foam::entry
+    - Foam::dictionaryEntry
+    - Foam::primitiveEntry
+
 \*---------------------------------------------------------------------------*/
 
 #ifndef dictionary_H
@@ -76,6 +107,7 @@ Ostream& operator<<(Ostream&, const dictionary&);
                         Class dictionaryName Declaration
 \*---------------------------------------------------------------------------*/
 
+//- Holds name for a dictionary
 class dictionaryName
 {
     // Private data
@@ -87,11 +119,11 @@ public:
 
     // Constructors
 
-        //- Construct dictionaryName null
+        //- Construct null
         dictionaryName()
         {}
 
-        //- Construct dictionaryName as copy of the given fileName
+        //- Construct as copy of the given fileName
         dictionaryName(const fileName& name)
         :
             name_(name)
@@ -116,16 +148,15 @@ public:
         const word dictName() const
         {
             const word scopedName = name_.name();
+            const std::string::size_type i = scopedName.rfind('.');
 
-            string::size_type i = scopedName.rfind('.');
-
-            if (i == scopedName.npos)
+            if (i == std::string::npos)
             {
                 return scopedName;
             }
             else
             {
-                return scopedName.substr(i + 1, scopedName.npos);
+                return scopedName.substr(i+1);
             }
         }
 };
@@ -142,8 +173,7 @@ class dictionary
 {
     // Private data
 
-        //- If true write optional keywords and values
-        //  if not present in dictionary
+        //- Report optional keywords and values if not present in dictionary
         static bool writeOptionalEntries;
 
         //- HashTable of the entries held on the DL-list for quick lookup
@@ -165,7 +195,7 @@ class dictionary
         //  otherwise return nullptr. Allows scoping using '.'
         const entry* lookupScopedSubEntryPtr
         (
-            const word&,
+            const word& keyword,
             bool recursive,
             bool patternMatch
         ) const;
@@ -217,38 +247,38 @@ public:
         (
             const fileName& name,
             const dictionary& parentDict,
-            Istream&
+            Istream& is
         );
 
         //- Construct top-level dictionary from Istream,
         //  reading entries until EOF
-        dictionary(Istream&);
+        dictionary(Istream& is);
 
         //- Construct top-level dictionary from Istream,
         //  reading entries until EOF, optionally keeping the header
-        dictionary(Istream&, const bool keepHeader);
+        dictionary(Istream& is, const bool keepHeader);
 
         //- Construct as copy given the parent dictionary
         dictionary(const dictionary& parentDict, const dictionary&);
 
         //- Construct top-level dictionary as copy
-        dictionary(const dictionary&);
+        dictionary(const dictionary& dict);
 
         //- Construct top-level dictionary as copy from pointer to dictionary.
         //  A null pointer is treated like an empty dictionary.
-        dictionary(const dictionary*);
+        dictionary(const dictionary* dictPtr);
 
         //- Construct by transferring parameter contents given parent dictionary
-        dictionary(const dictionary& parentDict, const Xfer<dictionary>&);
+        dictionary(const dictionary& parentDict, const Xfer<dictionary>& dict);
 
         //- Construct top-level dictionary by transferring parameter contents
-        dictionary(const Xfer<dictionary>&);
+        dictionary(const Xfer<dictionary>& dict);
 
         //- Construct and return clone
         autoPtr<dictionary> clone() const;
 
         //- Construct top-level dictionary on freestore from Istream
-        static autoPtr<dictionary> New(Istream&);
+        static autoPtr<dictionary> New(Istream& is);
 
 
     //- Destructor
@@ -286,8 +316,8 @@ public:
             //  If patternMatch, use regular expressions
             bool found
             (
-                const word&,
-                bool recursive=false,
+                const word& keyword,
+                bool recursive = false,
                 bool patternMatch = true
             ) const;
 
@@ -297,7 +327,7 @@ public:
             //  If patternMatch, use regular expressions
             const entry* lookupEntryPtr
             (
-                const word&,
+                const word& keyword,
                 bool recursive,
                 bool patternMatch
             ) const;
@@ -308,7 +338,7 @@ public:
             //  If patternMatch, use regular expressions.
             entry* lookupEntryPtr
             (
-                const word&,
+                const word& keyword,
                 bool recursive,
                 bool patternMatch
             );
@@ -318,7 +348,7 @@ public:
             //  If patternMatch, use regular expressions.
             const entry& lookupEntry
             (
-                const word&,
+                const word& keyword,
                 bool recursive,
                 bool patternMatch
             ) const;
@@ -328,22 +358,21 @@ public:
             //  If patternMatch, use regular expressions.
             ITstream& lookup
             (
-                const word&,
-                bool recursive=false,
-                bool patternMatch=true
+                const word& keyword,
+                bool recursive = false,
+                bool patternMatch = true
             ) const;
 
-            //- Find and return a T,
-            //  if not found return the given default value
+            //- Find and return a T, or return the given default value
             //  If recursive, search parent dictionaries.
             //  If patternMatch, use regular expressions.
             template<class T>
             T lookupOrDefault
             (
-                const word&,
-                const T&,
-                bool recursive=false,
-                bool patternMatch=true
+                const word& keyword,
+                const T& deflt,
+                bool recursive = false,
+                bool patternMatch = true
             ) const;
 
             //- Find and return a T, if not found return the given
@@ -353,10 +382,10 @@ public:
             template<class T>
             T lookupOrAddDefault
             (
-                const word&,
-                const T&,
-                bool recursive=false,
-                bool patternMatch=true
+                const word& keyword,
+                const T& deflt,
+                bool recursive = false,
+                bool patternMatch = true
             );
 
             //- Find an entry if present, and assign to T
@@ -366,10 +395,10 @@ public:
             template<class T>
             bool readIfPresent
             (
-                const word&,
-                T&,
-                bool recursive=false,
-                bool patternMatch=true
+                const word& keyword,
+                T& val,
+                bool recursive = false,
+                bool patternMatch = true
             ) const;
 
             //- Find and return an entry data stream pointer if present
@@ -377,33 +406,33 @@ public:
             //  Special handling for ':' at start of keyword and '..'.
             const entry* lookupScopedEntryPtr
             (
-                const word&,
+                const word& keyword,
                 bool recursive,
                 bool patternMatch
             ) const;
 
             //- Check if entry is a sub-dictionary
-            bool isDict(const word&) const;
+            bool isDict(const word& keyword) const;
 
             //- Find and return a sub-dictionary pointer if present
             //  otherwise return nullptr.
-            const dictionary* subDictPtr(const word&) const;
+            const dictionary* subDictPtr(const word& keyword) const;
 
             //- Find and return a sub-dictionary pointer if present
             //  otherwise return nullptr.
-            dictionary* subDictPtr(const word&);
+            dictionary* subDictPtr(const word& keyword);
 
             //- Find and return a sub-dictionary
-            const dictionary& subDict(const word&) const;
+            const dictionary& subDict(const word& keyword) const;
 
             //- Find and return a sub-dictionary for manipulation
-            dictionary& subDict(const word&);
+            dictionary& subDict(const word& keyword);
 
             //- Find and return a sub-dictionary as a copy, or
             //  return an empty dictionary if the sub-dictionary does not exist
             dictionary subOrEmptyDict
             (
-                const word&,
+                const word& keyword,
                 const bool mustRead = false
             ) const;
 
@@ -414,74 +443,78 @@ public:
             wordList sortedToc() const;
 
             //- Return the list of available keys or patterns
-            List<keyType> keys(bool patterns=false) const;
+            List<keyType> keys(bool patterns = false) const;
 
 
         // Editing
 
             //- Substitute the given keyword prepended by '$' with the
             //  corresponding sub-dictionary entries
-            bool substituteKeyword(const word& keyword);
+            bool substituteKeyword(const word& keyword, bool mergeEntry=false);
 
             //- Substitute the given scoped keyword prepended by '$' with the
             //  corresponding sub-dictionary entries
-            bool substituteScopedKeyword(const word& keyword);
+            bool substituteScopedKeyword
+            (
+                const word& keyword,
+                bool mergeEntry=false
+            );
 
             //- Add a new entry
             //  With the merge option, dictionaries are interwoven and
             //  primitive entries are overwritten
-            bool add(entry*, bool mergeEntry=false);
+            bool add(entry* entryPtr, bool mergeEntry=false);
 
             //- Add an entry
             //  With the merge option, dictionaries are interwoven and
             //  primitive entries are overwritten
-            void add(const entry&, bool mergeEntry=false);
+            void add(const entry& e, bool mergeEntry=false);
 
             //- Add a word entry
             //  optionally overwrite an existing entry
-            void add(const keyType&, const word&, bool overwrite=false);
+            void add(const keyType& k, const word& w, bool overwrite=false);
 
             //- Add a string entry
             //  optionally overwrite an existing entry
-            void add(const keyType&, const string&, bool overwrite=false);
+            void add(const keyType& k, const string& s, bool overwrite=false);
 
             //- Add a label entry
             //  optionally overwrite an existing entry
-            void add(const keyType&, const label, bool overwrite=false);
+            void add(const keyType&, const label l, bool overwrite=false);
 
             //- Add a scalar entry
             //  optionally overwrite an existing entry
-            void add(const keyType&, const scalar, bool overwrite=false);
+            void add(const keyType&, const scalar s, bool overwrite=false);
 
             //- Add a dictionary entry
             //  optionally merge with an existing sub-dictionary
             void add
             (
-                const keyType&,
-                const dictionary&,
-                bool mergeEntry=false
+                const keyType& k,
+                const dictionary& d,
+                bool mergeEntry = false
             );
 
             //- Add a T entry
             //  optionally overwrite an existing entry
             template<class T>
-            void add(const keyType&, const T&, bool overwrite=false);
+            void add(const keyType& k, const T& t, bool overwrite=false);
 
             //- Assign a new entry, overwrite any existing entry
-            void set(entry*);
+            void set(entry* entryPtr);
 
             //- Assign a new entry, overwrite any existing entry
-            void set(const entry&);
+            void set(const entry& e);
 
             //- Assign a dictionary entry, overwrite any existing entry
-            void set(const keyType&, const dictionary&);
+            void set(const keyType& k, const dictionary& d);
 
             //- Assign a T entry, overwrite any existing entry
             template<class T>
-            void set(const keyType&, const T&);
+            void set(const keyType& k, const T& t);
 
             //- Remove an entry specified by keyword
-            bool remove(const word&);
+            bool remove(const word& Keyword);
 
             //- Change the keyword for an entry,
             //  optionally forcing overwrite of an existing entry
@@ -494,13 +527,13 @@ public:
 
             //- Merge entries from the given dictionary.
             //  Also merge sub-dictionaries as required.
-            bool merge(const dictionary&);
+            bool merge(const dictionary& dict);
 
             //- Clear the dictionary
             void clear();
 
             //- Transfer the contents of the argument and annul the argument.
-            void transfer(dictionary&);
+            void transfer(dictionary& dict);
 
             //- Transfer contents to the Xfer container
             Xfer<dictionary> xfer();
@@ -509,53 +542,53 @@ public:
         // Read
 
             //- Read dictionary from Istream
-            bool read(Istream&);
+            bool read(Istream& is);
 
             //- Read dictionary from Istream, optionally keeping the header
-            bool read(Istream&, const bool keepHeader);
+            bool read(Istream& is, const bool keepHeader);
 
 
         // Write
 
             //- Write sub-dictionary with the keyword as its header
-            void writeEntry(const keyType& keyword, Ostream&) const;
+            void writeEntry(const keyType& keyword, Ostream& os) const;
 
             //- Write dictionary entries.
             //  Optionally with extra new line between entries for
             //  "top-level" dictionaries
-            void writeEntries(Ostream&, const bool extraNewLine=false) const;
+            void writeEntries(Ostream& os, const bool extraNewLine=false) const;
 
             //- Write dictionary, normally with sub-dictionary formatting
-            void write(Ostream&, const bool subDict=true) const;
+            void write(Ostream& os, const bool subDict=true) const;
 
 
     // Member Operators
 
         //- Find and return entry
-        ITstream& operator[](const word&) const;
+        ITstream& operator[](const word& keyword) const;
 
-        void operator=(const dictionary&);
+        void operator=(const dictionary& rhs);
 
         //- Include entries from the given dictionary.
         //  Warn, but do not overwrite existing entries.
-        void operator+=(const dictionary&);
+        void operator+=(const dictionary& rhs);
 
         //- Conditionally include entries from the given dictionary.
         //  Do not overwrite existing entries.
-        void operator|=(const dictionary&);
+        void operator|=(const dictionary& rhs);
 
         //- Unconditionally include entries from the given dictionary.
         //  Overwrite existing entries.
-        void operator<<=(const dictionary&);
+        void operator<<=(const dictionary& rhs);
 
 
     // IOstream operators
 
         //- Read dictionary from Istream
-        friend Istream& operator>>(Istream&, dictionary&);
+        friend Istream& operator>>(Istream& is, dictionary& dict);
 
         //- Write dictionary to Ostream
-        friend Ostream& operator<<(Ostream&, const dictionary&);
+        friend Ostream& operator<<(Ostream& os, const dictionary& dict);
 };
 
 
diff --git a/src/OpenFOAM/db/dictionary/dictionaryIO.C b/src/OpenFOAM/db/dictionary/dictionaryIO.C
index 231e3bc44b58a5041055ea02a0639e29cea6fc42..1d55ff27946c9b357592e63a554b4e6320744e7d 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryIO.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryIO.C
@@ -128,21 +128,21 @@ bool Foam::dictionary::read(Istream& is)
 }
 
 
-bool Foam::dictionary::substituteKeyword(const word& keyword)
+bool Foam::dictionary::substituteKeyword(const word& keyword, bool mergeEntry)
 {
-    word varName = keyword(1, keyword.size()-1);
+    const word varName = keyword(1, keyword.size()-1);
 
-    // lookup the variable name in the given dictionary
+    // Lookup the variable name in the given dictionary
     const entry* ePtr = lookupEntryPtr(varName, true, true);
 
-    // if defined insert its entries into this dictionary
+    // If defined insert its entries into this dictionary
     if (ePtr != nullptr)
     {
         const dictionary& addDict = ePtr->dict();
 
         forAllConstIter(IDLList<entry>, addDict, iter)
         {
-            add(iter());
+            add(iter(), mergeEntry);
         }
 
         return true;
diff --git a/src/OpenFOAM/db/dictionary/entry/entryIO.C b/src/OpenFOAM/db/dictionary/entry/entryIO.C
index 2a10aee4b89c73a6154fbc4483ccb83b9322bbbb..4f7b3e4f0fd318d7ecd6697968d93a4fda6ccad6 100644
--- a/src/OpenFOAM/db/dictionary/entry/entryIO.C
+++ b/src/OpenFOAM/db/dictionary/entry/entryIO.C
@@ -73,7 +73,7 @@ bool Foam::entry::getKeyword(keyType& keyword, token& keywordToken, Istream& is)
 bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
 {
     token keywordToken;
-    bool ok = getKeyword(keyword, keywordToken, is);
+    const bool ok = getKeyword(keyword, keywordToken, is);
 
     if (ok)
     {
@@ -112,7 +112,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
     token keyToken;
 
     // Get the next keyword and if a valid keyword return true
-    bool valid = getKeyword(keyword, keyToken, is);
+    const bool valid = getKeyword(keyword, keyToken, is);
 
     if (!valid)
     {
@@ -153,7 +153,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
     {
         if (keyword[0] == '#')      // ... Function entry
         {
-            word functionName = keyword(1, keyword.size()-1);
+            const word functionName = keyword(1, keyword.size()-1);
             if (disableFunctionEntries)
             {
                 return parentDict.add
@@ -195,7 +195,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
 
             if (nextToken == token::BEGIN_BLOCK)
             {
-                word varName = keyword(1, keyword.size()-1);
+                const word varName = keyword(1, keyword.size()-1);
 
                 // lookup the variable name in the given dictionary
                 const entry* ePtr = parentDict.lookupScopedEntryPtr
@@ -227,7 +227,14 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
             }
             else
             {
-                parentDict.substituteScopedKeyword(keyword);
+                // Deal with duplicate entries (at least partially)
+                const bool mergeEntry =
+                (
+                    functionEntries::inputModeEntry::merge()
+                 || functionEntries::inputModeEntry::overwrite()
+                );
+
+                parentDict.substituteScopedKeyword(keyword, mergeEntry);
             }
 
             return true;
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C
index 96472b71cd4a0e9a3063e229e67694c58773e828..fbb6787ca1b8a982a6d56cc9d15d3d59e6f9df7c 100644
--- a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C
+++ b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C
@@ -62,7 +62,7 @@ void Foam::functionEntries::inputModeEntry::setMode(Istream& is)
 {
     clear();
 
-    word mode(is);
+    const word mode(is);
     if (mode == "merge" || mode == "default")
     {
         mode_ = MERGE;
@@ -97,7 +97,7 @@ void Foam::functionEntries::inputModeEntry::setMode(Istream& is)
 
 bool Foam::functionEntries::inputModeEntry::execute
 (
-    dictionary& parentDict,
+    dictionary& unused,
     Istream& is
 )
 {
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H
index 623524cd8048e9de4e327aa5bca77ada10fb1d0d..66c98243ade466db489fdbc213fb90402690dce9 100644
--- a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H
+++ b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H
@@ -34,12 +34,20 @@ Description
     \endverbatim
 
     The possible input modes:
-      - \par merge      merge sub-dictionaries when possible
-      - \par overwrite  keep last entry and silently remove previous ones
-      - \par protect    keep initial entry and silently ignore subsequent ones
-      - \par warn       keep initial entry and warn about subsequent ones
-      - \par error      issue a FatalError for duplicate entries
-      - \par default    currently identical to merge
+      - \par merge
+        merge sub-dictionaries when possible
+      - \par overwrite
+        keep last entry and silently remove previous ones
+      - \par protect
+        keep initial entry and silently ignore subsequent ones
+      - \par warn
+        keep initial entry and warn about subsequent ones
+      - \par error
+        issue a FatalError for duplicate entries
+      - \par default
+        The default treatment - currently identical to \b merge.
+
+      Note that the clear() method resets to the default mode (merge).
 
 SourceFiles
     inputModeEntry.C
@@ -83,13 +91,13 @@ class inputModeEntry
     // Private Member Functions
 
         //- Read the mode as a word and set enum appropriately
-        static void setMode(Istream&);
+        static void setMode(Istream& is);
 
         //- Disallow default bitwise copy construct
-        inputModeEntry(const inputModeEntry&);
+        inputModeEntry(const inputModeEntry&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const inputModeEntry&);
+        void operator=(const inputModeEntry&) = delete;
 
 
 public:
@@ -101,7 +109,7 @@ public:
     // Member Functions
 
         //- Execute the functionEntry in a sub-dict context
-        static bool execute(dictionary& parentDict, Istream&);
+        static bool execute(dictionary& parentDict, Istream& is);
 
         //- Reset the inputMode to %default (ie, %merge)
         static void clear();
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H
index 6ad9eb402e3a883c942d51e1578eb1f5a44abcb1..8508141f64dbd0cba9bed55967785a1ae1f502b7 100644
--- a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H
+++ b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H
@@ -67,10 +67,10 @@ class removeEntry
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        removeEntry(const removeEntry&);
+        removeEntry(const removeEntry&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const removeEntry&);
+        void operator=(const removeEntry&) = delete;
 
 
 public:
@@ -82,7 +82,7 @@ public:
     // Member Functions
 
         //- Execute the functionEntry in a sub-dict context
-        static bool execute(dictionary& parentDict, Istream&);
+        static bool execute(dictionary& parentDict, Istream& is);
 };
 
 
diff --git a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C
index 8777819d450672c0b03be9f80f61982d01757541..1c447e88abcbe44dadb7ccb65a88538ca226fa24 100644
--- a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C
+++ b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C
@@ -21,9 +21,6 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Description
-    PrimitiveEntry constructor from Istream and Ostream output operator.
-
 \*---------------------------------------------------------------------------*/
 
 #include "primitiveEntry.H"
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index 7288489070c3567bbf6d1b7d51c1d6050b5320ff..fad74c2dd0abe63e349775d70cd8255c54bd4a8f 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -310,17 +310,17 @@ bool Foam::argList::postProcess(int argc, char *argv[])
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-// Convert argv -> args_
-// Transform sequences with "(" ... ")" into string lists in the process
 bool Foam::argList::regroupArgv(int& argc, char**& argv)
 {
-    int nArgs = 0;
-    int listDepth = 0;
+    int nArgs = 1;
+    unsigned listDepth = 0;
     string tmpString;
 
-    // Note: we also re-write directly into args_
+    // Note: we rewrite directly into args_
     // and use a second pass to sort out args/options
-    for (int argI = 0; argI < argc; ++argI)
+
+    args_[0] = fileName(argv[0]);
+    for (int argI = 1; argI < argc; ++argI)
     {
         if (strcmp(argv[argI], "(") == 0)
         {
@@ -333,7 +333,7 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
             {
                 --listDepth;
                 tmpString += ")";
-                if (listDepth == 0)
+                if (!listDepth)
                 {
                     args_[nArgs++] = tmpString;
                     tmpString.clear();
@@ -359,11 +359,21 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
 
     if (tmpString.size())
     {
+        // Group(s) not closed, but flush anything still pending
         args_[nArgs++] = tmpString;
     }
 
     args_.setSize(nArgs);
 
+    std::string::size_type len = (nArgs-1); // Spaces between args
+    forAll(args_, argi)
+    {
+        len += args_[argi].size();
+    }
+
+    // Length needed for regrouped command-line
+    argListStr_.reserve(len);
+
     return nArgs < argc;
 }
 
@@ -403,6 +413,8 @@ void Foam::argList::getRootCase()
     globalCase_ = casePath.name();
     case_       = globalCase_;
 
+    // The name of the executable, unless already present in the environment
+    setEnv("FOAM_EXECUTABLE", executable_, false);
 
     // Set the case and case-name as an environment variable
     if (rootPath_.isAbsolute())
@@ -440,7 +452,7 @@ Foam::argList::argList
 {
     // Check if this run is a parallel run by searching for any parallel option
     // If found call runPar which might filter argv
-    for (int argI = 0; argI < argc; ++argI)
+    for (int argI = 1; argI < argc; ++argI)
     {
         if (argv[argI][0] == '-')
         {
@@ -455,17 +467,11 @@ Foam::argList::argList
     }
 
     // Convert argv -> args_ and capture ( ... ) lists
-    // for normal arguments and for options
     regroupArgv(argc, argv);
+    argListStr_ += args_[0];
 
-    // Get executable name
-    args_[0]    = fileName(argv[0]);
-    executable_ = fileName(argv[0]).name();
-
-    // Check arguments and options, we already have argv[0]
+    // Check arguments and options, argv[0] was already handled
     int nArgs = 1;
-    argListStr_ = args_[0];
-
     for (int argI = 1; argI < args_.size(); ++argI)
     {
         argListStr_ += ' ';
@@ -525,6 +531,9 @@ Foam::argList::argList
 
     args_.setSize(nArgs);
 
+    // Set executable name
+    executable_ = fileName(args_[0]).name();
+
     parse(checkArgs, checkOpts, initialise);
 }
 
@@ -769,7 +778,7 @@ void Foam::argList::parse
                 }
 
                 // Distribute the master's argument list (with new root)
-                bool hadCaseOpt = options_.found("case");
+                const bool hadCaseOpt = options_.found("case");
                 for
                 (
                     int slave = Pstream::firstSlave();
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index 2bc6d288ccee38b853701910e466f3f2c5f56391..09c6777261cedff59a35f29fee42d26c6951b200 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -42,6 +42,8 @@ Description
     Default command-line options:
       - \par -case \<dir\>
         Select a case directory instead of the current working directory
+      - \par -decomposeParDict \<file\>
+        Read decomposePar dictionary from specified location
       - \par -parallel
         Specify case as a parallel job
       - \par -doc
@@ -51,10 +53,25 @@ Description
       - \par -help
         Print the usage
 
-    The environment variable \b FOAM_CASE is set to the path of the
-    global case (same for serial and parallel jobs).
-    The environment variable \b FOAM_CASENAME is set to the name of the
-    global case.
+    Additionally, the \b -noFunctionObjects and \b -postProcess options
+    may be present for some solvers or utilities.
+
+    Environment variables set by argList or by Time:
+      - \par FOAM_CASE
+        The path of the global case.
+        It is the same for serial and parallel jobs.
+      - \par FOAM_CASENAME
+        The name of the global case.
+      - \par FOAM_EXECUTABLE
+        If not already present in the calling environment,
+        it is set to the \a name portion of the calling executable.
+      - \par FOAM_APPLICATION
+        If not already present in the calling environment,
+        it is set to the value of the \c application entry
+        (from \c controlDict) if that entry is present.
+
+    The value of the \b FOAM_APPLICATION may be inconsistent if the value of
+    the \c application entry is adjusted during runtime.
 
 Note
     - The document browser used is defined by the \b FOAM_DOC_BROWSER
@@ -131,10 +148,12 @@ class argList
         //   * cwd
         //
         // Also export FOAM_CASE and FOAM_CASENAME environment variables
-        // so they can be used immediately (eg, in decomposeParDict)
+        // so they can be used immediately (eg, in decomposeParDict), as well
+        // as the FOAM_EXECUTABLE environment.
         void getRootCase();
 
-        //- Transcribe argv into internal args_
+        //- Transcribe argv into internal args_.
+        //  Transform sequences with "(" ... ")" into string lists
         //  return true if any "(" ... ")" sequences were captured
         bool regroupArgv(int& argc, char**& argv);