Index: translator/ArgTweak/FunctionFixer.cc
===================================================================
--- translator/ArgTweak/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,117 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FunctionFixer.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace ArgTweak {
+
+
+  FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind )
+  {
+    if ( index == 0 ) index = new SymTab::Indexer();
+  }
+
+  FunctionFixer::~FunctionFixer()
+  {
+    delete index;
+  }
+
+  DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl )
+  {
+    index->visit( functionDecl );
+    /* check for duplicate named parameters here?  It might not be an
+    error if they're never used, on the other hand, it might be to
+    costly to check for duplicates every time we try a match */
+    return Parent::mutate( functionDecl );
+  }
+
+  Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr )
+    throw ( SemanticError )
+  {
+    assert( untypedExpr != 0 );
+    NameExpr *function;
+
+    if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 )
+      {
+	std::list < DeclarationWithType * > options;
+	index->lookupId ( function->get_name(), options );
+ 	for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ )
+ 	  {
+ 	    FunctionType *f;
+ 	    if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 )
+ 	      {
+ 		std::list < DeclarationWithType * > &pars = f->get_parameters();
+
+ 		bool candidateExists ;
+ 		for( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
+ 		  if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
+
+ 		if ( !candidateExists ) throw SemanticError("Error in function call");
+ 	      }
+ 	  }
+      }
+    return untypedExpr;
+  }
+
+  template < class L1, class L2, class Helper >
+  bool align( L1 &pattern, L2 &possible_permutation, Helper help )
+  {
+    std::map < typename Helper::key, int > positions;
+    int p = 0;
+
+    for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
+      if ( help.extract_key( *i ) != Helper::null_key )
+	positions[ help.extract_key( *i ) ] = p;
+
+    L2 copy_pp( possible_permutation );
+
+    std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
+    for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
+      if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
+	temp [ positions [ help.extract_key( *i ) ] ] = *i;
+	*i = Helper::null_value;
+      }
+
+    // rest of the arguments
+    int a = 0;
+    bool goAhead = true;  // go ahead and change the list
+    for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
+      if (  *i != Helper::null_value )
+	if ( temp[a] == Helper::null_value )
+	  temp[a] = *i;
+	else
+	  { goAhead = false; /* there's something there already */; break; }
+      else
+	if ( temp[a] == Helper::null_value )
+	  { goAhead = false; /* can't leave empty spaces */ break; }
+	else
+	  ; // all good, this was filled during the first pass
+      assert ( temp[a] != Helper::null_value );
+    }
+
+    // Change the original list
+    if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
+
+    return goAhead;
+  }
+
+  std::string FunctionFixer::Matcher::null_key("");
+  Expression *FunctionFixer::Matcher::null_value = 0;
+
+  std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
+    return decl->get_name();
+  }
+
+  std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
+    if ( expression->get_argName() == 0 )
+      return std::string("");
+    else
+      return *(expression->get_argName());
+  }
+
+} // namespace ArgTweak
Index: translator/ArgTweak/FunctionFixer.h
===================================================================
--- translator/ArgTweak/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,50 @@
+#ifndef _DEFS_FUNCTION_FIXER_H_
+#define _DEFS_FUNCTION_FIXER_H_
+
+#include "SynTree/Mutator.h"
+#include "SymTab/Indexer.h"
+
+#include "SynTree/Expression.h"
+
+namespace ArgTweak {
+  class FunctionFixer : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionFixer(SymTab::Indexer *ind = 0);
+    ~FunctionFixer();
+
+    virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
+    virtual Expression *mutate( UntypedExpr *untypedExpr ) throw ( SemanticError );
+
+  private:
+    class Matcher {
+      typedef std::string key;
+      typedef DeclarationWithType * pattern_type;
+      typedef Expression * permutation_type;
+    public:
+      static key null_key;
+      static permutation_type null_value;
+
+      std::string extract_key( DeclarationWithType * );
+      std::string extract_key( Expression * );
+
+      bool operator()( DeclarationWithType *, Expression * ) { return true; }
+    };
+
+    SymTab::Indexer *index;
+  };
+
+  template < class L1, class L2, class Predicate > bool align( L1 &pattern, L2 &possible_permutation, Predicate pred ); 
+
+} // namespace ArgTweak
+
+
+#endif // #ifndef _DEFS_FUNCTION_FIXER_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ArgTweak/Mutate.cc
===================================================================
--- translator/ArgTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,17 @@
+#include "SynTree/Mutator.h"
+
+#include "Mutate.h"
+#include "FunctionFixer.h"
+
+namespace ArgTweak {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    FunctionFixer ff;
+
+    mutateAll( translationUnit, ff );
+  }
+
+} // namespace ArgTweak
+
+
Index: translator/ArgTweak/Mutate.h
===================================================================
--- translator/ArgTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+#ifndef ARGTWEAK_MUTATE_H
+#define ARGTWEAK_MUTATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/Declaration.h"
+
+namespace ArgTweak {
+
+  void mutate( std::list< Declaration* > translationUnit );
+
+} // namespace ArgTweak
+
+#endif // #ifndef ARGTWEAK_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ArgTweak/module.mk
===================================================================
--- translator/ArgTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,4 @@
+SRC +=  ArgTweak/Rewriter.cc \
+#	ArgTweak/Mutate.cc \
+	$(NULL)
+
