Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/AST/Stmt.hpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -238,4 +238,5 @@
 	ptr<Expr> inc;
 	ptr<Expr> range_over;
+	bool is_inc;
 	ptr<Stmt> body;
 	ptr<Stmt> else_;
@@ -251,7 +252,8 @@
 			range_over(nullptr), body(body), else_(else_) {}
 
-	ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, 
+	ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
 			 const Stmt * body, const Stmt * else_ )
-		: Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
+		: Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc), 
+		body(body), else_(else_) {}
 
 	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/ControlStruct/TranslateEnumRange.cpp
===================================================================
--- src/ControlStruct/TranslateEnumRange.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/ControlStruct/TranslateEnumRange.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -26,7 +26,11 @@
         auto enumDecl = enumInst->base;
 
-        auto init = stmt->inits.front();
+        auto objInit = stmt->inits.front();
 
-        if (auto declStmt = init.as<ast::DeclStmt>()) {
+        auto initLocation = objInit->location;
+        auto rangeLocation = stmt->range_over->location;
+        assert( stmt->inits.size() == 1 );
+
+        if (auto declStmt = objInit.as<ast::DeclStmt>()) {
             auto decl = declStmt->decl;
             if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
@@ -57,5 +61,8 @@
                 if ( !objDecl->init ) {
                     auto location = stmt->location;
-                    auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
+                    ast::SingleInit * newInit;
+                    newInit = new ast::SingleInit( location, 
+                        new ast::NameExpr( location, 
+                        stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
                     auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
                     auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
@@ -78,13 +85,17 @@
     auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
     auto enumDecl = enumInst->base;
-
-    auto condition = ast::UntypedExpr::createCall( location, "?<=?", {
-        new ast::NameExpr( location, indexName ),
-        // ast::ConstantExpr::from_ulong( location, enumDecl->members.size() )
-        new ast::NameExpr( location, enumDecl->members.back()->name )
-    });
-    auto increment = ast::UntypedExpr::createCall( location, "succ", {
-        new ast::NameExpr( location, indexName )
-    });
+    
+    // Both inc and dec check if the current posn less than the number of enumerator
+    // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
+    // it wraps around and become unsigned max
+    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
+        "?<=?",
+        { 
+            ast::UntypedExpr::createCall(location, "posn", { new ast::NameExpr( location, indexName ) } ),
+            ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 )
+        });
+    auto increment = ast::UntypedExpr::createCall( location, 
+        stmt->is_inc? "succ": "pred",
+        { new ast::NameExpr( location, indexName ) });
     auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
     auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
Index: src/Parser/StatementNode.cpp
===================================================================
--- src/Parser/StatementNode.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/Parser/StatementNode.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -216,5 +216,5 @@
 		return new ast::ForStmt( location,
 			std::move( astinit ),
-			range_over,
+			range_over, forctl->kind == OperKinds::LThan,
 			buildMoveSingle( stmt ),
 			buildMoveOptional( else_ )
Index: src/Parser/StatementNode.hpp
===================================================================
--- src/Parser/StatementNode.hpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/Parser/StatementNode.hpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -64,6 +64,6 @@
 	ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
 		init( stmt ), condition( condition ), change( change ), range_over( nullptr ) {}
-	ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
-		init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
+	ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) :
+		init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
 
 	StatementNode * init;
@@ -71,4 +71,5 @@
 	ExpressionNode * change;
 	ExpressionNode * range_over;
+	OperKinds kind;
 };
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/Parser/parser.yy	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -279,5 +279,5 @@
 		DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
 		assert( range_over_expr );
-		return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
+		return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
 	} else {
 		SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -698,8 +698,4 @@
 		void postvisit( const ast::CountExpr * countExpr );
 
-		const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src, 
-			const ast::EnumInstType * dst
-			, const ast::Expr * expr, Cost minCost );
-
 		void postvisit( const ast::InitExpr * ) {
 			assertf( false, "CandidateFinder should never see a resolved InitExpr." );
@@ -1213,47 +1209,4 @@
 	}
 
-	// src is a subset of dst
-	const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src, 
-		const ast::EnumInstType * dst,
-		const ast::Expr * expr,
-		Cost minCost ) {
-		
-		auto srcDecl = src->base;
-		auto dstDecl = dst->base;
-
-		if (srcDecl->name == dstDecl->name) return expr;
-
-		for (auto& dstChild: dstDecl->inlinedDecl) {
-			Cost c = castCost(src, dstChild, false, symtab, tenv);
-			ast::CastExpr * castToDst;
-			if (c<minCost) {
-				unsigned offset = dstDecl->calChildOffset(dstChild.get());
-				if (offset > 0) {
-					auto untyped = ast::UntypedExpr::createCall(
-						expr->location, 
-						"?+?", 
-						{ new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
-						ast::ConstantExpr::from_int(expr->location, offset)});
-					CandidateFinder finder(context, tenv);
-					finder.find( untyped );
-					CandidateList winners = findMinCost( finder.candidates );
-					CandidateRef & choice = winners.front();
-					// choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
-					choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
-					// castToDst = new ast::CastExpr(choice->expr, dstChild);
-					castToDst = new ast::CastExpr( 
-						makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
-					 dst);
-
-				} else {
-					castToDst = new ast::CastExpr( expr, dst );
-				}
-				return castToDst;
-			}
-		}
-		SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
-		return nullptr;
-	}
-
 	void Finder::postvisit( const ast::CastExpr * castExpr ) {
 		ast::ptr< ast::Type > toType = castExpr->result;
@@ -1309,6 +1262,7 @@
 			auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
 			auto toAsEnum = toType.as<ast::EnumInstType>();
-			if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {	
-				ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
+			if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
+				CandidateFinder subFinder(context, tenv);
+				ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
 				cand->expr = offsetExpr;
 			}
@@ -2193,6 +2147,9 @@
 					expr->location, 
 					"?+?", 
-					{ new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
-					ast::ConstantExpr::from_int(expr->location, offset)});
+					{ new ast::CastExpr( expr->location,
+						expr,
+						new ast::BasicType(ast::BasicKind::SignedInt),
+						ast::GeneratedFlag::ExplicitCast ),
+						ast::ConstantExpr::from_int(expr->location, offset)} );
 				CandidateFinder finder(context, env);
 				finder.find( untyped );
