Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/GenPoly/Box.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Thu Nov 26 17:01:55 2015
-// Update Count     : 191
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 15 15:30:31 2015
+// Update Count     : 215
 //
 
@@ -53,14 +53,14 @@
 		  public:
 			Pass1();
-			virtual Expression *mutate( ApplicationExpr *appExpr );
-			virtual Expression *mutate( AddressExpr *addrExpr );
-			virtual Expression *mutate( UntypedExpr *expr );
-			virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
-			virtual TypeDecl *mutate( TypeDecl *typeDecl );
-			virtual Expression *mutate( CommaExpr *commaExpr );
-			virtual Expression *mutate( ConditionalExpr *condExpr );
-			virtual Statement *mutate(ReturnStmt *catchStmt);
-			virtual Type *mutate( PointerType *pointerType );
-			virtual Type *mutate( FunctionType *pointerType );
+			virtual Expression * mutate( ApplicationExpr *appExpr );
+			virtual Expression * mutate( AddressExpr *addrExpr );
+			virtual Expression * mutate( UntypedExpr *expr );
+			virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
+			virtual TypeDecl * mutate( TypeDecl *typeDecl );
+			virtual Expression * mutate( CommaExpr *commaExpr );
+			virtual Expression * mutate( ConditionalExpr *condExpr );
+			virtual Statement * mutate( ReturnStmt *returnStmt );
+			virtual Type * mutate( PointerType *pointerType );
+			virtual Type * mutate( FunctionType *functionType );
   
 			virtual void doBeginScope();
@@ -190,6 +190,10 @@
 							if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
 								if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
-									name = typeInst->get_name();
-									return true;
+									if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
+										if ( typeInst->get_name() == typeInst2->get_name() ) {
+											name = typeInst->get_name();
+											return true;
+										} // if
+									} // if
 								} // if
 							} // if
@@ -340,23 +344,30 @@
 
 		Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
-			if ( useRetval ) {
-				assert( retval );
-				arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
-				arg++;
-			} else {
-				ObjectDecl *newObj = makeTemporary( retType->clone() );
-				Expression *paramExpr = new VariableExpr( newObj );
-				if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
-					paramExpr = new AddressExpr( paramExpr );
-				} // if
-				arg = appExpr->get_args().insert( arg, paramExpr );
-				arg++;
-///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
-				CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
-				commaExpr->set_env( appExpr->get_env() );
-				appExpr->set_env( 0 );
-				return commaExpr;
-			} // if
-			return appExpr;
+			// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+			// if ( useRetval ) {
+			// 	assert( retval );
+			// 	arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
+			// 	arg++;
+			// } else {
+
+			// Create temporary to hold return value of polymorphic function and produce that temporary as a result
+			// using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
+			// return values.
+			ObjectDecl *newObj = makeTemporary( retType->clone() );
+			Expression *paramExpr = new VariableExpr( newObj );
+			// If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
+			// temporary is already boxed and can be used directly.
+			if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
+				paramExpr = new AddressExpr( paramExpr );
+			} // if
+			arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
+			arg++;
+			// Build a comma expression to call the function and emulate a normal return.
+			CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
+			commaExpr->set_env( appExpr->get_env() );
+			appExpr->set_env( 0 );
+			return commaExpr;
+			// } // if
+			// return appExpr;
 		}
 
@@ -413,6 +424,6 @@
 			Type *newType = formal->clone();
 			std::list< FunctionType *> functions;
-			// instead of functions needing adapters, this really ought to look for
-			// any function mentioning a polymorphic type
+			// instead of functions needing adapters, this really ought to look for any function mentioning a
+			// polymorphic type
 			findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
 			if ( ! functions.empty() ) {
@@ -852,6 +863,24 @@
 		Expression *Pass1::mutate( AddressExpr *addrExpr ) {
 			assert( ! addrExpr->get_arg()->get_results().empty() );
+
+			bool needs = false;
+			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
+				if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
+					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
+						if ( name->get_name() == "*?" ) {
+							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
+								assert( ! appExpr->get_function()->get_results().empty() );
+								PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
+								assert( pointer );
+								FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
+								assert( function );
+								needs = needsAdapter( function, scopeTyVars );
+							} // if
+						} // if
+					} // if
+				} // if
+			} // if
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
-			if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
+			if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs ) {
 				Expression *ret = addrExpr->get_arg();
 				delete ret->get_results().front();
@@ -865,39 +894,40 @@
 		}
 
