diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
index 212d906775d8bf8c1df6e548a8b58c115626625f..9e2380ae0ba5312c795b4226e60f6665c49ecd51 100644
--- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
+++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
@@ -90,6 +90,7 @@ class StringLiteral;
 class NumericLiteral;
 
 class Scope;
+class TemplateParameters;
 
 // names
 class NameVisitor;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 08fdf712da80a503b893eaf732f9af569a041167..ab359d9c05784b8cc415d205114483252eff7faf 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -72,10 +72,10 @@ CheckDeclaration::~CheckDeclaration()
 { }
 
 void CheckDeclaration::check(DeclarationAST *declaration,
-                             Scope *scope, Scope *templateParameters)
+                             Scope *scope, TemplateParameters *templateParameters)
 {
     Scope *previousScope = switchScope(scope);
-    Scope *previousTemplateParameters = switchTemplateParameters(templateParameters);
+    TemplateParameters *previousTemplateParameters = switchTemplateParameters(templateParameters);
     DeclarationAST *previousDeclaration = switchDeclaration(declaration);
     accept(declaration);
     (void) switchDeclaration(previousDeclaration);
@@ -97,9 +97,9 @@ Scope *CheckDeclaration::switchScope(Scope *scope)
     return previousScope;
 }
 
-Scope *CheckDeclaration::switchTemplateParameters(Scope *templateParameters)
+TemplateParameters *CheckDeclaration::switchTemplateParameters(TemplateParameters *templateParameters)
 {
-    Scope *previousTemplateParameters = _templateParameters;
+    TemplateParameters *previousTemplateParameters = _templateParameters;
     _templateParameters = templateParameters;
     return previousTemplateParameters;
 }
@@ -395,13 +395,15 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
 
 bool CheckDeclaration::visit(TemplateDeclarationAST *ast)
 {
-    Scope *previousScope = switchScope(new Scope(_scope->owner()));
+    Scope *scope = new Scope(_scope->owner());
+
     for (DeclarationListAST *param = ast->template_parameters; param; param = param->next) {
-       semantic()->check(param->declaration, _scope);
+       semantic()->check(param->declaration, scope);
     }
 
-    Scope *templateParameters = switchScope(previousScope);
-    semantic()->check(ast->declaration, _scope, templateParameters);
+    semantic()->check(ast->declaration, _scope,
+                      new TemplateParameters(_templateParameters, scope));
+
     return false;
 }
 
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index f75a3dd2b3d94caf06b119c04ddb07cd8ff23f9b..27869c75ca3147cf34c8643686cd6aee66218afb 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -61,12 +61,12 @@ public:
     CheckDeclaration(Semantic *semantic);
     virtual ~CheckDeclaration();
 
-    void check(DeclarationAST *declaration, Scope *scope, Scope *templateParameters);
+    void check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters);
 
 protected:
     DeclarationAST *switchDeclaration(DeclarationAST *declaration);
     Scope *switchScope(Scope *scope);
-    Scope *switchTemplateParameters(Scope *templateParameters);
+    TemplateParameters *switchTemplateParameters(TemplateParameters *templateParameters);
 
     void checkFunctionArguments(Function *fun);
 
@@ -101,7 +101,7 @@ protected:
 private:
     DeclarationAST *_declaration;
     Scope *_scope;
-    Scope *_templateParameters;
+    TemplateParameters *_templateParameters;
     bool _checkAnonymousArguments: 1;
 };
 
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index 1dd4ec4fa8b15f45a2cc081f00c01a7d75db0b36..c2ea233d6978477d03eed4870c8e2b4f97932cc1 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -123,7 +123,7 @@ Control *Semantic::control() const
 FullySpecifiedType Semantic::check(SpecifierAST *specifier, Scope *scope)
 { return d->checkSpecifier->check(specifier, scope); }
 
-void Semantic::check(DeclarationAST *declaration, Scope *scope, Scope *templateParameters)
+void Semantic::check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters)
 { d->checkDeclaration->check(declaration, scope, templateParameters); }
 
 FullySpecifiedType Semantic::check(DeclaratorAST *declarator, FullySpecifiedType type,
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index c6c75280bc8c27b70d82e431261387617a678255..8a0df9a111fc7a6c620fb38f2ee997aaab73ce1c 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -78,7 +78,7 @@ public:
 
     FullySpecifiedType check(ExpressionAST *expression, Scope *scope);
 
-    void check(DeclarationAST *declaration, Scope *scope, Scope *templateParameters = 0);
+    void check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters = 0);
 
     void check(StatementAST *statement, Scope *scope);
 
diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp
index a0fbe7a56d78d1844bc0504c5c695827371c625c..27b33e621751147428fff5a54a28315b5ff60580 100644
--- a/src/shared/cplusplus/Symbols.cpp
+++ b/src/shared/cplusplus/Symbols.cpp
@@ -55,6 +55,26 @@
 
 CPLUSPLUS_BEGIN_NAMESPACE
 
+TemplateParameters::TemplateParameters(Scope *scope)
+    : _previous(0), _scope(scope)
+{ }
+
+TemplateParameters::TemplateParameters(TemplateParameters *previous, Scope *scope)
+    : _previous(previous), _scope(scope)
+{ }
+
+TemplateParameters::~TemplateParameters()
+{
+    delete _previous;
+    delete _scope;
+}
+
+TemplateParameters *TemplateParameters::previous() const
+{ return _previous; }
+
+Scope *TemplateParameters::scope() const
+{ return _scope; }
+
 UsingNamespaceDirective::UsingNamespaceDirective(TranslationUnit *translationUnit,
                                                  unsigned sourceLocation, Name *name)
     : Symbol(translationUnit, sourceLocation, name)
@@ -91,20 +111,10 @@ Declaration::Declaration(TranslationUnit *translationUnit, unsigned sourceLocati
 Declaration::~Declaration()
 { delete _templateParameters; }
 
-unsigned Declaration::templateParameterCount() const
-{
-    if (! _templateParameters)
-        return 0;
-    return _templateParameters->symbolCount();
-}
-
-Symbol *Declaration::templateParameterAt(unsigned index) const
-{ return _templateParameters->symbolAt(index); }
-
-Scope *Declaration::templateParameters() const
+TemplateParameters *Declaration::templateParameters() const
 { return _templateParameters; }
 
-void Declaration::setTemplateParameters(Scope *templateParameters)
+void Declaration::setTemplateParameters(TemplateParameters *templateParameters)
 { _templateParameters = templateParameters; }
 
 void Declaration::setType(FullySpecifiedType type)
@@ -170,16 +180,17 @@ unsigned Function::templateParameterCount() const
 {
     if (! _templateParameters)
         return 0;
-    return _templateParameters->symbolCount();
+
+    return _templateParameters->scope()->symbolCount();
 }
 
 Symbol *Function::templateParameterAt(unsigned index) const
-{ return _templateParameters->symbolAt(index); }
+{ return _templateParameters->scope()->symbolAt(index); }
 
-Scope *Function::templateParameters() const
+TemplateParameters *Function::templateParameters() const
 { return _templateParameters; }
 
-void Function::setTemplateParameters(Scope *templateParameters)
+void Function::setTemplateParameters(TemplateParameters *templateParameters)
 { _templateParameters = templateParameters; }
 
 bool Function::isEqualTo(const Type *other) const
@@ -435,20 +446,10 @@ ForwardClassDeclaration::ForwardClassDeclaration(TranslationUnit *translationUni
 ForwardClassDeclaration::~ForwardClassDeclaration()
 { delete _templateParameters; }
 
-unsigned ForwardClassDeclaration::templateParameterCount() const
-{
-    if (! _templateParameters)
-        return 0;
-    return _templateParameters->symbolCount();
-}
-
-Symbol *ForwardClassDeclaration::templateParameterAt(unsigned index) const
-{ return _templateParameters->symbolAt(index); }
-
-Scope *ForwardClassDeclaration::templateParameters() const
+TemplateParameters *ForwardClassDeclaration::templateParameters() const
 { return _templateParameters; }
 
-void ForwardClassDeclaration::setTemplateParameters(Scope *templateParameters)
+void ForwardClassDeclaration::setTemplateParameters(TemplateParameters *templateParameters)
 { _templateParameters = templateParameters; }
 
 FullySpecifiedType ForwardClassDeclaration::type() const
@@ -501,16 +502,17 @@ unsigned Class::templateParameterCount() const
 {
     if (! _templateParameters)
         return 0;
-    return _templateParameters->symbolCount();
+
+    return _templateParameters->scope()->symbolCount();
 }
 
 Symbol *Class::templateParameterAt(unsigned index) const
-{ return _templateParameters->symbolAt(index); }
+{ return _templateParameters->scope()->symbolAt(index); }
 
-Scope *Class::templateParameters() const
+TemplateParameters *Class::templateParameters() const
 { return _templateParameters; }
 
-void Class::setTemplateParameters(Scope *templateParameters)
+void Class::setTemplateParameters(TemplateParameters *templateParameters)
 { _templateParameters = templateParameters; }
 
 void Class::accept0(TypeVisitor *visitor)
diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h
index 881d464f4ec6c5c0f81fa7e931ff5a1e1103bd31..a911c21ab9738a8e2738f659f818dd042748205d 100644
--- a/src/shared/cplusplus/Symbols.h
+++ b/src/shared/cplusplus/Symbols.h
@@ -58,6 +58,21 @@
 CPLUSPLUS_BEGIN_HEADER
 CPLUSPLUS_BEGIN_NAMESPACE
 
+class TemplateParameters
+{
+public:
+    TemplateParameters(Scope *scope);
+    TemplateParameters(TemplateParameters *previous, Scope *scope);
+    ~TemplateParameters();
+
+    TemplateParameters *previous() const;
+    Scope *scope() const;
+
+private:
+    TemplateParameters *_previous;
+    Scope *_scope;
+};
+
 class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol
 {
 public:
@@ -102,11 +117,8 @@ public:
     Declaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
     virtual ~Declaration();
 
-    unsigned templateParameterCount() const;
-    Symbol *templateParameterAt(unsigned index) const;
-
-    Scope *templateParameters() const;
-    void setTemplateParameters(Scope *templateParameters);
+    TemplateParameters *templateParameters() const;
+    void setTemplateParameters(TemplateParameters *templateParameters);
 
     void setType(FullySpecifiedType type);
 
@@ -124,7 +136,7 @@ protected:
 
 private:
     FullySpecifiedType _type;
-    Scope *_templateParameters;
+    TemplateParameters *_templateParameters;
 };
 
 class CPLUSPLUS_EXPORT Argument: public Symbol
@@ -201,11 +213,8 @@ public:
     ForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
     virtual ~ForwardClassDeclaration();
 
-    unsigned templateParameterCount() const;
-    Symbol *templateParameterAt(unsigned index) const;
-
-    Scope *templateParameters() const;
-    void setTemplateParameters(Scope *templateParameters);
+    TemplateParameters *templateParameters() const;
+    void setTemplateParameters(TemplateParameters *templateParameters);
 
     virtual FullySpecifiedType type() const;
 
@@ -228,7 +237,7 @@ protected:
     virtual void accept0(TypeVisitor *visitor);
 
 private:
-    Scope *_templateParameters;
+    TemplateParameters *_templateParameters;
 };
 
 class CPLUSPLUS_EXPORT Enum: public ScopedSymbol, public Type
@@ -279,11 +288,11 @@ public:
     int methodKey() const;
     void setMethodKey(int key);
 
-    unsigned templateParameterCount() const;
-    Symbol *templateParameterAt(unsigned index) const;
+    unsigned templateParameterCount() const; // ### remove me
+    Symbol *templateParameterAt(unsigned index) const; // ### remove me
 
-    Scope *templateParameters() const;
-    void setTemplateParameters(Scope *templateParameters);
+    TemplateParameters *templateParameters() const;
+    void setTemplateParameters(TemplateParameters *templateParameters);
 
     FullySpecifiedType returnType() const;
     void setReturnType(FullySpecifiedType returnType);
@@ -336,7 +345,7 @@ protected:
     virtual void accept0(TypeVisitor *visitor);
 
 private:
-    Scope *_templateParameters;
+    TemplateParameters *_templateParameters;
     FullySpecifiedType _returnType;
     struct Flags {
         unsigned _isVariadic: 1;
@@ -425,11 +434,11 @@ public:
     Key classKey() const;
     void setClassKey(Key key);
 
-    unsigned templateParameterCount() const;
-    Symbol *templateParameterAt(unsigned index) const;
+    unsigned templateParameterCount() const; // ### remove me
+    Symbol *templateParameterAt(unsigned index) const; // ### remove me
 
-    Scope *templateParameters() const;
-    void setTemplateParameters(Scope *templateParameters);
+    TemplateParameters *templateParameters() const;
+    void setTemplateParameters(TemplateParameters *templateParameters);
 
     unsigned baseClassCount() const;
     BaseClass *baseClassAt(unsigned index) const;
@@ -459,7 +468,7 @@ protected:
 
 private:
     Key _key;
-    Scope *_templateParameters;
+    TemplateParameters *_templateParameters;
     Array<BaseClass *> _baseClasses;
 };
 
diff --git a/tests/manual/cplusplus/main.cpp b/tests/manual/cplusplus/main.cpp
index 5b22ac3f60dcc68cfdf87f5eadc761ea4aa4e7dd..cc69cb1681b1fbedf8356d77f24310911a1888d6 100644
--- a/tests/manual/cplusplus/main.cpp
+++ b/tests/manual/cplusplus/main.cpp
@@ -102,7 +102,7 @@ public:
             }
 
             if (! _removed.contains(i))
-                out->append(source + tk.begin(), tk.length);
+                out->append(source + tk.begin(), tk.f.length);
 
             it = _insertAfter.constFind(i);
             for (; it != _insertAfter.constEnd() && it.key() == i; ++it) {