From f18c7336ee6d61a426aa965c3f000aa21d60a111 Mon Sep 17 00:00:00 2001
From: Kevin Moore <kevmoo@google.com>
Date: Wed, 25 Nov 2015 18:21:46 -0800
Subject: [PATCH] Replace {{?}} syntax with __?__ syntax

Why? Now the replacement syntax is valid dart/yaml

This means templates can be opened, analyzer, ran as "real" packages

It'll make updating/adding templates easier and less error prone
---
 lib/generators/console_full_data.dart         | 30 ++++++-------
 lib/generators/console_simple_data.dart       |  2 +-
 lib/generators/package_simple_data.dart       | 44 +++++++++----------
 lib/generators/server_appengine_data.dart     | 20 ++++-----
 lib/generators/server_shelf_data.dart         | 12 ++---
 lib/generators/web_polymer_data.dart          | 32 +++++++-------
 lib/generators/web_simple_data.dart           | 16 +++----
 lib/src/common.dart                           | 32 ++++++++++----
 lib/stagehand.dart                            |  2 +-
 templates/console-full/LICENSE                |  2 +-
 templates/console-full/README.md              |  2 +-
 templates/console-full/bin/main.dart          |  6 +--
 templates/console-full/lib/projectName.dart   |  6 +--
 templates/console-full/pubspec.yaml           |  4 +-
 .../console-full/test/projectName_test.dart   |  6 +--
 templates/console-simple/pubspec.yaml         |  2 +-
 templates/package-simple/LICENSE              |  2 +-
 templates/package-simple/README.md            |  4 +-
 .../package-simple/example/projectName.dart   |  6 +--
 templates/package-simple/lib/projectName.dart |  8 ++--
 .../lib/src/projectName_base.dart             |  4 +-
 templates/package-simple/pubspec.yaml         |  4 +-
 .../package-simple/test/projectName_test.dart |  6 +--
 templates/server-appengine/LICENSE            |  2 +-
 templates/server-appengine/README.md          |  2 +-
 templates/server-appengine/bin/server.dart    |  4 +-
 .../server-appengine/build/web/index.html     |  2 +-
 templates/server-appengine/lib/memcache.dart  |  4 +-
 templates/server-appengine/pubspec.yaml       |  4 +-
 templates/server-shelf/LICENSE                |  2 +-
 templates/server-shelf/README.md              |  2 +-
 templates/server-shelf/bin/server.dart        |  2 +-
 templates/server-shelf/pubspec.yaml           |  4 +-
 templates/web-polymer/LICENSE                 |  2 +-
 templates/web-polymer/README.md               |  2 +-
 templates/web-polymer/lib/main_app.dart       |  4 +-
 templates/web-polymer/lib/main_app.html       |  8 ++--
 templates/web-polymer/pubspec.yaml            |  4 +-
 templates/web-polymer/web/index.dart          |  4 +-
 templates/web-polymer/web/index.html          |  4 +-
 templates/web-polymer/web/styles.css          |  2 +-
 templates/web-simple/LICENSE                  |  2 +-
 templates/web-simple/pubspec.yaml             |  4 +-
 templates/web-simple/web/index.html           |  4 +-
 templates/web-simple/web/main.dart            |  2 +-
 test/common_test.dart                         | 26 ++++++++---
 46 files changed, 189 insertions(+), 159 deletions(-)

diff --git a/lib/generators/console_full_data.dart b/lib/generators/console_full_data.dart
index 779ead8..bfe8d0f 100644
--- a/lib/generators/console_full_data.dart
+++ b/lib/generators/console_full_data.dart
@@ -18,7 +18,7 @@ RGFydCBJREVzKSAKLmlkZWEvCiouaW1sCiouaXByCiouaXdzCg==""",
 ZWhhbmQK""",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -47,37 +47,37 @@ VEhFIFVTRSBPRiBUSElTClNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
 SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
   "README.md",
   "text",
-  "IyB7e3Byb2plY3ROYW1lfX0KCkEgc2FtcGxlIGNvbW1hbmQtbGluZSBhcHBsaWNhdGlvbi4K",
+  "IyBfX3Byb2plY3ROYW1lX18KCkEgc2FtcGxlIGNvbW1hbmQtbGluZSBhcHBsaWNhdGlvbi4K",
   "bin/main.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKaW1wb3J0ICdw
-YWNrYWdlOnt7cHJvamVjdE5hbWV9fS97e3Byb2plY3ROYW1lfX0uZGFydCcgYXMge3twcm9qZWN0
-TmFtZX19OwoKbWFpbihMaXN0PFN0cmluZz4gYXJndW1lbnRzKSB7CiAgcHJpbnQoJ0hlbGxvIHdv
-cmxkOiAke3t7cHJvamVjdE5hbWV9fS5jYWxjdWxhdGUoKX0hJyk7Cn0K""",
+YWNrYWdlOl9fcHJvamVjdE5hbWVfXy9fX3Byb2plY3ROYW1lX18uZGFydCcgYXMgX19wcm9qZWN0
+TmFtZV9fOwoKbWFpbihMaXN0PFN0cmluZz4gYXJndW1lbnRzKSB7CiAgcHJpbnQoJ0hlbGxvIHdv
+cmxkOiAke19fcHJvamVjdE5hbWVfXy5jYWxjdWxhdGUoKX0hJyk7Cn0K""",
   "lib/projectName.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8vIFRoZSB7
-e3Byb2plY3ROYW1lfX0gbGlicmFyeS4KbGlicmFyeSB7e3Byb2plY3ROYW1lfX07CgppbnQgY2Fs
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8vIFRoZSBf
+X3Byb2plY3ROYW1lX18gbGlicmFyeS4KbGlicmFyeSBfX3Byb2plY3ROYW1lX187CgppbnQgY2Fs
 Y3VsYXRlKCkgewogIHJldHVybiA2ICogNzsKfQo=""",
   "pubspec.yaml",
   "text",
-  """bmFtZToge3twcm9qZWN0TmFtZX19CnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNhbXBs
-ZSBjb21tYW5kLWxpbmUgYXBwbGljYXRpb24uCiNhdXRob3I6IHt7YXV0aG9yfX0gPGVtYWlsQGV4
+  """bmFtZTogX19wcm9qZWN0TmFtZV9fCnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNhbXBs
+ZSBjb21tYW5kLWxpbmUgYXBwbGljYXRpb24uCiNhdXRob3I6IF9fYXV0aG9yX18gPGVtYWlsQGV4
 YW1wbGUuY29tPgojaG9tZXBhZ2U6IGh0dHBzOi8vd3d3LmV4YW1wbGUuY29tCgplbnZpcm9ubWVu
 dDoKICBzZGs6ICc+PTEuMC4wIDwyLjAuMCcKCiNkZXBlbmRlbmNpZXM6CiMgIGZvb19iYXI6ICc+
 PTEuMC4wIDwyLjAuMCcKCmRldl9kZXBlbmRlbmNpZXM6CiAgdGVzdDogJz49MC4xMi4wIDwwLjEz
 LjAnCg==""",
   "test/projectName_test.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7
