Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 7042c60b5ac335636cead43392db79c8e35cedf8)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision c5c123f63963ca0018deea205deb1482ee47b1b0)
@@ -906,5 +906,5 @@
 				}
 				CandidateRef & choice = winners.front();
-				choice->cost.incVar();
+				choice->cost.incSafe();
 				candidates.emplace_back( std::move(choice) );
 			}
@@ -1376,15 +1376,17 @@
 			ast::Expr * newExpr = data.combine( nameExpr->location, cost );
 
-			bool bentConversion = false;
-			if ( auto inst = newExpr->result.as<ast::EnumInstType>() ) {
-				if ( inst->base && inst->base->base ) {
-					bentConversion = true;
-				}
-			}
-
+			// bool bentConversion = false;
+			// if ( auto inst = newExpr->result.as<ast::EnumInstType>() ) {
+			// 	if ( inst->base && inst->base->base ) {
+			// 		bentConversion = true;
+			// 	}
+			// }
+
+			// CandidateRef newCand = std::make_shared<Candidate>(
+			// 	newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero,
+			// 	cost );
 			CandidateRef newCand = std::make_shared<Candidate>(
-				newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero,
+				newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
 				cost );
-
 			if (newCand->expr->env) {
 				newCand->env.add(*newCand->expr->env);
@@ -1829,10 +1831,14 @@
 					Cost cost = Cost::zero;
 					ast::Expr * newExpr = data.combine( expr->location, cost );
+					// CandidateRef newCand =
+					// 	std::make_shared<Candidate>(
+					// 		newExpr, copy( tenv ), ast::OpenVarSet{},
+					// 		ast::AssertionSet{}, Cost::safe, cost
+					// 	);
 					CandidateRef newCand =
 						std::make_shared<Candidate>(
 							newExpr, copy( tenv ), ast::OpenVarSet{},
-							ast::AssertionSet{}, Cost::safe, cost
+							ast::AssertionSet{}, Cost::zero, cost
 						);
-
 					if (newCand->expr->env) {
 						newCand->env.add(*newCand->expr->env);
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 7042c60b5ac335636cead43392db79c8e35cedf8)
+++ src/ResolvExpr/CastCost.cc	(revision c5c123f63963ca0018deea205deb1482ee47b1b0)
@@ -53,5 +53,43 @@
 			} else {
 				cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
+				if ( Cost::unsafe < cost ) {
+					if (auto enumInst =  dynamic_cast<const ast::EnumInstType *>(dst)) {
+						assert(enumInst->base->base);
+						cost = Cost::unsafe;
+					}
+				}
 			}
+		}
+
+		void postvisit( const ast::ZeroType * zero ) {
+			// auto ptr = dynamic_cast< const ast::PointerType * >( dst );
+			// if ( ptr && basicType->isInteger() ) {
+			// 	// needed for, e.g. unsigned long => void *
+			// 	cost = Cost::unsafe;
+			// } else {
+			cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
+			if ( Cost::unsafe < cost ) {
+				if (auto enumInst =  dynamic_cast<const ast::EnumInstType *>(dst)) {
+					assert(enumInst->base->base);
+					cost = Cost::unsafe;
+				}
+			}
+			// }
+		}
+
+		void postvisit( const ast::OneType * one ) {
+			// auto ptr = dynamic_cast< const ast::PointerType * >( dst );
+			// if ( ptr && basicType->isInteger() ) {
+			// 	// needed for, e.g. unsigned long => void *
+			// 	cost = Cost::unsafe;
+			// } else {
+			cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
+			if ( Cost::unsafe < cost ) {
+				if (auto enumInst =  dynamic_cast<const ast::EnumInstType *>(dst)) {
+					assert(enumInst->base->base);
+					cost = Cost::unsafe;
+				}
+			}
+			// }
 		}
 
@@ -80,4 +118,10 @@
 					cost = Cost::unsafe;
 				}
+			}
+		}
+
+		void postvist( const ast::EnumInstType * ) {
+			if ( auto basic = dynamic_cast< const ast::BasicType * >(dst) ) {
+				if ( basic->isInteger() ) cost = Cost::unsafe;
 			}
 		}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 7042c60b5ac335636cead43392db79c8e35cedf8)
+++ src/ResolvExpr/ConversionCost.cc	(revision c5c123f63963ca0018deea205deb1482ee47b1b0)
@@ -284,6 +284,5 @@
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
-			cost = Cost::zero;
-			cost.incUnsafe();
+			cost = Cost::unsafe;
 		}
 	}
@@ -482,6 +481,5 @@
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
-			cost = Cost::zero;
-			cost.incUnsafe();
+			cost = Cost::unsafe;
 		}
 	}