-		Statement * Pass1::mutate(ReturnStmt *retStmt) {
-			// a cast expr on a polymorphic return value is either redundant or invalid
-			while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
-				retStmt->set_expr( castExpr->get_arg() );
-				retStmt->get_expr()->set_env( castExpr->get_env() );
-				castExpr->set_env( 0 );
-				castExpr->set_arg( 0 );
-				delete castExpr;
-			}
-			if ( retval && retStmt->get_expr() ) {
-				assert( ! retStmt->get_expr()->get_results().empty() );
-				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
-///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-					TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
-					assert( typeInst );
-					std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
-					if ( assignIter == assignOps.end() ) {
-						throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
-					} // if
-					ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
-					Expression *retParm = new NameExpr( retval->get_name() );
-					retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
-					assignExpr->get_args().push_back( retParm );
-					assignExpr->get_args().push_back( retStmt->get_expr() );
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
-				} else {
-					useRetval = true;
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
-					useRetval = false;
-				} // if
-				retStmt->set_expr( 0 );
+		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
+			if ( retval && returnStmt->get_expr() ) {
+				assert( ! returnStmt->get_expr()->get_results().empty() );
+				// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+				// if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+				// a cast expr on a polymorphic return value is either redundant or invalid
+				while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
+					returnStmt->set_expr( castExpr->get_arg() );
+					returnStmt->get_expr()->set_env( castExpr->get_env() );
+					castExpr->set_env( 0 );
+					castExpr->set_arg( 0 );
+					delete castExpr;
+				} // while
+				TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
+				assert( typeInst );
+				std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
+				if ( assignIter == assignOps.end() ) {
+					throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
+				} // if
+				ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
+				Expression *retParm = new NameExpr( retval->get_name() );
+				retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
+				assignExpr->get_args().push_back( retParm );
+				assignExpr->get_args().push_back( returnStmt->get_expr() );
+				stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
+				// } else {
+				// 	std::cerr << "THOMAS " << std::endl;
+				// 	useRetval = true;
+				// 	stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
+				// 	useRetval = false;
+				// } // if
+				returnStmt->set_expr( 0 );
 			} else {
-				retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-			} // if
-			return retStmt;
+				returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
+			} // if
+			return returnStmt;
 		}
 
@@ -1097,6 +1127,5 @@
 			if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
 				if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
-					// change initialization of a polymorphic value object
-					// to allocate storage with alloca
+					// change initialization of a polymorphic value object to allocate storage with alloca
 					TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
 					assert( typeInst );
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/GenPoly/GenPoly.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Tue Nov 24 15:23:08 2015
-// Update Count     : 11
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec  1 15:18:54 2015
+// Update Count     : 12
 //
 
@@ -21,6 +21,5 @@
 
 namespace GenPoly {
-	// A function needs an adapter if it returns a polymorphic value or if any of its
-	// parameters have polymorphic type
+	// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
 	bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
 		if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/GenPoly/Lvalue.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:41:33 2015
-// Update Count     : 1
+// Last Modified On : Tue Dec 15 15:33:13 2015
+// Update Count     : 3
 //
 
@@ -120,12 +120,15 @@
 			if ( retval && retStmt->get_expr() ) {
 				assert( ! retStmt->get_expr()->get_results().empty() );
-				while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
-					retStmt->set_expr( castExpr->get_arg() );
-					retStmt->get_expr()->set_env( castExpr->get_env() );
-					castExpr->set_env( 0 );
-					castExpr->set_arg( 0 );
-					delete castExpr;
-				} // while
 				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+					// ***** Code Removal ***** because casts may be stripped already
+
+					// strip casts because not allowed to take address of cast
+					// while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
+					// 	retStmt->set_expr( castExpr->get_arg() );
+					// 	retStmt->get_expr()->set_env( castExpr->get_env() );
+					// 	castExpr->set_env( 0 );
+					// 	castExpr->set_arg( 0 );
+					// 	delete castExpr;
+					// } // while
 					retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
 				} else {
Index: src/InitTweak/RemoveInit.cc
===================================================================
--- src/InitTweak/RemoveInit.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/InitTweak/RemoveInit.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -7,9 +7,9 @@
 // RemoveInit.cc -- 
 //
-// Author           : Rodolfo G. Esteves
+// Author           : Rob Schluntz
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:39:32 2015
-// Update Count     : 1
+// Last Modified On : Tue Dec 15 15:37:26 2015
+// Update Count     : 15
 //
 
@@ -26,4 +26,24 @@
 		const std::list<Label> noLabels;
 	}