-e3Byb2plY3ROYW1lfX0udGVzdDsKCmltcG9ydCAncGFja2FnZTp7e3Byb2plY3ROYW1lfX0ve3tw
-cm9qZWN0TmFtZX19LmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6dGVzdC90ZXN0LmRhcnQnOwoKdm9p
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSBf
+X3Byb2plY3ROYW1lX18udGVzdDsKCmltcG9ydCAncGFja2FnZTpfX3Byb2plY3ROYW1lX18vX19w
+cm9qZWN0TmFtZV9fLmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6dGVzdC90ZXN0LmRhcnQnOwoKdm9p
 ZCBtYWluKCkgewogIHRlc3QoJ2NhbGN1bGF0ZScsICgpIHsKICAgIGV4cGVjdChjYWxjdWxhdGUo
 KSwgNDIpOwogIH0pOwp9Cg=="""
 ];
diff --git a/lib/generators/console_simple_data.dart b/lib/generators/console_simple_data.dart
index d0be2f9..e67c667 100644
--- a/lib/generators/console_simple_data.dart
+++ b/lib/generators/console_simple_data.dart
@@ -13,7 +13,7 @@ IGNoZWNrIGluIHlvdXIgbG9jayBmaWxlKQo=""",
   "bWFpbihMaXN0PFN0cmluZz4gYXJncykgewogIHByaW50KCdIZWxsbyB3b3JsZCEnKTsKfQo=",
   "pubspec.yaml",
   "text",
-  """bmFtZToge3twcm9qZWN0TmFtZX19CnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs
+  """bmFtZTogX19wcm9qZWN0TmFtZV9fCnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs
 ZSBjb25zb2xlIGFwcGxpY2F0aW9uLgojZGVwZW5kZW5jaWVzOgojICBmb29fYmFyOiAnPj0xLjAu
 MCA8Mi4wLjAnCg=="""
 ];
diff --git a/lib/generators/package_simple_data.dart b/lib/generators/package_simple_data.dart
index 06612a3..c769b4d 100644
--- a/lib/generators/package_simple_data.dart
+++ b/lib/generators/package_simple_data.dart
@@ -17,7 +17,7 @@ REVzKSAKLmlkZWEvCiouaW1sCiouaXByCiouaXdzCg==""",
 ZWhhbmQK""",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -46,53 +46,53 @@ VEhFIFVTRSBPRiBUSElTClNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
 SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
   "README.md",
   "text",
-  """IyB7e3Byb2plY3ROYW1lfX0KCkEgbGlicmFyeSBmb3IgRGFydCBkZXZlbG9wZXJzLiBJdCBpcyBh
+  """IyBfX3Byb2plY3ROYW1lX18KCkEgbGlicmFyeSBmb3IgRGFydCBkZXZlbG9wZXJzLiBJdCBpcyBh
 d2Vzb21lLgoKIyMgVXNhZ2UKCkEgc2ltcGxlIHVzYWdlIGV4YW1wbGU6CgogICAgaW1wb3J0ICdw
-YWNrYWdlOnt7cHJvamVjdE5hbWV9fS97e3Byb2plY3ROYW1lfX0uZGFydCc7CgogICAgbWFpbigp
+YWNrYWdlOl9fcHJvamVjdE5hbWVfXy9fX3Byb2plY3ROYW1lX18uZGFydCc7CgogICAgbWFpbigp
 IHsKICAgICAgdmFyIGF3ZXNvbWUgPSBuZXcgQXdlc29tZSgpOwogICAgfQoKIyMgRmVhdHVyZXMg
 YW5kIGJ1Z3MKClBsZWFzZSBmaWxlIGZlYXR1cmUgcmVxdWVzdHMgYW5kIGJ1Z3MgYXQgdGhlIFtp
 c3N1ZSB0cmFja2VyXVt0cmFja2VyXS4KClt0cmFja2VyXTogaHR0cDovL2V4YW1wbGUuY29tL2lz
 c3Vlcy9yZXBsYWNlbWUK""",
   "example/projectName.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7
-e3Byb2plY3ROYW1lfX0uZXhhbXBsZTsKCmltcG9ydCAncGFja2FnZTp7e3Byb2plY3ROYW1lfX0v
-e3twcm9qZWN0TmFtZX19LmRhcnQnOwoKbWFpbigpIHsKICB2YXIgYXdlc29tZSA9IG5ldyBBd2Vz
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSBf
+X3Byb2plY3ROYW1lX18uZXhhbXBsZTsKCmltcG9ydCAncGFja2FnZTpfX3Byb2plY3ROYW1lX18v
+X19wcm9qZWN0TmFtZV9fLmRhcnQnOwoKbWFpbigpIHsKICB2YXIgYXdlc29tZSA9IG5ldyBBd2Vz
 b21lKCk7CiAgcHJpbnQoJ2F3ZXNvbWU6ICR7YXdlc29tZS5pc0F3ZXNvbWV9Jyk7Cn0K""",
   "lib/projectName.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8vIFRoZSB7
-e3Byb2plY3ROYW1lfX0gbGlicmFyeS4KLy8vCi8vLyBUaGlzIGlzIGFuIGF3ZXNvbWUgbGlicmFy
-eS4gTW9yZSBkYXJ0ZG9jcyBnbyBoZXJlLgpsaWJyYXJ5IHt7cHJvamVjdE5hbWV9fTsKCi8vIFRP
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8vIFRoZSBf
+X3Byb2plY3ROYW1lX18gbGlicmFyeS4KLy8vCi8vLyBUaGlzIGlzIGFuIGF3ZXNvbWUgbGlicmFy
+eS4gTW9yZSBkYXJ0ZG9jcyBnbyBoZXJlLgpsaWJyYXJ5IF9fcHJvamVjdE5hbWVfXzsKCi8vIFRP
 RE86IEV4cG9ydCBhbnkgbGlicmFyaWVzIGludGVuZGVkIGZvciBjbGllbnRzIG9mIHRoaXMgcGFj
-a2FnZS4KCmV4cG9ydCAnc3JjL3t7cHJvamVjdE5hbWV9fV9iYXNlLmRhcnQnOwo=""",
+a2FnZS4KCmV4cG9ydCAnc3JjL19fcHJvamVjdE5hbWVfX19iYXNlLmRhcnQnOwo=""",
   "lib/src/projectName_base.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gVE9ETzog
-UHV0IHB1YmxpYyBmYWNpbmcgdHlwZXMgaW4gdGhpcyBmaWxlLgoKbGlicmFyeSB7e3Byb2plY3RO
-YW1lfX0uYmFzZTsKCi8vLyBDaGVja3MgaWYgeW91IGFyZSBhd2Vzb21lLiBTcG9pbGVyOiB5b3Ug
+UHV0IHB1YmxpYyBmYWNpbmcgdHlwZXMgaW4gdGhpcyBmaWxlLgoKbGlicmFyeSBfX3Byb2plY3RO
+YW1lX18uYmFzZTsKCi8vLyBDaGVja3MgaWYgeW91IGFyZSBhd2Vzb21lLiBTcG9pbGVyOiB5b3Ug
 YXJlLgpjbGFzcyBBd2Vzb21lIHsKICBib29sIGdldCBpc0F3ZXNvbWUgPT4gdHJ1ZTsKfQo=""",
   "pubspec.yaml",
   "text",
