Index: libcfa/prelude/builtins.c
===================================================================
--- libcfa/prelude/builtins.c	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/prelude/builtins.c	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Fri Jul 21 16:21:03 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 14 08:45:54 2021
-// Update Count     : 133
+// Last Modified On : Thu Feb  2 11:33:56 2023
+// Update Count     : 135
 //
 
@@ -64,5 +64,6 @@
 static inline void ^?{}(generator$ &) {}
 
-trait is_generator(T &) {
+forall( T & )
+trait is_generator {
       void main(T & this);
       generator$ * get_generator(T & this);
Index: libcfa/prelude/prelude-gen.cc
===================================================================
--- libcfa/prelude/prelude-gen.cc	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/prelude/prelude-gen.cc	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Sat Feb 16 08:44:58 2019
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Apr  2 17:18:24 2019
-// Update Count     : 37
+// Last Modified On : Thu Feb  2 11:40:01 2023
+// Update Count     : 38
 //
 
@@ -159,5 +159,5 @@
 int main() {
 	cout << "# 2 \"prelude.cfa\"  // needed for error messages from this file" << endl;
-	cout << "trait sized(T &) {};" << endl;
+	cout << "forall( T & ) trait sized {};" << endl;
 
 	cout << "//////////////////////////" << endl;
Index: libcfa/src/bits/containers.hfa
===================================================================
--- libcfa/src/bits/containers.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/bits/containers.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Tue Oct 31 16:38:50 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jan 15 07:42:35 2020
-// Update Count     : 28
+// Last Modified On : Thu Feb  2 11:33:08 2023
+// Update Count     : 29
 
 #pragma once
@@ -69,5 +69,6 @@
 
 #ifdef __cforall
-	trait is_node(T &) {
+	forall( T & )
+	trait is_node {
 		T *& get_next( T & );
 	};
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Mon Nov 28 12:27:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jan  6 16:33:16 2022
-// Update Count     : 12
+// Last Modified On : Thu Feb  2 11:31:42 2023
+// Update Count     : 13
 //
 
@@ -38,5 +38,6 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T))) {
+forall( T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T)) )
+trait is_coroutine {
 	void main(T & this);
 	coroutine$ * get_coroutine(T & this);
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/concurrency/locks.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -640,5 +640,6 @@
 //-----------------------------------------------------------------------------
 // is_blocking_lock
-trait is_blocking_lock(L & | sized(L)) {
+forall( L & | sized(L) )
+trait is_blocking_lock {
 	// For synchronization locks to use when acquiring
 	void on_notify( L &, struct thread$ * );
Index: libcfa/src/concurrency/monitor.hfa
===================================================================
--- libcfa/src/concurrency/monitor.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/concurrency/monitor.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Thd Feb 23 12:27:26 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec  4 07:55:32 2019
-// Update Count     : 11
+// Last Modified On : Thu Feb  2 11:29:21 2023
+// Update Count     : 12
 //
 
@@ -22,5 +22,6 @@
 #include "stdlib.hfa"
 
-trait is_monitor(T &) {
+forall( T & )
+trait is_monitor {
 	monitor$ * get_monitor( T & );
 	void ^?{}( T & mutex );
Index: libcfa/src/concurrency/mutex.hfa
===================================================================
--- libcfa/src/concurrency/mutex.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/concurrency/mutex.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -12,6 +12,6 @@
 // Created On       : Fri May 25 01:24:09 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec  4 09:16:53 2019
-// Update Count     : 1
+// Last Modified On : Thu Feb  2 11:46:08 2023
+// Update Count     : 2
 //
 
@@ -70,5 +70,6 @@
 void unlock(recursive_mutex_lock & this) __attribute__((deprecated("use concurrency/locks.hfa instead")));
 
-trait is_lock(L & | sized(L)) {
+forall( L & | sized(L) )
+trait is_lock {
 	void lock  (L &);
 	void unlock(L &);
Index: libcfa/src/concurrency/thread.hfa
===================================================================
--- libcfa/src/concurrency/thread.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/concurrency/thread.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Tue Jan 17 12:27:26 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Nov 22 22:18:34 2022
-// Update Count     : 35
+// Last Modified On : Thu Feb  2 11:27:59 2023
+// Update Count     : 37
 //
 
@@ -27,5 +27,6 @@
 //-----------------------------------------------------------------------------
 // thread trait
-trait is_thread(T &) {
+forall( T & )
+trait is_thread {
 	void ^?{}(T& mutex this);
 	void main(T& this);
Index: libcfa/src/containers/list.hfa
===================================================================
--- libcfa/src/containers/list.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/containers/list.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -9,7 +9,7 @@
 // Author           : Michael Brooks
 // Created On       : Wed Apr 22 18:00:00 2020
-// Last Modified By : Michael Brooks
-// Last Modified On : Wed Apr 22 18:00:00 2020
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Feb  2 11:32:26 2023
+// Update Count     : 2
 //
 
@@ -23,5 +23,6 @@
 };
 
-trait embedded( tOuter &, tMid &, tInner & ) {
+forall( tOuter &, tMid &, tInner & )
+trait embedded {
     tytagref( tMid, tInner ) ?`inner( tOuter & );
 };
Index: libcfa/src/containers/vector.hfa
===================================================================
--- libcfa/src/containers/vector.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/containers/vector.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Tue Jul  5 18:00:07 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun 17 11:02:46 2020
-// Update Count     : 4
+// Last Modified On : Thu Feb  2 11:41:24 2023
+// Update Count     : 5
 //
 
@@ -50,6 +50,6 @@
 //------------------------------------------------------------------------------
 //Declaration
-trait allocator_c(T, allocator_t)
-{
+forall( T, allocator_t )
+trait allocator_c {
 	void realloc_storage(allocator_t*, size_t);
 	T* data(allocator_t*);
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/exception.h	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Mon Jun 26 15:11:00 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:20:00 2021
-// Update Count     : 12
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Feb  2 11:20:19 2023
+// Update Count     : 13
 //
 
@@ -101,5 +101,6 @@
 // implemented in the .c file either so they all have to be inline.
 
-trait is_exception(exceptT &, virtualT &) {
+forall( exceptT &, virtualT & )
+trait is_exception {
 	/* The first field must be a pointer to a virtual table.
 	 * That virtual table must be a decendent of the base exception virtual table.
@@ -109,9 +110,11 @@
 };
 
-trait is_termination_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) {
+forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) )
+trait is_termination_exception {
 	void defaultTerminationHandler(exceptT &);
 };
 
-trait is_resumption_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) {
+forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) )
+trait is_resumption_exception {
 	void defaultResumptionHandler(exceptT &);
 };
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/iostream.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Oct 10 10:02:07 2021
-// Update Count     : 407
+// Last Modified On : Thu Feb  2 11:25:39 2023
+// Update Count     : 410
 //
 
@@ -22,5 +22,6 @@
 
 
-trait basic_ostream( ostype & ) {
+forall( ostype & )
+trait basic_ostream {
 	// private
 	bool sepPrt$( ostype & );							// get separator state (on/off)
@@ -51,5 +52,6 @@
 }; // basic_ostream
 	
-trait ostream( ostype & | basic_ostream( ostype ) ) {
+forall( ostype & | basic_ostream( ostype ) )
+trait ostream {
 	bool fail( ostype & );								// operation failed?
 	void clear( ostype & );
@@ -60,9 +62,11 @@
 }; // ostream
 
-// trait writeable( T ) {
+// forall( T )
+// trait writeable {
 // 	forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype &, T );
 // }; // writeable
 
-trait writeable( T, ostype & | ostream( ostype ) ) {
+forall( T, ostype & | ostream( ostype ) )
+	trait writeable {
 	ostype & ?|?( ostype &, T );
 }; // writeable
@@ -290,5 +294,6 @@
 
 
-trait basic_istream( istype & ) {
+forall( istype & )
+trait basic_istream {
 	// private
 	bool getANL$( istype & );							// get scan newline (on/off)
@@ -302,5 +307,6 @@
 }; // basic_istream
 
-trait istream( istype & | basic_istream( istype ) ) {
+forall( istype & | basic_istream( istype ) )
+trait istream {
 	bool fail( istype & );
 	void clear( istype & );
@@ -310,5 +316,6 @@
 }; // istream
 
-trait readable( T ) {
+forall( T )
+trait readable {
 	forall( istype & | istream( istype ) ) istype & ?|?( istype &, T );
 }; // readable
Index: libcfa/src/iterator.hfa
===================================================================
--- libcfa/src/iterator.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/iterator.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul  7 08:37:25 2017
-// Update Count     : 10
+// Last Modified On : Thu Feb  2 11:21:50 2023
+// Update Count     : 11
 //
 
@@ -17,5 +17,6 @@
 
 // An iterator can be used to traverse a data structure.
-trait iterator( iterator_type, elt_type ) {
+forall( iterator_type, elt_type )
+trait iterator {
 	// point to the next element
 //	iterator_type ?++( iterator_type & );
@@ -31,5 +32,6 @@
 };
 
-trait iterator_for( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) {
+forall( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) )
+	trait iterator_for {
 //	[ iterator_type begin, iterator_type end ] get_iterators( collection_type );
 	iterator_type begin( collection_type );
Index: libcfa/src/math.trait.hfa
===================================================================
--- libcfa/src/math.trait.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/math.trait.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,21 +10,24 @@
 // Created On       : Fri Jul 16 15:40:52 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 20 17:47:19 2021
-// Update Count     : 19
+// Last Modified On : Thu Feb  2 11:36:56 2023
+// Update Count     : 20
 // 
 
 #pragma once
 
-trait Not( U ) {
+forall( U )
+trait Not {
 	void ?{}( U &, zero_t );
 	int !?( U );
 }; // Not
 
-trait Equality( T | Not( T ) ) {
+forall( T | Not( T ) )
+trait Equality {
 	int ?==?( T, T );
 	int ?!=?( T, T );
 }; // Equality
 
-trait Relational( U | Equality( U ) ) {
+forall( U | Equality( U ) )
+trait Relational {
 	int ?<?( U, U );
 	int ?<=?( U, U );
@@ -33,5 +36,6 @@
 }; // Relational
 
-trait Signed( T ) {
+forall ( T )
+trait Signed {
 	T +?( T );
 	T -?( T );
@@ -39,5 +43,6 @@
 }; // Signed
 
-trait Additive( U | Signed( U ) ) {
+forall( U | Signed( U ) )
+trait Additive {
 	U ?+?( U, U );
 	U ?-?( U, U );
@@ -46,5 +51,6 @@
 }; // Additive
 
-trait Incdec( T | Additive( T ) ) {
+forall( T | Additive( T ) )
+trait Incdec {
 	void ?{}( T &, one_t );
 	// T ?++( T & );
@@ -54,5 +60,6 @@
 }; // Incdec
 
-trait Multiplicative( U | Incdec( U ) ) {
+forall( U | Incdec( U ) )
+trait Multiplicative {
 	U ?*?( U, U );
 	U ?/?( U, U );
@@ -61,5 +68,6 @@
 }; // Multiplicative
 
-trait Arithmetic( T | Relational( T ) | Multiplicative( T ) ) {
+forall( T | Relational( T ) | Multiplicative( T ) )
+trait Arithmetic {
 }; // Arithmetic
 
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ libcfa/src/stdlib.hfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Dec 11 18:25:53 2022
-// Update Count     : 765
+// Last Modified On : Thu Feb  2 11:30:04 2023
+// Update Count     : 766
 //
 
@@ -404,5 +404,6 @@
 //   calls( sprng );
 
-trait basic_prng( PRNG &, R ) {
+forall( PRNG &, R )
+trait basic_prng {
 	void set_seed( PRNG & prng, R seed );				// set seed
 	R get_seed( PRNG & prng );							// get seed
Index: src/Common/ScopedMap.h
===================================================================
--- src/Common/ScopedMap.h	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/Common/ScopedMap.h	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -37,5 +37,5 @@
 		template<typename N>
 		Scope(N && n) : map(), note(std::forward<N>(n)) {}
-		
+
 		Scope() = default;
 		Scope(const Scope &) = default;
@@ -46,5 +46,6 @@
 	typedef std::vector< Scope > ScopeList;
 
-	ScopeList scopes; ///< scoped list of maps
+	/// Scoped list of maps.
+	ScopeList scopes;
 public:
 	typedef typename MapType::key_type key_type;
@@ -58,158 +59,7 @@
 	typedef typename MapType::const_pointer const_pointer;
 
-	class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > {
-	friend class ScopedMap;
-	friend class const_iterator;
-		typedef typename ScopedMap::MapType::iterator wrapped_iterator;
-		typedef typename ScopedMap::ScopeList scope_list;
-		typedef typename scope_list::size_type size_type;
-
-		/// Checks if this iterator points to a valid item
-		bool is_valid() const {
-			return it != (*scopes)[level].map.end();
-		}
-
-		/// Increments on invalid
-		iterator & next_valid() {
-			if ( ! is_valid() ) { ++(*this); }
-			return *this;
-		}
-
-		/// Decrements on invalid
-		iterator & prev_valid() {
-			if ( ! is_valid() ) { --(*this); }
-			return *this;
-		}
-
-		iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)
-			: scopes(&_scopes), it(_it), level(inLevel) {}
-	public:
-		iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
-		iterator & operator= (const iterator & that) {
-			scopes = that.scopes; level = that.level; it = that.it;
-			return *this;
-		}
-
-		reference operator* () { return *it; }
-		pointer operator-> () const { return it.operator->(); }
-
-		iterator & operator++ () {
-			if ( it == (*scopes)[level].map.end() ) {
-				if ( level == 0 ) return *this;
-				--level;
-				it = (*scopes)[level].map.begin();
-			} else {
-				++it;
-			}
-			return next_valid();
-		}
-		iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
-
-		iterator & operator-- () {
-			// may fail if this is the begin iterator; allowed by STL spec
-			if ( it == (*scopes)[level].map.begin() ) {
-				++level;
-				it = (*scopes)[level].map.end();
-			}
-			--it;
-			return prev_valid();
-		}
-		iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
-
-		bool operator== (const iterator & that) const {
-			return scopes == that.scopes && level == that.level && it == that.it;
-		}
-		bool operator!= (const iterator & that) const { return !( *this == that ); }
-
-		size_type get_level() const { return level; }
-
-		Note & get_note() { return (*scopes)[level].note; }
-		const Note & get_note() const { return (*scopes)[level].note; }
-
-	private:
-		scope_list *scopes;
-		wrapped_iterator it;
-		size_type level;
-	};
-
-	class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
-	                                             value_type > {
-	friend class ScopedMap;
-		typedef typename ScopedMap::MapType::iterator wrapped_iterator;
-		typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
-		typedef typename ScopedMap::ScopeList scope_list;
-		typedef typename scope_list::size_type size_type;
-
-		/// Checks if this iterator points to a valid item
-		bool is_valid() const {
-			return it != (*scopes)[level].map.end();
-		}
-
-		/// Increments on invalid
-		const_iterator & next_valid() {
-			if ( ! is_valid() ) { ++(*this); }
-			return *this;
-		}
-
-		/// Decrements on invalid
-		const_iterator & prev_valid() {
-			if ( ! is_valid() ) { --(*this); }
-			return *this;
-		}
-
-		const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)
-			: scopes(&_scopes), it(_it), level(inLevel) {}
-	public:
-		const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
-		const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
-		const_iterator & operator= (const iterator & that) {
-			scopes = that.scopes; level = that.level; it = that.it;
-			return *this;
-		}
-		const_iterator & operator= (const const_iterator & that) {
-			scopes = that.scopes; level = that.level; it = that.it;
-			return *this;
-		}
-
-		const_reference operator* () { return *it; }
-		const_pointer operator-> () { return it.operator->(); }
-
-		const_iterator & operator++ () {
-			if ( it == (*scopes)[level].map.end() ) {
-				if ( level == 0 ) return *this;
-				--level;
-				it = (*scopes)[level].map.begin();
-			} else {
-				++it;
-			}
-			return next_valid();
-		}
-		const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
-
-		const_iterator & operator-- () {
-			// may fail if this is the begin iterator; allowed by STL spec
-			if ( it == (*scopes)[level].map.begin() ) {
-				++level;
-				it = (*scopes)[level].map.end();
-			}
-			--it;
-			return prev_valid();
-		}
-		const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
-
-		bool operator== (const const_iterator & that) const {
-			return scopes == that.scopes && level == that.level && it == that.it;
-		}
-		bool operator!= (const const_iterator & that) const { return !( *this == that ); }
-
-		size_type get_level() const { return level; }
-
-		const Note & get_note() const { return (*scopes)[level].note; }
-
-	private:
-		scope_list const *scopes;
-		wrapped_const_iterator it;
-		size_type level;
-	};
+	// Both iterator types are complete bidrectional iterators, see below.
+	class iterator;
+	class const_iterator;
 
 	/// Starts a new scope
@@ -297,11 +147,4 @@
 	}
 
-	template< typename value_type_t >
-	std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {
-		MapType & scope = (*at.scopes)[ at.level ].map;
-		std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
-		return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );
-	}
-
 	template< typename value_t >
 	std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }
@@ -324,9 +167,11 @@
 	}
 
-	iterator erase( iterator pos ) {
-		MapType & scope = (*pos.scopes)[ pos.level ].map;
-		const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it );
-		iterator it( *pos.scopes, new_it, pos.level );
-		return it.next_valid();
+	/// Erases element with key in the innermost scope that has it.
+	size_type erase( const Key & key ) {
+		for ( auto it = scopes.rbegin() ; it != scopes.rend() ; ++it ) {
+			size_type i = it->map.erase( key );
+			if ( 0 != i ) return i;
+		}
+		return 0;
 	}
 
@@ -343,4 +188,166 @@
 		return c;
 	}
+
+	bool contains( const Key & key ) const {
+		return find( key ) != cend();
+	}
+};
+
+template<typename Key, typename Value, typename Note>
+class ScopedMap<Key, Value, Note>::iterator :
+		public std::iterator< std::bidirectional_iterator_tag, value_type > {
+	friend class ScopedMap;
+	friend class const_iterator;
+	typedef typename ScopedMap::MapType::iterator wrapped_iterator;
+	typedef typename ScopedMap::ScopeList scope_list;
+	typedef typename scope_list::size_type size_type;
+
+	/// Checks if this iterator points to a valid item
+	bool is_valid() const {
+		return it != (*scopes)[level].map.end();
+	}
+
+	/// Increments on invalid
+	iterator & next_valid() {
+		if ( ! is_valid() ) { ++(*this); }
+		return *this;
+	}
+
+	/// Decrements on invalid
+	iterator & prev_valid() {
+		if ( ! is_valid() ) { --(*this); }
+		return *this;
+	}
+
+	iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)
+		: scopes(&_scopes), it(_it), level(inLevel) {}
+public:
+	iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
+	iterator & operator= (const iterator & that) {
+		scopes = that.scopes; level = that.level; it = that.it;
+		return *this;
+	}
+
+	reference operator* () { return *it; }
+	pointer operator-> () const { return it.operator->(); }
+
+	iterator & operator++ () {
+		if ( it == (*scopes)[level].map.end() ) {
+			if ( level == 0 ) return *this;
+			--level;
+			it = (*scopes)[level].map.begin();
+		} else {
+			++it;
+		}
+		return next_valid();
+	}
+	iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
+
+	iterator & operator-- () {
+		// may fail if this is the begin iterator; allowed by STL spec
+		if ( it == (*scopes)[level].map.begin() ) {
+			++level;
+			it = (*scopes)[level].map.end();
+		}
+		--it;
+		return prev_valid();
+	}
+	iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
+
+	bool operator== (const iterator & that) const {
+		return scopes == that.scopes && level == that.level && it == that.it;
+	}
+	bool operator!= (const iterator & that) const { return !( *this == that ); }
+
+	size_type get_level() const { return level; }
+
+	Note & get_note() { return (*scopes)[level].note; }
+	const Note & get_note() const { return (*scopes)[level].note; }
+
+private:
+	scope_list *scopes;
+	wrapped_iterator it;
+	size_type level;
+};
+
+template<typename Key, typename Value, typename Note>
+class ScopedMap<Key, Value, Note>::const_iterator :
+		public std::iterator< std::bidirectional_iterator_tag, value_type > {
+	friend class ScopedMap;
+	typedef typename ScopedMap::MapType::iterator wrapped_iterator;
+	typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
+	typedef typename ScopedMap::ScopeList scope_list;
+	typedef typename scope_list::size_type size_type;
+
+	/// Checks if this iterator points to a valid item
+	bool is_valid() const {
+		return it != (*scopes)[level].map.end();
+	}
+
+	/// Increments on invalid
+	const_iterator & next_valid() {
+		if ( ! is_valid() ) { ++(*this); }
+		return *this;
+	}
+
+	/// Decrements on invalid
+	const_iterator & prev_valid() {
+		if ( ! is_valid() ) { --(*this); }
+		return *this;
+	}
+
+	const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)
+		: scopes(&_scopes), it(_it), level(inLevel) {}
+public:
+	const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
+	const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
+	const_iterator & operator= (const iterator & that) {
+		scopes = that.scopes; level = that.level; it = that.it;
+		return *this;
+	}
+	const_iterator & operator= (const const_iterator & that) {
+		scopes = that.scopes; level = that.level; it = that.it;
+		return *this;
+	}
+
+	const_reference operator* () { return *it; }
+	const_pointer operator-> () { return it.operator->(); }
+
+	const_iterator & operator++ () {
+		if ( it == (*scopes)[level].map.end() ) {
+			if ( level == 0 ) return *this;
+			--level;
+			it = (*scopes)[level].map.begin();
+		} else {
+			++it;
+		}
+		return next_valid();
+	}
+	const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
+
+	const_iterator & operator-- () {
+		// may fail if this is the begin iterator; allowed by STL spec
+		if ( it == (*scopes)[level].map.begin() ) {
+			++level;
+			it = (*scopes)[level].map.end();
+		}
+		--it;
+		return prev_valid();
+	}
+	const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
+
+	bool operator== (const const_iterator & that) const {
+		return scopes == that.scopes && level == that.level && it == that.it;
+	}
+	bool operator!= (const const_iterator & that) const { return !( *this == that ); }
+
+	size_type get_level() const { return level; }
+
+	const Note & get_note() const { return (*scopes)[level].note; }
+
+private:
+	scope_list const *scopes;
+	wrapped_const_iterator it;
+	size_type level;
 };
 
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/Common/SemanticError.h	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  4 14:08:26 2022
-// Update Count     : 35
+// Last Modified On : Thu Feb  2 10:59:10 2023
+// Update Count     : 36
 //
 
@@ -54,12 +54,13 @@
 
 constexpr WarningData WarningFormats[] = {
-	{"self-assign"            , Severity::Warn    , "self assignment of expression: %s"                          },
-	{"reference-conversion"   , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
-	{"qualifiers-zero_t-one_t", Severity::Warn    , "questionable use of type qualifier %s with %s"              },
-	{"aggregate-forward-decl" , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
-	{"superfluous-decl"       , Severity::Warn    , "declaration does not allocate storage: %s"                  },
-	{"superfluous-else"       , Severity::Warn    , "else clause never executed for empty loop conditional"      },
-	{"gcc-attributes"         , Severity::Warn    , "invalid attribute: %s"                                      },
-	{"c++-like-copy"          , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
+	{"self-assign"              , Severity::Warn    , "self assignment of expression: %s"                          },
+	{"reference-conversion"     , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
+	{"qualifiers-zero_t-one_t"  , Severity::Warn    , "questionable use of type qualifier %s with %s"              },
+	{"aggregate-forward-decl"   , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
+	{"superfluous-decl"         , Severity::Warn    , "declaration does not allocate storage: %s"                  },
+	{"superfluous-else"         , Severity::Warn    , "else clause never executed for empty loop conditional"      },
+	{"gcc-attributes"           , Severity::Warn    , "invalid attribute: %s"                                      },
+	{"c++-like-copy"            , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
+	{"depreciated-trait-syntax" , Severity::Warn    , "trait type-parameters are now specified using the forall clause" },
 };
 
@@ -73,4 +74,5 @@
 	GccAttributes,
 	CppCopy,
+	DeprecTraitSyntax,
 	NUMBER_OF_WARNINGS, // This MUST be the last warning
 };
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/GenPoly/Box.cc	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -488,5 +488,5 @@
 				for ( FunctionType const * const funType : functions ) {
 					std::string mangleName = mangleAdapterName( funType, scopeTyVars );
-					if ( adapters.find( mangleName ) == adapters.end() ) {
+					if ( !adapters.contains( mangleName ) ) {
 						std::string adapterName = makeAdapterName( mangleName );
 						adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) );
@@ -1487,5 +1487,5 @@
 					if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
 						// do not try to monomorphize generic parameters
-						if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) {
+						if ( scopeTyVars.contains( typeInst->get_name() ) && ! genericParams.count( typeInst->name ) ) {
 							// polymorphic aggregate members should be converted into monomorphic members.
 							// Using char[size_T] here respects the expected sizing rules of an aggregate type.
@@ -1696,5 +1696,5 @@
 
 			if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) {
-				if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
+				if ( scopeTyVars.contains( typeInst->get_name() ) ) {
 					// NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
 					return true;
@@ -1704,5 +1704,5 @@
 				// check if this type already has a layout generated for it
 				std::string typeName = mangleType( ty );
-				if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
+				if ( knownLayouts.contains( typeName ) ) return true;
 
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
@@ -1741,5 +1741,5 @@
 				// check if this type already has a layout generated for it
 				std::string typeName = mangleType( ty );
-				if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
+				if ( knownLayouts.contains( typeName ) ) return true;
 
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
@@ -1832,5 +1832,5 @@
 			} else {
 				std::string offsetName = offsetofName( mangleType( ty ) );
-				if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
+				if ( knownOffsets.contains( offsetName ) ) {
 					// use the already-generated offsets for this type
 					ret = new NameExpr( offsetName );
Index: src/GenPoly/ErasableScopedMap.h
===================================================================
--- src/GenPoly/ErasableScopedMap.h	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/GenPoly/ErasableScopedMap.h	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ScopedMap.h --
+// ErasableScopedMap.h --
 //
 // Author           : Aaron B. Moss
@@ -51,5 +51,5 @@
 	typedef typename Scope::const_pointer const_pointer;
 
-	// Both iterator types are complete bidirection iterators, defined below.
+	// Both iterator types are complete bidirectional iterators, see below.
 	class iterator;
 	class const_iterator;
@@ -118,4 +118,10 @@
 	std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
 
+	Value& operator[] ( const Key &key ) {
+		iterator slot = find( key );
+		if ( slot != end() ) return slot->second;
+		return insert( key, Value() ).first->second;
+	}
+
 	/// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise
 	size_type erase( const Key &key ) {
@@ -130,8 +136,6 @@
 	}
 
-	Value& operator[] ( const Key &key ) {
-		iterator slot = find( key );
-		if ( slot != end() ) return slot->second;
-		return insert( key, Value() ).first->second;
+	bool contains( const Key & key ) const {
+		return find( key ) != cend();
 	}
 };
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/GenPoly/GenPoly.cc	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -172,5 +172,5 @@
 
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
-			if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
+			if ( tyVars.contains( typeInst->get_name() ) ) {
 				return type;
 			}
@@ -189,5 +189,5 @@
 
 		if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
-			return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr;
+			if ( tyVars.contains( typeInst->typeString() ) ) return type;
 		} else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
 			return isPolyType( arrayType->base, env );
@@ -205,5 +205,5 @@
 
 	if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
-		if ( typeVars.find( *inst ) != typeVars.end() ) return type;
+		if ( typeVars.contains( *inst ) ) return type;
 	} else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
 		return isPolyType( array->base, subst );
@@ -393,5 +393,5 @@
 
 		if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) {
-			if ( tyVars.find( typeInstType->get_name() ) != tyVars.end() ) {
+			if ( tyVars.contains( typeInstType->get_name() ) ) {
 				return true;
 			}
Index: src/GenPoly/ScopedSet.h
===================================================================
--- src/GenPoly/ScopedSet.h	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/GenPoly/ScopedSet.h	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -21,231 +21,243 @@
 
 namespace GenPoly {
-	/// A set where the items are placed into nested scopes;
-	/// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward
-	template<typename Value>
-	class ScopedSet {
-		typedef std::set< Value > Scope;
-		typedef std::vector< Scope > ScopeList;
-
-		ScopeList scopes; ///< scoped list of sets
-	public:
-		typedef typename Scope::key_type key_type;
-		typedef typename Scope::value_type value_type;
-		typedef typename ScopeList::size_type size_type;
-		typedef typename ScopeList::difference_type difference_type;
-		typedef typename Scope::reference reference;
-		typedef typename Scope::const_reference const_reference;
-		typedef typename Scope::pointer pointer;
-		typedef typename Scope::const_pointer const_pointer;
-
-		class iterator : public std::iterator< std::bidirectional_iterator_tag,
-		                                       value_type > {
-		friend class ScopedSet;
-		friend class const_iterator;
-			typedef typename std::set< Value >::iterator wrapped_iterator;
-			typedef typename std::vector< std::set< Value > > scope_list;
-			typedef typename scope_list::size_type size_type;
-
-			/// Checks if this iterator points to a valid item
-			bool is_valid() const {
-				return it != (*scopes)[i].end();
-			}
-
-			/// Increments on invalid
-			iterator& next_valid() {
-				if ( ! is_valid() ) { ++(*this); }
-				return *this;
-			}
-
-			/// Decrements on invalid
-			iterator& prev_valid() {
-				if ( ! is_valid() ) { --(*this); }
-				return *this;
-			}
-
-			iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i)
-				: scopes(&_scopes), it(_it), i(_i) {}
-		public:
-			iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
-			iterator& operator= (const iterator &that) {
-				scopes = that.scopes; i = that.i; it = that.it;
-				return *this;
-			}
-
-			reference operator* () { return *it; }
-			pointer operator-> () { return it.operator->(); }
-
-			iterator& operator++ () {
-				if ( it == (*scopes)[i].end() ) {
-					if ( i == 0 ) return *this;
-					--i;
-					it = (*scopes)[i].begin();
-				} else {
-					++it;
-				}
-				return next_valid();
-			}
-			iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
-
-			iterator& operator-- () {
-				// may fail if this is the begin iterator; allowed by STL spec
-				if ( it == (*scopes)[i].begin() ) {
-					++i;
-					it = (*scopes)[i].end();
-				}
-				--it;
-				return prev_valid();
-			}
-			iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
-
-			bool operator== (const iterator &that) {
-				return scopes == that.scopes && i == that.i && it == that.it;
-			}
-			bool operator!= (const iterator &that) { return !( *this == that ); }
-
-			size_type get_level() const { return i; }
-
-		private:
-			scope_list const *scopes;
-			wrapped_iterator it;
-			size_type i;
-		};
-
-		class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
-		                                             value_type > {
-		friend class ScopedSet;
-			typedef typename std::set< Value >::iterator wrapped_iterator;
-			typedef typename std::set< Value >::const_iterator wrapped_const_iterator;
-			typedef typename std::vector< std::set< Value > > scope_list;
-			typedef typename scope_list::size_type size_type;
-
-			/// Checks if this iterator points to a valid item
-			bool is_valid() const {
-				return it != (*scopes)[i].end();
-			}
-
-			/// Increments on invalid
-			const_iterator& next_valid() {
-				if ( ! is_valid() ) { ++(*this); }
-				return *this;
-			}
-
-			/// Decrements on invalid
-			const_iterator& prev_valid() {
-				if ( ! is_valid() ) { --(*this); }
-				return *this;
-			}
-
-			const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i)
-				: scopes(&_scopes), it(_it), i(_i) {}
-		public:
-			const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
-			const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
-			const_iterator& operator= (const iterator &that) {
-				scopes = that.scopes; i = that.i; it = that.it;
-				return *this;
-			}
-			const_iterator& operator= (const const_iterator &that) {
-				scopes = that.scopes; i = that.i; it = that.it;
-				return *this;
-			}
-
-			const_reference operator* () { return *it; }
-			const_pointer operator-> () { return it.operator->(); }
-
-			const_iterator& operator++ () {
-				if ( it == (*scopes)[i].end() ) {
-					if ( i == 0 ) return *this;
-					--i;
-					it = (*scopes)[i].begin();
-				} else {
-					++it;
-				}
-				return next_valid();
-			}
-			const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
-
-			const_iterator& operator-- () {
-				// may fail if this is the begin iterator; allowed by STL spec
-				if ( it == (*scopes)[i].begin() ) {
-					++i;
-					it = (*scopes)[i].end();
-				}
-				--it;
-				return prev_valid();
-			}
-			const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
-
-			bool operator== (const const_iterator &that) {
-				return scopes == that.scopes && i == that.i && it == that.it;
-			}
-			bool operator!= (const const_iterator &that) { return !( *this == that ); }
-
-			size_type get_level() const { return i; }
-
-		private:
-			scope_list const *scopes;
-			wrapped_const_iterator it;
-			size_type i;
-		};
-
-		/// Starts a new scope
-		void beginScope() {
-			Scope scope;
-			scopes.push_back(scope);
-		}
-
-		/// Ends a scope; invalidates any iterators pointing to elements of that scope
-		void endScope() {
-			scopes.pop_back();
-		}
-
-		/// Default constructor initializes with one scope
-		ScopedSet() { beginScope(); }
-
-		iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
-		const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
-		const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
-		iterator end() { return iterator(scopes, scopes[0].end(), 0); }
-		const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
-		const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); }
-
-		/// Gets the index of the current scope (counted from 1)
-		size_type currentScope() const { return scopes.size(); }
-
-		/// Finds the given key in the outermost scope it occurs; returns end() for none such
-		iterator find( const Value &key ) {
-			for ( size_type i = scopes.size() - 1; ; --i ) {
-				typename Scope::iterator val = scopes[i].find( key );
-				if ( val != scopes[i].end() ) return iterator( scopes, val, i );
-				if ( i == 0 ) break;
-			}
-			return end();
-		}
-		const_iterator find( const Value &key ) const {
-			return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) );
-		}
-
-		/// Finds the given key in the outermost scope inside the given scope where it occurs
-		iterator findNext( const_iterator &it, const Value &key ) {
-			if ( it.i == 0 ) return end();
+
+/// A set where the items are placed into nested scopes;
+/// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward
+template<typename Value>
+class ScopedSet {
+	typedef std::set< Value > Scope;
+	typedef std::vector< Scope > ScopeList;
+
+	/// Scoped list of sets.
+	ScopeList scopes;
+public:
+	typedef typename Scope::key_type key_type;
+	typedef typename Scope::value_type value_type;
+	typedef typename ScopeList::size_type size_type;
+	typedef typename ScopeList::difference_type difference_type;
+	typedef typename Scope::reference reference;
+	typedef typename Scope::const_reference const_reference;
+	typedef typename Scope::pointer pointer;
+	typedef typename Scope::const_pointer const_pointer;
+
+	// Both iterator types are complete bidirectional iterators, see below.
+	class iterator;
+	class const_iterator;
+
+	/// Starts a new scope
+	void beginScope() {
+		Scope scope;
+		scopes.push_back(scope);
+	}
+
+	/// Ends a scope; invalidates any iterators pointing to elements of that scope
+	void endScope() {
+		scopes.pop_back();
+	}
+
+	/// Default constructor initializes with one scope
+	ScopedSet() { beginScope(); }
+
+	iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
+	const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
+	const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
+	iterator end() { return iterator(scopes, scopes[0].end(), 0); }
+	const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
+	const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); }
+
+	/// Gets the index of the current scope (counted from 1)
+	size_type currentScope() const { return scopes.size(); }
+
+	/// Finds the given key in the outermost scope it occurs; returns end() for none such
+	iterator find( const Value &key ) {
+		for ( size_type i = scopes.size() - 1; ; --i ) {
+			typename Scope::iterator val = scopes[i].find( key );
+			if ( val != scopes[i].end() ) return iterator( scopes, val, i );
+			if ( i == 0 ) break;
+		}
+		return end();
+	}
+	const_iterator find( const Value &key ) const {
+		return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) );
+	}
+
+	/// Finds the given key in the outermost scope inside the given scope where it occurs
+	iterator findNext( const_iterator &it, const Value &key ) {
+		if ( it.i == 0 ) return end();
 			for ( size_type i = it.i - 1; ; --i ) {
-				typename Scope::iterator val = scopes[i].find( key );
-				if ( val != scopes[i].end() ) return iterator( scopes, val, i );
-				if ( i == 0 ) break;
-			}
-			return end();
-		}
-		const_iterator findNext( const_iterator &it, const Value &key ) const {
-			return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) );
-		}
-
-		/// Inserts the given value into the outermost scope
-		std::pair< iterator, bool > insert( const value_type &value ) {
-			std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value );
-			return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second );
-		}
-
-	};
+			typename Scope::iterator val = scopes[i].find( key );
+			if ( val != scopes[i].end() ) return iterator( scopes, val, i );
+			if ( i == 0 ) break;
+		}
+		return end();
+	}
+	const_iterator findNext( const_iterator &it, const Value &key ) const {
+		return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) );
+	}
+
+	/// Inserts the given value into the outermost scope
+	std::pair< iterator, bool > insert( const value_type &value ) {
+		std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value );
+		return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second );
+	}
+
+	bool contains( const Value & key ) const {
+		return find( key ) != cend();
+	}
+};
+
+template<typename Value>
+class ScopedSet<Value>::iterator :
+		public std::iterator< std::bidirectional_iterator_tag, value_type > {
+	friend class ScopedSet;
+	friend class const_iterator;
+	typedef typename std::set< Value >::iterator wrapped_iterator;
+	typedef typename std::vector< std::set< Value > > scope_list;
+	typedef typename scope_list::size_type size_type;
+
+	/// Checks if this iterator points to a valid item
+	bool is_valid() const {
+		return it != (*scopes)[i].end();
+	}
+
+	/// Increments on invalid
+	iterator& next_valid() {
+		if ( ! is_valid() ) { ++(*this); }
+		return *this;
+	}
+
+	/// Decrements on invalid
+	iterator& prev_valid() {
+		if ( ! is_valid() ) { --(*this); }
+		return *this;
+	}
+
+	iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i)
+		: scopes(&_scopes), it(_it), i(_i) {}
+public:
+	iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
+	iterator& operator= (const iterator &that) {
+		scopes = that.scopes; i = that.i; it = that.it;
+		return *this;
+	}
+
+	reference operator* () { return *it; }
+	pointer operator-> () { return it.operator->(); }
+
+	iterator& operator++ () {
+		if ( it == (*scopes)[i].end() ) {
+			if ( i == 0 ) return *this;
+			--i;
+			it = (*scopes)[i].begin();
+		} else {
+			++it;
+		}
+		return next_valid();
+	}
+	iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
+
+	iterator& operator-- () {
+		// may fail if this is the begin iterator; allowed by STL spec
+		if ( it == (*scopes)[i].begin() ) {
+			++i;
+			it = (*scopes)[i].end();
+		}
+		--it;
+		return prev_valid();
+	}
+	iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
+
+	bool operator== (const iterator &that) {
+		return scopes == that.scopes && i == that.i && it == that.it;
+	}
+	bool operator!= (const iterator &that) { return !( *this == that ); }
+
+	size_type get_level() const { return i; }
+
+private:
+	scope_list const *scopes;
+	wrapped_iterator it;
+	size_type i;
+};
+
+template<typename Value>
+class ScopedSet<Value>::const_iterator :
+		public std::iterator< std::bidirectional_iterator_tag, value_type > {
+	friend class ScopedSet;
+	typedef typename std::set< Value >::iterator wrapped_iterator;
+	typedef typename std::set< Value >::const_iterator wrapped_const_iterator;
+	typedef typename std::vector< std::set< Value > > scope_list;
+	typedef typename scope_list::size_type size_type;
+
+	/// Checks if this iterator points to a valid item
+	bool is_valid() const {
+		return it != (*scopes)[i].end();
+	}
+
+	/// Increments on invalid
+	const_iterator& next_valid() {
+		if ( ! is_valid() ) { ++(*this); }
+		return *this;
+	}
+
+	/// Decrements on invalid
+	const_iterator& prev_valid() {
+		if ( ! is_valid() ) { --(*this); }
+		return *this;
+	}
+
+	const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i)
+		: scopes(&_scopes), it(_it), i(_i) {}
+public:
+	const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
+	const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {}
+	const_iterator& operator= (const iterator &that) {
+		scopes = that.scopes; i = that.i; it = that.it;
+		return *this;
+	}
+	const_iterator& operator= (const const_iterator &that) {
+		scopes = that.scopes; i = that.i; it = that.it;
+		return *this;
+	}
+
+	const_reference operator* () { return *it; }
+	const_pointer operator-> () { return it.operator->(); }
+
+	const_iterator& operator++ () {
+		if ( it == (*scopes)[i].end() ) {
+			if ( i == 0 ) return *this;
+			--i;
+			it = (*scopes)[i].begin();
+		} else {
+			++it;
+		}
+		return next_valid();
+	}
+	const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
+
+	const_iterator& operator-- () {
+		// may fail if this is the begin iterator; allowed by STL spec
+		if ( it == (*scopes)[i].begin() ) {
+			++i;
+			it = (*scopes)[i].end();
+		}
+		--it;
+		return prev_valid();
+	}
+	const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
+
+	bool operator== (const const_iterator &that) {
+		return scopes == that.scopes && i == that.i && it == that.it;
+	}
+	bool operator!= (const const_iterator &that) { return !( *this == that ); }
+
+	size_type get_level() const { return i; }
+
+private:
+	scope_list const *scopes;
+	wrapped_const_iterator it;
+	size_type i;
+};
+
 } // namespace GenPoly
 
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/GenPoly/ScrubTyVars.cc	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -178,31 +178,27 @@
 
 ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) {
+	ast::TypeDecl::Kind kind;
 	// This implies that mode == ScrubMode::All.
 	if ( !typeVars ) {
-		if ( ast::TypeDecl::Ftype == type->kind ) {
-			return new ast::PointerType(
-				new ast::FunctionType( ast::FixedArgs ) );
-		} else {
-			return new ast::PointerType(
-				new ast::VoidType( type->qualifiers ) );
-		}
-	}
-
-	auto typeVar = typeVars->find( *type );
-	if ( typeVar == typeVars->end() ) {
-		return type;
-	}
-
-	switch ( typeVar->second.kind ) {
-	case ::TypeDecl::Dtype:
-	case ::TypeDecl::Ttype:
+		kind = type->kind;
+	} else {
+		// Otherwise, only scrub the type var if it is in map.
+		auto typeVar = typeVars->find( *type );
+		if ( typeVar == typeVars->end() ) {
+			return type;
+		}
+		kind = typeVar->second.kind;
+	}
+
+	switch ( kind ) {
+	case ast::TypeDecl::Dtype:
+	case ast::TypeDecl::Ttype:
 		return new ast::PointerType(
 			new ast::VoidType( type->qualifiers ) );
-	case ::TypeDecl::Ftype:
+	case ast::TypeDecl::Ftype:
 		return new ast::PointerType(
 			new ast::FunctionType( ast::VariableArgs ) );
 	default:
-		assertf( false,
-			"Unhandled type variable kind: %d", typeVar->second.kind );
+		assertf( false, "Unhandled type variable kind: %d", kind );
 		throw; // Just in case the assert is removed, stop here.
 	}
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/Parser/parser.yy	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jan 31 08:55:11 2023
-// Update Count     : 5861
+// Last Modified On : Thu Feb  2 21:36:16 2023
+// Update Count     : 5865
 //
 
@@ -2979,9 +2979,15 @@
 trait_specifier:										// CFA
 	TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
-		{ $$ = DeclarationNode::newTrait( $2, $4, nullptr ); }
-	| forall TRAIT identifier_or_type_name '{' '}' // alternate
+		{
+			SemanticWarning( yylloc, Warning::DeprecTraitSyntax, "" );
+			$$ = DeclarationNode::newTrait( $2, $4, nullptr );
+		}
+	| forall TRAIT identifier_or_type_name '{' '}'		// alternate
 		{ $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
 	| TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
-		{ $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
+		{
+			SemanticWarning( yylloc, Warning::DeprecTraitSyntax, "" );
+			$$ = DeclarationNode::newTrait( $2, $4, $8 );
+		}
 	| forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
 		{ $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/SymTab/Validate.cc	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -863,9 +863,5 @@
 
 	void ReplaceTypedef::premutate( TypeDecl * typeDecl ) {
-		TypedefMap::iterator i = typedefNames.find( typeDecl->name );
-		if ( i != typedefNames.end() ) {
-			typedefNames.erase( i ) ;
-		} // if
-
+		typedefNames.erase( typeDecl->name );
 		typedeclNames.insert( typeDecl->name, typeDecl );
 	}
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ src/Validate/ReplaceTypedef.cpp	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -186,8 +186,5 @@
 
 void ReplaceTypedefCore::previsit( ast::TypeDecl const * decl ) {
-	TypedefMap::iterator iter = typedefNames.find( decl->name );
-	if ( iter != typedefNames.end() ) {
-		typedefNames.erase( iter );
-	}
+	typedefNames.erase( decl->name );
 	typedeclNames.insert( decl->name, decl );
 }
Index: tests/.expect/forall.txt
===================================================================
--- tests/.expect/forall.txt	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ tests/.expect/forall.txt	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -1,1 +1,21 @@
-forall.cfa:244:25: warning: Compiled
+1
+f
+97
+f
+g
+f
+f
+g
+fT
+fT
+fT
+fTU
+fTU
+fTU
+1 2
+2 1
+1, 2
+@ 0 2 0 4 6.4 6.4 6.4 6.4+3.i 4
+3. 3.
+45
+12 3
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ tests/Makefile.am	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -11,6 +11,6 @@
 ## Created On       : Sun May 31 09:08:15 2015
 ## Last Modified By : Peter A. Buhr
-## Last Modified On : Sat Jun  5 14:49:25 2021
-## Update Count     : 92
+## Last Modified On : Fri Feb  3 23:06:44 2023
+## Update Count     : 94
 ###############################################################################
 
@@ -89,5 +89,5 @@
 	meta/fork+exec.hfa \
 	concurrent/unified_locking/mutex_test.hfa \
-    concurrent/channels/parallel_harness.hfa
+	concurrent/channels/parallel_harness.hfa
 
 dist-hook:
@@ -183,5 +183,5 @@
 CFACOMPILE_SYNTAX = $(CFACOMPILETEST) -Wno-unused-variable -Wno-unused-label -c -fsyntax-only -o $(abspath ${@})
 
-SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator forall \
+SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator \
 	init1 limits nested-types cast labelledExit array quasiKeyword include/stdincludes include/includes builtins/sync warnings/self-assignment
 $(SYNTAX_ONLY_CODE): % : %.cfa $(CFACCBIN)
Index: tests/forall.cfa
===================================================================
--- tests/forall.cfa	(revision 2d02803996cfedbb52f4de3ebb6f4777d17a0089)
+++ tests/forall.cfa	(revision 4616622d7d426ff9588603b0092ed43f35fd9933)
@@ -10,17 +10,20 @@
 // Created On       : Wed May  9 08:48:15 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jun  5 10:06:08 2021
-// Update Count     : 36
-//
+// Last Modified On : Sun Feb  5 07:54:43 2023
+// Update Count     : 90
+//
+
+#include <fstream.hfa>
 
 void g1() {
-	forall( T ) T f( T ) {};
-	void f( int ) {};
-	void h( void (*p)(void) ) {};
-
-	int x;
-	void (*y)(void);
-	char z;
-	float w;
+	forall( T ) T f( T p ) { sout | 'f'; return p;  };
+	void f( int p ) { sout | p; };
+	void g( void ) { sout | 'g'; };
+	void h( void (*p)(void) ) { p(); };
+
+	int x = 1;
+	void (*y)(void) = g;
+	char z = 'a';
+	float w = 3.5;
 
 	f( x );
@@ -28,16 +31,21 @@
 	f( z );
 	f( w );
+	h( y );
+	f( y );
 	h( f( y ) );
 }
 
 void g2() {
-	forall( T ) void f( T, T ) {}
-	forall( T, U ) void f( T, U ) {}
+	forall( T ) void f( T, T ) { sout | "fT"; }
+	forall( T, U ) void f( T, U ) { sout | "fTU"; }
 
 	int x;
 	float y;
-	int *z;
-	float *w;
-
+	int * z;
+	float * w;
+
+	f( x, x );
+	f( y, y );
+	f( w, w );
 	f( x, y );
 	f( z, w );
@@ -50,11 +58,16 @@
 
 forall( T )
-void swap( T left, T right ) {
-	T temp = left;
-	left = right;
-	right = temp;
-}
-
-trait sumable( T ) {
+void swap( T & left, T & right ) {						// by reference
+    T temp = left;
+    left = right;
+    right = temp;
+}
+
+forall( T )
+[ T, T ] swap( T i, T j ) {								// by value
+    return [ j, i ];
+}
+
+forall( T ) trait sumable {
 	void ?{}( T &, zero_t );							// 0 literal constructor
 	T ?+?( T, T );										// assortment of additions
@@ -64,5 +77,5 @@
 }; // sumable
 
-forall( T | sumable( T ) )						// use trait
+forall( T | sumable( T ) )								// use trait
 T sum( size_t size, T a[] ) {
 	T total = 0;										// initialize by 0 constructor
@@ -72,5 +85,5 @@
 } // sum
 
-forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &,T ); } )
+forall( T | { T ?+?( T, T ); T ?++( T & ); [T] ?+=?( T &, T ); } )
 T twice( T t ) {
 	return t + t;
@@ -82,12 +95,17 @@
 }
 
-int fred() {
-	int x = 1, y = 2, a[10];
+void fred() {
+	int x = 1, y = 2, a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 	float f;
 
+	sout | x | y;
 	swap( x, y );
-	twice( x );
+	sout | x | y | nl | swap( x, y );
+	// [ x, y ] = swap( y, x );
+	sout | twice( ' ' ) | ' ' | twice( 0hh ) | twice( 1h ) | twice( 0n ) | twice( 2 )
+		 | twice( 3.2f ) | twice( 3.2 ) | twice( 3.2d ) | twice( 3.2+1.5i ) | twice( x );
 	f = min( 4.0, 3.0 );
-	sum( 10, a );
+	sout | f | min( 4.0, 3.0 );
+	sout | sum( 10, a );
 }
 
@@ -186,8 +204,8 @@
 
 forall( T ) {
-	extern "C" {
+//	extern "C" {
 		struct SS { T t; };
-		T foo( T ) {}
-	}
+		T foo( T p ) { return p; }
+//	}
 }
 
@@ -195,8 +213,9 @@
 W(int,int) w;
 
-int jane() {
+void jane() {
 //	int j = bar( 3, 4 );
 	int k = baz( 3, 4, 5 );
 	int i = foo( 3 );
+	sout | k | i;
 }
 
@@ -211,4 +230,5 @@
 	T t;
 	T t2 = t;
+	sout | &tr | tp;
 }
 
@@ -242,5 +262,8 @@
 
 int main( void ) {
-    #pragma GCC warning "Compiled"                      // force non-empty .expect file, NO TABS!!!
+	g1();
+	g2();
+	fred();
+	jane();
 }
 
