diff --git a/modcc/blocks.hpp b/modcc/blocks.hpp
index 9ba8c65769f97afe631b8d9fc7779b4472758b4f..868f60bd601ba914d8f86f07e6294bd353d12b19 100644
--- a/modcc/blocks.hpp
+++ b/modcc/blocks.hpp
@@ -17,6 +17,7 @@ struct IonDep {
     std::string name;         // name of ion channel
     std::vector<Token> read;  // name of channels parameters to write
     std::vector<Token> write; // name of channels parameters to read
+    std::string valence;
 
     bool has_variable(std::string const& name) const {
         return writes_variable(name) || reads_variable(name);
diff --git a/modcc/functioninliner.cpp b/modcc/functioninliner.cpp
index da5dd5eb270fbb11f17e8a553687e57dbc1ea026..20c0c2ede1394a57f065c125192f6deab76a0bd2 100644
--- a/modcc/functioninliner.cpp
+++ b/modcc/functioninliner.cpp
@@ -18,6 +18,13 @@ expression_ptr inline_function_call(Expression* e)
                 "can only inline functions with one statement", func->location()
             );
         }
+
+        if(body.front()->is_if()) {
+            throw compiler_exception(
+                    "can not inline functions with if statements", func->location()
+            );
+        }
+
         // assume that the function body is correctly formed, with the last
         // statement being an assignment expression
         auto last = body.front()->is_assignment();
diff --git a/modcc/module.cpp b/modcc/module.cpp
index c78d9c7253c9b766ec67d65c37d27d75d6bbe059..97debcad3542b94e58fb3732bbb40f33d203f877 100644
--- a/modcc/module.cpp
+++ b/modcc/module.cpp
@@ -590,7 +590,11 @@ void Module::add_variables_to_symbols() {
         VariableExpression* state = nullptr;
         if (has_symbol(name)) {
             state = symbols_[name].get()->is_variable();
-            if (!state || !state->is_state()) {
+            if (!state) {
+                error(pprintf("the symbol defined % can't be redeclared", yellow(name)), tkn.location);
+                return;
+            }
+            if (!state->is_state()) {
                 error(pprintf("the symbol defined % at % can't be redeclared",
                     state->location(), yellow(name)), tkn.location);
                 return;
diff --git a/modcc/parser.cpp b/modcc/parser.cpp
index 6ce9258b1ca4a500a275df2529e3646ac0c1bbbd..1598711a9c919a37b8d8b74e33292e5af82e9a40 100644
--- a/modcc/parser.cpp
+++ b/modcc/parser.cpp
@@ -35,6 +35,15 @@ bool Parser::expect(tok tok, std::string const& str) {
     return false;
 }
 
+void Parser::parse_unit() {
+    if(token_.type == tok::lparen) {
+        while (token_.type != tok::rparen) {
+            get_token();
+        }
+        get_token(); // consume ')'
+    }
+}
+
 void Parser::error(std::string msg) {
     std::string location_info = pprintf(
             "%:% ", module_ ? module_->source_name() : "", token_.location);
@@ -125,6 +134,12 @@ bool Parser::parse() {
                 module_->add_callable(std::move(f));
                 }
                 break;
+            case tok::unitson :
+                get_token();
+                break;
+            case tok::unitsoff :
+                get_token();
+                break;
             default :
                 error(pprintf("expected block type, found '%'", token_.spelling));
                 break;
@@ -317,6 +332,13 @@ void Parser::parse_neuron_block() {
                             target.push_back(id);
                         }
                     }
+
+                    if(token_.type == tok::valence) {
+                        //Consume "Valence"
+                        get_token();
+                        ion.valence == value_literal();
+                    }
+
                     // add the ion dependency to the NEURON block
                     neuron_block.ions.push_back(std::move(ion));
                 }
@@ -715,6 +737,8 @@ expression_ptr Parser::parse_prototype(std::string name=std::string()) {
 
         get_token(); // consume the identifier
 
+        parse_unit(); // consume the unit if provided
+
         // look for a comma
         if(!(token_.type == tok::comma || token_.type==tok::rparen)) {
             error(  "expected a comma or closing parenthesis, found '"
@@ -839,6 +863,8 @@ symbol_ptr Parser::parse_function() {
     auto p = parse_prototype();
     if(p==nullptr) return nullptr;
 
+    parse_unit();
+
     // check for opening left brace {
     if(!expect(tok::lbrace)) return nullptr;
 
diff --git a/modcc/parser.hpp b/modcc/parser.hpp
index 43fb323b2d632ebf571636770a3abe6a241ca5af..8b9414237db2948a899eeed990881b08d93c8e6f 100644
--- a/modcc/parser.hpp
+++ b/modcc/parser.hpp
@@ -75,6 +75,7 @@ private:
     Parser();
     Parser(Parser const &);
 
+    void parse_unit();
     bool expect(tok, const char *str="");
     bool expect(tok, std::string const& str);
 };
diff --git a/modcc/token.cpp b/modcc/token.cpp
index 1ea8d27abf2a4f20305661e995ee57ac1e961c29..ba89e2ce8447492d1e79add7e5ad18fd4767282b 100644
--- a/modcc/token.cpp
+++ b/modcc/token.cpp
@@ -41,6 +41,7 @@ static Keyword keywords[] = {
     {"USEION",      tok::useion},
     {"READ",        tok::read},
     {"WRITE",       tok::write},
+    {"VALENCE",     tok::valence},
     {"RANGE",       tok::range},
     {"LOCAL",       tok::local},
     {"CONSERVE",    tok::conserve},
@@ -110,6 +111,7 @@ static TokenString token_strings[] = {
     {"USEION",      tok::useion},
     {"READ",        tok::read},
     {"WRITE",       tok::write},
+    {"VALENCE",     tok::valence},
     {"RANGE",       tok::range},
     {"LOCAL",       tok::local},
     {"SOLVE",       tok::solve},
diff --git a/modcc/token.hpp b/modcc/token.hpp
index 97667c2eb660c81d795e742d99bf917e0d84c994..149ee7435cdda2c6a4235a99a559ba7ddd735b19 100644
--- a/modcc/token.hpp
+++ b/modcc/token.hpp
@@ -59,7 +59,7 @@ enum class tok {
     // keywoards inside blocks
     unitsoff, unitson,
     suffix, nonspecific_current, useion,
-    read, write,
+    read, write, valence,
     range, local, conserve,
     solve, method,
     threadsafe, global,