-  """bmFtZToge3twcm9qZWN0TmFtZX19CmRlc2NyaXB0aW9uOiBBIHN0YXJ0aW5nIHBvaW50IGZvciBE
-YXJ0IGxpYnJhcmllcyBvciBhcHBsaWNhdGlvbnMuCnZlcnNpb246IDAuMC4xCiNhdXRob3I6IHt7
-YXV0aG9yfX0gPGVtYWlsQGV4YW1wbGUuY29tPgojaG9tZXBhZ2U6IGh0dHBzOi8vd3d3LmV4YW1w
+  """bmFtZTogX19wcm9qZWN0TmFtZV9fCmRlc2NyaXB0aW9uOiBBIHN0YXJ0aW5nIHBvaW50IGZvciBE
+YXJ0IGxpYnJhcmllcyBvciBhcHBsaWNhdGlvbnMuCnZlcnNpb246IDAuMC4xCiNhdXRob3I6IF9f
+YXV0aG9yX18gPGVtYWlsQGV4YW1wbGUuY29tPgojaG9tZXBhZ2U6IGh0dHBzOi8vd3d3LmV4YW1w
 bGUuY29tCgplbnZpcm9ubWVudDoKICBzZGs6ICc+PTEuMC4wIDwyLjAuMCcKCiNkZXBlbmRlbmNp
 ZXM6CiMgIGxpYl9uYW1lOiBhbnkKCmRldl9kZXBlbmRlbmNpZXM6CiAgdGVzdDogJz49MC4xMi4w
 IDwwLjEzLjAnCg==""",
   "test/projectName_test.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7
-e3Byb2plY3ROYW1lfX0udGVzdDsKCmltcG9ydCAncGFja2FnZTp7e3Byb2plY3ROYW1lfX0ve3tw
-cm9qZWN0TmFtZX19LmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6dGVzdC90ZXN0LmRhcnQnOwoKdm9p
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSBf
+X3Byb2plY3ROYW1lX18udGVzdDsKCmltcG9ydCAncGFja2FnZTpfX3Byb2plY3ROYW1lX18vX19w
+cm9qZWN0TmFtZV9fLmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6dGVzdC90ZXN0LmRhcnQnOwoKdm9p
 ZCBtYWluKCkgewogIGdyb3VwKCdBIGdyb3VwIG9mIHRlc3RzJywgKCkgewogICAgQXdlc29tZSBh
 d2Vzb21lOwoKICAgIHNldFVwKCgpIHsKICAgICAgYXdlc29tZSA9IG5ldyBBd2Vzb21lKCk7CiAg
 ICB9KTsKCiAgICB0ZXN0KCdGaXJzdCBUZXN0JywgKCkgewogICAgICBleHBlY3QoYXdlc29tZS5p
diff --git a/lib/generators/server_appengine_data.dart b/lib/generators/server_appengine_data.dart
index ebd9184..078ffb0 100644
--- a/lib/generators/server_appengine_data.dart
+++ b/lib/generators/server_appengine_data.dart
@@ -21,7 +21,7 @@ ZWhhbmQK""",
   "RlJPTSBnb29nbGUvZGFydC1ydW50aW1lCg==",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -50,7 +50,7 @@ VEhFIFVTRSBPRiBUSElTClNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
 SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
   "README.md",
   "text",
-  """IyB7e3Byb2plY3ROYW1lfX0KClRoaXMgaXMgYSBzaW1wbGUgQXBwIEVuZ2luZSBEYXJ0IGFwcGxp
+  """IyBfX3Byb2plY3ROYW1lX18KClRoaXMgaXMgYSBzaW1wbGUgQXBwIEVuZ2luZSBEYXJ0IGFwcGxp
 Y2F0aW9uLiBJdCBzaG93cyBhIHNpbXBsZSB3YXkgb2YgaGFuZGxpbmcKSFRUUCByZXF1ZXN0cyBh
 bmQgaG93IHRvIHVzZSB0aGUgcHJlY29uZmlndXJlZCBBcHAgRW5naW5lIG1lbWNhY2hlIEFQSSBz
 ZXJ2aWNlLgo=""",
@@ -61,12 +61,12 @@ Z2xlLmNvbS9hcHBlbmdpbmUvZG9jcy9tYW5hZ2VkLXZtcy9jb25maWcKcnVudGltZTogY3VzdG9t
 CnZtOiB0cnVlCmFwaV92ZXJzaW9uOiAxCg==""",
   "bin/server.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKaW1wb3J0ICdk
 YXJ0OmFzeW5jJzsKCmltcG9ydCAncGFja2FnZTpzaGVsZi9zaGVsZi5kYXJ0JzsKaW1wb3J0ICdw
 YWNrYWdlOnNoZWxmX2FwcGVuZ2luZS9zaGVsZl9hcHBlbmdpbmUuZGFydCcgYXMgc2hlbGZfYWU7
-CmltcG9ydCAncGFja2FnZTp7e3Byb2plY3ROYW1lfX0vbWVtY2FjaGUuZGFydCcgYXMgY2FjaGU7
+CmltcG9ydCAncGFja2FnZTpfX3Byb2plY3ROYW1lX18vbWVtY2FjaGUuZGFydCcgYXMgY2FjaGU7
 CgovLy8gQXBwbGljYXRpb24gZW50cnkgcG9pbnQgY2FsbGVkIGJ5IEFwcEVuZ2luZSBhdCBzdGFy
 dHVwLgptYWluKExpc3Q8U3RyaW5nPiBhcmdzKSBhc3luYyB7CiAgdmFyIHBvcnRBcmdzID0gYXJn
 cy53aGVyZSgoYSkgPT4gYS5zdGFydHNXaXRoKCctLXBvcnQ9JykpLnRvTGlzdCgpOwoKICBpbnQg
@@ -106,7 +106,7 @@ ZS5jbGVhcigpOwogIHJldHVybiBuZXcgUmVzcG9uc2Uub2soJ0NsZWFyZWQgY2FjaGUhJyk7Cn0K""",
   "build/web/index.html",
   "text",
   """PCFET0NUWVBFIGh0bWw+Cgo8aHRtbD4KICA8aGVhZD4KICAJPG1ldGEgY2hhcnNldD0idXRmLTgi
-PgogICAgPHRpdGxlPnt7cHJvamVjdE5hbWV9fTwvdGl0bGU+CiAgPC9oZWFkPgoKICA8Ym9keT4K
+PgogICAgPHRpdGxlPl9fcHJvamVjdE5hbWVfXzwvdGl0bGU+CiAgPC9oZWFkPgoKICA8Ym9keT4K
 ICAgIDxiPldlbGNvbWUgdG8geW91ciBvd24gb25saW5lIG1lbW9yeSBjYWNoZSBhcHBsaWNhdGlv
 biE8L2I+PGJyPjxicj4KICAgIFRoZSBmb2xsb3dpbmcgY29tbWFuZHMgYXJlIHN1cHBvcnRlZDoK
 ICAgIDxwcmU+CiAgICAgICZsdDtiYXNlLXVybD4vd3JpdGVfY2FjaGU/Jmx0O2tleTE+PSZsdDt2
@@ -119,10 +119,10 @@ ICAgICAgICAgICAgICAgICAgICAgICAgIC0gQ2xlYXJzIHRoZSBjYWNoZSBhbmQgc2V0cyB0aGUg
 aW5pdGlhbCBrZXkvdmFsdWUgcGFpci4KICAgIDwvcHJlPgogIDwvYm9keT4KPC9odG1sPgo=""",
   "lib/memcache.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
-bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7
-e3Byb2plY3ROYW1lfX0ubWVtY2FjaGU7CgppbXBvcnQgJ2RhcnQ6YXN5bmMnOwoKaW1wb3J0ICdw
+bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSBf
+X3Byb2plY3ROYW1lX18ubWVtY2FjaGU7CgppbXBvcnQgJ2RhcnQ6YXN5bmMnOwoKaW1wb3J0ICdw
 YWNrYWdlOmFwcGVuZ2luZS9hcHBlbmdpbmUuZGFydCc7Cgpjb25zdCBTdHJpbmcgREVGQVVMVF9L
 RVkgPSAnaGVsbG8nOwpib29sIGNhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vLyBJbml0aWFs
 aXplIHRoZSBjYWNoZS4KRnV0dXJlIGluaXRpYWxpemUoKSBhc3luYyB7CiAgLy8gSWYgdGhlIGNh
@@ -151,8 +151,8 @@ aCAoXykgewogICAgICBidWZmZXIud3JpdGVsbignIiR7a2V5fSI6IGVycm9yIHJlYWRpbmcga2V5
 IScpOwogICAgfQogIH0KfQo=""",
   "pubspec.yaml",
   "text",