Index: src/ResolvExpr/CastCost.cpp
===================================================================
--- src/ResolvExpr/CastCost.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/ResolvExpr/CastCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -53,4 +53,15 @@
 		void postvisit( const ast::EnumInstType * enumInst ) {
 			cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
+
+			if (Cost::unsafe < cost) {
+				static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
+				Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
+				cost = intCost < cost? intCost: cost;
+			}
+			if ( enumInst->base->isTyped && enumInst->base->base ) {
+				auto baseConversionCost = 
+					castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
+				cost = baseConversionCost < cost? baseConversionCost: cost;
+			}
 		}
 
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/ResolvExpr/ConversionCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -162,5 +162,5 @@
 Cost conversionCost(
 	const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
-	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
+const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
 ) {
 	if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
@@ -284,5 +284,5 @@
 	if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
-	}	else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
+	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
 			cost = Cost::unsafe;
@@ -368,7 +368,8 @@
 		return;
 	}
-	static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
-	cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
+
 	if ( !inst->base->isTyped ) {
+		static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
+		cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 		if ( cost < Cost::unsafe ) {
 			cost.incSafe();
@@ -376,5 +377,5 @@
 		return;
 	}
-	cost.incUnsafe();
+	// cost.incUnsafe();
 }
 
Index: src/ResolvExpr/Unify.cpp
===================================================================
--- src/ResolvExpr/Unify.cpp	(revision d5efcb72910e612e3c6dc8ed684f24bef154e8fd)
+++ src/ResolvExpr/Unify.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -276,6 +276,4 @@
 	void postvisit( const ast::VoidType * ) {
 		result = dynamic_cast< const ast::VoidType * >( type2 );
-			// || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
-		;
 	}
 
@@ -284,5 +282,4 @@
 			result = basic->kind == basic2->kind;
 		}
-		// result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -293,5 +290,4 @@
 				noWiden());
 		}
-		// result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -312,5 +308,4 @@
 		result = unifyExact(
 			array->base, array2->base, tenv, need, have, open, noWiden());
-			// || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -607,20 +602,16 @@
 
 		result = unifyList( types, types2, tenv, need, have, open );
-			// || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::VarArgsType * ) {
 		result = dynamic_cast< const ast::VarArgsType * >( type2 );
-			// || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::ZeroType * ) {
 		result = dynamic_cast< const ast::ZeroType * >( type2 );
-			// || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::OneType * ) {
 		result = dynamic_cast< const ast::OneType * >( type2 );
-			// || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
 	}
 };