+	
+	class RemoveInit : public Mutator {
+	  public:
+		RemoveInit();
+		virtual ObjectDecl * mutate(ObjectDecl *objDecl);
+		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
+
+		virtual Statement * mutate( ReturnStmt * returnStmt );
+		
+		virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
+		
+	  protected:
+		std::list< Statement* > stmtsToAddBefore;
+		std::list< Statement* > stmtsToAddAfter;
+		void mutateStatementList( std::list< Statement* > &statements );
+
+		std::list<DeclarationWithType*> returnVals;
+		UniqueName tempNamer;
+		std::string funcName;
+	};
 
 	void tweak( std::list< Declaration * > translationUnit ) {
@@ -32,4 +52,6 @@
 	}
 
+	RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
+	
 	void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
 		for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
@@ -38,4 +60,7 @@
 			} // if
 			*i = (*i)->acceptMutator( *this );
+			if ( ! stmtsToAddBefore.empty() ) {
+				statements.splice( i, stmtsToAddBefore );
+			} // if
 		} // for
 		if ( ! stmtsToAddAfter.empty() ) {
@@ -49,7 +74,6 @@
 	}
 
-// in the case where an object has an initializer and a polymorphic type, insert an assignment
-// immediately after the declaration. This will (seemingly) cause the later phases to do the right
-// thing with the assignment
+	// in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
+	// declaration. This will (seemingly) cause the later phases to do the right thing with the assignment
 	ObjectDecl *RemoveInit::mutate( ObjectDecl *objDecl ) {
 		if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
@@ -63,4 +87,36 @@
 		return objDecl;
 	}
+
+	Statement *RemoveInit::mutate( ReturnStmt *returnStmt ) {
+		// update for multiple return values
+		assert( returnVals.size() == 0 || returnVals.size() == 1 );
+		// hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
+		// is being returned
+		if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
+			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
+			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
+			
+			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+			assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
+			assign->get_args().push_back( returnStmt->get_expr() );
+			stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
+
+			returnStmt->set_expr( new VariableExpr( newObj ) );
+		} // if
+		return returnStmt;
+	}
+
+	DeclarationWithType* RemoveInit::mutate( FunctionDecl *functionDecl ) {
+		std::list<DeclarationWithType*> oldReturnVals = returnVals;
+		std::string oldFuncName = funcName;
+		
+		FunctionType * type = functionDecl->get_functionType();
+		returnVals = type->get_returnVals();
+		funcName = functionDecl->get_name();
+		DeclarationWithType * decl = Mutator::mutate( functionDecl );
+		returnVals = oldReturnVals;
+		funcName = oldFuncName;
+		return decl;
+	}
 } // namespace InitTweak
 
Index: src/InitTweak/RemoveInit.h
===================================================================
--- src/InitTweak/RemoveInit.h	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/InitTweak/RemoveInit.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:40:11 2015
-// Update Count     : 1
+// Last Modified On : Fri Nov 27 17:00:47 2015
+// Update Count     : 2
 //
 
@@ -27,14 +27,4 @@
 	/// Adds assignment statements for polymorphic type initializers
 	void tweak( std::list< Declaration * > translationUnit );
