Index: src/Common/PersistentMap.h
===================================================================
--- src/Common/PersistentMap.h	(revision b8665e3c26703eff3fd484461181d10e4ebc049a)
+++ src/Common/PersistentMap.h	(revision b419abbf67c78a1c8cb7d489fe599026745bad2b)
@@ -114,18 +114,4 @@
 	}
 
-	// PersistentMap( Mode m, Base&& b ) : data(), mode(m) {
-	// 	init<Base>(std::move(b));
-	// }
-
-	// template<typename P, typename K, typename V>
-	// PersistentMap( Mode m, P&& o, K&& k, V&& v ) : data(), mode(m) {
-	// 	init<Ins>(std::forward<P>(o), std::forward<K>(k), std::forward<V>(v));
-	// }
-
-	// template<typename P, typename K>
-	// PersistentMap( Mode m, P&& o, K&& k ) : data(), mode(m) {
-	// 	init<Rem>(std::forward<P>(o), std::forward<K>(k));
-	// }
-
 public:
 	using size_type = std::size_t;
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision b8665e3c26703eff3fd484461181d10e4ebc049a)
+++ src/SymTab/Indexer.cc	(revision b419abbf67c78a1c8cb7d489fe599026745bad2b)
@@ -17,5 +17,4 @@
 
 #include <cassert>                 // for assert, strict_dynamic_cast
-#include <iostream>                // for operator<<, basic_ostream, ostream
 #include <string>                  // for string, operator<<, operator!=
 #include <memory>                  // for shared_ptr, make_shared
@@ -40,74 +39,37 @@
 #include "SynTree/Type.h"          // for Type, StructInstType, UnionInstType
 
-#define debugPrint(x) if ( doDebug ) { std::cerr << x; }
-
 namespace SymTab {
 
 	// Statistics block
-	// namespace {
-
-	// 	static inline auto stats_idtable() {
-	// 		using namespace Stats::Counters;
-	// 		static auto group = build<CounterGroup>("IdTable");
-	// 		static struct {
-	// 			SimpleCounter * find;
-	// 			AverageCounter<double> * size;
-	// 			AverageCounter<double> * key;
-	// 		} ret = {
-	// 			.find = build<SimpleCounter>("Find calls", group),
-	// 			.size = build<AverageCounter<double>>("Average Size", group),
-	// 			.key  = build<AverageCounter<double>>("Average Key Size", group),
-	// 		};
-	// 		return ret;
-	// 	}
-
-	// 	static inline auto stats_indexers() {
-	// 		using namespace Stats::Counters;
-	// 		static auto group   = build<CounterGroup>("Indexers");
-	// 		static struct {
-	// 			SimpleCounter * count;
-	// 			AverageCounter<double> * size;
-	// 			AverageCounter<double> * depth_a;
-	// 			MaxCounter<size_t> * depth_m;
-	// 			SimpleCounter * new_scopes;
-	// 			AverageCounter<double> * avg_scope_depth;
-	// 			MaxCounter<size_t> * max_scope_depth;
-	// 			SimpleCounter * add_calls;
-	// 			SimpleCounter * lookup_calls;
-	// 			SimpleCounter * map_lookups;
-	// 		} ret = {
-	// 			.count   = build<SimpleCounter>("Count", group),
-	// 			.size    = build<AverageCounter<double>>("Average Size", group),
-	// 			.depth_a = build<AverageCounter<double>>("Average Depth", group),
-	// 			.depth_m = build<MaxCounter<size_t>>("Max Depth", group),
-	// 			.new_scopes = build<SimpleCounter>("Scopes", group),
-	// 			.avg_scope_depth = build<AverageCounter<double>>("Average Scope", group),
-	// 			.max_scope_depth = build<MaxCounter<size_t>>("Max Scope", group),
-	// 			.add_calls = build<SimpleCounter>("Add Calls", group),
-	// 			.lookup_calls = build<SimpleCounter>("Lookup Calls", group),
-	// 			.map_lookups = build<SimpleCounter>("Map Lookups", group),
-	// 		};
-	// 		return ret;
-	// 	}
-	// }
-
-	// std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) {
-	// 	return out << "(" << data.id << "," << data.baseExpr << ")";
-	// }
-
-	// void dump( const Indexer::IdTable &table, std::ostream &os ) {
-	// 	for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) {
-	// 		for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) {
-	// 			os << mangle->second << std::endl;
-	// 		}
-	// 	}
-	// }
-
-	// template< typename Decl >
-	// void dump( const PersistentMap< std::string, Decl* > &table, std::ostream &os ) {
-	// 	for ( auto decl : table ) {
-	// 		os << decl.second << std::endl;
-	// 	} // for
-	// }
+	namespace {
+		static inline auto stats() {
+			using namespace Stats::Counters;
+			static auto group   = build<CounterGroup>("Indexers");
+			static struct {
+				SimpleCounter * count;
+				AverageCounter<double> * size;
+				SimpleCounter * new_scopes;
+				SimpleCounter * lazy_scopes;
+				AverageCounter<double> * avg_scope_depth;
+				MaxCounter<size_t> * max_scope_depth;
+				SimpleCounter * add_calls;
+				SimpleCounter * lookup_calls;
+				SimpleCounter * map_lookups;
+				SimpleCounter * map_mutations;
+			} ret = {
+				.count   = build<SimpleCounter>("Count", group),
+				.size    = build<AverageCounter<double>>("Average Size", group),
+				.new_scopes = build<SimpleCounter>("Scopes", group),
+				.lazy_scopes = build<SimpleCounter>("Lazy Scopes", group),
+				.avg_scope_depth = build<AverageCounter<double>>("Average Scope", group),
+				.max_scope_depth = build<MaxCounter<size_t>>("Max Scope", group),
+				.add_calls = build<SimpleCounter>("Add Calls", group),
+				.lookup_calls = build<SimpleCounter>("Lookup Calls", group),
+				.map_lookups = build<SimpleCounter>("Map Lookups", group),
+				.map_mutations = build<SimpleCounter>("Map Mutations", group)
+			};
+			return ret;
+		}
+	}
 
 	void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
@@ -162,11 +124,12 @@
 		}
 