-  """bmFtZToge3twcm9qZWN0TmFtZX19CnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs
-ZSBBcHAgRW5naW5lIGFwcGxpY2F0aW9uLgojYXV0aG9yOiB7e2F1dGhvcn19IDxlbWFpbEBleGFt
+  """bmFtZTogX19wcm9qZWN0TmFtZV9fCnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs
+ZSBBcHAgRW5naW5lIGFwcGxpY2F0aW9uLgojYXV0aG9yOiBfX2F1dGhvcl9fIDxlbWFpbEBleGFt
 cGxlLmNvbT4KI2hvbWVwYWdlOiBodHRwczovL3d3dy5leGFtcGxlLmNvbQoKZW52aXJvbm1lbnQ6
 CiAgc2RrOiAnPj0xLjkuMCA8Mi4wLjAnCgpkZXBlbmRlbmNpZXM6CiAgYXBwZW5naW5lOiAnPj0w
 LjMuMCA8MC40LjAnCiAgc2hlbGY6IF4wLjYuMAogIHNoZWxmX2FwcGVuZ2luZTogXjAuMi4zCg=="""
diff --git a/lib/generators/server_shelf_data.dart b/lib/generators/server_shelf_data.dart
index 2205e62..2311056 100644
--- a/lib/generators/server_shelf_data.dart
+++ b/lib/generators/server_shelf_data.dart
@@ -18,7 +18,7 @@ RGFydCBJREVzKSAKLmlkZWEvCiouaW1sCiouaXByCiouaXdzCg==""",
 ZWhhbmQK""",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -47,11 +47,11 @@ VEhFIFVTRSBPRiBUSElTClNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
 SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
   "README.md",
   "text",
-  """IyB7e3Byb2plY3ROYW1lfX0KCkEgd2ViIHNlcnZlciBidWlsdCB1c2luZyBbU2hlbGZdKGh0dHBz
+  """IyBfX3Byb2plY3ROYW1lX18KCkEgd2ViIHNlcnZlciBidWlsdCB1c2luZyBbU2hlbGZdKGh0dHBz
 Oi8vcHViLmRhcnRsYW5nLm9yZy9wYWNrYWdlcy9zaGVsZikuCg==""",
   "bin/server.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKaW1wb3J0ICdk
 YXJ0OmlvJzsKCmltcG9ydCAncGFja2FnZTphcmdzL2FyZ3MuZGFydCc7CmltcG9ydCAncGFja2Fn
@@ -71,9 +71,9 @@ dHVybiBuZXcgc2hlbGYuUmVzcG9uc2Uub2soJ1JlcXVlc3QgZm9yICIke3JlcXVlc3QudXJsfSIn
 KTsKfQo=""",
   "pubspec.yaml",
   "text",
-  """bmFtZTogJ3t7cHJvamVjdE5hbWV9fScKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEEgd2Vi
-IHNlcnZlciBidWlsdCB1c2luZyB0aGUgc2hlbGYgcGFja2FnZS4KI2F1dGhvcjoge3thdXRob3J9
-fSA8ZW1haWxAZXhhbXBsZS5jb20+CiNob21lcGFnZTogaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20K
+  """bmFtZTogJ19fcHJvamVjdE5hbWVfXycKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEEgd2Vi
+IHNlcnZlciBidWlsdCB1c2luZyB0aGUgc2hlbGYgcGFja2FnZS4KI2F1dGhvcjogX19hdXRob3Jf
+XyA8ZW1haWxAZXhhbXBsZS5jb20+CiNob21lcGFnZTogaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20K
 CmVudmlyb25tZW50OgogIHNkazogJz49MS4wLjAgPDIuMC4wJwoKZGVwZW5kZW5jaWVzOgogIGFy
 Z3M6ICc+PTAuMTAuMCA8MC4xNC4wJwogIHNoZWxmOiAnPj0wLjYuMCA8MC43LjAnCg=="""
 ];
diff --git a/lib/generators/web_polymer_data.dart b/lib/generators/web_polymer_data.dart
index 5c76ffa..94ae078 100644
--- a/lib/generators/web_polymer_data.dart
+++ b/lib/generators/web_polymer_data.dart
@@ -18,7 +18,7 @@ RGFydCBJREVzKSAKLmlkZWEvCiouaW1sCiouaXByCiouaXdzCg==""",
 ZWhhbmQK""",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -47,13 +47,13 @@ VEhFIFVTRSBPRiBUSElTClNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
 SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
   "README.md",
   "text",
-  "IyB7eyBwcm9qZWN0TmFtZSB9fQoKQSB3ZWIgYXBwIGJ1aWx0IHVzaW5nIHBvbHltZXIuZGFydC4K",
+  "IyBfX3Byb2plY3ROYW1lX18KCkEgd2ViIGFwcCBidWlsdCB1c2luZyBwb2x5bWVyLmRhcnQuCg==",
   "lib/main_app.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgpASHRtbEltcG9y
-dCgnbWFpbl9hcHAuaHRtbCcpCmxpYnJhcnkge3twcm9qZWN0TmFtZX19LmxpYi5tYWluX2FwcDsK
+dCgnbWFpbl9hcHAuaHRtbCcpCmxpYnJhcnkgX19wcm9qZWN0TmFtZV9fLmxpYi5tYWluX2FwcDsK
 CmltcG9ydCAnZGFydDpodG1sJzsKCmltcG9ydCAncGFja2FnZTpwb2x5bWVyX2VsZW1lbnRzL3Bh
 cGVyX2lucHV0LmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6cG9seW1lci9wb2x5bWVyLmRhcnQnOwpp
 bXBvcnQgJ3BhY2thZ2U6d2ViX2NvbXBvbmVudHMvd2ViX2NvbXBvbmVudHMuZGFydCc7CgovLy8g