-
-	class RemoveInit : public Mutator {
-	  public:
-		// RemoveInit();
-		virtual ObjectDecl *mutate(ObjectDecl *objDecl);
-		virtual CompoundStmt *mutate(CompoundStmt *compoundStmt);
-	  protected:
-		std::list< Statement* > stmtsToAddAfter;
-		void mutateStatementList( std::list< Statement* > &statements );
-	};
 } // namespace 
 
Index: src/SynTree/PointerType.cc
===================================================================
--- src/SynTree/PointerType.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/SynTree/PointerType.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 10:15:16 2015
-// Update Count     : 2
+// Last Modified On : Tue Dec 15 15:39:10 2015
+// Update Count     : 5
 //
 
@@ -20,10 +20,8 @@
 PointerType::PointerType( const Type::Qualifiers &tq, Type *base )
 	: Type( tq ), base( base ), dimension( 0 ), isVarLen( false ), isStatic( false ) {
-	base->set_isLvalue( false );
 }
 
 PointerType::PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
 	: Type( tq ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) {
-	base->set_isLvalue( false );
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/SynTree/Type.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Nov 20 12:54:09 2015
-// Update Count     : 15
+// Last Modified On : Fri Nov 27 17:54:31 2015
+// Update Count     : 16
 //
 
@@ -188,6 +188,6 @@
 	virtual ~FunctionType();
 
-	std::list<DeclarationWithType*>& get_returnVals() { return returnVals; }
-	std::list<DeclarationWithType*>& get_parameters() { return parameters; }
+	std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
+	std::list<DeclarationWithType*> & get_parameters() { return parameters; }
 	bool get_isVarArgs() { return isVarArgs; }
 	void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
Index: src/examples/fstream_test.c
===================================================================
--- src/examples/fstream_test.c	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/fstream_test.c	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May 27 18:13:43 2015
-// Update Count     : 2
+// Last Modified On : Mon Nov 23 14:43:32 2015
+// Update Count     : 40
 //
 
@@ -20,7 +20,18 @@
 	ifstream *sin = ifstream_stdin();
 	int nombre;
-	sout << "Appuyez un nombre, s'il vous plâit:\n";
-	sin >> &nombre;
-	sout << "Vous avez appuyé: " << nombre << "\n";
+	sout | "Entrez un nombre, s'il vous plaît:\n";
+	sin  | &nombre;
+	sout | "Vous avez entré " | nombre | " stocké à l'adresse " | &nombre | endl;
+	sout | "nombre " | nombre | " est "
+		 | (nombre > 0 ? "plus grand que" :
+		   nombre == 0 ? "égal à" : "moins de")
+		 | " zéro" | endl;
+
+	sout | "Entrez trois nombres, s'il vous plaît:\n";
+	int i, j, k;
+	sin  | &i | &j | &k;
+	sout | "Vous avez entré " | "i:" | i | " j:" | j | " k:" | k | endl;
+
+	sout | 3 | ' ' | 3.5 | ' ' | 'a' | ' ' | "abc" | endl;
 }
 
Index: src/examples/hello.c
===================================================================
--- src/examples/hello.c	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/hello.c	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Nov 20 16:02:50 2015
-// Update Count     : 3
+// Last Modified On : Sun Nov 22 17:40:37 2015
+// Update Count     : 5
 //
 
@@ -19,9 +19,5 @@
 	ofstream *sout = ofstream_stdout();
 	ifstream *sin = ifstream_stdin();
-	sout << "Bonjour au monde!\n";
-	sout << 3 << " " << 3.5 << " " << 'a' << " " << "abc" << "\n";
-	int i, j, k;
-	sin >> &i >> &j >> &k;
-	sout << "i:" << i << " j:" << j << " k:" << k << "\n";
+	sout | "Bonjour au monde!\n";
 }
 
Index: src/examples/iostream.c
===================================================================
--- src/examples/iostream.c	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/iostream.c	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Nov 20 13:19:19 2015
-// Update Count     : 9
+// Last Modified On : Mon Dec  7 23:08:02 2015
+// Update Count     : 24
 //
 