-		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
-		// the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
-		// a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
-		// and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
-		// If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
-		// ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
-		// then the generated copy constructor is unavailable, and likewise for the assignment operator.
+		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
+		// determinethe set of ctor/dtor/assign that can be used  by the requester. In particular, 
+		// if the user defines a default ctor, then the generated default ctor is unavailable, 
+		// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
+		// field ctors are available. If the user defines any ctor then the generated default ctor 
+		// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
+		// anything that looks like a copy constructor, then the generated copy constructor is 
+		// unavailable, and likewise for the assignment operator.
 		for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
 			ValueType & val = pair.second;
@@ -177,11 +140,13 @@
 
 				// only implicitly delete non-user defined functions that are not intrinsic, and are
-				// not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
-				// do not pass along the non-user-defined copy functions since signatures do not have to match,
-				// and the generated functions will often be cheaper.
+				// not copy functions (assignment or copy constructor). If a  user-defined copy 
+				// function exists, do not pass along the non-user-defined copy functions since 
+				// signatures do not have to match, and the generated functions will often be 
+				// cheaper.
 				if ( isNotUserDefinedFunc ) {
 					if ( isCopyFunc ) {
-						// Skip over non-user-defined copy functions when there is a user-defined copy function.
-						// Since their signatures do not have to be exact, deleting them is the wrong choice.
+						// Skip over non-user-defined copy functions when there is a user-defined 
+						// copy function. Since their signatures do not have to be exact, deleting 
+						// them is the wrong choice.
 						if ( existsUserDefinedCopyFunc ) continue;
 					} else {
@@ -198,36 +163,43 @@
 	Indexer::Indexer() 
 	: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
-	  prevScope(), scope( 0 ) {}
-
-	Indexer::~Indexer() {}
+	  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
+
+	Indexer::~Indexer() {
+		stats().size->push( idTable ? idTable->size() : 0 );
+	}
+
+	void Indexer::lazyInitScope() {
+		if ( repScope < scope ) {
+			++*stats().lazy_scopes;
+			// create rollback
+			prevScope = std::make_shared<Indexer>( *this );
+			// update repScope
+			repScope = scope;
+		}
+	}
 
 	void Indexer::enterScope() {
-		// save current state in prevScope and increment scope
-		prevScope = std::make_shared<Indexer>( *this );
 		++scope;
 
-		// if ( doDebug ) {
-		// 	std::cerr << "--- Entering scope " << scope << std::endl;
-		// }
+		++*stats().new_scopes;
+		stats().avg_scope_depth->push( scope );
+		stats().max_scope_depth->push( scope );
 	}
 
 	void Indexer::leaveScope() {
-		// if ( doDebug ) {
-		// 	std::cerr << "--- Leaving scope " << scope << " containing" << std::endl;
-		// 	dump( idTable, std::cerr );
-		// 	dump( typeTable, std::cerr );
-		// 	dump( structTable, std::cerr );
-		// 	dump( enumTable, std::cerr );
-		// 	dump( unionTable, std::cerr );
-		// 	dump( traitTable, std::cerr );
-		// }
-
-		// replace all maps and scope index with previous scope's versions
-		*this = *prevScope;
+		if ( repScope == scope ) {
+			// replace all maps and scope index with previous scope's versions
+			Ptr prev = prevScope;           // make sure prevScope stays live
+			*this = std::move(*prevScope);  // replace with previous scope
+		}
+
+		--scope;
 	}
 
 	void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
+		++*stats().lookup_calls;
 		if ( ! idTable ) return;
 
+		++*stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return;
@@ -244,5 +216,7 @@
 
 	NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
+		++*stats().lookup_calls;
 		if ( ! typeTable ) return nullptr;
+		++*stats().map_lookups;
 		auto it = typeTable->find( id );
 		return it == typeTable->end() ? nullptr : it->second.decl;
@@ -250,5 +224,7 @@
 
 	StructDecl *Indexer::lookupStruct( const std::string &id ) const {
+		++*stats().lookup_calls;
 		if ( ! structTable ) return nullptr;
+		++*stats().map_lookups;
 		auto it = structTable->find( id );
 		return it == structTable->end() ? nullptr : it->second.decl;
@@ -256,5 +232,7 @@
 
 	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
+		++*stats().lookup_calls;
 		if ( ! enumTable ) return nullptr;
+		++*stats().map_lookups;
 		auto it = enumTable->find( id );
 		return it == enumTable->end() ? nullptr : it->second.decl;
@@ -262,5 +240,7 @@
 
 	UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
+		++*stats().lookup_calls;
 		if ( ! unionTable ) return nullptr;
+		++*stats().map_lookups;
 		auto it = unionTable->find( id );
 		return it == unionTable->end() ? nullptr : it->second.decl;
@@ -268,104 +248,20 @@
 
 	TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
+		++*stats().lookup_calls;
 		if ( ! traitTable ) return nullptr;
+		++*stats().map_lookups;
 		auto it = traitTable->find( id );
 		return it == traitTable->end() ? nullptr : it->second.decl;
 	}
 
-	const Indexer* Indexer::atScope( unsigned long scope ) const {
-		// scan back to scope; guaranteed one indexer per scope by construction of enterScope,
-		// final indexer in list has scope 0, cannot be > scope
+	const Indexer* Indexer::atScope( unsigned long target ) const {
+		// by lazy construction, final indexer in list has repScope 0, cannot be > target
+		// otherwise, will find first scope representing the target
 		const Indexer* indexer = this;
-		while ( indexer->scope > scope ) {
+		while ( indexer->repScope > target ) {
 			indexer = indexer->prevScope.get();
 		}
 		return indexer;
 	}
-
-	// const Indexer::IdData * Indexer::localLookupId( 
-	// 		const std::string &id, const std::string &mangleName ) const {
-	// 	if ( ! idTable ) return nullptr;
-
-	// 	// lookup name
-	// 	auto decls = idTable->find( id );
-	// 	if ( decls == idTable->end() ) return nullptr;
-
-	// 	// lookup mangleName
-	// 	// assume any mangle-table pointer added is non-null
-	// 	const MangleTable& mangleTable = *(decls->second);
-	// 	auto decl = mangleTable.find( mangleName );
-	// 	if ( decl == mangleTable.end() ) return nullptr;
-		
-	// 	// skip identifiers not defined in this scope
-	// 	if ( decl->second.scope != scope ) return nullptr;
-	// 	return &decl->second;
-	// }
-
-	// Indexer::IdData * Indexer::lookupIdAtScope( 
-	// 		const std::string &id, const std::string &mangleName, unsigned long scope ) {
-	// 	return const_cast<IdData *>(
-	// 		const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
-	// }
-
-	// NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
-
-	// 	if ( ! tables ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope < scope ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );
-
-	// 	++*stats_indexers().map_lookups;
-	// 	TypeTable::const_iterator ret = tables->typeTable.find( id );
-	// 	return ret != tables->typeTable.end() ? 
-	// 		++*stats_indexers().lookup_calls, ret->second : 
-	// 		tables->base.lookupTypeAtScope( id, scope );
-	// }
-
-	// StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
-	// 	if ( ! tables ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope < scope ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );
-
-	// 	++*stats_indexers().map_lookups;
-	// 	StructTable::const_iterator ret = tables->structTable.find( id );
-	// 	return ret != tables->structTable.end() ? 
-	// 		++*stats_indexers().lookup_calls, ret->second : 
-	// 		tables->base.lookupStructAtScope( id, scope );
-	// }
-
-	// EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
-	// 	if ( ! tables ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope < scope ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );
-
-	// 	++*stats_indexers().map_lookups;
-	// 	EnumTable::const_iterator ret = tables->enumTable.find( id );
-	// 	return ret != tables->enumTable.end() ? 
-	// 		++*stats_indexers().lookup_calls, ret->second : 
-	// 		tables->base.lookupEnumAtScope( id, scope );
-	// }
-
-	// UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
-	// 	if ( ! tables ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope < scope ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );
-
-	// 	++*stats_indexers().map_lookups;
-	// 	UnionTable::const_iterator ret = tables->unionTable.find( id );
-	// 	return ret != tables->unionTable.end() ? 
-	// 		++*stats_indexers().lookup_calls, ret->second : 
-	// 		tables->base.lookupUnionAtScope( id, scope );
-	// }
-
-	// TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
-	// 	if ( ! tables ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope < scope ) return ++*stats_indexers().lookup_calls, nullptr;
-	// 	if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );
-
-	// 	++*stats_indexers().map_lookups;
-	// 	TraitTable::const_iterator ret = tables->traitTable.find( id );
-	// 	return ret != tables->traitTable.end() ? 
-	// 		++*stats_indexers().lookup_calls, ret->second : 
-	// 		tables->base.lookupTraitAtScope( id, scope );
-	// }
 
 	NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
@@ -408,5 +304,6 @@
 			const Indexer::IdData & existing, DeclarationWithType *added, 
 			Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {
-		// if we're giving the same name mangling to things of different types then there is something wrong
+		// if we're giving the same name mangling to things of different types then there is 
+		// something wrong
 		assert( (isObject( added ) && isObject( existing.id ) )
 			|| ( isFunction( added ) && isFunction( existing.id ) ) );
@@ -454,4 +351,5 @@
 		if ( ! idTable ) return false;
 
+		++*stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return false;
@@ -473,4 +371,5 @@
 		if ( ! idTable ) return false;
 
+		++*stats().map_lookups;
 		auto decls = idTable->find( id );
 		if ( decls == idTable->end() ) return false;
@@ -491,6 +390,6 @@
 			DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 
 			BaseSyntaxNode * deleteStmt ) {
+		++*stats().add_calls;
 		if ( decl->name == "" ) return;
-		// debugPrint( "Adding Id " << decl->name << std::endl );
 		
 		const std::string &name = decl->name;
@@ -525,4 +424,5 @@
 			mangleTable = MangleTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto decls = idTable->find( name );
 			if ( decls == idTable->end() ) {
@@ -531,4 +431,5 @@
 				mangleTable = decls->second;
 				// skip in-scope repeat declarations of same identifier
+				++*stats().map_lookups;
 				auto existing = mangleTable->find( mangleName );
 				if ( existing != mangleTable->end()
@@ -538,4 +439,6 @@
 						if ( handleConflicts.mode == OnConflict::Delete ) {
 							// set delete expression for conflicting identifier
+							lazyInitScope();
+							*stats().map_mutations += 2;
 							idTable = idTable->set(
 								name,
@@ -551,4 +454,6 @@
 
 		// add/overwrite with new identifier
+		lazyInitScope();
+		*stats().map_mutations += 2;
 		idTable = idTable->set( 
 			name,
@@ -578,9 +483,11 @@
 			}
 		}
-		// does not need to be added to the table if both existing and added have a base that are the same
+		// does not need to be added to the table if both existing and added have a base that are 
+		// the same
 		return true;
 	}
 
 	void Indexer::addType( NamedTypeDecl *decl ) {
+		++*stats().add_calls;
 		const std::string &id = decl->name;
 
@@ -588,4 +495,5 @@
 			typeTable = TypeTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto existing = typeTable->find( id );
 			if ( existing != typeTable->end() 
@@ -594,4 +502,6 @@
 		}
 		
+		lazyInitScope();
+		++*stats().map_mutations;
 		typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
 	}
@@ -611,4 +521,5 @@
 
 	void Indexer::addStruct( StructDecl *decl ) {
+		++*stats().add_calls;
 		const std::string &id = decl->name;
 
@@ -616,4 +527,5 @@
 			structTable = StructTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto existing = structTable->find( id );
 			if ( existing != structTable->end()  
@@ -622,8 +534,11 @@
 		}
 
+		lazyInitScope();
+		++*stats().map_mutations;
 		structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
 	}
 
 	void Indexer::addEnum( EnumDecl *decl ) {
+		++*stats().add_calls;
 		const std::string &id = decl->name;
 
@@ -631,4 +546,5 @@
 			enumTable = EnumTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto existing = enumTable->find( id );
 			if ( existing != enumTable->end()  
@@ -637,4 +553,6 @@
 		}
 		
+		lazyInitScope();
+		++*stats().map_mutations;
 		enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
 	}
@@ -645,4 +563,5 @@
 
 	void Indexer::addUnion( UnionDecl *decl ) {
+		++*stats().add_calls;
 		const std::string &id = decl->name;
 
@@ -650,4 +569,5 @@
 			unionTable = UnionTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto existing = unionTable->find( id );
 			if ( existing != unionTable->end() 
@@ -656,8 +576,11 @@
 		}
 
+		lazyInitScope();
+		++*stats().map_mutations;
 		unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
 	}
 
 	void Indexer::addTrait( TraitDecl *decl ) {
+		++*stats().add_calls;
 		const std::string &id = decl->name;
 
@@ -665,4 +588,5 @@
 			traitTable = TraitTable::new_ptr();
 		} else {
+			++*stats().map_lookups;
 			auto existing = traitTable->find( id );
 			if ( existing != traitTable->end() 
@@ -671,4 +595,6 @@
 		}
 
+		lazyInitScope();
+		++*stats().map_mutations;
 		traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
 	}
@@ -722,29 +648,4 @@
 	}
 
-	// void Indexer::print( std::ostream &os, int indent ) const {
-	// 	using std::cerr;
-
-	// 	if ( tables ) {
-	// 		os << "--- scope " << tables->scope << " ---" << std::endl;
-
-	// 		os << "===idTable===" << std::endl;
-	// 		dump( tables->idTable, os );
-	// 		os << "===typeTable===" << std::endl;
-	// 		dump( tables->typeTable, os );
-	// 		os << "===structTable===" << std::endl;
-	// 		dump( tables->structTable, os );
-	// 		os << "===enumTable===" << std::endl;
-	// 		dump( tables->enumTable, os );
-	// 		os << "===unionTable===" << std::endl;
-	// 		dump( tables->unionTable, os );
-	// 		os << "===contextTable===" << std::endl;
-	// 		dump( tables->traitTable, os );
-
-	// 		tables->base.print( os, indent );
-	// 	} else {
-	// 		os << "--- end ---" << std::endl;
-	// 	}
-	// }
-
 	Expression * Indexer::IdData::combine( ResolvExpr::Cost & cost ) const {
 		Expression * ret = nullptr;
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision b8665e3c26703eff3fd484461181d10e4ebc049a)
+++ src/SymTab/Indexer.h	(revision b419abbf67c78a1c8cb7d489fe599026745bad2b)
@@ -17,5 +17,4 @@
 
 #include <functional>              // for function
-#include <iosfwd>                  // for ostream
 #include <list>                    // for list
 #include <memory>                  // for shared_ptr, enable_shared_from_this
@@ -35,6 +34,6 @@
 		virtual ~Indexer();
 
-		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
-		// explicitly when scopes begin and end
+		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
+		// tell the indexer explicitly when scopes begin and end
 		void enterScope();
 		void leaveScope();
@@ -74,16 +73,4 @@
 		TraitDecl *lookupTrait( const std::string &id ) const;
 
-		// void print( std::ostream &os, int indent = 0 ) const;
-
-		/// looks up a specific mangled ID in local scope only
-		// IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
-		// const IdData * localLookupId( const std::string &id, const std::string &mangleName ) const;
-		// equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
-		// NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
-		// StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
-		// EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
-		// UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
-		// TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
-
 		/// Gets the type declaration with the given ID at global scope
 		NamedTypeDecl *globalLookupType( const std::string &id ) const;
@@ -118,5 +105,4 @@
 		void addFunctionType( FunctionType * ftype );
 
-		// bool doDebug = false; ///< Display debugging trace?
 	  private:
 	  	/// Wraps a Decl* with a scope
@@ -148,4 +134,8 @@
 		Ptr prevScope;                 ///< reference to indexer for parent scope
 		unsigned long scope;           ///< Scope index of this indexer
+		unsigned long repScope;        ///< Scope index of currently represented scope
+
+		/// Ensures that a proper backtracking scope exists before a mutation
+		void lazyInitScope();
 
 		/// Gets the indexer at the given scope