@@ -77,19 +77,19 @@ T00gY3JlYXRlZCwKLy8gIC8vLyBwcm9wZXJ0eSBvYnNlcnZlcnMgc2V0IHVwLCBldmVudCBsaXN0
 ZW5lcnMgYXR0YWNoZWQpLgovLyAgcmVhZHkoKSB7Ci8vICB9Cn0K""",
   "lib/main_app.html",
   "text",
-  """PCEtLQogIENvcHlyaWdodCAoYykge3t5ZWFyfX0sIHt7YXV0aG9yfX0uIEFsbCByaWdodHMgcmVz
+  """PCEtLQogIENvcHlyaWdodCAoYykgX195ZWFyX18sIF9fYXV0aG9yX18uIEFsbCByaWdodHMgcmVz
 ZXJ2ZWQuIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlCiAgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5
 bGUgbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgotLT4KCjxk
 b20tbW9kdWxlIGlkPSJtYWluLWFwcCI+CiAgPHN0eWxlPgogICAgOmhvc3QgewogICAgICBkaXNw
 bGF5OiBibG9jazsKICAgIH0KICA8L3N0eWxlPgoKICA8dGVtcGxhdGU+CiAgICA8cGFwZXItaW5w
-dXQgbGFiZWw9IlR5cGUgc29tZXRoaW5nLi4uIiB2YWx1ZT0ie3t0ZXh0fX0iPjwvcGFwZXItaW5w
-dXQ+CiAgICA8cD4KICAgICAgVGV4dDogPHNwYW4+e3t0ZXh0fX08L3NwYW4+PGJyIC8+CiAgICAg
-IFJldmVyc2VkOiA8c3Bhbj57e3JldmVyc2VUZXh0KHRleHQpfX08L3NwYW4+CiAgICA8L3A+CiAg
+dXQgbGFiZWw9IlR5cGUgc29tZXRoaW5nLi4uIiB2YWx1ZT0iX190ZXh0X18iPjwvcGFwZXItaW5w
+dXQ+CiAgICA8cD4KICAgICAgVGV4dDogPHNwYW4+X190ZXh0X188L3NwYW4+PGJyIC8+CiAgICAg
+IFJldmVyc2VkOiA8c3Bhbj5fX3JldmVyc2VUZXh0KHRleHQpX188L3NwYW4+CiAgICA8L3A+CiAg
 PC90ZW1wbGF0ZT4KPC9kb20tbW9kdWxlPgo=""",
   "pubspec.yaml",
   "text",
-  """bmFtZTogJ3t7cHJvamVjdE5hbWV9fScKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEEgd2Vi
-IGFwcCBidWlsdCB1c2luZyBwb2x5bWVyLmRhcnQuCiNhdXRob3I6IHt7YXV0aG9yfX0gPGVtYWls
+  """bmFtZTogJ19fcHJvamVjdE5hbWVfXycKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEEgd2Vi
+IGFwcCBidWlsdCB1c2luZyBwb2x5bWVyLmRhcnQuCiNhdXRob3I6IF9fYXV0aG9yX18gPGVtYWls
 QGV4YW1wbGUuY29tPgojaG9tZXBhZ2U6IGh0dHBzOi8vd3d3LmV4YW1wbGUuY29tCgplbnZpcm9u
 bWVudDoKICBzZGs6ICc+PTEuOS4wIDwyLjAuMCcKCmRlcGVuZGVuY2llczoKICBicm93c2VyOiBe
 MC4xMC4wCiAgcG9seW1lcl9lbGVtZW50czogXjEuMC4wLXJjLjEKICBwb2x5bWVyOiBeMS4wLjAt
@@ -279,22 +279,22 @@ aMRAd3u25f4qyPOGbaPAUmrzqWeb2xNdBrteEcme2QZ2vY/2dXBwcHBwcHDwgL8Ua6ehihvSBAAA
 AABJRU5ErkJggg==""",
   "web/index.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgpsaWJyYXJ5IG15
-X3Byb2plY3Qud2ViLmluZGV4OwoKaW1wb3J0ICdwYWNrYWdlOnt7cHJvamVjdE5hbWV9fS9tYWlu
+X3Byb2plY3Qud2ViLmluZGV4OwoKaW1wb3J0ICdwYWNrYWdlOl9fcHJvamVjdE5hbWVfXy9tYWlu
 X2FwcC5kYXJ0JzsKaW1wb3J0ICdwYWNrYWdlOnBvbHltZXIvcG9seW1lci5kYXJ0JzsKCi8vLyBb
 TWFpbkFwcF0gdXNlZCEKbWFpbigpIGFzeW5jIHsKICBhd2FpdCBpbml0UG9seW1lcigpOwp9Cg==""",
   "web/index.html",
   "text",
-  """PCFET0NUWVBFIGh0bWw+Cgo8IS0tCiAgQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9
-fS4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKICBpcyBnb3Zl
+  """PCFET0NUWVBFIGh0bWw+Cgo8IS0tCiAgQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3Jf
+Xy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKICBpcyBnb3Zl
 cm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNF
 TlNFIGZpbGUuCi0tPgoKPGh0bWw+CjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8
 bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogIDxt
 ZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwt
 c2NhbGU9MS4wIj4KICA8bWV0YSBuYW1lPSJzY2FmZm9sZGVkLWJ5IiBjb250ZW50PSJodHRwczov
-L2dpdGh1Yi5jb20vZ29vZ2xlL3N0YWdlaGFuZCI+CiAgPHRpdGxlPnt7cHJvamVjdE5hbWV9fTwv
+L2dpdGh1Yi5jb20vZ29vZ2xlL3N0YWdlaGFuZCI+CiAgPHRpdGxlPl9fcHJvamVjdE5hbWVfXzwv
 dGl0bGU+CgogIDwhLS0gQWRkIHRvIGhvbWVzY3JlZW4gZm9yIENocm9tZSBvbiBBbmRyb2lkIC0t
 PgogIDxtZXRhIG5hbWU9Im1vYmlsZS13ZWItYXBwLWNhcGFibGUiIGNvbnRlbnQ9InllcyI+CiAg
 PGxpbmsgcmVsPSJpY29uIiBzaXplcz0iMTkyeDE5MiIgaHJlZj0iaW1hZ2VzL3RvdWNoL2Nocm9t
@@ -320,7 +320,7 @@ InBhY2thZ2VzL2Jyb3dzZXIvZGFydC5qcyI+PC9zY3JpcHQ+CjwvYm9keT4KPC9odG1sPgo=""",
 ci1hZ2VudDogKgpEaXNhbGxvdzoK""",
   "web/styles.css",
   "text",
-  """LyogQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """LyogQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgKi8KLyogaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5
 bGUgbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLiAqLwoKYm9k
 eSB7CiAgICBmb250LWZhbWlseTogUm9ib3RvRHJhZnQsIHNhbnMtc2VyaWY7CiAgICBjb2xvcjog
diff --git a/lib/generators/web_simple_data.dart b/lib/generators/web_simple_data.dart
index 3de5225..01bfd60 100644
--- a/lib/generators/web_simple_data.dart
+++ b/lib/generators/web_simple_data.dart
@@ -18,7 +18,7 @@ RGFydCBJREVzKSAKLmlkZWEvCiouaW1sCiouaXByCiouaXdzCg==""",
 ZWhhbmQK""",
   "LICENSE",
   "text",
-  """Q29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
+  """Q29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4KQWxsIHJpZ2h0cyByZXNlcnZlZC4K
 ClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg
 b3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg
 Zm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNv
@@ -51,30 +51,30 @@ SVRZIE9GIFNVQ0ggREFNQUdFLgo=""",
 ZW5lcmF0ZWQgYnkgU3RhZ2VoYW5kLiBTZWUgTElDRU5TRS4K""",
   "pubspec.yaml",
   "text",
