diff --git a/applications/test/IndirectList/Test-IndirectList.C b/applications/test/IndirectList/Test-IndirectList.C
index b06df501b5b47161779135879301cfecfc8b63a9..bbe8b00f2990b5748b6b94093c0f04ade51fa482 100644
--- a/applications/test/IndirectList/Test-IndirectList.C
+++ b/applications/test/IndirectList/Test-IndirectList.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2010-2010, 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010-2010, 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011 OpenFOAM Foundation
@@ -27,19 +27,21 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#include "IndirectList.H"
-#include "IOstreams.H"
+#include "argList.H"
 #include "Fstream.H"
 #include "ListOps.H"
+#include "IndirectList.H"
 #include "labelIndList.H"
-#include "argList.H"
+#include "SortList.H"
+#include "Random.H"
+#include <functional>
 
 using namespace Foam;
 
 template<class ListType>
 void printInfo(const ListType& lst)
 {
-    Info<< "full: " << flatOutput(lst.completeList()) << nl
+    Info<< "full: " << flatOutput(lst.values()) << nl
         << "addr: " << flatOutput(lst.addressing()) << nl
         << "list: " << flatOutput(lst) << nl
         << endl;
@@ -103,7 +105,7 @@ int main(int argc, char *argv[])
 
     inplaceReverseList(addresses);
 
-    idl1.resetAddressing(std::move(addresses));
+    idl1.addressing() = std::move(addresses);
 
     printInfo(idl1);
 
@@ -114,10 +116,10 @@ int main(int argc, char *argv[])
 
     printInfo(uidl1);
 
-    idl1.resetAddressing(List<label>());
-//    idl2.resetAddressing(List<label>());
+    idl1.addressing().clear();
+    // idl2.addressing().clear();
 
-    Info<<"after resetAddressing:" << nl << endl;
+    Info<<"after reset addressing:" << nl << endl;
 
     printInfo(uidl1);
     printInfo(idl1);
@@ -140,7 +142,7 @@ int main(int argc, char *argv[])
     {
         if (Pstream::master())
         {
-            Pout<< "full: " << flatOutput(idl3.completeList()) << nl
+            Pout<< "full: " << flatOutput(idl3.values()) << nl
                 << "send: " << flatOutput(idl3) << endl;
 
             for
@@ -173,6 +175,61 @@ int main(int argc, char *argv[])
         Pstream::scatter(barrier);
     }
 
+    // SortList
+    {
+        List<scalar> list1(20);
+
+        Random rnd(1234);
+
+        for (scalar& val : list1)
+        {
+            val = 100 * rnd.sample01<scalar>();
+        }
+
+        // Pick out 1/2 the values and make the negative
+        for (label i=0; i < list1.size()/2; ++i)
+        {
+            label pos = rnd.position(0, list1.size()-1);
+            list1[pos] = -list1[pos];
+        }
+
+        Info<< nl << "Random list: " << flatOutput(list1) << nl;
+
+        SortList<scalar> sorter1(list1);
+
+        Info<< nl << "Sort indices: " << flatOutput(sorter1.indices()) << nl;
+
+        Info<< nl << "Reverse indices: " << flatOutput(sorter1.indices()) << nl;
+
+        sorter1.reverse();
+
+        Info<< nl << "Again indices: " << flatOutput(sorter1.indices()) << nl;
+
+        sorter1.reverseSort();
+
+        Info<< nl << "Reverse indices: " << flatOutput(sorter1.indices()) << nl;
+
+        Info<< nl << "Sorted  : " << flatOutput(sorter1) << nl;
+
+        sorter1.sort(std::greater<scalar>());
+
+        SortList<scalar> sorter2(list1, std::greater<scalar>());
+
+        sorter2.reverse();
+
+        Info<< "sorted: ";
+        for (const auto& val : sorter2)
+        {
+            Info<< ' ' << val;
+        }
+        Info<< nl;
+
+
+        sorter2.sort([](scalar a, scalar b) { return mag(a) < mag(b); });
+
+        Info<< nl << "Mag sorted: " << flatOutput(sorter2) << nl;
+    }
+
     Info<< "End\n" << endl;
 
     return 0;
diff --git a/applications/test/sliceRange/Test-sliceRange.C b/applications/test/sliceRange/Test-sliceRange.C
index 477283ebb7270a1ec306a78d65f474826268e049..f398c6fbbe5f38febec6240adcb3af60d762e47e 100644
--- a/applications/test/sliceRange/Test-sliceRange.C
+++ b/applications/test/sliceRange/Test-sliceRange.C
@@ -29,6 +29,9 @@ Description
 #include "labelList.H"
 #include "FixedList.H"
 #include "sliceRange.H"
+#include "SliceList.H"
+#include "IndirectList.H"
+#include "Random.H"
 
 using namespace Foam;
 
@@ -128,9 +131,60 @@ int main(int argc, char *argv[])
         }
     }
 
+    // Sliced lists
+    {
+        List<scalar> list1(100);
+
+        Random rnd(1234);
+
+        for (scalar& val : list1)
+        {
+            val = 100 * rnd.sample01<scalar>();
+        }
+
+        Info<< nl << "Random list: " << flatOutput(list1) << nl;
+
+        SliceList<scalar> slice1(list1, sliceRange(0, 15, 3));
+
+        Info<< nl << "slicing with: " << slice1.addressing() << nl;
+
+        Info<< nl << "Sliced list: " << flatOutput(slice1) << nl;
+
+        for (scalar& val : slice1)
+        {
+            val = -val;
+        }
+
+        // Changed list via slice:
+        Info<< nl << "Changed via slice: " << flatOutput(list1) << nl;
+
+        // Some indirect list
+
+        IndirectList<scalar> indlist
+        (
+            list1,
+            identity(slice1.size(), list1.size()-slice1.size())
+        );
+
+        Info<< nl << "Indirect slice: " << flatOutput(indlist) << nl;
+
+        indlist = 1000;
+        Info<< nl << "zeroed slice: " << flatOutput(indlist) << nl;
+
+        slice1 = indlist;
+
+        Info<< nl << "self-copy: " << flatOutput(list1) << nl;
+
+        slice1 = 100000;
+
+        Info<< nl << "set values: " << flatOutput(slice1) << nl
+            << " = " << flatOutput(list1) << nl;
+    }
+
     Info<< "\nEnd\n" << endl;
 
     return 0;
 }
 
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.C b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C
index 19dd1d53984f627492b01e99dba63db7e2b61a10..32fd5bddaf628cb27d854b101b1d883991fc5613 100644
--- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.C
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C
@@ -47,10 +47,11 @@ Foam::PackedList<Width>::PackedList
 
 
 template<unsigned Width>
+template<class Addr>
 Foam::PackedList<Width>::PackedList
 (
     const PackedList<Width>& list,
-    const labelUIndList& addr
+    const IndirectListBase<label, Addr>& addr
 )
 :
     PackedList<Width>(addr.size())
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
index cdf705473bb10729c98a044563649a33f7980355..cb73cbb749879cb18e8c279defff3ae005354126 100644
--- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
@@ -93,7 +93,7 @@ SourceFiles
 
 #include "BitOps.H"
 #include "labelList.H"
-#include "UIndirectList.H"
+#include "IndirectListBase.H"
 #include "InfoProxy.H"
 #include "PackedListCore.H"
 
@@ -252,7 +252,12 @@ public:
         PackedList(const PackedList<Width>& list, const labelUList& addr);
 
         //- Copy construct a subset
-        PackedList(const PackedList<Width>& list, const labelUIndList& addr);
+        template<class Addr>
+        PackedList
+        (
+            const PackedList<Width>& list,
+            const IndirectListBase<label, Addr>& addr
+        );
 
         //- Copy construct a subset range
         PackedList(const PackedList<Width>& list, const labelRange& range);
@@ -260,8 +265,9 @@ public:
         //- Construct from a list of values
         inline explicit PackedList(const labelUList& values);
 
-        //- Construct from a list of values
-        inline explicit PackedList(const labelUIndList& values);
+        //- Construct from a indirect list of values
+        template<class Addr>
+        inline explicit PackedList(const IndirectListBase<label, Addr>& values);
 
         //- Clone
         inline autoPtr<PackedList<Width>> clone() const;
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
index 1c86e05125ce15f33886c3e8d50aad0de9ad4474..81a7ab47e7a466b0e555cede63f981d1ba7814b2 100644
--- a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -242,7 +242,11 @@ inline Foam::PackedList<Width>::PackedList(const labelUList& values)
 
 
 template<unsigned Width>