@@ -504,6 +502,5 @@
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) {
-			cost = Cost::zero;
-			cost.incUnsafe();
+			cost = Cost::unsafe;
 		}
 	}
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 7042c60b5ac335636cead43392db79c8e35cedf8)
+++ src/Validate/ImplementEnumFunc.cpp	(revision c5c123f63963ca0018deea205deb1482ee47b1b0)
@@ -30,5 +30,5 @@
 	void genAttrFunctions();
 	void genSuccPredPosn();
-	void genSuccPredDecl();
+	// void genSuccPredDecl();
 
 	void appendReturnThis(ast::FunctionDecl* decl) {
@@ -73,9 +73,28 @@
 	const ast::Decl* getDecl() const { return decl; }
 
+	// Implement Bounded trait for enum
+    void genBoundedFunctions();
+	// Implement Serial trait for enum
+	void genSerialTraitFuncs();
+
+	// Bounded trait
+	ast::FunctionDecl* genLowerBoundProto() const;
+	ast::FunctionDecl* genUpperBoundProto() const;
+	void genLowerBoundBody(ast::FunctionDecl* func) const;
+	void genUpperBoundBody(ast::FunctionDecl* func) const;
+
 	ast::FunctionDecl* genPosnProto() const;
 	ast::FunctionDecl* genLabelProto() const;
 	ast::FunctionDecl* genValueProto() const;
+
+	// Serial trait
+	ast::FunctionDecl* genFromIntProto() const;
+	ast::FunctionDecl* genFromInstanceProto() const;
 	ast::FunctionDecl* genSuccProto() const;
 	ast::FunctionDecl* genPredProto() const;
+
+	void genFromIntBody(ast::FunctionDecl *) const; 
+	void genFromInstanceBody(ast::FunctionDecl *) const;
+	////////////////
 
 	ast::FunctionDecl* genSuccPosProto() const;
@@ -313,4 +332,63 @@
 }
 
+ast::FunctionDecl* EnumAttrFuncGenerator::genFromIntProto() const {
+	return genProto(
+		"fromInt",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::BasicType(ast::BasicKind::UnsignedInt))},
+		{new ast::ObjectDecl(getLocation(), "_ret", new ast::EnumInstType(decl))}
+	);
+}
+
+ast::FunctionDecl* EnumAttrFuncGenerator::genFromInstanceProto() const {
+	return genProto(
+		"fromInstance",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret", new ast::BasicType(ast::BasicKind::UnsignedInt))}
+	);
+}
+
+void EnumAttrFuncGenerator::genFromIntBody(ast::FunctionDecl* func) const {
+	auto params = func->params;
+	assert( params.size() == 1 );
+	auto param = params.front();
+	auto castExpr = new ast::CastExpr(
+		func->location,
+		new ast::VariableExpr(func->location, param),
+		new ast::EnumInstType(decl),
+		ast::GeneratedFlag::ExplicitCast
+	);
+	func->stmts = new ast::CompoundStmt(
+		func->location, {new ast::ReturnStmt(func->location, castExpr)}
+	);
+}
+
+void EnumAttrFuncGenerator::genFromInstanceBody(ast::FunctionDecl* func) const {
+	auto params = func->params;
+	assert( params.size() == 1 );
+	auto param = params.front();
+	ast::UntypedExpr* untyped = ast::UntypedExpr::createCall(
+		func->location, "posE", { new ast::VariableExpr(func->location, param) });
+	func->stmts = new ast::CompoundStmt(
+		func->location, {new ast::ReturnStmt(func->location, untyped)}
+	);
+}
+
+void EnumAttrFuncGenerator::genSerialTraitFuncs() {
+	auto fromIntProto = genFromIntProto();
+	produceForwardDecl(fromIntProto);
+	genFromIntBody(fromIntProto);
+	produceDecl(fromIntProto);
+
+	auto fromInstanceProto = genFromInstanceProto();
+	produceForwardDecl(fromInstanceProto);
+	genFromInstanceBody(fromInstanceProto);
+	produceDecl(fromInstanceProto);
+
+	auto succProto = genSuccProto();
+	auto predProto = genPredProto();
+	produceForwardDecl(succProto);
+	produceForwardDecl(predProto);
+}
+
 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccProto() const {
 	return genProto(
@@ -327,4 +405,45 @@
 		{new ast::ObjectDecl(getLocation(), "_ret",
 		                     new ast::EnumInstType(decl))});
+}
+
+ast::FunctionDecl* EnumAttrFuncGenerator::genLowerBoundProto() const {
+    return genProto("lowerBound", {}, {
+        new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))
+    });
+}
+
+ast::FunctionDecl* EnumAttrFuncGenerator::genUpperBoundProto() const {
+    return genProto("upperBound", {}, {
+        new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))
+    });
+}
+
+void EnumAttrFuncGenerator::genLowerBoundBody(ast::FunctionDecl* func) const {
+	const CodeLocation & loc = func->location;
+	auto mem = decl->members.front();
+	// auto expr = new ast::QualifiedNameExpr( loc, decl, mem->name );
+	// expr->result = new ast::EnumInstType( decl );
+	auto expr = new ast::NameExpr( loc, mem->name );
+	func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)});
+}
+
+void EnumAttrFuncGenerator::genUpperBoundBody(ast::FunctionDecl* func) const {
+	const CodeLocation & loc = func->location;
+	auto mem = decl->members.back();
+	auto expr = new ast::NameExpr( loc, mem->name );
+	// expr->result = new ast::EnumInstType( decl );
+	func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)});	
+}
+
+void EnumAttrFuncGenerator::genBoundedFunctions() {
+	ast::FunctionDecl * upperDecl = genUpperBoundProto();
+	produceForwardDecl(upperDecl);
+	genUpperBoundBody(upperDecl);
+	produceDecl(upperDecl);
+
+	ast::FunctionDecl * lowerDecl = genLowerBoundProto();
+	produceForwardDecl(lowerDecl);
+	genLowerBoundBody(lowerDecl);
+	produceDecl(lowerDecl);
 }
 