-  """bmFtZTogJ3t7cHJvamVjdE5hbWV9fScKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEFuIGFi
-c29sdXRlIGJhcmUtYm9uZXMgd2ViIGFwcC4KI2F1dGhvcjoge3thdXRob3J9fSA8ZW1haWxAZXhh
+  """bmFtZTogJ19fcHJvamVjdE5hbWVfXycKdmVyc2lvbjogMC4wLjEKZGVzY3JpcHRpb246IEFuIGFi
+c29sdXRlIGJhcmUtYm9uZXMgd2ViIGFwcC4KI2F1dGhvcjogX19hdXRob3JfXyA8ZW1haWxAZXhh
 bXBsZS5jb20+CiNob21lcGFnZTogaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20KCmVudmlyb25tZW50
 OgogIHNkazogJz49MS4wLjAgPDIuMC4wJwoKZGVwZW5kZW5jaWVzOgogIGJyb3dzZXI6ICc+PTAu
 MTAuMCA8MC4xMS4wJwogIGRhcnRfdG9fanNfc2NyaXB0X3Jld3JpdGVyOiAnXjAuMS4wJwoKdHJh
 bnNmb3JtZXJzOgotIGRhcnRfdG9fanNfc2NyaXB0X3Jld3JpdGVy""",
   "web/index.html",
   "text",
-  """PCFET0NUWVBFIGh0bWw+Cgo8IS0tCiAgQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9
-fS4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKICBpcyBnb3Zl
+  """PCFET0NUWVBFIGh0bWw+Cgo8IS0tCiAgQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3Jf
+Xy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKICBpcyBnb3Zl
 cm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNF
 TlNFIGZpbGUuCi0tPgoKPGh0bWw+CjxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgog
 ICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4K
 ICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGlu
 aXRpYWwtc2NhbGU9MS4wIj4KICAgIDxtZXRhIG5hbWU9InNjYWZmb2xkZWQtYnkiIGNvbnRlbnQ9
-Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc3RhZ2VoYW5kIj4KICAgIDx0aXRsZT57e3Byb2pl
-Y3ROYW1lfX08L3RpdGxlPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJzdHlsZXMu
+Imh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc3RhZ2VoYW5kIj4KICAgIDx0aXRsZT5fX3Byb2pl
+Y3ROYW1lX188L3RpdGxlPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJzdHlsZXMu
 Y3NzIj4KICAgIDxzY3JpcHQgYXN5bmMgc3JjPSJtYWluLmRhcnQiIHR5cGU9ImFwcGxpY2F0aW9u
 L2RhcnQiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBhc3luYyBzcmM9InBhY2thZ2VzL2Jyb3dzZXIv
 ZGFydC5qcyI+PC9zY3JpcHQ+CjwvaGVhZD4KCjxib2R5PgoKICA8ZGl2IGlkPSJvdXRwdXQiPjwv
 ZGl2PgoKPC9ib2R5Pgo8L2h0bWw+Cg==""",
   "web/main.dart",
   "text",
-  """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl
+  """Ly8gQ29weXJpZ2h0IChjKSBfX3llYXJfXywgX19hdXRob3JfXy4gQWxsIHJpZ2h0cyByZXNlcnZl
 ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg
 bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKaW1wb3J0ICdk
 YXJ0Omh0bWwnOwoKdm9pZCBtYWluKCkgewogIHF1ZXJ5U2VsZWN0b3IoJyNvdXRwdXQnKS50ZXh0
diff --git a/lib/src/common.dart b/lib/src/common.dart
index d6bd334..ef2f9f0 100644
--- a/lib/src/common.dart
+++ b/lib/src/common.dart
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 /**
- * Some utilty methods for stagehand.
+ * Some utility methods for stagehand.
  */
 library stagehand.utils;
 
@@ -15,6 +15,9 @@ import '../stagehand.dart';
 
 const int _RUNE_SPACE = 32;
 