-inline Foam::PackedList<Width>::PackedList(const labelUIndList& values)
+template<class Addr>
+inline Foam::PackedList<Width>::PackedList
+(
+    const IndirectListBase<label, Addr>& values
+)
 :
     blocks_(num_blocks(values.size()), 0u),
     size_(values.size())
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.C b/src/OpenFOAM/containers/Bits/bitSet/bitSet.C
index 3218145d86ae06ba0ac0f3c8c63e0e26cda15e53..93f1a5b6692b9891ceba3e41633d2b003634f2ac 100644
--- a/src/OpenFOAM/containers/Bits/bitSet/bitSet.C
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.C
@@ -306,19 +306,6 @@ Foam::bitSet::bitSet(const bitSet& bitset, const labelUList& addr)
 }
 
 
-Foam::bitSet::bitSet(const bitSet& bitset, const labelUIndList& addr)
-:
-    bitSet(addr.size())
-{
-    const label len = addr.size();
-
-    for (label i = 0; i < len; ++i)
-    {
-        set(i, bitset.get(addr[i]));
-    }
-}
-
-
 Foam::bitSet::bitSet(const bitSet& bitset, const labelRange& range)
 :
     bitSet(range.size())
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H
index 00d943059686761e69f56e7efc65f14de9bbdea6..2d7cbf0cc9e5cc47606b6592fed32c65930d4cb6 100644
--- a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H
@@ -156,7 +156,12 @@ public:
         bitSet(const bitSet& bitset, const labelUList& addr);
 
         //- Copy construct a subset
-        bitSet(const bitSet& bitset, const labelUIndList& addr);
+        template<class Addr>
+        bitSet
+        (
+            const bitSet& bitset,
+            const IndirectListBase<label, Addr>& addr
+        );
 
         //- Copy construct a subset range
         bitSet(const bitSet& bitset, const labelRange& range);
@@ -170,7 +175,12 @@ public:
 
         //- Construct with given size with all bits set to 0,
         //- subsequently add specified locations as 1.
-        inline bitSet(const label n, const labelUIndList& locations);
+        template<class Addr>
+        bitSet
+        (
+            const label n,
+            const IndirectListBase<label, Addr>& locations
+        );
 
         //- Construct with given size with all bits set to 0,
         //- subsequently add specified locations as 1.
@@ -187,7 +197,8 @@ public:
 
         //- Construct with automatic sizing (filled with 0),
         //- and populate with specified locations as 1.
-        inline explicit bitSet(const labelUIndList& locations);
+        template<class Addr>
+        inline explicit bitSet(const IndirectListBase<label, Addr>& locations);
 
         //- Construct with automatic sizing (filled with 0),
         //- and populate with specified locations as 1.
@@ -381,7 +392,8 @@ public:
         //  Does auto-vivify for non-existent entries.
         //
         //  \return number of locations changed
-        inline label set(const labelUIndList& locations);
+        template<class Addr>
+        inline label set(const IndirectListBase<label, Addr>& locations);
 
         //- Set the listed locations to true.
         //  Does auto-vivify for non-existent entries.
@@ -405,7 +417,8 @@ public:
         //- Unset the listed locations, never auto-vivifies.
         //
         //  \return number of locations changed
-        inline label unset(const labelUIndList& locations);
+        template<class Addr>
+        inline label unset(const IndirectListBase<label, Addr>& locations);
 
         //- Unset the listed locations, never auto-vivifies.
         //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H b/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H
index 5312caa3d1b1c086890ab94a5423e34e9158e568..0525b9468647a2a1af0411cd604b361592fc09a5 100644
--- a/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H
@@ -120,7 +120,12 @@ inline Foam::bitSet::bitSet(const label n, const labelUList& locations)
 }
 
 
-inline Foam::bitSet::bitSet(const label n, const labelUIndList& locations)
+template<class Addr>
+inline Foam::bitSet::bitSet
+(
+    const label n,
+    const IndirectListBase<label, Addr>& locations
+)
 :
     bitSet(n)
 {
@@ -148,7 +153,11 @@ inline Foam::bitSet::bitSet(const labelUList& locations)
 }
 
 
-inline Foam::bitSet::bitSet(const labelUIndList& locations)
+template<class Addr>
+inline Foam::bitSet::bitSet
+(
+    const IndirectListBase<label, Addr>& locations
+)
 :
     bitSet()
 {
@@ -537,7 +546,11 @@ inline Foam::label Foam::bitSet::set(const labelUList& locations)
 }
 
 
-inline Foam::label Foam::bitSet::set(const labelUIndList& locations)
+template<class Addr>
+inline Foam::label Foam::bitSet::set
+(
+    const IndirectListBase<label, Addr>& locations
+)
 {
     return setMany(locations.begin(), locations.end());
 }
@@ -549,7 +562,11 @@ inline Foam::label Foam::bitSet::unset(const labelUList& locations)
 }
 
 
-inline Foam::label Foam::bitSet::unset(const labelUIndList& locations)
+template<class Addr>
+inline Foam::label Foam::bitSet::unset
+(
+    const IndirectListBase<label, Addr>& locations
+)
 {
     return unset(locations.begin(), locations.end());
 }
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C b/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C
index a41ad03c37f396955f83ced4961d8589d2dc8775..38dd1f00cf9f7522a2dba03d801802d3e077811e 100644
--- a/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -48,6 +48,25 @@ Foam::bitSet::bitSet(const FixedList<label, N>& locations)
 }
 
 
+template<class Addr>
+Foam::bitSet::bitSet
+(
+    const bitSet& bitset,
+    const IndirectListBase<label, Addr>& addr
+)
+:
+    bitSet(addr.size())
+{
+    const label len = addr.size();
+
+    for (label i = 0; i < len; ++i)
+    {
+        set(i, bitset.get(addr[i]));
+    }
+}
+
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class InputIter>
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
index 0f90b63f4a0601837ee69f7ad869e465a634ee68..a0511ac5ac3440b563789e133b1f72e4bff88baf 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
@@ -84,7 +84,8 @@ Foam::HashSet<Key, Hash>::HashSet(const UList<Key>& list)
 
 
 template<class Key, class Hash>