@@ -373,9 +492,9 @@
 		func->location, "?[?]",
 		{new ast::NameExpr(func->location, arrDecl->name),
-			new ast::CastExpr(
-				func->location,
-				new ast::VariableExpr( func->location, func->params.front() ),
-				new ast::EnumAttrType( new ast::EnumInstType(decl),
-					ast::EnumAttribute::Posn))});
+		new ast::CastExpr(
+			func->location,
+			new ast::VariableExpr( func->location, func->params.front() ),
+			new ast::EnumAttrType( new ast::EnumInstType(decl),
+				ast::EnumAttribute::Posn))});
 	func->stmts = new ast::CompoundStmt(
 		func->location, {new ast::ReturnStmt(func->location, untyped)});
@@ -450,29 +569,23 @@
 
 void EnumAttrFuncGenerator::genAttrFunctions() {
-	if (decl->base) {
-		genAttributesDecls(ast::EnumAttribute::Value);
-		genAttributesDecls(ast::EnumAttribute::Label);
-		genAttributesDecls(ast::EnumAttribute::Posn);
-	}
-}
-
-void EnumAttrFuncGenerator::genSuccPredDecl() {
-	if (decl->base) {
-		auto succProto = genSuccProto();
-		auto predProto = genPredProto();
-
-		produceForwardDecl(succProto);
-		produceForwardDecl(predProto);
-	}
-}
+	genAttributesDecls(ast::EnumAttribute::Value);
+	genAttributesDecls(ast::EnumAttribute::Label);
+	genAttributesDecls(ast::EnumAttribute::Posn);	
+}
+
+// void EnumAttrFuncGenerator::genSuccPredDecl() {
+// 	auto succProto = genSuccProto();
+// 	auto predProto = genPredProto();
+
+// 	produceForwardDecl(succProto);
+// 	produceForwardDecl(predProto);
+// }
 
 void EnumAttrFuncGenerator::genSuccPredPosn() {
-	if (decl->base) {
-		ast::FunctionDecl* succ = genSuccPredFunc(true);
-		ast::FunctionDecl* pred = genSuccPredFunc(false);
-
-		produceDecl(succ);
-		produceDecl(pred);
-	}
+	ast::FunctionDecl* succ = genSuccPredFunc(true);
+	ast::FunctionDecl* pred = genSuccPredFunc(false);
+
+	produceDecl(succ);
+	produceDecl(pred);
 }
 
@@ -482,6 +595,8 @@
 	genAttrStandardFuncs();
 	genAttrFunctions();
-	genSuccPredDecl();
-	genSuccPredPosn(); // Posn
+	genSerialTraitFuncs();
+	genSuccPredPosn();
+	// problematic
+	genBoundedFunctions();
 	// Now export the lists contents.
 	decls.splice(decls.end(), forwards);
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 7042c60b5ac335636cead43392db79c8e35cedf8)
+++ src/main.cc	(revision c5c123f63963ca0018deea205deb1482ee47b1b0)
@@ -325,4 +325,7 @@
 		PASS( "Validate Generic Parameters", Validate::fillGenericParameters, transUnit );
 		PASS( "Translate Dimensions", Validate::translateDimensionParameters, transUnit );
+		// Need to happen before fixing returns because implementEnumFunc has ReturnStmt
+		
+		PASS( "Generate Enum Attributes Functions", Validate::implementEnumFunc, transUnit );
 		PASS( "Check Function Returns", Validate::checkReturnStatements, transUnit );
 		PASS( "Fix Return Statements", InitTweak::fixReturnStatements, transUnit );
@@ -333,6 +336,5 @@
 
 		PASS( "Generate Autogen Routines", Validate::autogenerateRoutines, transUnit );
-		PASS( "Generate Enum Attributes Functions", Validate::implementEnumFunc, transUnit );
-
+		
 		PASS( "Implement Actors", Concurrency::implementActors, transUnit );
 		PASS( "Implement Virtual Destructors", Virtual::implementVirtDtors, transUnit );