+final _substitueRegExp = new RegExp(r'__([a-zA-Z]+)__');
+final _nonValidSubstitueRegExp = new RegExp('[^a-zA-Z]');
+
 List<TemplateFile> decodeConcatenatedData(List<String> data) {
   List<TemplateFile> results = [];
 
@@ -51,10 +54,10 @@ String normalizeProjectName(String name) {
 }
 
 /**
- * Given a String [str] with mustache templates, and a [Map] of String key /
- * value pairs, substitute all instances of `{{key}}` for `value`. I.e.,
+ * Given a `String` [str] with mustache templates, and a [Map] of String key /
+ * value pairs, substitute all instances of `__key__` for `value`. I.e.,
  *
- *     Foo {{projectName}} baz.
+ *     Foo __projectName__ baz.
  *
  * and
  *
@@ -63,13 +66,26 @@ String normalizeProjectName(String name) {
  * becomes:
  *
  *     Foo bar baz.
+ *
+ * A key value can only be an ASCII string made up of letters: A-Z, a-z.
+ * No whitespace, numbers, or other characters are allowed.
  */
 String substituteVars(String str, Map<String, String> vars) {
-  vars.forEach((key, value) {
-    String sub = '{{${key}}}';
-    str = str.replaceAll(sub, value);
+  var nonValidKeys =
+      vars.keys.where((k) => k.contains(_nonValidSubstitueRegExp)).toList();
+  if (nonValidKeys.isNotEmpty) {
+    throw new ArgumentError('vars.keys can only contain letters.');
+  }
+
+  return str.replaceAllMapped(_substitueRegExp, (match) {
+    var item = vars[match[1]];
+
+    if (item == null) {
+      return match[0];
+    } else {
+      return item;
+    }
   });
-  return str;
 }
 
 /**
diff --git a/lib/stagehand.dart b/lib/stagehand.dart
index b9d48aa..47071b8 100644
--- a/lib/stagehand.dart
+++ b/lib/stagehand.dart
@@ -152,7 +152,7 @@ abstract class GeneratorTarget {
 /**
  * This class represents a file in a generator template. The contents could
  * either be binary or text. If text, the contents may contain mustache
- * variables that can be substituted (`{{myVar}}`).
+ * variables that can be substituted (`__myVar__`).
  */
 class TemplateFile {
   final String path;
diff --git a/templates/console-full/LICENSE b/templates/console-full/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/console-full/LICENSE
+++ b/templates/console-full/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/console-full/README.md b/templates/console-full/README.md
index d64f652..cb063bb 100644
--- a/templates/console-full/README.md
+++ b/templates/console-full/README.md
@@ -1,3 +1,3 @@
-# {{projectName}}
+# __projectName__
 
 A sample command-line application.
diff --git a/templates/console-full/bin/main.dart b/templates/console-full/bin/main.dart
index 2f53242..39c3070 100644
--- a/templates/console-full/bin/main.dart
+++ b/templates/console-full/bin/main.dart
@@ -1,8 +1,8 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-import 'package:{{projectName}}/{{projectName}}.dart' as {{projectName}};
+import 'package:__projectName__/__projectName__.dart' as __projectName__;
 
 main(List<String> arguments) {
-  print('Hello world: ${{{projectName}}.calculate()}!');
+  print('Hello world: ${__projectName__.calculate()}!');
 }
diff --git a/templates/console-full/lib/projectName.dart b/templates/console-full/lib/projectName.dart
index f842c10..a9715f9 100644
--- a/templates/console-full/lib/projectName.dart
+++ b/templates/console-full/lib/projectName.dart
@@ -1,8 +1,8 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-/// The {{projectName}} library.
-library {{projectName}};
+/// The __projectName__ library.
+library __projectName__;
 
 int calculate() {
   return 6 * 7;
diff --git a/templates/console-full/pubspec.yaml b/templates/console-full/pubspec.yaml
index bdffc10..0f5c805 100644
--- a/templates/console-full/pubspec.yaml
+++ b/templates/console-full/pubspec.yaml
@@ -1,7 +1,7 @@
-name: {{projectName}}
+name: __projectName__
 version: 0.0.1
 description: A sample command-line application.
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/console-full/test/projectName_test.dart b/templates/console-full/test/projectName_test.dart
index e3741e6..6aaa4ab 100644
--- a/templates/console-full/test/projectName_test.dart
+++ b/templates/console-full/test/projectName_test.dart
@@ -1,9 +1,9 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-library {{projectName}}.test;
+library __projectName__.test;
 
-import 'package:{{projectName}}/{{projectName}}.dart';
+import 'package:__projectName__/__projectName__.dart';
 import 'package:test/test.dart';
 
 void main() {
diff --git a/templates/console-simple/pubspec.yaml b/templates/console-simple/pubspec.yaml
index 647ce3a..69a80dc 100644
--- a/templates/console-simple/pubspec.yaml
+++ b/templates/console-simple/pubspec.yaml
@@ -1,4 +1,4 @@
-name: {{projectName}}
+name: __projectName__
 version: 0.0.1
 description: A simple console application.
 #dependencies:
diff --git a/templates/package-simple/LICENSE b/templates/package-simple/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/package-simple/LICENSE
+++ b/templates/package-simple/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/package-simple/README.md b/templates/package-simple/README.md
index 0e07e6f..3da306d 100644
--- a/templates/package-simple/README.md
+++ b/templates/package-simple/README.md
@@ -1,4 +1,4 @@
-# {{projectName}}
+# __projectName__
 
 A library for Dart developers. It is awesome.
 
@@ -6,7 +6,7 @@ A library for Dart developers. It is awesome.
 
 A simple usage example:
 
-    import 'package:{{projectName}}/{{projectName}}.dart';
+    import 'package:__projectName__/__projectName__.dart';
 
     main() {
       var awesome = new Awesome();
diff --git a/templates/package-simple/example/projectName.dart b/templates/package-simple/example/projectName.dart
index 384587d..4628602 100644
--- a/templates/package-simple/example/projectName.dart
+++ b/templates/package-simple/example/projectName.dart
@@ -1,9 +1,9 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-library {{projectName}}.example;
+library __projectName__.example;
 
-import 'package:{{projectName}}/{{projectName}}.dart';
+import 'package:__projectName__/__projectName__.dart';
 
 main() {
   var awesome = new Awesome();
diff --git a/templates/package-simple/lib/projectName.dart b/templates/package-simple/lib/projectName.dart
index c190037..9a1492e 100644
--- a/templates/package-simple/lib/projectName.dart
+++ b/templates/package-simple/lib/projectName.dart
@@ -1,11 +1,11 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-/// The {{projectName}} library.
+/// The __projectName__ library.
 ///
 /// This is an awesome library. More dartdocs go here.
-library {{projectName}};
+library __projectName__;
 
 // TODO: Export any libraries intended for clients of this package.
 
-export 'src/{{projectName}}_base.dart';
+export 'src/__projectName___base.dart';
diff --git a/templates/package-simple/lib/src/projectName_base.dart b/templates/package-simple/lib/src/projectName_base.dart
index 4f8b5b9..e747730 100644
--- a/templates/package-simple/lib/src/projectName_base.dart
+++ b/templates/package-simple/lib/src/projectName_base.dart
@@ -1,9 +1,9 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
 // TODO: Put public facing types in this file.
 
-library {{projectName}}.base;
+library __projectName__.base;
 
 /// Checks if you are awesome. Spoiler: you are.
 class Awesome {
diff --git a/templates/package-simple/pubspec.yaml b/templates/package-simple/pubspec.yaml
index a007e91..0385c37 100644
--- a/templates/package-simple/pubspec.yaml
+++ b/templates/package-simple/pubspec.yaml
@@ -1,7 +1,7 @@
-name: {{projectName}}
+name: __projectName__
 description: A starting point for Dart libraries or applications.
 version: 0.0.1
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/package-simple/test/projectName_test.dart b/templates/package-simple/test/projectName_test.dart
index 70a40fb..5563f7d 100644
--- a/templates/package-simple/test/projectName_test.dart
+++ b/templates/package-simple/test/projectName_test.dart
@@ -1,9 +1,9 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-library {{projectName}}.test;
+library __projectName__.test;
 
-import 'package:{{projectName}}/{{projectName}}.dart';
+import 'package:__projectName__/__projectName__.dart';
 import 'package:test/test.dart';
 
 void main() {
diff --git a/templates/server-appengine/LICENSE b/templates/server-appengine/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/server-appengine/LICENSE
+++ b/templates/server-appengine/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/server-appengine/README.md b/templates/server-appengine/README.md
index 97fce7b..5d32519 100644
--- a/templates/server-appengine/README.md
+++ b/templates/server-appengine/README.md
@@ -1,4 +1,4 @@
-# {{projectName}}
+# __projectName__
 
 This is a simple App Engine Dart application. It shows a simple way of handling
 HTTP requests and how to use the preconfigured App Engine memcache API service.
diff --git a/templates/server-appengine/bin/server.dart b/templates/server-appengine/bin/server.dart
index ebc5908..405c0e4 100644
--- a/templates/server-appengine/bin/server.dart
+++ b/templates/server-appengine/bin/server.dart
@@ -1,11 +1,11 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
 
 import 'package:shelf/shelf.dart';
 import 'package:shelf_appengine/shelf_appengine.dart' as shelf_ae;
-import 'package:{{projectName}}/memcache.dart' as cache;
+import 'package:__projectName__/memcache.dart' as cache;
 
 /// Application entry point called by AppEngine at startup.
 main(List<String> args) async {
diff --git a/templates/server-appengine/build/web/index.html b/templates/server-appengine/build/web/index.html
index 84bb1bf..aaaad91 100644
--- a/templates/server-appengine/build/web/index.html
+++ b/templates/server-appengine/build/web/index.html
@@ -3,7 +3,7 @@
 <html>
   <head>
   	<meta charset="utf-8">
-    <title>{{projectName}}</title>
+    <title>__projectName__</title>
   </head>
 
   <body>
diff --git a/templates/server-appengine/lib/memcache.dart b/templates/server-appengine/lib/memcache.dart
index e9574d7..fd0a0ea 100644
--- a/templates/server-appengine/lib/memcache.dart
+++ b/templates/server-appengine/lib/memcache.dart
@@ -1,7 +1,7 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
-library {{projectName}}.memcache;
+library __projectName__.memcache;
 
 import 'dart:async';
 
diff --git a/templates/server-appengine/pubspec.yaml b/templates/server-appengine/pubspec.yaml
index f8922e1..8101b2c 100644
--- a/templates/server-appengine/pubspec.yaml
+++ b/templates/server-appengine/pubspec.yaml
@@ -1,7 +1,7 @@
-name: {{projectName}}
+name: __projectName__
 version: 0.0.1
 description: A simple App Engine application.
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/server-shelf/LICENSE b/templates/server-shelf/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/server-shelf/LICENSE
+++ b/templates/server-shelf/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/server-shelf/README.md b/templates/server-shelf/README.md
index c0afe70..cf37b79 100644
--- a/templates/server-shelf/README.md
+++ b/templates/server-shelf/README.md
@@ -1,3 +1,3 @@
-# {{projectName}}
+# __projectName__
 
 A web server built using [Shelf](https://pub.dartlang.org/packages/shelf).
diff --git a/templates/server-shelf/bin/server.dart b/templates/server-shelf/bin/server.dart
index 4fa9eac..2b1ffb0 100644
--- a/templates/server-shelf/bin/server.dart
+++ b/templates/server-shelf/bin/server.dart
@@ -1,4 +1,4 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io';
diff --git a/templates/server-shelf/pubspec.yaml b/templates/server-shelf/pubspec.yaml
index c400803..5d624cb 100644
--- a/templates/server-shelf/pubspec.yaml
+++ b/templates/server-shelf/pubspec.yaml
@@ -1,7 +1,7 @@
-name: '{{projectName}}'
+name: '__projectName__'
 version: 0.0.1
 description: A web server built using the shelf package.
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/web-polymer/LICENSE b/templates/web-polymer/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/web-polymer/LICENSE
+++ b/templates/web-polymer/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/web-polymer/README.md b/templates/web-polymer/README.md
index f90ee78..a9e2167 100644
--- a/templates/web-polymer/README.md
+++ b/templates/web-polymer/README.md
@@ -1,3 +1,3 @@
-# {{ projectName }}
+# __projectName__
 
 A web app built using polymer.dart.
diff --git a/templates/web-polymer/lib/main_app.dart b/templates/web-polymer/lib/main_app.dart
index 6420772..f2be3a6 100644
--- a/templates/web-polymer/lib/main_app.dart
+++ b/templates/web-polymer/lib/main_app.dart
@@ -1,7 +1,7 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 @HtmlImport('main_app.html')
-library {{projectName}}.lib.main_app;
+library __projectName__.lib.main_app;
 
 import 'dart:html';
 
diff --git a/templates/web-polymer/lib/main_app.html b/templates/web-polymer/lib/main_app.html
index eb9f4a8..cd24203 100644
--- a/templates/web-polymer/lib/main_app.html
+++ b/templates/web-polymer/lib/main_app.html
@@ -1,5 +1,5 @@
 <!--
-  Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+  Copyright (c) __year__, __author__. All rights reserved. Use of this source code
   is governed by a BSD-style license that can be found in the LICENSE file.
 -->
 
@@ -11,10 +11,10 @@
   </style>
 
   <template>
-    <paper-input label="Type something..." value="{{text}}"></paper-input>
+    <paper-input label="Type something..." value="__text__"></paper-input>
     <p>
-      Text: <span>{{text}}</span><br />
-      Reversed: <span>{{reverseText(text)}}</span>
+      Text: <span>__text__</span><br />
+      Reversed: <span>__reverseText(text)__</span>
     </p>
   </template>
 </dom-module>
diff --git a/templates/web-polymer/pubspec.yaml b/templates/web-polymer/pubspec.yaml
index f3728b8..b0a3ed5 100644
--- a/templates/web-polymer/pubspec.yaml
+++ b/templates/web-polymer/pubspec.yaml
@@ -1,7 +1,7 @@
-name: '{{projectName}}'
+name: '__projectName__'
 version: 0.0.1
 description: A web app built using polymer.dart.
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/web-polymer/web/index.dart b/templates/web-polymer/web/index.dart
index d51a9d9..90c36fa 100644
--- a/templates/web-polymer/web/index.dart
+++ b/templates/web-polymer/web/index.dart
@@ -1,8 +1,8 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 library my_project.web.index;
 
-import 'package:{{projectName}}/main_app.dart';
+import 'package:__projectName__/main_app.dart';
 import 'package:polymer/polymer.dart';
 
 /// [MainApp] used!
diff --git a/templates/web-polymer/web/index.html b/templates/web-polymer/web/index.html
index 5ea28aa..9558570 100644
--- a/templates/web-polymer/web/index.html
+++ b/templates/web-polymer/web/index.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 
 <!--
-  Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+  Copyright (c) __year__, __author__. All rights reserved. Use of this source code
   is governed by a BSD-style license that can be found in the LICENSE file.
 -->
 
@@ -11,7 +11,7 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta name="scaffolded-by" content="https://github.com/google/stagehand">
-  <title>{{projectName}}</title>
+  <title>__projectName__</title>
 
   <!-- Add to homescreen for Chrome on Android -->
   <meta name="mobile-web-app-capable" content="yes">
diff --git a/templates/web-polymer/web/styles.css b/templates/web-polymer/web/styles.css
index 51272df..ed3f9d4 100644
--- a/templates/web-polymer/web/styles.css
+++ b/templates/web-polymer/web/styles.css
@@ -1,4 +1,4 @@
-/* Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code */
+/* Copyright (c) __year__, __author__. All rights reserved. Use of this source code */
 /* is governed by a BSD-style license that can be found in the LICENSE file. */
 
 body {
diff --git a/templates/web-simple/LICENSE b/templates/web-simple/LICENSE
index 01c8232..5a1b438 100644
--- a/templates/web-simple/LICENSE
+++ b/templates/web-simple/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) {{year}}, {{author}}.
+Copyright (c) __year__, __author__.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/templates/web-simple/pubspec.yaml b/templates/web-simple/pubspec.yaml
index 917d306..e363759 100644
--- a/templates/web-simple/pubspec.yaml
+++ b/templates/web-simple/pubspec.yaml
@@ -1,7 +1,7 @@
-name: '{{projectName}}'
+name: '__projectName__'
 version: 0.0.1
 description: An absolute bare-bones web app.
-#author: {{author}} <email@example.com>
+#author: __author__ <email@example.com>
 #homepage: https://www.example.com
 
 environment:
diff --git a/templates/web-simple/web/index.html b/templates/web-simple/web/index.html
index a72b0c7..bc01282 100644
--- a/templates/web-simple/web/index.html
+++ b/templates/web-simple/web/index.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 
 <!--
-  Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+  Copyright (c) __year__, __author__. All rights reserved. Use of this source code
   is governed by a BSD-style license that can be found in the LICENSE file.
 -->
 
@@ -11,7 +11,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta name="scaffolded-by" content="https://github.com/google/stagehand">
-    <title>{{projectName}}</title>
+    <title>__projectName__</title>
     <link rel="stylesheet" href="styles.css">
     <script async src="main.dart" type="application/dart"></script>
     <script async src="packages/browser/dart.js"></script>
diff --git a/templates/web-simple/web/main.dart b/templates/web-simple/web/main.dart
index c8dfe75..1429525 100644
--- a/templates/web-simple/web/main.dart
+++ b/templates/web-simple/web/main.dart
@@ -1,4 +1,4 @@
-// Copyright (c) {{year}}, {{author}}. All rights reserved. Use of this source code
+// Copyright (c) __year__, __author__. All rights reserved. Use of this source code
 // is governed by a BSD-style license that can be found in the LICENSE file.
 
 import 'dart:html';
diff --git a/test/common_test.dart b/test/common_test.dart
index 78dcbe7..682389b 100644
--- a/test/common_test.dart
+++ b/test/common_test.dart
@@ -14,12 +14,26 @@ void main() {
       expect(normalizeProjectName('foo-bar'), 'foo_bar');
     });
 
-    test('substituteVars simple', () {
-      _expect('foo {{bar}} baz', {'bar': 'baz'}, 'foo baz baz');
-    });
-
-    test('substituteVars nosub', () {
-      _expect('foo {{bar}} baz', {'aaa': 'bbb'}, 'foo {{bar}} baz');
+    group('substitueVars', () {
+      test('simple', () {
+        _expect('foo __bar__ baz', {'bar': 'baz'}, 'foo baz baz');
+      });
+
+      test('nosub', () {
+        _expect('foo __bar__ baz', {'aaa': 'bbb'}, 'foo __bar__ baz');
+      });
+
+      test('matching input', () {
+        _expect('foo __bar__ baz', {'bar': '__baz__', 'baz': 'foo'},
+            'foo __baz__ baz');
+      });
+
+      test('vars must be alpha + numeric', () {
+        expect(() => substituteVars('str', {'with space': 'noop'}), throws);
+        expect(() => substituteVars('str', {'with!symbols': 'noop'}), throws);
+        expect(() => substituteVars('str', {'with1numbers': 'noop'}), throws);
+        expect(() => substituteVars('str', {'with_under': 'noop'}), throws);
+      });
     });
 
     test('wrap', () {
-- 
GitLab