Index: libcfa/src/enum.cfa
===================================================================
--- libcfa/src/enum.cfa	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ libcfa/src/enum.cfa	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -5,4 +5,35 @@
 
 #pragma GCC visibility push(default)
+
+forall( E | Serial( E ) ) {
+    E fromInt( unsigned i ) {
+        E upper = upperBound();
+        E lower = lowerBound();
+        // It is okay to overflow as overflow will be theoretically caught by the other bound
+        assert( i <= fromInstance(upper) && i >= fromInstance(lower) 
+            &&  "Not a valid value");
+        return fromInt_unsafe( i );
+    }
+
+    E succ( E e ) {
+        E upper = upperBound();
+        assert( (fromInstance(e) < fromInstance(upper)) 
+            && "Calling succ() on the last" );
+        return succ_unsafe(e);
+    }
+
+    E pred( E e ) {
+        E lower = lowerBound();
+        assert( (fromInstance(e) > fromInstance(lower)) 
+            && "Calling pred() on the first" );
+        return pred_unsafe(e);
+    }
+
+    int Countof( __attribute__((unused)) E e ) {
+        E upper = upperBound();
+        E lower = lowerBound();
+		return fromInstance( upper ) + fromInstance( lower ) + 1;
+    }
+}
 
 int scmp( const void * str1, const void * str2 ) {
Index: libcfa/src/enum.hfa
===================================================================
--- libcfa/src/enum.hfa	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ libcfa/src/enum.hfa	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -1,4 +1,5 @@
 #pragma once
 
+#include <assert.h>
 #include "iostream.hfa"
 
@@ -10,8 +11,27 @@
 forall( E | Bounded( E ) ) trait Serial {
     unsigned fromInstance( E e );
+    E fromInt_unsafe( unsigned i );
+    E succ_unsafe( E e );
+    E pred_unsafe( E e );
+};
+
+forall( E | Serial( E ) ) {
     E fromInt( unsigned i );
     E succ( E e );
     E pred( E e );
-};
+    int Countof( E e );
+}
+
+// forall( E | Bounded(E) ) trait SafeSerial {
+//     // unsigned fromInstance( E e );
+//     E fromInt_unsafe( unsigned i );
+//     // E succ_unsafe( E e );
+//     //E pred_unsafe( E e );
+
+//     unsigned fromInstance( E e );
+//     E fromInt( unsigned i );
+//     E succ( E e );
+//     E pred( E e );
+// };
 
 forall( E | Serial( E ) ) trait CfaEnum {
@@ -33,19 +53,4 @@
 	OSTYPE_VOID( E );
 }
-
-// forall( ostype & | ostream( ostype ), E | CfaEnum( E, quasi_void ) ) {
-// 	ostype & ?|?( ostype &, E );
-// 	OSTYPE_VOID( E );
-// }
-
-// Design two <- should go for this if we have change the cost model
-// forall( E | Serial( E ) ) trait CfaEnum {
-//     char * label( E e );
-//     unsigned int posn( E e );
-// };
-
-// forall( E, V| CfaEnum( E)) trait TypedEnum {
-//     V value( E e);
-// };
 
 static inline
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/AST/Expr.cpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -284,6 +284,9 @@
 // --- CountExpr
 
+CountExpr::CountExpr( const CodeLocation & loc, const Expr * e )
+: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(e), type( nullptr ) {}
+
 CountExpr::CountExpr( const CodeLocation & loc, const Type * t )
-: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), type( t ) {}
+: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(nullptr), type( t ) {}
 
 // --- AlignofExpr
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/AST/Expr.hpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -496,6 +496,8 @@
 class CountExpr final : public Expr {
 public:
+	ptr<Expr> expr;
 	ptr<Type> type;
 
+	CountExpr( const CodeLocation & loc, const Expr * t );
 	CountExpr( const CodeLocation & loc, const Type * t );
 
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/AST/Pass.impl.hpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -1339,5 +1339,9 @@
 			maybe_accept( node, &CountExpr::result );
 		}