@@ -21,33 +21,46 @@
 
 forall( dtype ostype | ostream( ostype ) )
-ostype * ?<<?( ostype *os, char c ) {
+ostype * ?|?( ostype *os, char c ) {
 	return write( os, &c, 1 );
-} // ?<<?
+} // ?|?
 
 forall( dtype ostype | ostream( ostype ) )
-ostype * ?<<?( ostype *os, int i ) {
+ostype * ?|?( ostype *os, int i ) {
 	char buffer[32];									// larger than the largest integer
 	sprintf( buffer, "%d", i );
 	return write( os, buffer, strlen( buffer ) );
-} // ?<<?
+} // ?|?
 
 forall( dtype ostype | ostream( ostype ) )
-ostype * ?<<?( ostype *os, double d ) {
+ostype * ?|?( ostype *os, double d ) {
 	char buffer[32];									// larger than the largest double
 	sprintf( buffer, "%g", d );
 	return write( os, buffer, strlen( buffer ) );
-} // ?<<?
+} // ?|?
 
 forall( dtype ostype | ostream( ostype ) )
-ostype * ?<<?( ostype *os, const char *cp ) {
+ostype * ?|?( ostype *os, const char *cp ) {
 	return write( os, cp, strlen( cp ) );
-} // ?<<?
+} // ?|?
 
 forall( dtype ostype | ostream( ostype ) )
-ostype * ?<<?( ostype *os, const void *p ) {
+ostype * ?|?( ostype *os, const void *p ) {
 	char buffer[32];									// larger than the largest pointer
 	sprintf( buffer, "%p", p );
 	return write( os, buffer, strlen( buffer ) );
-} // ?<<?
+} // ?|?
+
+
+forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) ) 
+retostype * ?|?( ostype *os, retostype * (*manip)(ostype*) ) {
+  return manip(os);
+}
+
+forall( dtype ostype | ostream( ostype ) ) 
+ostype * endl( ostype * os ) {
+  os | "\n";
+  // flush
+  return os;
+} // endl
 
 forall( type elt_type | writeable( elt_type ),
@@ -56,8 +69,8 @@
 void write( iterator_type begin, iterator_type end, os_type *os ) {
 	void print( elt_type i ) {
-		os << i << ' ';
+		os | i | ' ';
 	}
 	for_each( begin, end, print );
-} // ?<<?
+} // ?|?
 
 forall( type elt_type | writeable( elt_type ),
@@ -65,23 +78,21 @@
 		dtype os_type | ostream( os_type ) )
 void write_reverse( iterator_type begin, iterator_type end, os_type *os ) {
-	void print( elt_type i ) {
-		os << i << ' ';
-	}
+	void print( elt_type i ) { os | i | ' '; }
 	for_each_reverse( begin, end, print );
-} // ?<<?
+} // ?|?
 
 
 forall( dtype istype | istream( istype ) )
-istype * ?>>?( istype *is, char *cp ) {
+istype * ?|?( istype *is, char *cp ) {
 	return read( is, cp, 1 );
-} // ?>>?
+} // ?|?
 
 forall( dtype istype | istream( istype ) )
-istype * ?>>?( istype *is, int *ip ) {
+istype * ?|?( istype *is, int *ip ) {
 	char cur;
   
 	// skip some whitespace
 	do {
-		is >> &cur;
+		is | &cur;
 		if ( fail( is ) || eof( is ) ) return is;
 	} while ( !( cur >= '0' && cur <= '9' ) );
@@ -91,5 +102,5 @@
 	while ( cur >= '0' && cur <= '9' ) {
 		*ip = *ip * 10 + ( cur - '0' );
-		is >> &cur;
+		is | &cur;
 		if ( fail( is ) || eof( is ) ) return is;
 	}
@@ -97,5 +108,5 @@
 	unread( is, cur );
 	return is;
-} // ?>>?
+} // ?|?
 
 // Local Variables: //
