diff --git a/interpreter/cling/lib/MetaProcessor/InputValidator.cpp b/interpreter/cling/lib/MetaProcessor/InputValidator.cpp
index f0a757a7c127908479f94cd9df9c823f29edde48..61fcda01afad6a2ec464dd304ec6fa540dc65805 100644
--- a/interpreter/cling/lib/MetaProcessor/InputValidator.cpp
+++ b/interpreter/cling/lib/MetaProcessor/InputValidator.cpp
@@ -75,10 +75,22 @@ namespace cling {
     bool multilineComment = inBlockComment();
     int commentTok = multilineComment ? tok::asterik : tok::slash;
 
+    if (!multilineComment && m_ParenStack.empty()) {
+      // Only check for 'template' if we're not already indented
+      MetaLexer Lex(curPos, true);
+      Lex.Lex(Tok);
+      curPos = Lex.getLocation();
+      if (Tok.is(tok::ident)) {
+        if (Tok.getIdent()=="template")
+          m_ParenStack.push_back(tok::greater);
+      } else
+        curPos -= Tok.getLength(); // Rewind buffer for LexPunctuatorAndAdvance
+    }
+
     do {
       const char* prevStart = curPos;
       MetaLexer::LexPunctuatorAndAdvance(curPos, Tok);
-      int kind = (int)Tok.getKind();
+      const int kind = (int)Tok.getKind();
 
       if (kind == commentTok) {
         if (kind == tok::slash) {
@@ -145,6 +157,12 @@ namespace cling {
               break;
             }
             m_ParenStack.pop_back();
+
+            // Right brace will pop a template if their is one
+            if (kind == tok::r_brace && m_ParenStack.size() == 1 ) {
+              if (m_ParenStack.back() == tok::greater)
+                m_ParenStack.pop_back();
+            }
           }
           else
             m_ParenStack.push_back(kind);
@@ -166,12 +184,16 @@ namespace cling {
             m_ParenStack.push_back(tok::hash);
           }
         }
+        else if (kind == tok::semicolon) {
+          // Template forward declatation
+          if (m_ParenStack.size() == 1 && m_ParenStack.back()==tok::greater)
+            m_ParenStack.pop_back();
+        }
         else if (kind >= (int)tok::stringlit && kind <= (int)tok::charlit) {
           MetaLexer::LexQuotedStringAndAdvance(curPos, Tok);
         }
       }
-    }
-    while (Tok.isNot(tok::eof));
+    } while (Tok.isNot(tok::eof));
 
     if (!m_ParenStack.empty() && Res != kMismatch)
       Res = kIncomplete;
diff --git a/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp b/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp
index 60db7d66e82894b1c65cd85f65f4a8613b108c58..9c77dd07ffa74b164d488f790686a1b9f17588cd 100644
--- a/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp
+++ b/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp
@@ -39,9 +39,11 @@ namespace cling {
     return value;
   }
 
-  MetaLexer::MetaLexer(llvm::StringRef line)
-    : bufferStart(line.data()), curPos(line.data())
-  { }
+  MetaLexer::MetaLexer(llvm::StringRef line, bool skipWhite)
+    : bufferStart(line.data()), curPos(line.data()) {
+    if (skipWhite)
+      SkipWhitespace();
+  }
 
   void MetaLexer::reset(llvm::StringRef line) {
     bufferStart = line.data();
@@ -56,7 +58,7 @@ namespace cling {
       return LexQuotedStringAndAdvance(curPos, Tok);
     case '[': case ']': case '(': case ')': case '{': case '}':
     case '\\': case ',': case '.': case '!': case '?': case '>':
-    case '&': case '#': case '@': case '*':
+    case '&': case '#': case '@': case '*': case ';':
       // INTENTIONAL FALL THROUGHs
       return LexPunctuator(curPos - 1, Tok);
 
@@ -127,6 +129,7 @@ namespace cling {
     case '&'  : Tok.setKind(tok::ampersand); break;
     case '#'  : Tok.setKind(tok::hash); break;
     case '*'  : Tok.setKind(tok::asterik); break;
+    case ';'  : Tok.setKind(tok::semicolon); break;
     case '\0' : Tok.setKind(tok::eof); Tok.setLength(0); break;// if static call
     default: Tok.setLength(0); break;
     }
@@ -224,11 +227,15 @@ namespace cling {
     }
   }
 
-  void MetaLexer::LexWhitespace(char C, Token& Tok) {
+  void MetaLexer::SkipWhitespace() {
+    char C = *curPos;
     while((C == ' ' || C == '\t') && C != '\0')
-      C = *curPos++;
+      C = *(++curPos);
+  }
+
+  void MetaLexer::LexWhitespace(char C, Token& Tok) {
+    SkipWhitespace();
 
-    --curPos; // Back up over the non whitespace char.
     Tok.setLength(curPos - Tok.getBufStart());
     Tok.setKind(tok::space);
   }
diff --git a/interpreter/cling/lib/MetaProcessor/MetaLexer.h b/interpreter/cling/lib/MetaProcessor/MetaLexer.h
index a7ac2623a34788ebd33d2cff2213774c53ffedec..4479d8c70e95d311a2a12abc00187bdb1984425d 100644
--- a/interpreter/cling/lib/MetaProcessor/MetaLexer.h
+++ b/interpreter/cling/lib/MetaProcessor/MetaLexer.h
@@ -40,6 +40,7 @@ namespace cling {
       constant,   // {0-9}
       at,         // @
       asterik,    // *
+      semicolon,  // ;
       eof,
       unknown
     };
@@ -83,7 +84,7 @@ namespace cling {
     const char* bufferStart;
     const char* curPos;
   public:
-    MetaLexer(llvm::StringRef input);
+    MetaLexer(llvm::StringRef input, bool skipWhiteSpace = false);
     void reset(llvm::StringRef Line);
 
     void Lex(Token& Tok);
@@ -98,9 +99,7 @@ namespace cling {
     void LexEndOfFile(char C, Token& Tok);
     void LexWhitespace(char C, Token& Tok);
     void SkipWhitespace();
-    inline char getAndAdvanceChar(const char *&Ptr) {
-      return *Ptr++;
-    }
+    const char* getLocation() const { return curPos; }
   };
 } //end namespace cling