Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/Common/utility.h	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -252,8 +252,8 @@
 
 template< typename T >
-struct reverseIterate_t {
+struct reverse_iterate_t {
 	T& ref;
 
-	reverseIterate_t( T & ref ) : ref(ref) {}
+	reverse_iterate_t( T & ref ) : ref(ref) {}
 
 	typedef typename T::reverse_iterator iterator;
@@ -263,8 +263,44 @@
 
 template< typename T >
-reverseIterate_t< T > reverseIterate( T & ref ) {
-	return reverseIterate_t< T >( ref );
-}
-
+reverse_iterate_t< T > reverseIterate( T & ref ) {
+	return reverse_iterate_t< T >( ref );
+}
+
+// -----------------------------------------------------------------------------
+// Helper struct and function to support
+// for ( val : group_iterate( container1, container2, ... ) ) {}
+// syntax to have a for each that iterates multiple containers of the same length
+// TODO: update to use variadic arguments
+
+template< typename T1, typename T2 >
+struct group_iterate_t {
+	group_iterate_t( const T1 & v1, const T2 & v2 ) : args(v1, v2) {
+		assertf(v1.size() == v2.size(), "group iteration requires containers of the same size.");
+	};
+
+	struct iterator {
+		typedef std::tuple<typename T1::value_type, typename T2::value_type> value_type;
+		typedef typename T1::iterator T1Iter;
+		typedef typename T2::iterator T2Iter;
+		typedef std::tuple<T1Iter, T2Iter> IterTuple;
+		IterTuple it;
+		iterator( T1Iter i1, T2Iter i2 ) : it( i1, i2 ) {}
+		iterator operator++() {
+			return iterator( ++std::get<0>(it), ++std::get<1>(it) );
+		}
+		bool operator!=( const iterator &other ) const { return it != other.it; }
+		value_type operator*() const { return std::make_tuple( *std::get<0>(it), *std::get<1>(it) ); }
+	};
+	iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); }
+	iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); }
+
+private:
+	std::tuple<T1, T2> args;
+};
+
+template< typename... Args >
+group_iterate_t<Args...> group_iterate( const Args &... args ) {
+	return group_iterate_t<Args...>(args...);
+}
 #endif // _UTILITY_H
 
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/Parser/TypeData.cc	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -57,4 +57,5 @@
 		aggregate.actuals = nullptr;
 		aggregate.fields = nullptr;
+		aggregate.body = false;
 		break;
 	  case AggregateInst:
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/ResolvExpr/Unify.cc	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -123,31 +123,4 @@
 	}
 
-	struct CompleteTypeChecker : public Visitor {
-		virtual void visit( VoidType *basicType ) { status = false; }
-		virtual void visit( BasicType *basicType ) {}
-		virtual void visit( PointerType *pointerType ) {}
-		virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }
-		virtual void visit( FunctionType *functionType ) {}
-		virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }
-		virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }
-		// xxx - enum inst does not currently contain a pointer to base, this should be fixed.
-		virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }
-		virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }
-		virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }
-		virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness
-		virtual void visit( TypeofType *typeofType ) { assert( false ); }
-		virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here
-		virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?
-		virtual void visit( ZeroType *zeroType ) {}
-		virtual void visit( OneType *oneType ) {}
-		bool status = true;
-	};
-	bool isComplete( Type * type ) {
-		CompleteTypeChecker checker;
-		assert( type );
-		type->accept( checker );
-		return checker.status;
-	}
-
 	bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
 		switch ( data.kind ) {
@@ -158,5 +131,5 @@
 			// type must also be complete
 			// xxx - should this also check that type is not a tuple type and that it's not a ttype?
-			return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
+			return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() );
 		  case TypeDecl::Ftype:
 			return isFtype( type, indexer );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/SymTab/Validate.cc	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -114,5 +114,5 @@
 		LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
 	  private:
-  		using Indexer::visit;
+  		using Parent::visit;
 		void visit( StructInstType *structInst ) final;
 		void visit( UnionInstType *unionInst ) final;
@@ -131,11 +131,12 @@
 
 	/// Replaces array and function types in forall lists by appropriate pointer type
