Index: src/ResolvExpr/FindOpenVars.cc
===================================================================
--- src/ResolvExpr/FindOpenVars.cc	(revision 9a1960866db1333a2a85fb5a506c9d9fafb42ba1)
+++ src/ResolvExpr/FindOpenVars.cc	(revision 9519aba7964e345345fd95d48fcca0103be2c788)
@@ -19,4 +19,6 @@
 #include <map>                    // for map<>::mapped_type
 
+#include "AST/Pass.hpp"
+#include "AST/Type.hpp"
 #include "Common/PassVisitor.h"
 #include "SynTree/Declaration.h"  // for TypeDecl, DeclarationWithType (ptr ...
@@ -24,6 +26,6 @@
 
 namespace ResolvExpr {
-	struct FindOpenVars : public WithGuards {
-		FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
+	struct FindOpenVars_old : public WithGuards {
+		FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
 
 		void previsit( PointerType * pointerType );
@@ -40,13 +42,13 @@
 
 	void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
-		PassVisitor<FindOpenVars> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
+		PassVisitor<FindOpenVars_old> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
 		type->accept( finder );
 	}
 
-	FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
+	FindOpenVars_old::FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
 		: openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen )	{
 	}
 
-	void FindOpenVars::common_action( Type *type ) {
+	void FindOpenVars_old::common_action( Type *type ) {
 		if ( nextIsOpen ) {
 			for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
@@ -76,13 +78,13 @@
 	}
 
-	void FindOpenVars::previsit(PointerType *pointerType) {
+	void FindOpenVars_old::previsit(PointerType *pointerType) {
 		common_action( pointerType );
 	}
 
-	void FindOpenVars::previsit(ArrayType *arrayType) {
+	void FindOpenVars_old::previsit(ArrayType *arrayType) {
 		common_action( arrayType );
 	}
 
-	void FindOpenVars::previsit(FunctionType *functionType) {
+	void FindOpenVars_old::previsit(FunctionType *functionType) {
 		common_action( functionType );
 		nextIsOpen = ! nextIsOpen;
@@ -90,6 +92,45 @@
 	}
 
-	void FindOpenVars::previsit(TupleType *tupleType) {
+	void FindOpenVars_old::previsit(TupleType *tupleType) {
 		common_action( tupleType );
+	}
+
+	namespace {
+		struct FindOpenVars_new final : public ast::WithGuards {
+			ast::OpenVarSet & open;
+			ast::OpenVarSet & closed;
+			ast::AssertionSet & need;
+			ast::AssertionSet & have;
+			bool nextIsOpen;
+
+			FindOpenVars_new( 
+				ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n, 
+				ast::AssertionSet & h, FirstMode firstIsOpen )
+			: open( o ), closed( c ), need( n ), have( h ), nextIsOpen( firstIsOpen ) {}
+
+			void previsit( const ast::FunctionType * type ) {
+				// mark open/closed variables
+				if ( nextIsOpen ) {
+					for ( const ast::TypeDecl * decl : type->forall ) {
+						open[ decl->name ] = ast::TypeDecl::Data{ decl };
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
+							need[ assert ].isUsed = false;
+						}
+					}
+				} else {
+					for ( const ast::TypeDecl * decl : type->forall ) {
+						closed[ decl->name ] = ast::TypeDecl::Data{ decl };
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
+							have[ assert ].isUsed = false;
+						}
+					}
+				}
+
+				// flip open variables for contained function types
+				nextIsOpen = ! nextIsOpen;
+				GuardAction( [this](){ nextIsOpen = ! nextIsOpen; } );
+			}
+
+		};
 	}
 
@@ -97,7 +138,6 @@
 			const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed, 
 			ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ) {
-		#warning unimplemented
-		(void)type; (void)open; (void)closed; (void)need; (void)have; (void)firstIsOpen;
-		assert(false);
+		ast::Pass< FindOpenVars_new > finder{ open, closed, need, have, firstIsOpen };
+		type->accept( finder );
 	}
 } // namespace ResolvExpr
