Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 675d8166196da4f57bc368b82d7a4641323e2570)
+++ src/AST/Convert.cpp	(revision 19e567ddd7b3d0af80fcbf6caca69894939adc7f)
@@ -16,6 +16,4 @@
 #include "Convert.hpp"
 
-#include "AST/Pass.hpp"
-
 #include "AST/Attribute.hpp"
 #include "AST/Decl.hpp"
@@ -23,8 +21,9 @@
 #include "AST/Init.hpp"
 #include "AST/Stmt.hpp"
-
+#include "AST/TypeSubstitution.hpp"
 
 #include "SynTree/Attribute.h"
 #include "SynTree/Declaration.h"
+#include "SynTree/TypeSubstitution.h"
 
 //================================================================================================
@@ -413,16 +412,88 @@
 	}
 
+	TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
+
+		TypeSubstitution *rslt = new TypeSubstitution();
+
+		for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
+			rslt->add( src_i->first,
+			           get<Type>().accept1(src_i->second) );
+		}
+
+		for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
+			rslt->addVar( src_i->first,
+			              get<Expression>().accept1(src_i->second) );
+		}
+
+		return rslt;
+	}
+
+	void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
+						   std::vector<UniqueId>         &tgtResnSlots,
+						   const ast::Expr::InferUnion   &srcInferred ) {
+
+		assert( tgtInferParams.empty() );
+		assert( tgtResnSlots.empty() );
+
+		if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
+			const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
+			for (auto srcParam : srcParams) {
+				tgtInferParams[srcParam.first] = ParamEntry(
+					srcParam.second.decl,
+					get<Type>().accept1(srcParam.second.actualType),
+					get<Type>().accept1(srcParam.second.formalType),
+					get<Expression>().accept1(srcParam.second.expr)
+				);
+			}
+		} else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
+			const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
+			for (auto srcSlot : srcSlots) {
+				tgtResnSlots.push_back(srcSlot);
+			}
+		}
+	}
+
+	Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
+
+		tgt->location = src->location;
+
+		tgt->result = get<Type>().accept1(src->result);
+		tgt->env    = convertTypeSubstitution(src->env);
+
+		tgt->extension = src->extension;
+		convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
+
+		return tgt;
+	}
+
 	const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new ApplicationExpr(
+				get<Expression>().accept1(node->func),
+				get<Expression>().acceptL(node->args)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new UntypedExpr(
+				get<Expression>().accept1(node->func),
+				get<Expression>().acceptL(node->args)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::NameExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new NameExpr(
+				node->name
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
@@ -1172,18 +1243,94 @@
 	}
 
-	virtual void visit( ApplicationExpr * ) override final {
-
-	}
-
-	virtual void visit( UntypedExpr * ) override final {
-
-	}
-
-	virtual void visit( NameExpr * ) override final {
-
-	}
-
-	virtual void visit( CastExpr * ) override final {
-
+	ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
+
+		ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
+
+		for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
+			rslt->add( old_i->first,
+			           getAccept1<ast::Type>(old_i->second) );
+		}
+
+		for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
+			rslt->addVar( old_i->first,
+			              getAccept1<ast::Expr>(old_i->second) );
+		}
+
+		return rslt;
+	}
+
+	void convertInferUnion(ast::Expr::InferUnion               &newInferred, 
+						   const std::map<UniqueId,ParamEntry> &oldInferParams,
+						   const std::vector<UniqueId>         &oldResnSlots) {
+
+		assert( oldInferParams.empty() || oldResnSlots.empty() );
+		assert( newInferred.mode == ast::Expr::InferUnion::Empty );
+
+		if ( !oldInferParams.empty() ) {
+			ast::InferredParams &tgt = newInferred.inferParams();
+			for (auto old : oldInferParams) {
+				tgt[old.first] = ast::ParamEntry(
+					old.second.decl,
+					getAccept1<ast::Type>(old.second.actualType),
+					getAccept1<ast::Type>(old.second.formalType),
+					getAccept1<ast::Expr>(old.second.expr)
+				);
+			}
+		} else if ( !oldResnSlots.empty() ) {
+			ast::ResnSlots &tgt = newInferred.resnSlots();
+			for (auto old : oldResnSlots) {
+				tgt.push_back(old);
+			}
+		}
+	}
+
+	ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
+
+		nw->result = GET_ACCEPT_1(result, Type);
+		nw->env    = convertTypeSubstitution(old->env);
+
+		nw->extension = old->extension;
+		convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
+
+		return nw;
+	}
+
+	virtual void visit( ApplicationExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::ApplicationExpr(
+				old->location,
+				GET_ACCEPT_1(function, Expr),
+				GET_ACCEPT_V(args, Expr)
+			)
+		);
+	}
+
+	virtual void visit( UntypedExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::UntypedExpr(
+				old->location,
+				GET_ACCEPT_1(function, Expr),
+				GET_ACCEPT_V(args, Expr)
+			)
+		);
+	}
+
+	virtual void visit( NameExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::NameExpr(
+				old->location,
+				old->get_name()
+			)
+		);
+	}
+
+	virtual void visit( CastExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::CastExpr(
+				old->location,
+				nullptr, // cast's "to" type is expr's result type; converted in visitBaseExpr
+				old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
+			)
+		);
 	}
 