-Foam::HashSet<Key, Hash>::HashSet(const UIndirectList<Key>& list)
+template<class Addr>
+Foam::HashSet<Key, Hash>::HashSet(const IndirectListBase<Key, Addr>& list)
 :
     parent_type(2*list.size())
 {
@@ -177,9 +178,10 @@ inline Foam::label Foam::HashSet<Key, Hash>::insert
 
 
 template<class Key, class Hash>
+template<class Addr>
 inline  Foam::label Foam::HashSet<Key, Hash>::insert
 (
-    const UIndirectList<Key>& list
+    const IndirectListBase<Key, Addr>& list
 )
 {
     return insert(list.begin(), list.end());
@@ -230,9 +232,10 @@ inline Foam::label Foam::HashSet<Key, Hash>::unset
 
 
 template<class Key, class Hash>
+template<class Addr>
 inline Foam::label Foam::HashSet<Key, Hash>::unset
 (
-    const UIndirectList<Key>& list
+    const IndirectListBase<Key, Addr>& list
 )
 {
     return unset(list.begin(), list.end());
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
index 297b6013336440ae631fe778b871fe4d256bda26..44f6b0ad3ab5cae9a2499c9b5fdad65b0c8e1ba6 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
@@ -65,7 +65,7 @@ Description
 #define HashSet_H
 
 #include "HashTable.H"
-#include "UIndirectList.H"
+#include "IndirectList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -143,7 +143,8 @@ public:
         explicit HashSet(const UList<Key>& list);
 
         //- Construct from an indirect list
-        explicit HashSet(const UIndirectList<Key>& list);
+        template<class Addr>
+        explicit HashSet(const IndirectListBase<Key, Addr>& list);
 
         //- Construct from an initializer list of Key
         HashSet(std::initializer_list<Key> list);
@@ -222,7 +223,8 @@ public:
 
         //- Insert keys from the list of Key
         //  \return The number of new elements inserted
-        inline label insert(const UIndirectList<Key>& list);
+        template<class Addr>
+        inline label insert(const IndirectListBase<Key, Addr>& list);
 
         //- Same as insert (no value to overwrite)
         template<class InputIter>
@@ -251,7 +253,8 @@ public:
         }
 
         //- Same as insert (no value to overwrite)
-        inline label set(const UIndirectList<Key>& list)
+        template<class Addr>
+        inline label set(const IndirectListBase<Key, Addr>& list)
         {
             return insert(list);
         }
@@ -284,7 +287,8 @@ public:
 
         //- Unset the listed keys - same as erase
         //  \return The number of items removed
-        inline label unset(const UIndirectList<Key>& list);
+        template<class Addr>
+        inline label unset(const IndirectListBase<Key, Addr>& list);
 
 
     // STL iterators
diff --git a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H b/src/OpenFOAM/containers/IndirectLists/BiIndirectList/BiIndirectList.H
similarity index 100%
rename from src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H
rename to src/OpenFOAM/containers/IndirectLists/BiIndirectList/BiIndirectList.H
diff --git a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H b/src/OpenFOAM/containers/IndirectLists/BiIndirectList/BiIndirectListI.H
similarity index 100%
rename from src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H
rename to src/OpenFOAM/containers/IndirectLists/BiIndirectList/BiIndirectListI.H
diff --git a/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H b/src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectList.H
similarity index 58%
rename from src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H
rename to src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectList.H
index 6899616b4a4950680148d4df237217838afe2762..8ffec9e95604862eea53f748081d8def8c0a3ce4 100644
--- a/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectList.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2010-2010, 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010, 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -30,8 +30,7 @@ Description
     A List with indirect addressing.
 
 See also
-    Foam::UIndirectList for a version without any allocation for the
-    addressing.
+    Foam::UIndirectList for a version without any addressing allocation.
 
 SourceFiles
     IndirectListI.H
@@ -41,6 +40,7 @@ SourceFiles
 #ifndef IndirectList_H
 #define IndirectList_H
 
+#include "IndirectListAddressing.H"
 #include "UIndirectList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -48,53 +48,6 @@ SourceFiles
 namespace Foam
 {
 
-/*---------------------------------------------------------------------------*\
-                   Class IndirectListAddressing Declaration
-\*---------------------------------------------------------------------------*/
-
-//- A helper class for storing addresses.
-class IndirectListAddressing
-{
-    // Private data
-
-        //- Storage for the list addressing
-        List<label> addressing_;
-
-
-    // Private Member Functions
-
-        //- No copy construct
-        IndirectListAddressing(const IndirectListAddressing&) = delete;
-
-        //- No copy assignment
-        void operator=(const IndirectListAddressing&) = delete;
-
-
-protected:
-
-    // Constructors
-
-        //- Copy construct from addressing array
-        inline explicit IndirectListAddressing(const labelUList& addr);
-
-        //- Move construct from addressing array
-        inline explicit IndirectListAddressing(List<label>&& addr);
-
-
-    // Member Functions
-
-        //- Return the list addressing
-        inline const List<label>& addressing() const;
-
-        //- Copy reset addressing
-        inline void resetAddressing(const labelUList& addr);
-
-        //- Move reset addressing
-        inline void resetAddressing(List<label>&& addr);
-
-};
-
-
 /*---------------------------------------------------------------------------*\
                         Class IndirectList Declaration
 \*---------------------------------------------------------------------------*/
@@ -102,43 +55,30 @@ protected:
 template<class T>
 class IndirectList
 :
-    private IndirectListAddressing,
-    public  UIndirectList<T>
+    private IndirectListAddressing<labelList>,
+    public UIndirectList<T>
 {
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const IndirectList<T>&) = delete;
-
-        //- No copy assignment from UIndirectList
-        void operator=(const UIndirectList<T>&) = delete;
-
-
 public:
 
     // Constructors
 
-        //- Copy construct addressing, shallow copy values list reference.
+        //- Copy construct addressing, shallow copy values list reference
         inline IndirectList(const UList<T>& values, const labelUList& addr);
 
-        //- Move construct addressing, shallow copy values list reference.
-        inline IndirectList(const UList<T>& values, List<label>&& addr);
+        //- Move construct addressing, shallow copy values list reference
+        inline IndirectList(const UList<T>& values, labelList&& addr);
 
-        //- Copy construct addressing, shallow copy values list reference.
+        //- Copy construct addressing, shallow copy values list reference
         inline IndirectList(const IndirectList<T>& list);
 
         //- Copy construct addressing, shallow copy values list reference
-        //- from UIndirectList
         inline explicit IndirectList(const UIndirectList<T>& list);
 
 
     // Member Functions
 
-        //- Return the list addressing
-        using UIndirectList<T>::addressing;
-
-        //- Reset the list addressing
-        using IndirectListAddressing::resetAddressing;
+        //- The list addressing
+        using IndirectListAddressing::addressing;
 
 
     // Member Operators
@@ -146,6 +86,11 @@ public:
         //- Assignment operator
         using UIndirectList<T>::operator=;
 
+        //- Deep copy values, Fatal if list sizes are not identical
+        void operator=(const IndirectList<T>& rhs)
+        {
+            this->copyList(rhs);
+        }
 };
 
 
diff --git a/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H b/src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectListI.H
similarity index 57%
rename from src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H
rename to src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectListI.H
index b2d53fde10e172ad75546d9c0ac4c84dc4a3e66b..ca428d5a4f79e31490b6a4a1ebb2cf696cf28990 100644
--- a/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectList/IndirectListI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010, 2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -27,24 +27,6 @@ License
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-inline Foam::IndirectListAddressing::IndirectListAddressing
-(
-    const labelUList& addr
-)
-:
-    addressing_(addr)
-{}
-
-
-inline Foam::IndirectListAddressing::IndirectListAddressing
-(
-    List<label>&& addr
-)
-:
-    addressing_(std::move(addr))
-{}
-
-
 template<class T>
 inline Foam::IndirectList<T>::IndirectList
 (
@@ -52,11 +34,11 @@ inline Foam::IndirectList<T>::IndirectList
     const labelUList& addr
 )
 :
-    IndirectListAddressing(addr),
+    IndirectListAddressing<labelList>(addr),
     UIndirectList<T>
     (
         values,
-        IndirectListAddressing::addressing()
+        IndirectListAddressing<labelList>::addressing()
     )
 {}
 
@@ -65,73 +47,42 @@ template<class T>
 inline Foam::IndirectList<T>::IndirectList
 (
     const UList<T>& values,
-    List<label>&& addr
+    labelList&& addr
 )
 :
-    IndirectListAddressing(std::move(addr)),
+    IndirectListAddressing<labelList>(std::move(addr)),
     UIndirectList<T>
     (
         values,
-        IndirectListAddressing::addressing()
+        IndirectListAddressing<labelList>::addressing()
     )
 {}
 
 
 template<class T>
-inline Foam::IndirectList<T>::IndirectList
-(
-    const IndirectList<T>& list
-)
+inline Foam::IndirectList<T>::IndirectList(const IndirectList<T>& list)
 :
-    IndirectListAddressing(list.addressing()),  // Copy addressing
+    // Copy addressing
+    IndirectListAddressing<labelList>(list.addressing()),
     UIndirectList<T>
     (
-        list.completeList(),
-        IndirectListAddressing::addressing()
+        list.values(),
+        IndirectListAddressing<labelList>::addressing()
     )
 {}
 
 
 template<class T>
-inline Foam::IndirectList<T>::IndirectList
-(
-    const UIndirectList<T>& list
-)
+inline Foam::IndirectList<T>::IndirectList(const UIndirectList<T>& list)
 :
-    IndirectListAddressing(list.addressing()),  // Copy addressing
+    // Copy addressing
+    IndirectListAddressing<labelList>(list.addressing()),
     UIndirectList<T>
     (
-        list.completeList(),
-        IndirectListAddressing::addressing()
+        list.values(),
+        IndirectListAddressing<labelList>::addressing()
     )
 {}
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-inline const Foam::List<Foam::label>&
-Foam::IndirectListAddressing::addressing() const
-{
-    return addressing_;
-}
-
-
-inline void Foam::IndirectListAddressing::resetAddressing
-(
-    const labelUList& addr
-)
-{
-    addressing_ = addr;
-}
-
-
-inline void Foam::IndirectListAddressing::resetAddressing
-(
-    List<label>&& addr
-)
-{
-    addressing_.transfer(addr);
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListAddressing.H b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListAddressing.H
new file mode 100644
index 0000000000000000000000000000000000000000..5fd10f25f907d36424c4365018c3c44be9d22e10
--- /dev/null
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListAddressing.H
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010, 2017-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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/>.
+
+Class
+    Foam::IndirectListAddressing
+
+Description
+    A class for storing list addressing (labels, slices etc) which are
+    normally to used by IndirectList. A private inheritance is often used
+    by any inheriting classes.
+
+SourceFiles
+    IndirectListAddressing.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IndirectListAddressing_H
+#define IndirectListAddressing_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class IndirectListAddressing Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Addr>
+class IndirectListAddressing
+{
+    // Private Data
+
+        //- Storage for addressing
+        Addr storedAddr_;
+
+
+public:
+
+    // Constructors
+
+        //- Copy construct from addressing information
+        IndirectListAddressing(const Addr& addr)
+        :
+            storedAddr_(addr)
+        {}
+
+        //- Move construct from addressing information
+        IndirectListAddressing(Addr&& addr)
+        :
+            storedAddr_(std::move(addr))
+        {}
+
+
+    // Member Functions
+
+        //- Const access to the addressing
+        const Addr& addressing() const
+        {
+            return storedAddr_;
+        }
+
+        //- Non-const access to the addressing
+        Addr& addressing()
+        {
+            return storedAddr_;
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.C
similarity index 72%
rename from src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C
rename to src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.C
index 68eb14802408c979a43d2bc51de75f15dbdb9259..1f41ea100549514202ce1a5d3c3fb4f61f2bcddb 100644
--- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.C
@@ -2,7 +2,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
@@ -25,23 +25,22 @@ License
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class T>
-inline Foam::label Foam::UIndirectList<T>::find
+template<class T, class Addr>
+Foam::label Foam::IndirectListBase<T, Addr>::find
 (
     const T& val,
     const label start
 ) const
 {
-    if (start >= 0)
+    const label len = addr_.size();
+
+    if (start >= 0 && len)
     {
         List_CONST_ACCESS(T, values_, vals);
-        List_CONST_ACCESS(label, addressing_, addr);
-
-        const label len = addressing_.size();
 
         for (label i = start; i < len; ++i)
         {
-            if (vals[addr[i]] == val)
+            if (vals[addr_[i]] == val)
             {
                 return i;
             }
@@ -52,29 +51,21 @@ inline Foam::label Foam::UIndirectList<T>::find
 }
 
 
-template<class T>
-inline Foam::label Foam::UIndirectList<T>::rfind
+template<class T, class Addr>
+Foam::label Foam::IndirectListBase<T, Addr>::rfind
 (
     const T& val,
     const label pos
 ) const
 {
     List_CONST_ACCESS(T, values_, vals);
-    List_CONST_ACCESS(label, addressing_, addr);
-
-    for
-    (
-        label i =
-        (
-            pos < 0
-          ? (addressing_.size()-1)
-          : min(pos, (addressing_.size()-1))
-        );
-        i >= 0;
-        --i
-    )
+
+    const label len1 = (addr_.size()-1);
+
+    // pos == -1 has same meaning as std::string::npos - search from end
+    for (label i = ((pos >= 0 && pos < len1) ? pos : len1); i >= 0; --i)
     {
-        if (vals[addr[i]] == val)
+        if (vals[addr_[i]] == val)
         {
             return i;
         }
diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H
similarity index 61%
rename from src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H
rename to src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H
index 335618019f14f2bd14f5bcd760fdc9fce7c5e135..680c818edb2200e52b39c6f1a35f1c912b1b4b72 100644
--- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H
@@ -24,24 +24,23 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::UIndirectList
+    Foam::IndirectListBase
 
 Description
-    A List with indirect addressing.
-
-    Like IndirectList but does not store addressing.
-
-    Note the const_cast of the list values. This is so we can use it both
-    on const and non-const lists. Alternative would be to have a const_
-    variant etc.
+    Base for lists with indirect addressing, templated on the list contents
+    type and the addressing type. Storage for both values and addressing
+    is held outside of the class.
 
 SourceFiles
-    UIndirectListI.H
+    IndirectListBase.H
+    IndirectListBase.C
+    IndirectListBaseI.H
+    IndirectListBaseIO.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef UIndirectList_H
-#define UIndirectList_H
+#ifndef IndirectListBase_H
+#define IndirectListBase_H
 
 #include "List.H"
 
@@ -50,28 +49,34 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declarations
-template<class T> class UIndirectList;
-
-// Common list types
-typedef UIndirectList<bool> boolUIndList;       //!< UIndirectList of bools
-typedef UIndirectList<label> labelUIndList;     //!< UIndirectList of labels
-
 /*---------------------------------------------------------------------------*\
-                        Class UIndirectList Declaration
+                      Class IndirectListBase Declaration
 \*---------------------------------------------------------------------------*/
 
-template<class T>
-class UIndirectList
+template<class T, class Addr>
+class IndirectListBase
 {
-    // Private data
+    // Private Data
 
+        //- The list values
         UList<T>& values_;
-        const labelUList& addressing_;
+
+        //- Reference to the addressing for the list values
+        const Addr& addr_;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Copy values The number of elements in the list
+        template<class ListType>
+        inline void copyList(const ListType& rhs);
+
 
 public:
 
-    // STL type definitions
+    // Type definitions (STL)
 
         //- Type of values the list contains.
         typedef T value_type;
@@ -100,43 +105,79 @@ public:
         //- Forward iterator with const access
         class const_iterator;
 
+        //- The addressing type (non-stl definition)
+        typedef Addr addressing_type;
+
 
     // Constructors
 
-        //- Copy construct from the values list and the addressing array
-        inline UIndirectList(const UList<T>& values, const labelUList& addr);
+        //- No null construct
+        IndirectListBase() = delete;
+
+        //- Store references to the values list and the addressing array
+        inline IndirectListBase(const UList<T>& values, const Addr& addr);
 
 
     // Member Functions
 
     // Access
 
-        //- Return the number of elements in the list
-        inline label size() const;
+        //- The number of elements in the list
+        inline label size() const
+        {
+            return addr_.size();
+        }
 
-        //- Return true if the list is empty (ie, size() is zero).
-        inline bool empty() const;
+        //- True if the list is empty (ie, size() is zero).
+        inline bool empty() const
+        {
+            return addr_.empty();
+        }
 
         //- True if all entries have identical values, and list is non-empty
         inline bool uniform() const;
 
-        //- Return the first element of the list.
-        inline T& first();
+        //- The first element of the list.
+        inline T& first()
+        {
+            return values_[addr_.first()];
+        }
 
-        //- Return first element of the list.
-        inline const T& first() const;
+        //- The first element of the list.
+        inline const T& first() const
+        {
+            return values_[addr_.first()];
+        }
 
-        //- Return the last element of the list.
-        inline T& last();
+        //- The last element of the list.
+        inline T& last()
+        {
+            return values_[addr_.last()];
+        }
 
-        //- Return the last element of the list.
-        inline const T& last() const;
+        //- The last element of the list.
+        inline const T& last() const
+        {
+            return values_[addr_.last()];
+        }
 
-        //- Return the complete list of values
-        inline const UList<T>& completeList() const;
+        //- The list of values (without addressing)
+        inline const UList<T>& values() const
+        {
+            return values_;
+        }
+
+        //- The list of values (without addressing)
+        inline UList<T>& values()
+        {
+            return values_;
+        }
 
-        //- Return the list addressing
-        inline const List<label>& addressing() const;
+        //- The addressing used for the list
+        inline const Addr& addressing() const
+        {
+            return addr_;
+        }
 
 
     // Search
@@ -162,26 +203,39 @@ public:
         //- Return the addressed elements as a List
         inline List<T> operator()() const;
 
-        //- Return non-const access to an element
+        //- Non-const access to an element in the list
         inline T& operator[](const label i);
 
-        //- Return const access to an element
+        //- Const access to an element in the list
         inline const T& operator[](const label i) const;
 
-        //- Copy assignment from a list of the addressed elements
+        //- Assign all addressed elements to the given value
+        inline void operator=(const T& val);
+
+        //- Assignment of all entries to zero
+        inline void operator=(const zero);
+
+        //- Deep copy values from a list of the addressed elements
+        //  Fatal if list sizes are not identical
         inline void operator=(const UList<T>& rhs);
 
-        //- Copy assignment from a indirect list of the addressed elements
-        inline void operator=(const UIndirectList<T>& rhs);
+        //- Deep copy values from a list of the addressed elements
+        //  Fatal if list sizes are not identical
+        inline void operator=(const IndirectListBase<T, Addr>& rhs);
 
-        //- Assignment of all entries to the given value
-        inline void operator=(const T& val);
+        //- Deep copy values from a list of the addressed elements
+        //  Fatal if list sizes are not identical
+        template<class AnyAddr>
+        inline void operator=(const IndirectListBase<T, AnyAddr>& rhs);
+
+
+    // Iterators
 
-        //- An iterator for an indirect list
+        //- A non-const iterator for an indirect list
         class iterator
         {
             typename UList<T>::pointer data_;
-            labelUList::const_iterator base_;
+            typename addressing_type::const_iterator iter_;
 
         public:
 
@@ -194,32 +248,32 @@ public:
             iterator
             (
                 UList<T>& list,
-                labelUList::const_iterator baseIter
+                typename addressing_type::const_iterator baseIter
             )
             :
                 data_(list.begin()),
-                base_(baseIter)
+                iter_(baseIter)
             {}
 
             reference operator*() const
             {
-                return data_[*base_];
+                return data_[*iter_];
             }
 
             iterator& operator++()
             {
-                ++base_;
+                ++iter_;
                 return *this;
             }
 
             bool operator==(iterator& rhs) const
             {
-                return base_ == rhs.base_;
+                return iter_ == rhs.iter_;
             }
 
             bool operator!=(iterator& rhs) const
             {
-                return (base_ != rhs.base_);
+                return (iter_ != rhs.iter_);
             }
         };
 
@@ -228,7 +282,7 @@ public:
         class const_iterator
         {
             typename UList<T>::const_pointer data_;
-            labelUList::const_iterator base_;
+            typename addressing_type::const_iterator iter_;
 
         public:
 
@@ -241,63 +295,63 @@ public:
             const_iterator
             (
                 const UList<T>& list,
-                labelUList::const_iterator baseIter
+                typename addressing_type::const_iterator baseIter
             )
             :
                 data_(list.begin()),
-                base_(baseIter)
+                iter_(baseIter)
             {}
 
             reference operator*() const
             {
-                return data_[*base_];
+                return data_[*iter_];
             }
 
             const_iterator& operator++()
             {
-                ++base_;
+                ++iter_;
                 return *this;
             }
 
             bool operator==(const_iterator& rhs) const
             {
-                return base_ == rhs.base_;
+                return iter_ == rhs.iter_;
             }
 
             bool operator!=(const_iterator& rhs) const
             {
-                return base_ != rhs.base_;
+                return iter_ != rhs.iter_;
             }
         };
 
 
-    // iterator (non-const)
+    // Iterator (non-const)
 
         //- Return an iterator at begin of list
         inline iterator begin()
         {
-            return iterator(values_, addressing_.cbegin());
+            return iterator(values_, addr_.cbegin());
         }
 
         //- Return an iterator at end of list
         inline iterator end()
         {
-            return iterator(values_, addressing_.cend());
+            return iterator(values_, addr_.cend());
         }
 
 
-    // iterator (const)
+    // Iterator (const)
 
         //- Return a const_iterator at begin of list
         inline const_iterator cbegin() const
         {
-            return const_iterator(values_, addressing_.cbegin());
+            return const_iterator(values_, addr_.cbegin());
         }
 
         //- Return a const_iterator at end of list
         inline const_iterator cend() const
         {
-            return const_iterator(values_, addressing_.cend());
+            return const_iterator(values_, addr_.cend());
         }
 
         //- Return a const_iterator at end of list
@@ -325,8 +379,8 @@ public:
 
 //- Write List to Ostream, as per UList::writeList() with default length.
 //  The default short-length is given by Detail::ListPolicy::short_length
-template<class T>
-Ostream& operator<<(Ostream& os, const UIndirectList<T>& list)
+template<class T, class Addr>
+Ostream& operator<<(Ostream& os, const IndirectListBase<T, Addr>& list)
 {
     return list.writeList(os, Detail::ListPolicy::short_length<T>::value);
 }
@@ -338,11 +392,11 @@ Ostream& operator<<(Ostream& os, const UIndirectList<T>& list)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "UIndirectListI.H"
+#include "IndirectListBaseI.H"
 
 #ifdef NoRepository
-    #include "UIndirectList.C"
-    #include "UIndirectListIO.C"
+    #include "IndirectListBase.C"
+    #include "IndirectListBaseIO.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H
similarity index 53%
rename from src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H
rename to src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H
index f297a588012f7602a56978ebbad7371b285e3ee6..e7888c63f2a967ce1b3d7835cf29a46d01e67b60 100644
--- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H
@@ -25,40 +25,48 @@ License
 
 \*---------------------------------------------------------------------------*/
 
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<class T, class Addr>
+template<class ListType>
+inline void Foam::IndirectListBase<T, Addr>::copyList(const ListType& rhs)
+{
+    const label len = addr_.size();
+
+    if (len != rhs.size())
+    {
+        FatalErrorInFunction
+            << "Addressing and list of addressed elements "
+               "have different sizes: " << len << " " << rhs.size()
+            << abort(FatalError);
+    }
+
+    // Or std::copy(rhs.cbegin(), rhs.cend(), this->begin());
+    for (label i = 0; i < len; ++i)
+    {
+        values_[addr_[i]] = rhs[i];
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-template<class T>
-inline Foam::UIndirectList<T>::UIndirectList
+template<class T, class Addr>
+inline Foam::IndirectListBase<T, Addr>::IndirectListBase
 (
     const UList<T>& values,
-    const labelUList& addr
+    const Addr& addr
 )
 :
     values_(const_cast<UList<T>&>(values)),
-    addressing_(addr)
+    addr_(addr)
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class T>
-inline Foam::label Foam::UIndirectList<T>::size() const
-{
-    return addressing_.size();
-}
-
-
-template<class T>
-inline bool Foam::UIndirectList<T>::empty() const
-{
-    return addressing_.empty();
-}
-
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-template<class T>
-inline bool Foam::UIndirectList<T>::uniform() const
+template<class T, class Addr>
+inline bool Foam::IndirectListBase<T, Addr>::uniform() const
 {
     const label len = this->size();
 
@@ -81,50 +89,8 @@ inline bool Foam::UIndirectList<T>::uniform() const
 }
 
 
-template<class T>
-inline T& Foam::UIndirectList<T>::first()
-{
-    return values_[addressing_.first()];
-}
-
-
-template<class T>
-inline const T& Foam::UIndirectList<T>::first() const
-{
-    return values_[addressing_.first()];
-}
-
-
-template<class T>
-inline T& Foam::UIndirectList<T>::last()
-{
-    return values_[addressing_.last()];
-}
-
-
-template<class T>
-inline const T& Foam::UIndirectList<T>::last() const
-{
-    return values_[addressing_.last()];
-}
-
-
-template<class T>
-inline const Foam::UList<T>& Foam::UIndirectList<T>::completeList() const
-{
-    return values_;
-}
-
-
-template<class T>
-inline const Foam::List<Foam::label>& Foam::UIndirectList<T>::addressing() const
-{
-    return addressing_;
-}
-
-
-template<class T>
-inline bool Foam::UIndirectList<T>::found
+template<class T, class Addr>
+inline bool Foam::IndirectListBase<T, Addr>::found
 (
     const T& val,
     const label pos
@@ -136,81 +102,89 @@ inline bool Foam::UIndirectList<T>::found
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-template<class T>
-inline Foam::List<T> Foam::UIndirectList<T>::operator()() const
+template<class T, class Addr>
+inline Foam::List<T>
+Foam::IndirectListBase<T, Addr>::operator()() const
 {
-    List<T> result(size());
+    const label len = addr_.size();
 
-    forAll(*this, i)
+    List<T> result(len);
+
+    // Or std::copy(this->cbegin(), this->cend(), result.begin());
+    for (label i = 0; i < len; ++i)
     {
-        result[i] = operator[](i);
+        result[i] = values_[addr_[i]];
     }
 
     return result;
 }
 
 
-template<class T>
-inline T& Foam::UIndirectList<T>::operator[](const label i)
+template<class T, class Addr>
+inline T& Foam::IndirectListBase<T, Addr>::operator[](const label i)
 {
-    return values_[addressing_[i]];
+    return values_[addr_[i]];
 }
 
 
-template<class T>
-inline const T& Foam::UIndirectList<T>::operator[](const label i) const
+template<class T, class Addr>
+inline const T&
+Foam::IndirectListBase<T, Addr>::operator[](const label i) const
 {
-    return values_[addressing_[i]];
+    return values_[addr_[i]];
 }
 
 
-template<class T>
-inline void Foam::UIndirectList<T>::operator=(const UList<T>& rhs)
+template<class T, class Addr>
+inline void Foam::IndirectListBase<T, Addr>::operator=(const T& val)
 {
-    const label len = addressing_.size();
-
-    if (len != rhs.size())
+    // Or std::fill(this->begin(), this->end(), val);
+    for (const label idx : addr_)
     {
-        FatalErrorInFunction
-            << "Addressing and list of addressed elements "
-               "have different sizes: " << len << " " << rhs.size()
-            << abort(FatalError);
+        values_[idx] = val;
     }
+}
 
-    for (label i = 0; i < len; ++i)
+
+template<class T, class Addr>
+inline void Foam::IndirectListBase<T, Addr>::operator=(const zero)
+{
+    // Or std::fill(this->begin(), this->end(), Zero);
+    for (const label idx : addr_)
     {
-        values_[addressing_[i]] = rhs[i];
+        values_[idx] = Zero;
     }
 }
 
 
-template<class T>
-inline void Foam::UIndirectList<T>::operator=(const UIndirectList<T>& rhs)
+template<class T, class Addr>
+inline void Foam::IndirectListBase<T, Addr>::operator=
+(
+    const UList<T>& rhs
+)
 {
-    const label len = addressing_.size();
+    this->copyList(rhs);
+}
 
-    if (len != rhs.size())
-    {
-        FatalErrorInFunction
-            << "Addressing and list of addressed elements "
-               "have different sizes: " << len << " " << rhs.size()
-            << abort(FatalError);
-    }
 
-    for (label i = 0; i < len; ++i)
-    {
-        values_[addressing_[i]] = rhs[i];
-    }
+template<class T, class Addr>
+inline void Foam::IndirectListBase<T, Addr>::operator=
+(
+    const IndirectListBase<T, Addr>& rhs
+)
+{
+    this->copyList(rhs);
 }
 
 
-template<class T>
-inline void Foam::UIndirectList<T>::operator=(const T& val)
+template<class T, class Addr>
+template<class AnyAddr>
+inline void Foam::IndirectListBase<T, Addr>::operator=
+(
+    const IndirectListBase<T, AnyAddr>& rhs
+)
 {
-    for (const label idx : addressing_)
-    {
-        values_[idx] = val;
-    }
+    this->copyList(rhs);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseIO.C
similarity index 95%
rename from src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C
rename to src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseIO.C
index bb434711c24095c70d3bdb6a05cb1aa015d21dcb..9a4da1c5a50cee52a3798633b0fec16ac3644367 100644
--- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C
+++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseIO.C
@@ -25,21 +25,21 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "UIndirectList.H"
+#include "IndirectListBase.H"
 #include "Ostream.H"
 #include "token.H"
 #include "contiguous.H"
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
-template<class T>
-Foam::Ostream& Foam::UIndirectList<T>::writeList
+template<class T, class Addr>
+Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
 (
     Ostream& os,
     const label shortLen
 ) const
 {
-    const UIndirectList<T>& list = *this;
+    const IndirectListBase<T, Addr>& list = *this;
 
     const label len = list.size();
 
diff --git a/src/OpenFOAM/containers/IndirectLists/SliceList/SliceList.H b/src/OpenFOAM/containers/IndirectLists/SliceList/SliceList.H
new file mode 100644
index 0000000000000000000000000000000000000000..bb7b2913539299f52026dfddb348316660273d76
--- /dev/null
+++ b/src/OpenFOAM/containers/IndirectLists/SliceList/SliceList.H
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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/>.
+
+Class
+    Foam::SliceList
+
+Description
+    A List with indirect slice addressing.
+
+SourceFiles
+    SliceList.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SliceList_H
+#define SliceList_H
+
+#include "IndirectListAddressing.H"
+#include "IndirectListBase.H"
+#include "sliceRange.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class SliceList Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class T>
+class SliceList
+:
+    private IndirectListAddressing<sliceRange>,
+    public IndirectListBase<T, sliceRange>
+{
+public:
+
+    // Constructors
+
+        //- Copy construct from values list and slicing
+        SliceList(const UList<T>& values, const sliceRange& addr)
+        :
+            IndirectListAddressing<sliceRange>(addr),
+            IndirectListBase<T, sliceRange>
+            (
+                values,
+                IndirectListAddressing<sliceRange>::addressing()
+            )
+        {}
+
+
+    // Member Functions
+
+        //- The list addressing
+        using IndirectListAddressing::addressing;
+
+
+    // Member Operators
+
+        //- Use standard assignment operations
+        using IndirectListBase<T, sliceRange>::operator=;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/IndirectLists/SortList/SortList.H b/src/OpenFOAM/containers/IndirectLists/SortList/SortList.H
new file mode 100644
index 0000000000000000000000000000000000000000..132bc7b45220fdaf26402a0b7dea5d5252e0441a
--- /dev/null
+++ b/src/OpenFOAM/containers/IndirectLists/SortList/SortList.H
@@ -0,0 +1,118 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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/>.
+
+Class
+    Foam::SortList
+
+Description
+    An indirect list with addressing based on sorting.
+    The list is sorted upon construction or when explicitly requested.
+
+    Uses the std::stable_sort() algorithm.
+
+SourceFiles
+    SortListI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SortList_H
+#define SortList_H
+
+#include "IndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class SortList Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class T>
+class SortList
+:
+    public IndirectList<T>
+{
+public:
+
+    // Constructors
+
+        //- Shallow copy values list reference, sort immediately
+        inline explicit SortList(const UList<T>& values);
+
+        //- Shallow copy values list reference,
+        //- sort with given \b value comparator.
+        //  \note The comparator is not stored in the class.
+        template<class Compare>
+        inline SortList(const UList<T>& values, const Compare& comp);
+
+
+    // Member Functions
+
+        //- Return the list of sorted indices. Updated every sort
+        //  Same as addressing()
+        inline const labelUList& indices() const;
+
+        //- Return the list of indices. Updated every sort
+        //  Same as addressing()
+        inline labelList& indices();
+
+        //- Reverse the indices
+        inline void reverse();
+
+        //- Reset list indices to identity
+        inline void reset();
+
+        //- Sort the list using the given \b value comparator
+        template<class Compare>
+        inline void sort(const Compare& comp);
+
+        //- Forward (stable) sort the list.
+        //- Functionally identical to sort with std::less\<T\>()
+        inline void sort();
+
+        //- Reverse (stable) sort the list
+        inline void reverseSort();
+
+
+    // Member Operators
+
+        //- Assignment operators
+        using IndirectList<T>::operator=;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "SortListI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/IndirectLists/SortList/SortListI.H b/src/OpenFOAM/containers/IndirectLists/SortList/SortListI.H
new file mode 100644
index 0000000000000000000000000000000000000000..5f3dcd8aafc9ac519ac26359bb334c93836a505f
--- /dev/null
+++ b/src/OpenFOAM/containers/IndirectLists/SortList/SortListI.H
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "ListOps.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class T>
+inline Foam::SortList<T>::SortList(const UList<T>& values)
+:
+    IndirectList<T>(values, identity(values.size()))
+{
+    sort();
+}
+
+
+template<class T>
+template<class Compare>
+inline Foam::SortList<T>::SortList(const UList<T>& values, const Compare& comp)
+:
+    IndirectList<T>(values, identity(values.size()))
+{
+    sort<Compare>(comp);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class T>
+inline const Foam::labelUList& Foam::SortList<T>::indices() const
+{
+    return this->addressing();
+}
+
+
+template<class T>
+inline Foam::labelList& Foam::SortList<T>::indices()
+{
+    return this->addressing();
+}
+
+
+template<class T>
+inline void Foam::SortList<T>::reverse()
+{
+    Foam::reverse(this->indices());
+}
+
+
+template<class T>
+inline void Foam::SortList<T>::reset()
+{
+    const label len = this->values().size();
+
+    labelList& addr = this->indices();
+    addr.resize(len);
+    ListOps::identity(addr);
+}
+
+
+template<class T>
+template<class Compare>
+inline void Foam::SortList<T>::sort(const Compare& comp)
+{
+    UList<T>& vals = this->values();
+    labelList& addr = this->indices();
+
+    if (addr.size() != vals.size())
+    {
+        addr.resize(vals.size());
+        ListOps::identity(addr);
+    }
+
+    std::stable_sort
+    (
+        addr.begin(),
+        addr.end(),
+        [&](label a, label b) -> bool { return comp(vals[a], vals[b]); }
+    );
+}
+
+
+template<class T>
+inline void Foam::SortList<T>::sort()
+{
+    UList<T>& vals = this->values();
+    labelList& addr = this->indices();
+
+    if (addr.size() != vals.size())
+    {
+        addr.resize(vals.size());
+        ListOps::identity(addr);
+    }
+
+    // Forward sort of indices
+    std::stable_sort
+    (
+        addr.begin(),
+        addr.end(),
+        [&](label a, label b) -> bool { return vals[a] < vals[b]; }
+    );
+}
+
+
+template<class T>
+inline void Foam::SortList<T>::reverseSort()
+{
+    UList<T>& vals = this->values();
+    labelList& addr = this->indices();
+
+    if (addr.size() != vals.size())
+    {
+        addr.resize(vals.size());
+        ListOps::identity(addr);
+    }
+
+    // Reverse sort of indices
+    std::stable_sort
+    (
+        addr.begin(),
+        addr.end(),
+        [&](label a, label b) -> bool { return vals[b] < vals[a]; }
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/IndirectLists/UIndirectList/UIndirectList.H b/src/OpenFOAM/containers/IndirectLists/UIndirectList/UIndirectList.H
new file mode 100644
index 0000000000000000000000000000000000000000..e81ffb52d27a1cdf3520f78d891f0a6b29759294
--- /dev/null
+++ b/src/OpenFOAM/containers/IndirectLists/UIndirectList/UIndirectList.H
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010, 2017-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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/>.
+
+Class
+    Foam::UIndirectList
+
+Description
+    A List with indirect addressing.
+
+    Like IndirectList but does not store addressing.
+
+    Note the const_cast of the list values. This is so we can use it both
+    on const and non-const lists. Alternative would be to have a const_
+    variant etc.
+
+SourceFiles
+    UIndirectListI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UIndirectList_H
+#define UIndirectList_H
+
+#include "List.H"
+#include "IndirectListBase.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+template<class T> class UIndirectList;
+
+// Common list types
+typedef UIndirectList<bool> boolUIndList;       //!< UIndirectList of bools
+typedef UIndirectList<label> labelUIndList;     //!< UIndirectList of labels
+
+/*---------------------------------------------------------------------------*\
+                        Class UIndirectList Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class T>
+class UIndirectList
+:
+    public IndirectListBase<T, labelUList>
+{
+public:
+
+    // Constructors
+
+        //- Shallow copy values and addressing arrays
+        UIndirectList(const UList<T>& values, const labelUList& addr)
+        :
+            IndirectListBase<T, labelUList>(values, addr)
+        {}
+
+        //- Copy construct from UIndirectList with
+        //- shallow copy of values and addressing arrays
+        UIndirectList(const UIndirectList<T>& list)
+        :
+            UIndirectList<T>(list.values(), list.addressing())
+        {}
+
+
+    // Member Operators
+
+        //- Use standard assignment operations
+        using IndirectListBase<T, labelUList>::operator=;
+
+        //- Deep copy values, Fatal if list sizes are not identical
+        void operator=(const UIndirectList<T>& rhs)
+        {
+            this->copyList(rhs);
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index bfbb1c3c6326b70aa7c016affc404f759ab9e48e..d5045fb1190cf723d3c7627a900c158148ec43ab 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -151,8 +151,9 @@ public:
         //- Construct from an initializer list. Size set to list size.
         inline explicit DynamicList(std::initializer_list<T> lst);
 
-        //- Construct from UIndirectList. Size set to UIndirectList size.
-        inline explicit DynamicList(const UIndirectList<T>& lst);
+        //- Construct from IndirectList. Size set to addressing size.
+        template<class Addr>
+        inline explicit DynamicList(const IndirectListBase<T, Addr>& lst);
 
         //- Move construct.
         inline DynamicList(DynamicList<T, SizeMin>&& lst);
@@ -259,9 +260,10 @@ public:
             inline DynamicList<T, SizeMin>&
             append(std::initializer_list<T> lst);
 
-            //- Append a UIndirectList at the end of this list
+            //- Append a IndirectList at the end of this list
+            template<class Addr>
             inline DynamicList<T, SizeMin>&
-            append(const UIndirectList<T>& lst);
+            append(const IndirectListBase<T, Addr>& lst);
 
             //- Move append list
             inline DynamicList<T, SizeMin>& append(List<T>&& lst);
@@ -338,8 +340,9 @@ public:
             //- Assignment from initializer list
             inline void operator=(std::initializer_list<T> lst);
 
-            //- Assignment to UIndirectList
-            inline void operator=(const UIndirectList<T>& lst);
+            //- Assignment from IndirectList
+            template<class Addr>
+            inline void operator=(const IndirectListBase<T, Addr>& lst);
 
             //- Move assignment
             inline void operator=(List<T>&& lst);
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index cceeb79f8fe38e64d6a33e493f2a5f72b9d29178..b5d1a9ca0e9cddba2859179c104c7053a24d088a 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -169,9 +169,10 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
 
 
 template<class T, int SizeMin>
+template<class Addr>
 inline Foam::DynamicList<T, SizeMin>::DynamicList
 (
-    const UIndirectList<T>& lst
+    const IndirectListBase<T, Addr>& lst
 )
 :
     List<T>(lst),
@@ -555,10 +556,11 @@ Foam::DynamicList<T, SizeMin>::append
 
 
 template<class T, int SizeMin>
+template<class Addr>
 inline Foam::DynamicList<T, SizeMin>&
 Foam::DynamicList<T, SizeMin>::append
 (
-    const UIndirectList<T>& lst
+    const IndirectListBase<T, Addr>& lst
 )
 {
     label idx = List<T>::size();
@@ -827,9 +829,10 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
 
 
 template<class T, int SizeMin>
+template<class Addr>
 inline void Foam::DynamicList<T, SizeMin>::operator=
 (
-    const UIndirectList<T>& lst
+    const IndirectListBase<T, Addr>& lst
 )
 {
     assignDynList(lst);
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index ffaf37ebaa456ef3f3d42278d4bc463f4bdc50be..5e2c1b575021ed666b1c1945c76bf1c71687f691 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.C
@@ -30,8 +30,6 @@ License
 #include "FixedList.H"
 #include "PtrList.H"
 #include "SLList.H"
-#include "IndirectList.H"
-#include "UIndirectList.H"
 #include "contiguous.H"
 #include <utility>
 
@@ -330,7 +328,8 @@ Foam::List<T>::List(const SLList<T>& list)
 
 
 template<class T>
-Foam::List<T>::List(const UIndirectList<T>& list)
+template<class Addr>
+Foam::List<T>::List(const IndirectListBase<T, Addr>& list)
 :
     UList<T>(nullptr, list.size())
 {
@@ -511,7 +510,8 @@ void Foam::List<T>::operator=(const SLList<T>& list)
 
 
 template<class T>
-void Foam::List<T>::operator=(const UIndirectList<T>& list)
+template<class Addr>
+void Foam::List<T>::operator=(const IndirectListBase<T, Addr>& list)
 {
     const label len = list.size();
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index d2996b9cd5f2977df7a32d7080862af2e4636c25..425a853498e2cb81690766966a8029e50ce06944 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.H
@@ -65,8 +65,7 @@ template<class T, int SizeMin> class DynamicList;
 
 template<class T> class PtrList;
 template<class T> class SortableList;
-template<class T> class IndirectList;
-template<class T> class UIndirectList;
+template<class T, class Addr> class IndirectListBase;
 
 template<class T> Istream& operator>>(Istream& is, List<T>& list);
 
@@ -169,8 +168,9 @@ public:
         //- Construct as copy of SLList<T>
         explicit List(const SLList<T>& list);
 
-        //- Construct as copy of UIndirectList<T>
-        explicit List(const UIndirectList<T>& list);
+        //- Construct as copy of IndirectList contents
+        template<class Addr>
+        explicit List(const IndirectListBase<T, Addr>& list);
 
         //- Construct from an initializer list
         List(std::initializer_list<T> list);
@@ -234,8 +234,9 @@ public:
             //- Append a List to the end of this list
             inline void append(const UList<T>& list);
 
-            //- Append a UIndirectList at the end of this list
-            inline void append(const UIndirectList<T>& list);
+            //- Append IndirectList contents at the end of this list
+            template<class Addr>
+            inline void append(const IndirectListBase<T, Addr>& list);
 
             //- Transfer the contents of the argument List into this list
             //- and annul the argument list
@@ -266,8 +267,9 @@ public:
         //- Assignment to SLList operator. Takes linear time
         void operator=(const SLList<T>& list);
 
-        //- Assignment to UIndirectList operator. Takes linear time
-        void operator=(const UIndirectList<T>& list);
+        //- Assignment from IndirectList. Takes linear time
+        template<class Addr>
+        void operator=(const IndirectListBase<T, Addr>& list);
 
         //- Assignment to an initializer list
         void operator=(std::initializer_list<T> list);
diff --git a/src/OpenFOAM/containers/Lists/List/ListI.H b/src/OpenFOAM/containers/Lists/List/ListI.H
index 29c84d312635ef2dec859eb2bc0a94a271a1a12d..1eeebd90fea9b87cab224e16530f9bf10a770a0b 100644
--- a/src/OpenFOAM/containers/Lists/List/ListI.H
+++ b/src/OpenFOAM/containers/Lists/List/ListI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -208,7 +208,8 @@ inline void Foam::List<T>::append(const UList<T>& list)
 
 
 template<class T>
-inline void Foam::List<T>::append(const UIndirectList<T>& list)
+template<class Addr>
+inline void Foam::List<T>::append(const IndirectListBase<T, Addr>& list)
 {
     label idx = this->size();
     const label n = list.size();
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
index f9649bace9d02ca86a9b6ae775ecc38e5402b371..362fa047743c86a52ce63f6d342002530c8d1a58 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
@@ -75,7 +75,7 @@ inline Foam::SortableList<T>::SortableList(SortableList<T>&& lst)
 
 
 template<class T>
-Foam::SortableList<T>::SortableList(const UList<T>& values)
+inline Foam::SortableList<T>::SortableList(const UList<T>& values)
 :
     List<T>(values)
 {
@@ -84,7 +84,7 @@ Foam::SortableList<T>::SortableList(const UList<T>& values)
 
 
 template<class T>
-Foam::SortableList<T>::SortableList(List<T>&& values)
+inline Foam::SortableList<T>::SortableList(List<T>&& values)
 :
     List<T>(std::move(values))
 {
@@ -107,7 +107,7 @@ inline Foam::SortableList<T>::SortableList
 
 
 template<class T>
-Foam::SortableList<T>::SortableList(std::initializer_list<T> values)
+inline Foam::SortableList<T>::SortableList(std::initializer_list<T> values)
 :
     List<T>(values)
 {
@@ -138,8 +138,8 @@ void Foam::SortableList<T>::sort()
 {
     Foam::sortedOrder(*this, indices_);
 
-    List<T> lst(*this, indices_); // Copy with indices for mapping
-    List<T>::transfer(lst);
+    List<T> list(*this, indices_); // Copy with indices for mapping
+    List<T>::transfer(list);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
index d8adb1568818d8a1fb8eda771cf61ae9348b5d92..1146f9d78e2231f64499c5ab1edf248be6ac5ce8 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
@@ -30,7 +30,7 @@ Description
     A list that is sorted upon construction or when explicitly requested
     with the sort() method.
 
-    Uses the Foam::stableSort() algorithm.
+    Uses the std::stable_sort() algorithm.
 
 SourceFiles
     SortableList.C
@@ -88,10 +88,10 @@ public:
         inline SortableList(SortableList<T>&& lst);
 
         //- Copy construct from UList, sorting immediately
-        explicit SortableList(const UList<T>& values);
+        explicit inline SortableList(const UList<T>& values);
 
         //- Move construct from List, sorting immediately
-        SortableList(List<T>&& values);
+        inline SortableList(List<T>&& values);
 
         //- Construct given begin/end iterators.
         //  Uses std::distance to determine the size.
@@ -99,7 +99,7 @@ public:
         inline SortableList(InputIterator begIter, InputIterator endIter);
 
         //- Construct from an initializer list, sorting immediately
-        SortableList(std::initializer_list<T> values);
+        inline SortableList(std::initializer_list<T> values);
 
 
     // Member Functions
@@ -122,11 +122,12 @@ public:
         //- Clear the indices and return a reference to the underlying List
         List<T>& shrink();
 
-        //- (stable) sort the list (if changed after construction time).
+        //- Forward (stable) sort the list (if changed after construction).
         //  Resizes the indices as required
         void sort();
 
         //- Reverse (stable) sort the list
+        //  Resizes the indices as required
         void reverseSort();
 
         //- Swap content with another SortableList in constant time
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
index dea1dda867f757c9483f3c7a1d6614f3ee48a33f..1313623a6eecd1adbaf7f152e7c9748a981c729c 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2009-2011, 2016-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2009-2011, 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -124,8 +124,9 @@ public:
         //  Also constructs from DynamicField with different sizing parameters.
         inline explicit DynamicField(const UList<T>& list);
 
-        //- Copy construct from UIndirectList
-        inline explicit DynamicField(const UIndirectList<T>& list);
+        //- Copy construct from IndirectList
+        template<class Addr>
+        inline explicit DynamicField(const IndirectListBase<T, Addr>& list);
 
         //- Move construct from List contents
         inline explicit DynamicField(List<T>&& content);
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
index 5356512c0f4371db3097a2645373ec7779049223..b2d372638b904fa84e16ee2527f1f96fe4a599f0 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2009-2010, 2016-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2009-2010, 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -132,9 +132,10 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
 
 
 template<class T, int SizeMin>
+template<class Addr>
 inline Foam::DynamicField<T, SizeMin>::DynamicField
 (
-    const UIndirectList<T>& list
+    const IndirectListBase<T, Addr>& list
 )
 :
     Field<T>(list),
diff --git a/src/OpenFOAM/fields/Fields/Field/Field.H b/src/OpenFOAM/fields/Fields/Field/Field.H
index 8a2926922cfbabf092c98663738199d4a0de0acc..c7ad8907e1dfad91a55f2ef12e57ea3908140e0f 100644
--- a/src/OpenFOAM/fields/Fields/Field/Field.H
+++ b/src/OpenFOAM/fields/Fields/Field/Field.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2015-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2010, 2015-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -120,8 +120,9 @@ public:
         //- Copy construct from UList\<Type\>
         inline explicit Field(const UList<Type>& list);
 
-        //- Copy construct from UIndirectList\<Type\>
-        inline explicit Field(const UIndirectList<Type>& list);
+        //- Copy construct from IndirectList
+        template<class Addr>
+        inline explicit Field(const IndirectListBase<Type, Addr>& list);
 
         //- Move construct from Field
         inline Field(Field<Type>&& fld);
diff --git a/src/OpenFOAM/fields/Fields/Field/FieldI.H b/src/OpenFOAM/fields/Fields/Field/FieldI.H
index f6a9ed15cf829b6ffae3063ea587569fecfb30a5..235cdadaafb7a51cfe6b5c0bf48ba0d2a3400c95 100644
--- a/src/OpenFOAM/fields/Fields/Field/FieldI.H
+++ b/src/OpenFOAM/fields/Fields/Field/FieldI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -68,7 +68,8 @@ inline Foam::Field<Type>::Field(const UList<Type>& list)
 
 
 template<class Type>
-inline Foam::Field<Type>::Field(const UIndirectList<Type>& list)
+template<class Addr>
+inline Foam::Field<Type>::Field(const IndirectListBase<Type, Addr>& list)
 :
     List<Type>(list)
 {}
diff --git a/src/conversion/ccm/reader/ccmReaderMesh.C b/src/conversion/ccm/reader/ccmReaderMesh.C
index 1a1616c50f070e8cdad34469c3a2884300919242..77899f7db870960c34487f22239c050718c5e711 100644
--- a/src/conversion/ccm/reader/ccmReaderMesh.C
+++ b/src/conversion/ccm/reader/ccmReaderMesh.C
@@ -555,7 +555,7 @@ void Foam::ccm::reader::readCells
             }
         }
 
-        ccmLookupOrder.resetAddressing(std::move(addr));
+        ccmLookupOrder.addressing() = std::move(addr);
     }
 
 
diff --git a/src/meshTools/output/foamVtkWriteCellSetFaces.C b/src/meshTools/output/foamVtkWriteCellSetFaces.C
index b6323a3e3e096377383852d37eded1af47b332a7..fccd91102766772bd5bb89c88540efcdf0536092 100644
--- a/src/meshTools/output/foamVtkWriteCellSetFaces.C
+++ b/src/meshTools/output/foamVtkWriteCellSetFaces.C
@@ -2,7 +2,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
@@ -84,7 +84,7 @@ bool Foam::vtk::writeCellSetFaces
     }
 
     // Use these faces
-    faces.resetAddressing(cellFaces.sortedToc());
+    faces.addressing() = cellFaces.sortedToc();
 
     //-------------------------------------------------------------------------
 
diff --git a/src/meshTools/output/foamVtkWriteFaceSet.C b/src/meshTools/output/foamVtkWriteFaceSet.C
index 7cc75e04fcfe72d98216befed37d30e76725cdfc..6cb13de0d43ca9048b9cfa28cda141bf4083e74c 100644
--- a/src/meshTools/output/foamVtkWriteFaceSet.C
+++ b/src/meshTools/output/foamVtkWriteFaceSet.C
@@ -2,7 +2,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
@@ -50,7 +50,7 @@ bool Foam::vtk::writeFaceSet
     FaceListType& faces = pp;
 
     // Use the faces from faceSet
-    faces.resetAddressing(set.sortedToc());
+    faces.addressing() = set.sortedToc();
 
     //-------------------------------------------------------------------------