Index: src/examples/iostream.h
===================================================================
--- src/examples/iostream.h	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/iostream.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Nov 19 17:56:51 2015
-// Update Count     : 5
+// Last Modified On : Mon Nov 23 14:15:25 2015
+// Update Count     : 17
 //
 
@@ -27,14 +27,17 @@
 
 context writeable( type T ) {
-	forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, T );
+	forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T );
 };
 
 // implement writable for some intrinsic types
 
-forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, char );
-forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, int );
-forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, double );
-forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * );
-forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, void * );
+forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, char );
+forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, int );
+forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, double );
+forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * );
+forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * );
+
+forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) ) retostype * ?|?( ostype *os, retostype * (* manip)(ostype*) );
+forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * );
 
 // writes the range [begin, end) to the given stream
@@ -49,4 +52,5 @@
 void write_reverse( iterator_type begin, iterator_type end, os_type *os );
 
+//******************************************************************************
 
 context istream( dtype istype ) {
@@ -58,12 +62,12 @@
 
 context readable( type T ) {
-	forall( dtype istype | istream( istype ) ) istype * ?<<?( istype *, T );
+	forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T );
 };
 
 forall( dtype istype | istream( istype ) )
-istype * ?>>?( istype *, char * );
+istype * ?|?( istype *, char * );
 
 forall( dtype istype | istream( istype ) )
-istype * ?>>?( istype *, int * );
+istype * ?|?( istype *, int * );
 
 #endif // IOSTREAM_H
Index: src/examples/sum.c
===================================================================
--- src/examples/sum.c	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/sum.c	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Sep 28 15:09:55 2015
-// Update Count     : 118
+// Last Modified On : Sat Nov 21 18:08:18 2015
+// Update Count     : 119
 //
 
@@ -53,5 +53,5 @@
 	}
 	sout << "sum from " << low << " to " << High << " is "
-		 << (int)sum( size, a ) << ", check " << (int)s << "\n";
+		 << (int)sum( size, a ) << ", check " << (int)s << endl;
 
 	int s = 0, a[size];
@@ -62,5 +62,5 @@
 	}
 	sout << "sum from " << low << " to " << High << " is "
-		 << sum( size, (int *)a ) << ", check " << (int)s << "\n";
+		 << sum( size, (int *)a ) << ", check " << (int)s << endl;
 
 	double s = 0.0, a[size];
@@ -72,5 +72,5 @@
 	printf( "%g\n", sum( size, (double *)a ) );
 //	sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is "
-//		 << sum( size, (double *)a ) << ", check " << (double)s << "\n";
+//		 << sum( size, (double *)a ) << ", check " << (double)s << endl;
 
 	float s = 0.0, a[size];
@@ -82,5 +82,5 @@
 	printf( "%g\n", sum( size, (float *)a ) );
 //	sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is "
-//		 << sum( size, (float *)a ) << ", check " << (float)s << "\n";
+//		 << sum( size, (float *)a ) << ", check " << (float)s << endl;
 }
 
Index: src/examples/vector_test.c
===================================================================
--- src/examples/vector_test.c	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/examples/vector_test.c	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Nov 19 17:54:34 2015
-// Update Count     : 9
+// Last Modified On : Tue Dec 15 16:02:56 2015
+// Update Count     : 13
 //
 
@@ -27,7 +27,7 @@
 	int num;
 
-	sout << "enter N elements and C-d on a separate line:\n";
+	sout | "enter N elements and C-d on a separate line:" | endl;
 	for ( ;; ) {
-		sin >> &num;
+		sin | &num;
 	  if ( fail( sin ) || eof( sin ) ) break;
 		append( &vec, num );
@@ -35,11 +35,11 @@
 	// write out the numbers
 
-	sout << "Array elements:\n";
+	sout | "Array elements:" | endl;
 	write( begin( vec ), end( vec ), sout );
-	sout << "\n";
+	sout | endl;
 
-	sout << "Array elements reversed:\n";
+	sout | "Array elements reversed:" | endl;
 	write_reverse( begin( vec ), end( vec ), sout );
-	sout << "\n";
+	sout | endl;
 }
 