-		maybe_accept( node, &CountExpr::type );
+		if ( node->type ) {
+			maybe_accept( node, &CountExpr::type );
+		} else {
+			maybe_accept( node, &CountExpr::expr );
+		}
 	}
 	VISIT_END( Expr, node );
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/AST/Print.cpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -1146,5 +1146,6 @@
 		os << "Count Expression on: ";
 		++indent;
-		node->type->accept( *this );
+		if ( node->type ) node->type->accept( *this );
+		else safe_print( node->expr );
 		--indent;
 		postprint( node );
Index: src/ControlStruct/TranslateEnumRange.cpp
===================================================================
--- src/ControlStruct/TranslateEnumRange.cpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/ControlStruct/TranslateEnumRange.cpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -81,5 +81,5 @@
             ast::UntypedExpr::createCall( location, "upperBound", {} )  });
     auto increment = ast::UntypedExpr::createCall( location, 
-        stmt->is_inc? "succ": "pred",
+        stmt->is_inc? "succ_unsafe": "pred_unsafe",
         { new ast::NameExpr( location, indexName ) });
     auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/Parser/parser.yy	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -970,8 +970,8 @@
 			// $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) );
 		}
+	| COUNTOF unary_expression
+		{  $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
 	| COUNTOF '(' type_no_function ')'
 		{ $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
-	| COUNTOF unary_expression
-		{ SemanticError( yylloc, "countof for expressions is currently unimplemented. "); $$ = nullptr; }
 	;
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -1485,10 +1485,32 @@
 
 	void Finder::postvisit( const ast::CountExpr * countExpr ) {
-		assert( countExpr->type );
-		auto enumInst = countExpr->type.as<ast::EnumInstType>();
-		if ( !enumInst ) {
-			SemanticError( countExpr, "Count Expression only supports Enum Type as operand: ");
-		}
-		addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
+		const ast::UntypedExpr * untyped;
+		if ( countExpr->type ) {
+			auto enumInst = countExpr->type.as<ast::EnumInstType>();
+			if ( enumInst ) {
+				addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
+				return;
+			}
+			auto untypedFirst = ast::UntypedExpr::createCall( countExpr->location, "lowerBound", {} );
+			auto castFirst = new ast::CastExpr( countExpr->location, untypedFirst , countExpr->type );
+			untyped = ast::UntypedExpr::createCall(
+				countExpr->location, "Countof", { castFirst }
+			);
+		}
+		if (!untyped) untyped = ast::UntypedExpr::createCall(
+				countExpr->location, "Countof", { countExpr->expr }
+		);
+		CandidateFinder finder( context, tenv );
+		finder.find( untyped );
+		CandidateList winners = findMinCost( finder.candidates );
+		if ( winners.size() == 0 ) {
+			SemanticError( countExpr->expr, "Countof is not implemented for operand: " );
+		}
+		if ( winners.size() !=  1 ) {
+			SemanticError( countExpr->expr, "Ambiguous expression in countof operand: " );
+		}
+		CandidateRef & choice = winners.front();
+		choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
+		addCandidate( *choice, choice->expr );
 	}
 
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 9c447e225244a18c96cc4536ae39da1e56abe7b3)
+++ src/Validate/ImplementEnumFunc.cpp	(revision 0c327cee778443a440104253db33557cee4d2a92)
@@ -228,5 +228,5 @@
 ast::FunctionDecl* EnumAttrFuncGenerator::genFromIntProto() const {
 	return genProto(
-		"fromInt",
+		"fromInt_unsafe",
 		{new ast::ObjectDecl(getLocation(), "_i", new ast::BasicType(ast::BasicKind::UnsignedInt))},
 		{new ast::ObjectDecl(getLocation(), "_ret", new ast::EnumInstType(decl))}
@@ -313,6 +313,6 @@
 		genFromIntProto(),
 		genFromInstanceProto(),
-		genInstToInstFuncProto("succ"),
-		genInstToInstFuncProto("pred")
+		genInstToInstFuncProto("succ_unsafe"),
+		genInstToInstFuncProto("pred_unsafe")
 	};
 	for (auto& proto: protos) produceForwardDecl(proto);
