Index: translator/GenPoly/Box.cc
===================================================================
--- translator/GenPoly/Box.cc	(revision bdd516a5257cb93cc0c5b4a4c343cc112252022a)
+++ translator/GenPoly/Box.cc	(revision 5c7fb6c8dfabfe6c6b4c365a4f378706430fd1bf)
@@ -7,4 +7,5 @@
 
 #include <set>
+#include <stack>
 #include <string>
 #include <iterator>
@@ -50,4 +51,5 @@
 	    virtual Type *mutate( FunctionType *pointerType );
   
+	    virtual void doBeginScope();
 	    virtual void doEndScope();
 	  private:
@@ -66,5 +68,6 @@
   
 	    std::map< std::string, DeclarationWithType *> assignOps;
-	    std::map< std::string, FunctionDecl *> adapters;
+	    typedef std::map< std::string, FunctionDecl *> AdapterMap;
+	    std::stack< AdapterMap > adapters;
 	    DeclarationWithType *retval;
 	    bool useRetval;
@@ -126,4 +129,8 @@
 
     namespace {
+	std::string makeAdapterName( const std::string &mangleName ) {
+	    return "_adapter" + mangleName;
+	}
+
 	bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
 	    bool doTransform = false;
@@ -219,5 +226,5 @@
 		retval = oldRetval;
 		useRetval = oldUseRetval;
-		doEndScope();
+		// doEndScope();
 	    } // if
 	    return functionDecl;
@@ -316,5 +323,5 @@
 	    Type *concrete = env->lookup( typeName );
 	    if ( concrete == 0 ) {
-		throw SemanticError( "Unbound type variable " + typeName + " in", appExpr );
+		throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
 	    } // if
 	    return addRetParam( appExpr, function, concrete, arg );
@@ -326,6 +333,9 @@
 		ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
 	    } // if
+	    std::string mangleName = SymTab::Mangler::mangle( function );
+	    std::string adapterName = makeAdapterName( mangleName );
+
 	    appExpr->get_args().push_front( appExpr->get_function() );
-	    appExpr->set_function( new NameExpr( "_adapter" + SymTab::Mangler::mangle( function ) ) );
+	    appExpr->set_function( new NameExpr( adapterName ) );
   
 	    return ret;
@@ -337,5 +347,9 @@
 	    TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
 	    if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
-		if ( arg->get_results().front()->get_isLvalue() ) {
+	        if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {
+	            // if the argument's type is a type parameter, we don't need to box again!
+	            return;
+	        } else if ( arg->get_results().front()->get_isLvalue() ) {
+	            // VariableExpr and MemberExpr are lvalues
 		    arg = new AddressExpr( arg );
 		} else {
@@ -371,5 +385,5 @@
 	    for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
 ///     std::cout << "parameter is ";
-///     (*param)->print( std::cout );
+///     (*param)->print( std::fcout );
 ///     std::cout << std::endl << "argument is ";
 ///     (*arg)->print( std::cout );
@@ -448,4 +462,6 @@
 	}
 
+
+
 	FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
 	    FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
@@ -496,5 +512,6 @@
 	    CompoundStmt *adapterBody = new CompoundStmt( noLabels );
 	    adapterBody->get_kids().push_back( bodyStmt );
-	    return new FunctionDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
+	    std::string adapterName = makeAdapterName( mangleName );
+	    return new FunctionDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
 	}
 
@@ -515,9 +532,18 @@
 		assert( env );
 		env->apply( realFunction );
+
 		std::string mangleName = SymTab::Mangler::mangle( realFunction );
 		if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
-		    std::map< std::string, FunctionDecl *>::iterator adapter = adapters.find( mangleName );
-		    if ( adapter == adapters.end() ) {
-			FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
+		    AdapterMap & adapters = Pass1::adapters.top();
+		    AdapterMap::iterator adapter = adapters.find( mangleName );
+
+		    if ( needsAdapter( realFunction, exprTyVars, true ) ) {
+		    	// the function still contains type variables, which means we are in a polymorphic
+		    	// context and the adapter function is a parameter - call the parameter and don't 
+		    	// create a new adapter.
+		        appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
+		        continue;
+		    } else if ( adapter == adapters.end() ) {
+		    	FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
 			adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) );
 			stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