-	class Pass3 : public Indexer {
+	class Pass3 final : public Indexer {
 		typedef Indexer Parent;
 	  public:
+	  	using Parent::visit;
 		Pass3( const Indexer *indexer );
 	  private:
-		virtual void visit( ObjectDecl *object );
-		virtual void visit( FunctionDecl *func );
+		virtual void visit( ObjectDecl *object ) override;
+		virtual void visit( FunctionDecl *func ) override;
 
 		const Indexer *indexer;
@@ -375,12 +376,12 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
-		Parent::visit( contextInst );
-		if ( contextInst->get_name() == "sized" ) {
+	void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
+		Parent::visit( traitInst );
+		if ( traitInst->get_name() == "sized" ) {
 			// "sized" is a special trait with no members - just flick the sized status on for the type variable
-			if ( contextInst->get_parameters().size() != 1 ) {
-				throw SemanticError( "incorrect number of context parameters: ", contextInst );
+			if ( traitInst->get_parameters().size() != 1 ) {
+				throw SemanticError( "incorrect number of trait parameters: ", traitInst );
 			}
-			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
+			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
 			TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
 			TypeDecl * decl = inst->get_baseType();
@@ -389,27 +390,33 @@
 			return;
 		}
-		TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
-		if ( ! ctx ) {
-			throw SemanticError( "use of undeclared context " + contextInst->get_name() );
-		} // if
-		for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
-			for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
-				if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
-					cloneAll( otherCtx->get_members(), contextInst->get_members() );
-				} else {
-					contextInst->get_members().push_back( (*assert )->clone() );
-				} // if
+		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
+		if ( ! traitDecl ) {
+			throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
+		} // if
+		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
+			throw SemanticError( "incorrect number of trait parameters: ", traitInst );
+		} // if
+
+		for ( TypeDecl * td : traitDecl->get_parameters() ) {
+			for ( DeclarationWithType * assert : td->get_assertions() ) {
+				traitInst->get_members().push_back( assert->clone() );
 			} // for
 		} // for
 
-		if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
-			throw SemanticError( "incorrect number of context parameters: ", contextInst );
-		} // if
-
-		// need to clone members of the context for ownership purposes
+		// need to clone members of the trait for ownership purposes
 		std::list< Declaration * > members;
-		std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
-
-		applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
+		std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
+
+		applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
+
+		// need to carry over the 'sized' status of each decl in the instance
+		for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
+			TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
+			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
+				TypeDecl * formalDecl = std::get<0>(p);
+				TypeDecl * instDecl = inst->get_baseType();
+				if ( formalDecl->get_sized() ) instDecl->set_sized( true );
+			}
+		}
 	}
 
@@ -457,25 +464,26 @@
 	}
 
-	/// Fix up assertions
-	void forallFixer( Type *func ) {
-		for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
+	/// Fix up assertions - flattens assertion lists, removing all trait instances
+	void forallFixer( Type * func ) {
+		for ( TypeDecl * type : func->get_forall() ) {
 			std::list< DeclarationWithType * > toBeDone, nextRound;
-			toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
+			toBeDone.splice( toBeDone.end(), type->get_assertions() );
 			while ( ! toBeDone.empty() ) {
-				for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
-					if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
-						for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
-							DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
-							assert( dwt );
+				for ( DeclarationWithType * assertion : toBeDone ) {
+					if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
+						// expand trait instance into all of its members
+						for ( Declaration * member : traitInst->get_members() ) {
+							DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
 							nextRound.push_back( dwt->clone() );
 						}
-						delete ctx;
+						delete traitInst;
 					} else {
+						// pass assertion through
 						FixFunction fixer;
-						*assertion = (*assertion )->acceptMutator( fixer );
+						assertion = assertion->acceptMutator( fixer );
 						if ( fixer.get_isVoid() ) {
 							throw SemanticError( "invalid type void in assertion of function ", func );
 						}
-						(*type )->get_assertions().push_back( *assertion );
+						type->get_assertions().push_back( assertion );
 					} // if
 				} // for
Index: src/SynTree/AggregateDecl.cc
===================================================================
--- src/SynTree/AggregateDecl.cc	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/SynTree/AggregateDecl.cc	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -69,5 +69,5 @@
 std::string EnumDecl::typeString() const { return "enum"; }
 
-std::string TraitDecl::typeString() const { return "context"; }
+std::string TraitDecl::typeString() const { return "trait"; }
 
 // Local Variables: //
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/SynTree/ReferenceToType.cc	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -64,4 +64,6 @@
 }
 
+bool StructInstType::isComplete() const { return baseStruct->has_body(); }
+
 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseStruct );
@@ -90,4 +92,6 @@
 }
 
+bool UnionInstType::isComplete() const { return baseUnion->has_body(); }
+
 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseUnion );
@@ -111,5 +115,5 @@
 std::string EnumInstType::typeString() const { return "enum"; }
 
-std::string TraitInstType::typeString() const { return "context"; }
+std::string TraitInstType::typeString() const { return "trait"; }
 
 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
@@ -120,4 +124,6 @@
 	deleteAll( members );
 }
+
+bool TraitInstType::isComplete() const { assert( false ); }
 
 TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name ) {
@@ -143,4 +149,6 @@
 std::string TypeInstType::typeString() const { return "type"; }
 
+bool TypeInstType::isComplete() const { return baseType->isComplete(); }
+
 void TypeInstType::print( std::ostream &os, int indent ) const {
 	using std::endl;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/SynTree/Type.h	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -74,4 +74,6 @@
 	virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
 
+	virtual bool isComplete() const { return true; }
+
 	virtual Type *clone() const = 0;
 	virtual void accept( Visitor &v ) = 0;
@@ -90,4 +92,5 @@
 
 	virtual unsigned size() const { return 0; };
+	virtual bool isComplete() const { return false; }
 
 	virtual VoidType *clone() const { return new VoidType( *this ); }
@@ -185,4 +188,6 @@
 	void set_isStatic( bool newValue ) { isStatic = newValue; }
 
+	virtual bool isComplete() const { return ! isVarLen; }
+
 	virtual ArrayType *clone() const { return new ArrayType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -258,4 +263,6 @@
 	std::list<TypeDecl*> * get_baseParameters();
 
+	virtual bool isComplete() const;
+
 	/// Looks up the members of this struct named "name" and places them into "foundDecls".
 	/// Clones declarations into "foundDecls", caller responsible for freeing
@@ -287,4 +294,6 @@
 	std::list<TypeDecl*> * get_baseParameters();
 
+	virtual bool isComplete() const;
+
 	/// looks up the members of this union named "name" and places them into "foundDecls"
 	/// Clones declarations into "foundDecls", caller responsible for freeing
@@ -310,4 +319,7 @@
 	EnumInstType( const EnumInstType &other ) : Parent( other ) {}
 
+	// xxx - enum inst does not currently contain a pointer to base, this should be fixed.
+	// virtual bool isComplete() const { return baseEnum()->hasBody(); }
+
 	virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -325,4 +337,6 @@
 
 	std::list< Declaration* >& get_members() { return members; }
+
+	virtual bool isComplete() const;
 
 	virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
@@ -349,4 +363,6 @@
 	bool get_isFtype() const { return isFtype; }
 	void set_isFtype( bool newValue ) { isFtype = newValue; }
+
+	virtual bool isComplete() const;
 
 	virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
@@ -382,4 +398,6 @@
 	}
 
+	// virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
+
 	virtual TupleType *clone() const { return new TupleType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -398,4 +416,6 @@
 	Expression *get_expr() const { return expr; }
 	void set_expr( Expression *newValue ) { expr = newValue; }
+
+	virtual bool isComplete() const { assert( false ); return false; }
 
 	virtual TypeofType *clone() const { return new TypeofType( *this ); }
@@ -423,4 +443,6 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
+	virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
+
 	virtual AttrType *clone() const { return new AttrType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -439,4 +461,6 @@
 	VarArgsType();
 	VarArgsType( Type::Qualifiers tq );
+
+	virtual bool isComplete() const{ return true; } // xxx - is this right?
 
 	virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
Index: src/tests/vector/array.c
===================================================================
--- src/tests/vector/array.c	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/tests/vector/array.c	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -16,11 +16,8 @@
 #include "array.h"
 
-/// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
-/// [ array_iterator begin, array_iterator end ]
-/// get_iterators( array_type array )
-/// {
-///   begin = 0;
-///   end = last( array );
-/// }
+forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
+[ elt_type * begin, elt_type * end ] get_iterators( array_type * array ) {
+	return [ begin( array ), end( array ) ];
+}
 
 // The first element is always at index 0.
Index: src/tests/vector/array.h
===================================================================
--- src/tests/vector/array.h	(revision 0bfaf80c317420b403ff7b65089016bc08f99922)
+++ src/tests/vector/array.h	(revision 4a9ccc35f7b5fed64bf53eee245fc9caa37f687d)
@@ -32,8 +32,6 @@
 // implement iterator_for
 
-typedef int array_iterator;
-
-/// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
-/// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
+forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
+[ elt_type * begin, elt_type * end ] get_iterators( array_type * );
 
 
