Index: translator/Tuples/AssignExpand.cc
===================================================================
--- translator/Tuples/AssignExpand.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/AssignExpand.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,131 @@
+#include <ctime>
+#include <cstdlib>
+
+#include <list>
+#include <cassert>
+#include <algorithm>
+
+#include "AssignExpand.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+
+namespace Tuples {
+  AssignExpander::AssignExpander() : temporaryNamer("__tpl") {}
+
+  Statement *AssignExpander::mutate( ExprStmt *exprStmt ) {
+    replace.clear();
+    extra.clear();
+    extra2.clear();
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
+
+    CompoundStmt *newSt = 0;
+    if (! extra.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      newSt->get_kids().splice(newSt->get_kids().end(), extra);
+    }
+
+    if (! extra2.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      newSt->get_kids().splice(newSt->get_kids().end(), extra2);
+    }
+
+    if (! replace.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      for ( std::list<Expression *>::iterator r = replace.begin(); r != replace.end(); r++ )
+	newSt->get_kids().push_back( new ExprStmt( std::list<Label>(), *r ));
+    }
+
+    if( newSt ) return newSt; else return exprStmt;
+  }
+
+  Expression *AssignExpander::mutate( SolvedTupleExpr *tupleExpr ) {
+    /* 
+    std::list<Expression *> &exprs = tupleExpr->get_exprs();
+
+    if ( tupleExpr->get_type() == SolvedTupleExpr::MASS ) {
+      // extract lhs of assignments, assert that rhs is the same, create temporaries
+      assert (! exprs.empty());
+      ApplicationExpr *ap1 = dynamic_cast< ApplicationExpr * >( exprs.front() );
+      std::list<Expression *> &args = ap1->get_args();
+      assert(args.size() == 2);
+      std::list<Type *> &temp_types = args.back()->get_results();
+      assert(temp_types.size() == 1);
+      extra.push_back(new DeclStmt( std::list<Label>(), new ObjectDecl(temporaryNamer.newName(), Declaration::Auto, LinkageSpec::C, 0, temp_types.front(), 0 ) ));
+
+      for ( std::list<Expression *>::iterator e = exprs.begin(); e != exprs.end(); e++ ) {
+	ApplicationExpr *ap = dynamic_cast< ApplicationExpr * >( *e );
+	assert( ap != 0 );
+	replace.push_back(ap);
+      }
+
+      return tupleExpr;
+    } else if ( tupleExpr->get_type() == SolvedTupleExpr::MULTIPLE ||
+		   tupleExpr->get_type() == SolvedTupleExpr::MASS ) */ {
+      std::list<Expression *> &comps = tupleExpr->get_exprs();
+      for( std::list<Expression *>::iterator i = comps.begin(); i != comps.end(); ++i ) {
+	std::list<Statement *> decls;
+	std::list<Statement *> temps;
+	std::list<Statement *> assigns;
+	if( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >(*i) ) {
+	  assert( app->get_args().size() == 2 );
+
+	  Expression *lhsT = app->get_args().front();
+	  Expression *rhsT = app->get_args().back();
+	  // after the round of type analysis this should be true
+	  assert( lhsT->get_results().size() == 1 );
+	  assert( rhsT->get_results().size() == 1 );
+	  // declare temporaries
+	  ObjectDecl *lhs = new ObjectDecl( temporaryNamer.newName("_lhs_"), Declaration::NoStorageClass, LinkageSpec::Intrinsic, 0,
+					    lhsT->get_results().front(), 0 );
+	  decls.push_back( new DeclStmt( std::list< Label >(), lhs ) );
+	  ObjectDecl *rhs = new ObjectDecl( temporaryNamer.newName("_rhs_"), Declaration::NoStorageClass, LinkageSpec::Intrinsic, 0,
+					    rhsT->get_results().front(), 0);
+	  decls.push_back( new DeclStmt( std::list< Label >(), rhs ));
+
+
+	  // create temporary for lhs, assign address
+	  UntypedExpr *assgnL = new UntypedExpr( new NameExpr( "?=?" ) );
+	  assgnL->get_args().push_back( new VariableExpr( lhs ) );
+	  assgnL->get_args().push_back( lhsT );
+	  temps.push_back( new ExprStmt(std::list<Label>(), assgnL) );
+
+	  // create temporary for rhs, assign value
+	  UntypedExpr *assgnR = new UntypedExpr( new NameExpr( "?=?" ) );
+	  assgnR->get_args().push_back( new VariableExpr( rhs ) );
+	  assgnR->get_args().push_back( rhsT );
+	  temps.push_back( new ExprStmt(std::list<Label>(), assgnR) );
+
+	  // assign rhs to lhs
+	  UntypedExpr *assgn = new UntypedExpr( new NameExpr( "?=?" ) );
+	  UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+	  deref->get_args().push_back( new VariableExpr( lhs ) );
+	  assgn->get_args().push_back( deref );
+	  assgn->get_args().push_back( new VariableExpr( rhs ) );
+	  assigns.push_back( new ExprStmt(std::list<Label>(), assgn) );
+
+	} else
+	  throw CompilerError("Solved Tuple should contain only assignment statements");
+	  
+	extra.splice( extra.begin(), decls );
+	extra.splice( extra.end(), temps );
+	extra2.splice( extra2.end(), assigns );
+      }
+
+      return tupleExpr;
+    }
+
+    throw 0; // shouldn't be here
+  }
+
+
+} // namespace Tuples
+
Index: translator/Tuples/AssignExpand.h
===================================================================
--- translator/Tuples/AssignExpand.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/AssignExpand.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,37 @@
+#ifndef _ASSIGN_EXPAND_H_
+#define _ASSIGN_EXPAND_H_
+
+#include <cstdlib>
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+
+#include "UniqueName.h"
+
+namespace Tuples {
+  class AssignExpander : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    AssignExpander();
+    virtual Statement *mutate( ExprStmt *expr );
+    virtual Expression *mutate( SolvedTupleExpr *tupleExpr );
+
+  private:
+    std::list<Statement *> extra, extra2;
+    std::list<Expression *> replace;
+    UniqueName temporaryNamer;
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _ASSIGN_EXPAND_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FlattenTuple.cc
===================================================================
--- translator/Tuples/FlattenTuple.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FlattenTuple.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,51 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FlattenTuple.h"
+
+
+namespace Tuples {
+
+  FlattenTuple::FlattenTuple()
+  {
+  }
+
+  FlattenTuple::~FlattenTuple()
+  {
+  }
+
+  Expression *FlattenTuple::mutate( TupleExpr *tupleExpr )
+  {
+    CollectArgs c;
+
+    acceptAll( tupleExpr->get_exprs(), c );
+    tupleExpr->set_exprs( c.get_args() );
+
+    return tupleExpr;
+  }
+
+  void FlattenTuple::CollectArgs::visit( UntypedExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( NameExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( CastExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( AddressExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( UntypedMemberExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( MemberExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( VariableExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( ConditionalExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( CommaExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( TypeExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( UntypedValofExpr  *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+
+  void FlattenTuple::CollectArgs::visit( TupleExpr *tupleExpr)
+  {
+    acceptAll( tupleExpr->get_exprs(), *this );
+
+    //currentArgs.splice( currentArgs.end(), c.get_args() );
+  }
+} // namespace Tuples
Index: translator/Tuples/FlattenTuple.h
===================================================================
--- translator/Tuples/FlattenTuple.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FlattenTuple.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,58 @@
+#ifndef _FLATTEN_TUPLE_H_
+#define _FLATTEN_TUPLE_H_
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Visitor.h"
+
+#include "SynTree/Expression.h"
+
+namespace Tuples {
+  class FlattenTuple : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FlattenTuple();
+    ~FlattenTuple();
+
+    virtual Expression *mutate( TupleExpr *tupleExpr );
+
+  private:
+    class CollectArgs : public Visitor
+    {
+    public:
+      virtual void visit( UntypedExpr * );
+      virtual void visit( NameExpr * );
+      virtual void visit( CastExpr *);
+      virtual void visit( AddressExpr * );
+      virtual void visit( UntypedMemberExpr * );
+      virtual void visit( MemberExpr * );
+      virtual void visit( VariableExpr * );
+      virtual void visit( ConstantExpr * ); 
+      virtual void visit( SizeofExpr * );
+      virtual void visit( AttrExpr * );
+      virtual void visit( LogicalExpr * );
+      virtual void visit( ConditionalExpr * );
+      virtual void visit( CommaExpr * );
+      virtual void visit( TypeExpr * );
+      virtual void visit( UntypedValofExpr * );
+
+      virtual void visit( TupleExpr *tupleExpr );
+
+      std::list< Expression *> &get_args() { return currentArgs; }
+    private:
+      std::list< Expression * > currentArgs;
+    };
+
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _FLATTEN_TUPLE_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FunctionChecker.cc
===================================================================
--- translator/Tuples/FunctionChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,120 @@
+#include "FunctionChecker.h"
+#include "FunctionFixer.h"
+#include "SemanticError.h"
+
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+
+namespace Tuples {
+  using namespace std;
+
+  void checkFunctions( std::list< Declaration * > translationUnit )
+  {
+    FunctionChecker fchk(true);
+    TupleDistrib td;
+    FunctionFixer ff;
+
+    mutateAll( translationUnit , fchk );
+    mutateAll( translationUnit , ff );
+    mutateAll( translationUnit , td );
+    return;
+  }
+
+  FunctionChecker::FunctionChecker( bool _topLevel, UniqueName *_nameGen ) : topLevel( _topLevel ), nameGen( _nameGen ) {
+    if( topLevel) {
+      assert( !nameGen );
+      nameGen = new UniqueName("_MVR_");
+    } else
+      assert( nameGen );
+  }
+
+  FunctionChecker::~FunctionChecker() {
+    if( topLevel) {
+      delete nameGen;
+      nameGen = 0;
+    }
+  }
+
+  Statement* FunctionChecker::mutate(ExprStmt *exprStmt) {
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
+    if ( !tempExpr.empty() ) {
+      assert ( !temporaries.empty() );
+      CompoundStmt *newBlock = new CompoundStmt( std::list< Label >() );
+      // declarations
+      for( std::list< ObjectDecl *>::iterator d = temporaries.begin(); d != temporaries.end(); ++d )
+	newBlock->get_kids().push_back( new DeclStmt( std::list<Label>(), *d ) );
+      // new expression statements
+      for( std::list< Expression *>::iterator e = tempExpr.begin(); e != tempExpr.end(); ++e )
+	newBlock->get_kids().push_back( new ExprStmt( std::list<Label>(), *e ) );
+
+      newBlock->get_kids().push_back( exprStmt );
+      return newBlock;
+    } else
+      return exprStmt;
+  }
+
+  Expression* FunctionChecker::mutate(ApplicationExpr *applicationExpr) {
+    if ( topLevel )
+      ; // In top level of Functionchecker
+
+    if ( applicationExpr->get_results().size() > 1 ) {
+      for ( std::list< Type *>::iterator res = applicationExpr->get_results().begin(); res != applicationExpr->get_results().end(); res++ )
+	temporaries.push_back( new ObjectDecl(nameGen->newName(),Declaration::Auto,LinkageSpec::AutoGen, 0, (*res)->clone(), 0 ) );
+
+      assert( ! temporaries.empty() );
+    }
+
+    applicationExpr->set_function(  maybeMutate( applicationExpr->get_function(), *this ) );
+
+    std::list< Expression * > newArgs;
+    for( std::list< Expression *>::iterator e = applicationExpr->get_args().begin(); e != applicationExpr->get_args().end(); ++e ) {
+      FunctionChecker rec( false, nameGen );
+      (*e)->acceptMutator( rec );
+
+      if ( !rec.temporaries.empty() ) {
+	TupleExpr *lhs = new TupleExpr;
+	std::list< Expression * > &tmem = lhs->get_exprs();
+	for( std::list<ObjectDecl *>::iterator d = rec.temporaries.begin();  d != rec.temporaries.end(); ++d ) {
+	  tmem.push_back( new VariableExpr( *d ) );
+	  newArgs.push_back( new VariableExpr( *d ) );
+	}
+
+	// construct tuple assignment
+	std::list<Expression *> args;
+	args.push_back( new AddressExpr(lhs) );
+	args.push_back( *e );
+	tempExpr.push_back( new UntypedExpr( new NameExpr("?=?"), args ) );
+
+	temporaries.splice( temporaries.end(), rec.temporaries );
+      } else
+	newArgs.push_back( *e );
+      // percolate to recursive calls
+    }
+
+    applicationExpr->get_args().clear();
+    std::copy( newArgs.begin(), newArgs.end(), back_inserter(applicationExpr->get_args()) );
+
+    return applicationExpr;
+  }
+
+  Expression* TupleDistrib::mutate(UntypedExpr *expr) {
+    if(  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
+      if( assgnop->get_name() == std::string("?=?") ) {
+	std::list<Expression *> &args = expr->get_args();
+	assert(args.size() == 2);
+	//if args.front() points to a tuple and if args.back() is already resolved
+	if( AddressExpr *addr = dynamic_cast<AddressExpr *>(args.front()) )
+	  if( TupleExpr *lhs = dynamic_cast<TupleExpr *>(addr->get_arg()) )
+	    if( ApplicationExpr *rhs = dynamic_cast<ApplicationExpr *>( args.back() ) ) {
+	      for ( std::list<Expression *>::iterator tc = lhs->get_exprs().begin(); tc != lhs->get_exprs().end(); ++tc )
+		rhs->get_args().push_back( new AddressExpr( *tc ) );
+	      return rhs; // XXX
+	    }
+      } else
+	assert(false); // It's not an assignment, shouldn't be here
+    }
+    return expr;
+  }
+
+} // namespace Tuples
Index: translator/Tuples/FunctionChecker.h
===================================================================
--- translator/Tuples/FunctionChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+#ifndef _TUPLE_FUNCHK_H_
+#define _TUPLE_FUNCHK_H_
+
+#include <string>
+#include <list>
+#include <iostream>
+
+#include "UniqueName.h"
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+
+namespace Tuples {
+  class FunctionChecker : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionChecker( bool _topLevel = false, UniqueName *_nameGen = 0 );
+    ~FunctionChecker();
+
+    virtual Expression* mutate(ApplicationExpr *applicationExpr);
+    virtual Statement* mutate(ExprStmt *exprStmt);
+
+  private:
+    bool topLevel;
+    UniqueName *nameGen;
+    std::list< ObjectDecl * > temporaries;
+    std::list< Expression * > tempExpr;
+  };
+
+  class TupleDistrib : public Mutator {
+  public:
+    virtual Expression* mutate(UntypedExpr *utExpr);
+
+  private:
+  };
+
+  void checkFunctions( std::list< Declaration * > translationUnit );
+
+} // namespace Tuples
+
+#endif // #ifndef _TUPLE_FUNCHK_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FunctionFixer.cc
===================================================================
--- translator/Tuples/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,109 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FunctionFixer.h"
+
+namespace Tuples {
+  DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) {
+    functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
+    mutateAll( functionDecl->get_oldDecls(), *this );
+    functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
+    index.visit( functionDecl );
+    rets.clear();
+    return functionDecl;
+  }
+
+  Type *FunctionFixer::mutate( FunctionType *functionType )
+  {
+    typedef std::list< DeclarationWithType * >  Decls;
+
+    if ( functionType->get_returnVals().size() <= 1 )  return functionType;
+    std::copy( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), back_inserter(rets) );
+
+    Type::Qualifiers qual;
+    for ( Decls::iterator i = rets.begin(); i != rets.end(); i++ ) {
+      (*i)->set_type( new PointerType( qual, (*i)->get_type() ) );
+      functionType->get_parameters().push_back( *i );
+    }
+
+    functionType->get_returnVals() = *(new std::list< DeclarationWithType * >());
+
+    functionType->set_isVarArgs( false );
+    return functionType;
+  }
+
+  Statement *FunctionFixer::mutate( ReturnStmt *retStmt )
+  {
+    bool tupleReturn = false;
+    Expression *rhs = 0;
+    // also check if returning multiple values
+    if( CastExpr *cst = dynamic_cast<CastExpr *>( retStmt->get_expr() ) ) {
+      if( ApplicationExpr *app = dynamic_cast<ApplicationExpr *>( cst->get_arg() ) ) {
+	if( app->get_results().size() > 1 ) { // doesn't need to be ApplicationExpr
+	  tupleReturn = true;
+	  rhs = app;
+	}
+      } else if( TupleExpr *t = dynamic_cast<TupleExpr *>( cst->get_arg() ) ) {
+	tupleReturn = true;
+	assert( rets.size() == t->get_exprs().size() ); // stupid check, resolve expression
+	rhs = t;
+      }
+
+      if( tupleReturn ) {
+	assert ( rhs != 0 );
+	std::list< Expression * > lhs;
+	for( std::list< DeclarationWithType * >::iterator d = rets.begin(); d != rets.end(); ++d ) {
+	  std::list<Expression *> largs;
+	  largs.push_back(new VariableExpr( *d ));
+	  Expression *exp = ResolvExpr::resolveInVoidContext( new CastExpr( new UntypedExpr(new NameExpr("*?"), largs), (*d)->get_type()),
+								       index );
+	  lhs.push_back(exp);
+	}
+	std::list< Expression * > args;
+	TupleExpr *tlhs = new TupleExpr; tlhs->set_exprs( lhs );
+	args.push_back( new AddressExpr(tlhs) );
+	args.push_back(rhs);
+
+	return new ExprStmt( std::list< Label>(), new UntypedExpr( new NameExpr("?=?"), args ) );
+      }
+    }
+    /*
+    else
+      std::cerr << "Empty return statement" << std::endl;
+    */
+
+    return retStmt;
+  }
+
+  Expression* FunctionFixer::mutate( VariableExpr *variableExpr ) {
+    if ( rets.empty() ) return variableExpr;
+    mutateAll( variableExpr->get_results(), *this );
+    if( std::find( rets.begin(), rets.end(), variableExpr->get_var() ) != rets.end() )
+//      if ( PointerType *ptr = dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) ) {
+      if ( dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) != 0 ) {
+	std::list<Expression *> largs;
+	largs.push_back( new AddressExpr(variableExpr) );
+	  Expression *expr = ResolvExpr::resolveInVoidContext( /*new CastExpr(*/new UntypedExpr( new NameExpr( "*?" ), largs )/*,
+																 ptr->get_base()),*/, index);
+	  if( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >( expr ) ) {
+	    assert( app->get_args().size() == 1 );
+	    app->get_args().pop_front();
+	    app->get_args().push_back( variableExpr );
+	    return app;
+	  }
+      }
+    return variableExpr;
+  }
+
+  /*
+  Expression* FunctionFixer::mutate(ApplicationExpr *applicationExpr) {
+    std::cerr << "In Application Expression" << std::endl;
+    mutateAll( applicationExpr->get_results(), *this );
+    applicationExpr->set_function(  maybeMutate( applicationExpr->get_function(), *this ) );
+    mutateAll( applicationExpr->get_args(), *this );
+    return applicationExpr;
+  }
+  */
+} // namespace Tuples
Index: translator/Tuples/FunctionFixer.h
===================================================================
--- translator/Tuples/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,63 @@
+#ifndef _FUNFIX_H_
+#define _FUNFIX_H_
+
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Type.h"
+
+#include "SymTab/Indexer.h"
+#include "ResolvExpr/Resolver.h"
+#include "ResolvExpr/AlternativeFinder.h"
+
+namespace Tuples {
+  class FunctionFixer : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionFixer() {}
+    virtual ~FunctionFixer() {}
+    virtual Type       *mutate( FunctionType *functionType );
+    virtual Statement  *mutate( ReturnStmt   *retStmt  );
+    virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
+    virtual Expression *mutate( VariableExpr *variableExpr);
+
+    // indexer runs
+    virtual ObjectDecl     *mutate( ObjectDecl *objectDecl )
+    { index.visit( objectDecl ); return objectDecl; }
+    virtual TypeDecl       *mutate( TypeDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual TypedefDecl    *mutate( TypedefDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual StructDecl     *mutate( StructDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual UnionDecl      *mutate( UnionDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual EnumDecl       *mutate( EnumDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+
+    virtual Type           *mutate( StructInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+    virtual Type           *mutate( UnionInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+
+
+
+  private:
+    std::list< DeclarationWithType * > rets;
+    SymTab::Indexer index;
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _FUNFIX_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/MultRet.cc
===================================================================
--- translator/Tuples/MultRet.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/MultRet.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,157 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "MultRet.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+
+  MVRMutator::MVRMutator() : newVars( 0 ), newCode( 0 )
+  {
+  }
+
+  MVRMutator::~MVRMutator()
+  {
+  }
+
+  int MVRMutator::curVal = 0;
+
+  Statement *MVRMutator::mutate( ExprStmt *exprStmt ){
+    MVRMutator toplevel;
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), toplevel ) );
+
+    if ( toplevel.hasCode() ) {
+      assert ( toplevel.getVars() != 0 );
+
+      typedef std::list<Statement *> Statements;
+
+      CompoundStmt *code = new CompoundStmt( std::list< Label >() );
+
+      // copy variables
+      Statements &vars = toplevel.getVars()->get_kids();
+      for( Statements::iterator i = vars.begin(); i != vars.end(); i++ )
+	code->get_kids().push_back( *i );
+
+      // copy statements
+      Statements &block = toplevel.getCode()->get_kids();
+      for( Statements::iterator i = block.begin(); i != block.end(); i++ )
+	code->get_kids().push_back( *i );
+
+      return code;
+    } else
+      return exprStmt;
+  }
+
+
+  Expression *MVRMutator::mutate( ApplicationExpr *appExpr )
+  {
+    // appExpr->set_function(  maybeMutate( appExpr->get_function(), *this ) );
+    bool mulretp = false;
+    VariableExpr *funname;
+    if ( (funname = dynamic_cast<VariableExpr *>(appExpr->get_function())) == 0 ) goto DoArgs;
+
+    FunctionDecl *fundecl;
+    if ((fundecl = dynamic_cast<FunctionDecl *>(funname->get_var())) == 0) goto DoArgs;
+
+    {
+      typedef std::list<DeclarationWithType*> RetType;
+
+      RetType &rets = fundecl->get_functionType()->get_returnVals();
+      if ( rets.size() <= 1 ) goto DoArgs;
+      mulretp = true;
+
+      if( newVars == 0 )
+	newVars = new CompoundStmt( std::list<Label>(0) );
+
+      for (RetType::iterator i = rets.begin() ; i != rets.end(); i++) {
+	DeclStmt *arg = newVar( *i );
+	newVars->get_kids().push_back( arg );
+	add_pending( arg->get_decl() );
+      }
+    }
+
+  DoArgs:
+     // mutate the argument list
+    typedef std::list< Expression *> Exprs;
+    Exprs &args = appExpr->get_args();
+    std::list< Expression * > newArgs;
+    for( Exprs::iterator i = args.begin(); i != args.end(); i++ ) {
+      MVRMutator next;
+      Expression *mutated = (*i)->acceptMutator( next );
+
+      if ( next.hasCode() ) {
+	// merge new vars and bodies
+	typedef std::list< Statement * > Stmts;
+	Stmts &vars = next.getVars()->get_kids();
+	Stmts &block = next.getCode()->get_kids();
+
+	if (newVars == 0)
+	  newVars = new CompoundStmt( std::list< Label >() );
+	for( Stmts::iterator i = vars.begin(); i != vars.end(); i++ )  // std::splice? -- need to append lists
+	  newVars->get_kids().push_back( *i );
+
+	if (newCode == 0)
+	  newCode = new CompoundStmt( std::list< Label >() );
+	for( Stmts::iterator i = block.begin(); i != block.end(); i++ )
+	  newCode->get_kids().push_back( *i );
+
+      }
+
+      if ( next.hasResults() ) {
+	Exprs &res = next.get_results();
+	for( Exprs::iterator i = res.begin(); i != res.end(); i++ )
+	  newArgs.push_back( *i );
+      } else
+	newArgs.push_back( mutated );
+    }
+
+    appExpr->get_args() = newArgs;  // new argument list
+
+
+    if ( mulretp ) {
+      // add 'out' parameters
+      if ( ! argsToAdd.empty() )
+	for(std::list< Expression *>::iterator i = argsToAdd.begin(); i != argsToAdd.end(); i++)
+	  (appExpr->get_args()).push_back( *i );
+      // clear 'out' parameters ( so that the list can be reused -- substitute by auto_ptr later? )
+
+      if (newCode == 0)
+	newCode = new CompoundStmt( std::list<Label>(0) );
+    }
+
+    // add to block of code
+    if ( newCode != 0 )
+      newCode->get_kids().push_back( new ExprStmt( std::list<Label>(), appExpr ) );
+
+    return appExpr;
+  }
+
+  // Auxiliary function to generate new names for the `output' parameters
+  DeclStmt *MVRMutator::newVar( DeclarationWithType *reqDecl ) {
+    // std::ostrstream os;
+    // os << "__" << curVal++ << "__";// << std::ends;
+    // os.freeze( false );
+
+    ObjectDecl *decl;
+    if ((decl = dynamic_cast<ObjectDecl *>( reqDecl )) != 0)
+      // return new DeclStmt( new ObjectDecl( std::string (os.str(), os.pcount()), );
+      return new DeclStmt( std::list<Label>(), decl );
+    else
+      return 0;
+  }
+
+  void MVRMutator::add_pending( Declaration *decl ) {
+    ObjectDecl *obj;
+    if ( (obj = dynamic_cast< ObjectDecl * >( decl )) == 0 ) return;
+
+    VariableExpr *var = new VariableExpr(obj, 0 );
+    results.push_back( var ); // probably change this name to newResults or something
+    argsToAdd.push_back( new AddressExpr( var ) );
+    return;
+  }
+}
Index: translator/Tuples/MultRet.h
===================================================================
--- translator/Tuples/MultRet.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/MultRet.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+#ifndef _MULTRET_H_
+#define _MULTRET_H_
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Visitor.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+namespace Tuples {
+  class MVRMutator : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    MVRMutator();
+    ~MVRMutator();
+
+    virtual Statement  *mutate( ExprStmt        *exprStmt );
+    virtual Expression *mutate( ApplicationExpr *appExpr  );
+
+    bool hasCode() const { return ( newCode != 0 ); }
+    CompoundStmt *getCode() const { return newCode; }
+    CompoundStmt *getVars() const { return newVars; }
+
+    bool hasResults() const { return (! results.empty()); }
+    std::list<Expression *> &get_results() { return results; }
+
+  private:
+    CompoundStmt *newVars;
+    CompoundStmt *newCode;
+    std::list<Expression *> argsToAdd;
+    std::list<Expression *> results;
+
+    static int curVal;
+    DeclStmt *newVar( DeclarationWithType * );
+    void add_pending( Declaration * );
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _MULTRET_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/Mutate.cc
===================================================================
--- translator/Tuples/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#include "SynTree/Mutator.h"
+
+#include "Mutate.h"
+//#include "TupleFixer.h"
+//#include "FlattenTuple.h"
+//#include "MultRet.h"
+#include "FunctionFixer.h"
+#include "AssignExpand.h"
+//#include "FixReturn.h"
+//#include "MassAssignment.h"
+
+namespace Tuples {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    //FunctionFixer fst;
+    AssignExpander snd;
+
+    //mutateAll( translationUnit, fst );
+    mutateAll( translationUnit, snd );
+  }
+} // namespace Tuples
+
+
Index: translator/Tuples/Mutate.h
===================================================================
--- translator/Tuples/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,23 @@
+#ifndef TUPLES_MUTATE_H
+#define TUPLES_MUTATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/Declaration.h"
+
+
+namespace Tuples {
+
+  void mutate( std::list< Declaration* > translationUnit );
+  void mulReturn( std::list< Declaration * > translationUnit );
+
+} // namespace Tuples
+
+#endif // #ifndef TUPLES_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/NameMatcher.cc
===================================================================
--- translator/Tuples/NameMatcher.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/NameMatcher.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,47 @@
+#include "NameMatcher.h"
+#include "NameMatcher.h"
+
+namespace Tuples {
+  NameMatcher::NameMatcher( std::list< DeclarationWithType* > &formals )
+    : current( 0 ) {
+    int cnt = 0;
+    for( std::list< DeclarationWithType *>::const_iterator f = formals.begin(); f != formals.end(); ++f ) {
+      table.insert( std::pair< std::string, int >( (*f)->get_name(), cnt++ ) );
+      index.push_back(*f);
+    }
+    exprs.reserve( index.size() );
+  }
+
+  NameMatcher::~NameMatcher() {}
+
+  void NameMatcher::match( ResolvExpr::AltList &alternatives ) throw (NoMatch) {
+    if( alternatives.size() != index.size() )
+      throw NoMatch("Length of actuals and formals differ");
+
+    for( ResolvExpr::AltList::const_iterator a = alternatives.begin(); a != alternatives.end(); ++a ) {
+      if( a->expr->get_argName() != 0 )
+	if ( NameExpr *name = dynamic_cast<NameExpr *>( a->expr->get_argName() ) ) {
+	  if ( table.find( name->get_name() ) != table.end() ) {
+	    std::cerr << "Rearranging to " << table[ name->get_name() ] << "position in the list." << std::endl;
+	    exprs[ table[ name->get_name() ] ] = &(*a);
+	  } else
+	    throw NoMatch( name->get_name() + "no such  designation" );
+	} /*else if( TupleExpr *tup = dynamic_cast<TupleExpr *>( a->expr->get_argName() ) )
+	    std::cerr << "Designated expression" << std::endl; */
+      exprs.push_back( &(*a) );
+    }
+
+    /*std::cerr << "In matcher/match: ";
+    if ( exprs.size() != index.size() )
+      std::cerr << "exprs and index differ in length" << std::endl;
+    else
+      std::cerr << "is all good." << std::endl;
+    */
+  }
+
+  ResolvExpr::Alternative &NameMatcher::get_next() throw (NoMoreElements) {
+    if( current++ >= (int)(index.size()) )
+      throw NoMoreElements();
+    return *(new ResolvExpr::Alternative());
+  }
+} // namespace Tuples
Index: translator/Tuples/NameMatcher.h
===================================================================
--- translator/Tuples/NameMatcher.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/NameMatcher.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+#ifndef _TUPLE_NAMEMATCH_H_
+#define _TUPLE_NAMEMATCH_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+#include "ResolvExpr/Alternative.h"
+
+namespace Tuples {
+  struct NoMoreElements {};
+  struct NoMatch {
+    NoMatch( std::string msg ) : message( msg ) {}
+    std::string message;
+  };
+
+  class NameMatcher
+  {
+  public:
+    NameMatcher( std::list< DeclarationWithType* >& );
+    ~NameMatcher();
+
+    void match( ResolvExpr::AltList &alternatives ) throw (NoMatch) ;
+    ResolvExpr::Alternative &get_next() throw (NoMoreElements);
+
+  private:
+    int current;
+    std::vector< DeclarationWithType* > index;
+    std::vector< const ResolvExpr::Alternative * > exprs;
+    std::map< std::string, int> table;
+  };
+
+} // namespace Tuples
+
+#endif // #ifndef _TUPLE_NAMEMATCH_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/TupleAssignment.cc
===================================================================
--- translator/Tuples/TupleAssignment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/TupleAssignment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,400 @@
+#include "ResolvExpr/AlternativeFinder.h"
+#include "ResolvExpr/Alternative.h"
+#include "ResolvExpr/typeops.h"
+#include "SynTree/Expression.h"
+#include "TupleAssignment.h"
+#include "SemanticError.h"
+
+#include <functional>
+#include <algorithm>
+#include <iterator>
+#include <iostream>
+#include <cassert>
+#include <set>
+
+namespace Tuples {
+  TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f = 0 )
+    : currentFinder(f), matcher(0), hasMatched( false ) {}
+
+  bool TupleAssignSpotter::pointsToTuple( Expression *expr ) {
+    // also check for function returning tuple of reference types
+    if(AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )
+      if( isTuple(addr->get_arg() ) )
+	return true;
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) {
+    if( dynamic_cast<TupleType *>(decl->get_type()) )
+      return true;
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) {
+    // true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function
+    if ( !expr ) return false;
+
+    if( dynamic_cast<TupleExpr *>(expr) )
+      return true;
+    else if( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) {
+      if( isTupleVar(var->get_var()) )
+	return true;
+    }
+
+    return false;
+  }
+
+  bool TupleAssignSpotter::match() {
+    assert ( matcher != 0 );
+
+    std::list< Expression * > new_assigns;
+    if (! matcher->match(new_assigns) )
+      return false;
+
+    if( new_assigns.empty() ) return false;
+    /*return */matcher->solve( new_assigns );
+    if( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
+      // now resolve new assignments
+      std::list< Expression * > solved_assigns;
+      ResolvExpr::AltList solved_alts;
+      assert( currentFinder != 0 );
+
+      ResolvExpr::AltList current;
+      for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+	//try {
+	ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+	finder.findWithAdjustment(*i);
+	// prune expressions that don't coincide with
+	ResolvExpr::AltList alts = finder.get_alternatives();
+	assert( alts.size() == 1 );
+	assert(alts.front().expr != 0 );
+	current.push_back( finder.get_alternatives().front() );
+	solved_assigns.push_back( alts.front().expr->clone() );
+	//solved_assigns.back()->print(std::cerr);
+	/*} catch( ... ) {
+	  continue; // no reasonable alternative found
+	  }*/
+      }
+      options.add_option( current );
+
+      return true;
+    } else { // mass assignment
+      //if( new_assigns.empty() ) return false;
+      std::list< Expression * > solved_assigns;
+      ResolvExpr::AltList solved_alts;
+      assert( currentFinder != 0 );
+
+      ResolvExpr::AltList current;
+      if ( optMass.empty() ) {
+	for( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
+	  optMass.push_back( ResolvExpr::AltList() );
+      }
+      int cnt = 0;
+      for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
+
+	ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+	finder.findWithAdjustment(*i);
+	ResolvExpr::AltList alts = finder.get_alternatives();
+	assert( alts.size() == 1 );
+	assert(alts.front().expr != 0 );
+	current.push_back( finder.get_alternatives().front() );
+	optMass[cnt].push_back( finder.get_alternatives().front() );
+	solved_assigns.push_back( alts.front().expr->clone() );
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  bool TupleAssignSpotter::isMVR( Expression *expr ) {
+    if( expr->get_results().size() > 1 ) {
+      // MVR processing
+      return true;
+    }
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+    if(  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
+
+      if( assgnop->get_name() == std::string("?=?") ) {
+
+	for( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
+	  assert( ali->size() == 2 );
+	  ResolvExpr::AltList::iterator opit = ali->begin();
+	  ResolvExpr::Alternative op1 = *opit, op2 = *(++opit);
+
+	  if( pointsToTuple(op1.expr) ) { // also handles tuple vars
+	    if ( isTuple( op2.expr, true ) )
+	      matcher = new MultipleAssignMatcher(op1.expr, op2.expr);
+	    else if( isMVR( op2.expr ) ) {
+	      // handle MVR differently
+	    } else
+	      // mass assignment
+	      matcher = new MassAssignMatcher(op1.expr, op2.expr);
+
+	    std::list< ResolvExpr::AltList > options;
+	    if( match() )
+	      /*
+	      if( hasMatched ) {
+		// throw SemanticError("Ambiguous tuple assignment");
+	      } else {*/
+		// Matched for the first time
+		hasMatched = true;
+		/*} */
+	  } /* else if ( isTuple( op2 ) )
+	    throw SemanticError("Inapplicable tuple assignment.");
+	    */
+	}
+
+	if( hasMatched ) {
+	  if( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
+	    //options.print( std::cerr );
+	    std::list< ResolvExpr::AltList >best = options.get_best();
+	    if( best.size() == 1 ) {
+	      std::list<Expression *> solved_assigns;
+	      for( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ){
+		solved_assigns.push_back( i->expr );
+	      }
+	      /* assigning cost zero? */
+	      currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+	    }
+	  } else {
+	    assert(! optMass.empty() );
+	    ResolvExpr::AltList winners;
+	    for( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i )
+	      findMinCostAlt( i->begin(), i->end(), back_inserter(winners) );
+
+	    std::list< Expression *> solved_assigns;
+	    for( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i )
+	      solved_assigns.push_back( i->expr );
+	    currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+	  }
+	}
+      }
+    }
+    return hasMatched;
+  }
+
+  void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) {
+    lhs.clear();
+    if(AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) )
+      if( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
+	std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) );
+
+    rhs.clear();
+  }
+
+  TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{
+    init(_lhs,_rhs);
+  }
+
+  TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{
+    init(_lhs,_rhs);
+
+    if( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) )
+      std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) );
+  }
+
+  UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
+    if ( left && right ) {
+      std::list< Expression * > args;
+      args.push_back(new AddressExpr(left->clone()));  args.push_back(right->clone());
+      return new UntypedExpr(new NameExpr("?=?"), args);
+    } else
+      throw 0; // xxx - diagnose the problem
+  }
+
+  bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
+    if ( lhs.empty() || (rhs.size() != 1) ) return false;
+
+    for( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) {
+      std::list< Expression * > args;
+      args.push_back( new AddressExpr(*l) );
+      args.push_back( rhs.front() );
+      out.push_back( new UntypedExpr(new NameExpr("?=?"), args) );
+    }
+
+    return true;
+  }
+
+  bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) {
+    /*
+    std::list< Expression * > solved_assigns;
+    ResolvExpr::AltList solved_alts;
+    assert( currentFinder != 0 );
+
+    ResolvExpr::AltList current;
+    if ( optMass.empty() ) {
+      for( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
+	optMass.push_back( ResolvExpr::AltList() );
+    }
+    int cnt = 0;
+    for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
+
+      ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+      finder.findWithAdjustment(*i);
+      ResolvExpr::AltList alts = finder.get_alternatives();
+      assert( alts.size() == 1 );
+      assert(alts.front().expr != 0 );
+      current.push_back( finder.get_alternatives().front() );
+      optMass[cnt].push_back( finder.get_alternatives().front() );
+      solved_assigns.push_back( alts.front().expr->clone() );
+    }
+    */
+    return true;
+  }
+
+  bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
+    // need more complicated matching
+    if( lhs.size() == rhs.size() ) {
+      zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
+      return true;
+    } //else
+    //std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/
+    return false;
+  }
+
+  bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) {
+    /*
+    std::list< Expression * > solved_assigns;
+    ResolvExpr::AltList solved_alts;
+    assert( currentFinder != 0 );
+
+    ResolvExpr::AltList current;
+    for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+      //try {
+      ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+      finder.findWithAdjustment(*i);
+      // prune expressions that don't coincide with
+      ResolvExpr::AltList alts = finder.get_alternatives();
+      assert( alts.size() == 1 );
+      assert(alts.front().expr != 0 );
+      current.push_back( finder.get_alternatives().front() );
+      solved_assigns.push_back( alts.front().expr->clone() );
+      //solved_assigns.back()->print(std::cerr);
+      //} catch( ... ) {
+      //continue; // no reasonable alternative found
+      //}
+    }
+    options.add_option( current );
+    */
+
+    return true;
+  }
+
+  void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) {
+    using namespace std;
+
+    options.push_back( opt );
+    /*
+      vector< Cost > costs;
+      costs.reserve( opt.size() );
+      transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) );
+    */
+    // transpose matrix
+    if ( costMatrix.empty() )
+      for( unsigned int i = 0; i< opt.size(); ++i)
+	costMatrix.push_back( vector<ResolvExpr::Cost>() );
+
+    int cnt = 0;
+    for( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ )
+      costMatrix[cnt].push_back( i->cost );
+
+    return;
+  }
+
+  std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
+    using namespace std;
+    using namespace ResolvExpr;
+    list< ResolvExpr::AltList > ret;
+    list< multiset<int> > solns;
+    for( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
+      list<int> current;
+      findMinCost( i->begin(), i->end(), back_inserter(current) );
+      solns.push_back( multiset<int>(current.begin(), current.end()) );
+    }
+    // need to combine
+    multiset<int> result;
+    lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) );
+    if( result.size() != 1 )
+      throw SemanticError("Ambiguous tuple expression");
+    ret.push_back(get_option( *(result.begin() )));
+    return ret;
+  }
+
+  void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
+    using namespace std;
+
+    for( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
+      for( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )
+	ostr << *j << " " ;
+      ostr << std::endl;
+    }
+    
+    return;
+  }
+
+  ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {
+    return alt.cost;
+  }
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out )
+  {
+    using namespace ResolvExpr;
+    std::list<int> alternatives;
+
+    // select the alternatives that have the minimum parameter cost
+    Cost minCost = Cost::infinity;
+    unsigned int index = 0;
+    for( InputIterator i = begin; i != end; ++i, index++ ) {
+      if( *i < minCost ) {
+        minCost = *i;
+        alternatives.clear();
+        alternatives.push_back( index );
+      } else if( *i == minCost ) {
+        alternatives.push_back( index );
+      }
+    }
+    std::copy( alternatives.begin(), alternatives.end(), out );
+  }
+
+  template< class InputIterator, class OutputIterator >
+  void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ){
+    if( begin == end ) return;
+    InputIterator test = begin;
+
+    if(++test == end)
+      { copy(begin->begin(), begin->end(), out); return; }
+
+
+    std::multiset<int> cur; // InputIterator::value_type::value_type
+    copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );
+
+    while( test != end ) {
+      std::multiset<int> temp;
+      set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );
+      cur.clear();
+      copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));
+      ++test;
+    }
+
+    copy( cur.begin(), cur.end(), out );
+    return;
+  }
+
+
+  ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {
+    if( index >= options.size() )
+      throw 0; // XXX
+    std::list< ResolvExpr::AltList >::iterator it = options.begin();
+    for( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );
+    return *it;
+  }
+
+
+} // namespace Tuples
Index: translator/Tuples/TupleAssignment.h
===================================================================
--- translator/Tuples/TupleAssignment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/TupleAssignment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,127 @@
+#ifndef _TUPLE_ASSIGNMENT_H_
+#define _TUPLE_ASSIGNMENT_H_
+
+#include <string>
+#include <vector>
+#include "ResolvExpr/AlternativeFinder.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+  class TupleAssignSpotter {
+  public:
+    // dispatcher for Tuple (multiple and mass) assignment operations
+    TupleAssignSpotter( ResolvExpr::AlternativeFinder * );
+    ~TupleAssignSpotter() { delete matcher; matcher = 0; }
+
+    bool pointsToTuple( Expression * );
+    static bool isTupleVar( DeclarationWithType * );
+    bool isTuple( Expression *, bool isRight = false );
+    bool isMVR( Expression * );
+    bool isTupleAssignment( UntypedExpr *, std::list<ResolvExpr::AltList> & );
+    bool match();
+
+  private:
+    // records for assignment generation
+    class Options {
+    public:
+      void add_option( ResolvExpr::AltList &opt );
+      std::list< ResolvExpr::AltList > get_best();
+      void print( std::ostream & );
+      int size() const { return options.size(); }
+      ResolvExpr::AltList get_option( std::list< ResolvExpr::AltList >::size_type index );
+
+      // should really use the one in ResolvExpr/AlternativeFinder, but it's too coupled with the object
+      template< typename InputIterator, typename OutputIterator >
+      void findMinCost( InputIterator begin, InputIterator end, OutputIterator out );
+
+      template< typename InputIterator, typename OutputIterator >
+      void lift_intersection( InputIterator begin, InputIterator end, OutputIterator out );
+    private:
+      std::list< ResolvExpr::AltList > options;
+      std::vector< std::vector< ResolvExpr::Cost > > costMatrix;
+    };
+
+    class Matcher {
+    public:
+      Matcher( /*TupleAssignSpotter &spot, */Expression *_lhs, Expression *_rhs );
+      virtual ~Matcher() {}
+      virtual bool match( std::list< Expression * > &out ) = 0;
+      virtual bool solve( std::list< Expression * > &assigns ) = 0;
+      static UntypedExpr *createAssgn( Expression *left, Expression *right );
+    protected:
+      Matcher() /*: own_spotter( TupleAssignSpotter(0) ) */{}
+      void init(/* TupleAssignSpotter &, */Expression *_lhs, Expression *_rhs );
+      std::list< Expression * > lhs, rhs;
+      //TupleAssignSpotter &own_spotter;
+    };
+
+    class MassAssignMatcher : public Matcher {
+    public:
+      MassAssignMatcher( Expression *_lhs, Expression *_rhs ) : Matcher( _lhs, _rhs ) {
+	rhs.push_back( _rhs );
+      }
+      virtual bool match( std::list< Expression * > &out );
+      virtual bool solve( std::list< Expression * > &assigns );
+    private:
+      //std::vector< ResolvExpr::AltList > optMass;
+    };
+
+    class MultipleAssignMatcher : public Matcher {
+    public:
+      MultipleAssignMatcher( Expression *_lhs, Expression *_rhs );
+      virtual bool match( std::list< Expression * > &out );
+      virtual bool solve( std::list< Expression * > &assigns );
+    private:
+      //Options options;
+    };
+
+    friend class Matcher;
+
+    ResolvExpr::AlternativeFinder *currentFinder;
+    //std::list<Expression *> rhs, lhs;
+    Expression *rhs, *lhs;
+    Matcher *matcher;
+    bool hasMatched;
+    Options options;
+    std::vector< ResolvExpr::AltList > optMass;
+  };
+
+
+  ResolvExpr::Cost extract_cost( ResolvExpr::Alternative & );
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  findMinCostAlt( InputIterator begin, InputIterator end, OutputIterator out )
+  {
+    using namespace ResolvExpr;
+    AltList alternatives;
+
+    // select the alternatives that have the minimum parameter cost
+    Cost minCost = Cost::infinity;
+    for( AltList::iterator i = begin; i != end; ++i ) {
+      if( i->cost < minCost ) {
+        minCost = i->cost;
+        i->cost = i->cvtCost;
+        alternatives.clear();
+        alternatives.push_back( *i );
+      } else if( i->cost == minCost ) {
+        i->cost = i->cvtCost;
+        alternatives.push_back( *i );
+      }
+    }
+    std::copy( alternatives.begin(), alternatives.end(), out );
+  }
+
+} // namespace Tuples
+
+
+#endif // #ifndef _TUPLE_ASSIGNMENT_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/module.mk
===================================================================
--- translator/Tuples/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+SRC += 	Tuples/Mutate.cc \
+	Tuples/AssignExpand.cc \
+	Tuples/FunctionFixer.cc \
+	Tuples/TupleAssignment.cc \
+	Tuples/FunctionChecker.cc \
+	Tuples/NameMatcher.cc \
+#	Tuples/MultipleAssign.cc \
+#	Tuples/FlattenTuple.cc \
+#	Tuples/MultRet.cc \
+#	Tuples/FixReturn.cc \
+#	Tuples/MassAssignment.cc \
+#	Tuples/TupleFixer.cc \
+	$(NULL)
+
