diff --git a/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.h b/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.h
index 40b645f432ff9193971f62bd96b2f0f14cd6c3db..16be8f3572e18159334c02615d91b964b7baba91 100644
--- a/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.h
+++ b/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.h
@@ -479,6 +479,13 @@ public:
   size_t trim (const std::vector<key_query_type>& keys);
 
 
+  /**
+   * @brief Remove all entries in the container.
+   *        Mostly for testing --- should not normally be used.
+   */
+  void clear();
+
+
   /**
    * @brief Return the current number of elements in the map.
    */
diff --git a/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.icc b/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.icc
index c1f76ca0169a4018b7a4a3906ccd42277077950b..39d06f5148bbf3a9caac1b2eb7ee2733fcedbde9 100644
--- a/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.icc
+++ b/Control/CxxUtils/CxxUtils/ConcurrentRangeMap.icc
@@ -486,7 +486,7 @@ T_CONCURRENTRANGEMAP
 void
 CONCURRENTRANGEMAP::updateRanges (std::function<void (RANGE&)> rangeUpdater,
                                   const typename Updater_t::Context_t& ctx
-                                   /*= Updater_t::defaultContext()*/)
+                                  /*= Updater_t::defaultContext()*/)
 {
   lock_t lock (m_mutex);
 
@@ -609,6 +609,38 @@ CONCURRENTRANGEMAP::trim (const std::vector<key_query_type>& keys)
 }
 
 
+/**
+ * @brief Remove all entries in the container.
+ *        Mostly for testing --- should not normally be used.
+ */
+T_CONCURRENTRANGEMAP
+void CONCURRENTRANGEMAP::clear()
+{
+  lock_t lock (m_mutex);
+
+  // Don't do anything if the container's already empty.
+  value_type* last = m_last;
+  if (last == nullptr) return;
+
+  value_type* begin = m_begin; 
+
+  while (begin != last) {
+    mapped_type todel = begin->second;
+    ++begin;
+    m_begin = begin;
+    m_payloadDeleter->discard (todel);
+  }
+
+  // Now have one element left.  Be sure to clean m_begin first.
+  mapped_type todel = begin->second;
+  ++begin;
+  m_begin = nullptr;
+  m_last = nullptr;
+  m_begin = begin;
+  m_payloadDeleter->discard (todel);
+}
+
+
 /**
  * @brief Return the current number of elements in the map.
  */
diff --git a/Control/CxxUtils/share/ConcurrentRangeMap_test.ref b/Control/CxxUtils/share/ConcurrentRangeMap_test.ref
index 11ca5cbbb100bb0f0d72a26771ffcff60b29f8c9..b3de8bf1011e209cc76e893c3f16d53147e78c4d 100644
--- a/Control/CxxUtils/share/ConcurrentRangeMap_test.ref
+++ b/Control/CxxUtils/share/ConcurrentRangeMap_test.ref
@@ -1,4 +1,5 @@
 test1a
 test1b
 test1c
+test1d
 test2
diff --git a/Control/CxxUtils/test/ConcurrentRangeMap_test.cxx b/Control/CxxUtils/test/ConcurrentRangeMap_test.cxx
index 27bb6abd39b07f16dbce61ed1fc1e44b9752c4cf..49ef80e9f9080124f439a601e0c7362116a62ea2 100644
--- a/Control/CxxUtils/test/ConcurrentRangeMap_test.cxx
+++ b/Control/CxxUtils/test/ConcurrentRangeMap_test.cxx
@@ -869,6 +869,34 @@ void test1c()
 }
 
 
+// Test clear();
+void test1d()
+{
+  std::cout << "test1d\n";
+  Payload::Hist phist;
+  TestMap map (TestMap::Updater_t(), std::make_shared<PayloadDeleter>(), 3);
+  assert (map.emplace (Range (10, 20), std::make_unique<Payload> (10, &phist)) ==
+          TestMap::EmplaceResult::SUCCESS);
+  assert (map.emplace (Range (20, 30), std::make_unique<Payload> (20, &phist)) ==
+          TestMap::EmplaceResult::SUCCESS);
+  assert (map.size() == 2);
+  assert (phist.size() == 2);
+  map.clear();
+  assert (map.size() == 0);
+  assert (phist.size() == 2);
+  for (int i=0; i < nslots; i++) {
+    map.quiescent (i);
+  }
+  assert (map.size() == 0);
+  assert (phist.size() == 0);
+
+  assert (map.emplace (Range (40, 50), std::make_unique<Payload> (40, &phist)) ==
+          TestMap::EmplaceResult::SUCCESS);
+  assert (map.size() == 1);
+  assert (phist.size() == 1);
+}
+
+
 //***************************************************************************
 // Threaded test.
 //
@@ -1088,6 +1116,7 @@ int main()
   test1a();
   test1b();
   test1c();
+  test1d();
   test2();
   return 0;
 }