Template instantion fixes when template parameter is used twice in type

For example T in:
Y<T>::YYY<T>::value_type
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 6794c2e..595ba4a 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -560,6 +560,7 @@
 
 # C++11 test cases.
 CPP11_TEST_CASES += \
+	cpp11_alias_nested_template_scoping \
 	cpp11_alignment \
 	cpp11_alternate_function_syntax \
 	cpp11_constexpr \
@@ -575,7 +576,6 @@
 	cpp11_initializer_list \
 	cpp11_initializer_list_extend \
 	cpp11_lambda_functions \
-	cpp11_std_array \
 	cpp11_noexcept \
 	cpp11_null_pointer_constant \
 	cpp11_raw_string_literals \
@@ -588,6 +588,7 @@
 	cpp11_rvalue_reference3 \
 	cpp11_sizeof_object \
 	cpp11_static_assert \
+	cpp11_std_array \
 	cpp11_strongly_typed_enumerations \
 	cpp11_thread_local \
 	cpp11_template_double_brackets \
diff --git a/Examples/test-suite/cpp11_alias_nested_template_scoping.i b/Examples/test-suite/cpp11_alias_nested_template_scoping.i
new file mode 100644
index 0000000..0cf5ea3
--- /dev/null
+++ b/Examples/test-suite/cpp11_alias_nested_template_scoping.i
@@ -0,0 +1,45 @@
+%module cpp11_alias_nested_template_scoping
+
+// Test to check a template parameter type is expanded when the template parameter
+// is used twice in a type name. Expansion was
+// Y< short >::YYY< T >::value_type >
+// instead of
+// Y< short >::YYY< short >::value_type >
+
+#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
+%feature("flatnested") ZZZ;
+#endif
+
+%inline %{
+template<typename T> struct Y {
+  typedef T value_type;
+  typedef Y YY;
+  template<typename T2> using YYY = Y<T2>;
+  template<typename T2> struct ZZZ {
+    typedef T2 another_type;
+  };
+  value_type create1() const { return T(); }
+  Y::value_type create2() const { return T(); }
+  Y<T>::value_type create3() const { return T(); }
+  YY::value_type create4() const { return T(); }
+  Y<T>::YY::value_type create5() const { return T(); }
+  Y<T>::YYY<T>::value_type create6() const { return T(); }
+  typename Y<T>::template ZZZ<T>::another_type create7() const { return T(); }
+
+  // With global scope prefix
+  ::Y<T>::value_type create13() const { return T(); }
+
+  ::Y<T>::YY::value_type create15() const { return T(); }
+  ::Y<T>::YYY<T>::value_type create16() const { return T(); }
+  typename ::Y<T>::template ZZZ<T>::another_type create17() const { return T(); }
+};
+%}
+
+%extend Y {
+%template() YYY<short>;
+%template() ZZZ<short>;
+};
+// Use above workaround instead of below (which currently gives syntax error)
+// %template() Y<short>::YYY<short>;
+
+%template(Yshort) Y<short>;
diff --git a/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java b/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java
new file mode 100644
index 0000000..7afa83a
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java
@@ -0,0 +1,32 @@
+
+import cpp11_alias_nested_template_scoping.*;
+
+public class cpp11_alias_nested_template_scoping_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_alias_nested_template_scoping");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Yshort ys = new Yshort();
+    short val = 0;
+    val = ys.create1();
+    val = ys.create2();
+    val = ys.create3();
+    val = ys.create4();
+    val = ys.create5();
+    val = ys.create6();
+    val = ys.create7();
+
+    val = ys.create13();
+
+    val = ys.create15();
+    val = ys.create16();
+    val = ys.create17();
+  }
+}
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 364329d..66518f5 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -1310,6 +1310,7 @@
 	      Putc(',', nt);
 	  }
 	  tsuffix = SwigType_templatesuffix(e);
+	  SwigType_typename_replace(tsuffix, pat, rep);
 	  Printf(nt, ")>%s", tsuffix);
 	  Delete(tsuffix);
 	  Clear(e);
@@ -1318,13 +1319,24 @@
 	  Delete(tparms);
 	}
       } else if (Swig_scopename_check(e)) {
-	String *first, *rest;
-	first = Swig_scopename_first(e);
-	rest = Swig_scopename_suffix(e);
-	SwigType_typename_replace(rest, pat, rep);
-	SwigType_typename_replace(first, pat, rep);
+	String *first = 0;
+	String *rest = 0;
+	Swig_scopename_split(e, &first, &rest);
+
+	/* Swig_scopename_split doesn't handle :: prefix very well ... could do with a rework */
+	if (Strncmp(rest, "::", 2) == 0) {
+	  String *tmp = NewString(Char(rest) + 2);
+	  Clear(rest);
+	  Printv(rest, tmp, NIL);
+	  Delete(tmp);
+	  assert(!first);
+	}
+
 	Clear(e);
-	Printv(e, first, "::", rest, NIL);
+	if (first)
+	  SwigType_typename_replace(first, pat, rep);
+	SwigType_typename_replace(rest, pat, rep);
+	Printv(e, first ? first : "", "::", rest, NIL);
 	Delete(first);
 	Delete(rest);
       }