@@ -525,4 +551,5 @@
 		    assert( adapter != adapters.end() );
 		    appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
+		    // appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
 		    adaptersDone.insert( adaptersDone.begin(), mangleName );
 		} // if
@@ -845,6 +872,10 @@
 	}
 
+	void Pass1::doBeginScope() {
+	    adapters.push(AdapterMap());
+	}
+
 	void Pass1::doEndScope() {
-	    adapters.clear();
+	    adapters.pop();
 	}
 
@@ -865,5 +896,6 @@
 		std::string mangleName = SymTab::Mangler::mangle( *funType );
 		if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
-		    paramList.push_front( new ObjectDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
+		    std::string adapterName = makeAdapterName( mangleName );
+		    paramList.push_front( new ObjectDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
 		    adaptersDone.insert( adaptersDone.begin(), mangleName );
 		}
Index: translator/GenPoly/GenPoly.cc
===================================================================
--- translator/GenPoly/GenPoly.cc	(revision bdd516a5257cb93cc0c5b4a4c343cc112252022a)
+++ translator/GenPoly/GenPoly.cc	(revision 5c7fb6c8dfabfe6c6b4c365a4f378706430fd1bf)
@@ -9,9 +9,20 @@
 #include "SynTree/Type.h"
 
+#include <iostream>
+using namespace std;
 
 namespace GenPoly {
 
+// interface functions
+bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
+  return isPolyVal( type, tyVars, false );
+}
+
+bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {  
+  return needsAdapter( adaptee, tyVars, false );
+}
+
 bool
-isPolyVal( Type *type, const TyVarMap &tyVars )
+isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars )
 {
   if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
@@ -19,4 +30,5 @@
       return true;
     }
+    return considerAllTyVars;
   }
   return false;
@@ -26,12 +38,12 @@
 // parameters have polymorphic type
 bool
-needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars )
+needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars )
 {
   bool needsAdapter = false;
-  if( !adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+  if( !adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) {
     needsAdapter = true;
   }
   for( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); !needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
-    if( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
+    if( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) {
       needsAdapter = true;
     }
Index: translator/GenPoly/GenPoly.h
===================================================================
--- translator/GenPoly/GenPoly.h	(revision bdd516a5257cb93cc0c5b4a4c343cc112252022a)
+++ translator/GenPoly/GenPoly.h	(revision 5c7fb6c8dfabfe6c6b4c365a4f378706430fd1bf)
@@ -5,4 +5,7 @@
  *
  */
+
+#ifndef GENPOLY_H
+#define GENPOLY_H
 
 #include <map>
@@ -15,8 +18,15 @@
 typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
 
-bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars );
+// considerAllTyVars allows ignoring the contents of the TyVarMap parameter, for the situations where
+// it is important only that a TypeInstType node exists.
+
+bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
+bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars );
 bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
 bool isPolyVal( Type *type, const TyVarMap &tyVars );
+bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars );
 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
 
 } // namespace GenPoly
+
+#endif
Index: translator/GenPoly/PolyMutator.cc
===================================================================
--- translator/GenPoly/PolyMutator.cc	(revision bdd516a5257cb93cc0c5b4a4c343cc112252022a)
+++ translator/GenPoly/PolyMutator.cc	(revision 5c7fb6c8dfabfe6c6b4c365a4f378706430fd1bf)
@@ -51,5 +51,5 @@
     compound->get_kids().push_back( newStmt );
     compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
-    doEndScope();
+    // doEndScope();
     return compound;
   } else {
@@ -74,4 +74,5 @@
 PolyMutator::mutate(CompoundStmt *compoundStmt)
 {
+  doBeginScope();
   mutateStatementList( compoundStmt->get_kids() );
   doEndScope();
Index: translator/GenPoly/PolyMutator.h
===================================================================
--- translator/GenPoly/PolyMutator.h	(revision bdd516a5257cb93cc0c5b4a4c343cc112252022a)
+++ translator/GenPoly/PolyMutator.h	(revision 5c7fb6c8dfabfe6c6b4c365a4f378706430fd1bf)
@@ -41,4 +41,5 @@
   
   // template method
+  virtual void doBeginScope() {}
   virtual void doEndScope() {}
 
