Update docs, fix comments
diff --git a/README.md b/README.md
index 0ebcd9c..04561fc 100644
--- a/README.md
+++ b/README.md
@@ -2,15 +2,55 @@
 
 A Dart library to parse and render [mustache templates](http://mustache.github.com/mustache.5.html).
 
-# Example
+## Example
 ```dart
-import 'package:mustache/mustache.dart';
+	import 'package:mustache/mustache.dart' as mustache;
 
-main() {
-	var source = '{{#section}}_{{var}}_{{/section}}';
-	var values = {"section": {"var": "bob"}};
-	var template = parse(source);
-	var output = template.render(values);
-	print(output);
-}
+	main() {
+		var source = '{{#names}}<div>{{lastname}}, {{firstname}}</div>{{/names}}';
+		var template = mustache.parse(source);
+		var output = template.render({'names': [
+			{'fistname': 'Greg', 'lastname': 'Lowe'},
+			{'fistname': 'Bob', 'lastname': 'Johnson'}
+		]});
+		print(output);
+	}
 ```
+
+## API
+
+```dart
+
+Template parse(String source, {bool lenient : false});
+
+abstract class Template {
+	String render(values, {bool lenient : false});
+}
+
+```
+
+Once a template has been created it can be rendered any number of times.
+
+Both parse and render throw a FormatException if there is a problem with the template or rendering the values.
+
+When lenient mode is enabled tag names may use any characters, otherwise only a-z, A-Z, 0-9, underscore and minus. Lenient mode will also silently ignore nulls passed as values.
+
+
+## Supported 
+```
+ Variables             {{var-name}}
+ Sections              {{#section}}Blah{{/section}}
+ Inverse sections      {{^section}}Blah{{/section}}
+ Comments              {{! Not output. }}
+```
+See the [mustache templates tutorial](http://mustache.github.com/mustache.5.html) for more information.
+
+## To do
+
+Escape tags {{{ ... }}}, and {{& ... }}
+Partial tags {{>partial}}
+Functions as values
+And maybe later:
+  Incremental parser, and renderer (i.e. Stream based)
+  Allow the incremental renderer to handle values which are Futures and Streams.
+
diff --git a/lib/mustache.dart b/lib/mustache.dart
index cdd604b..ff6dac7 100644
--- a/lib/mustache.dart
+++ b/lib/mustache.dart
@@ -4,23 +4,26 @@
 part 'scanner.dart';
 part 'template.dart';
 
-/// Mustache docs http://mustache.github.com/mustache.5.html
+/// [Mustache template documentation](http://mustache.github.com/mustache.5.html)
 
-/// Returns a [Template] which can be used to render the template with substituted
-/// values.
+/// Returns a [Template] which can be used to render the mustache template 
+/// with substituted values.
+/// Tag names may only contain characters a-z, A-Z, 0-9, underscore, and minus,
+/// unless lenient mode is specified.
 /// Throws [FormatException] if the syntax of the source is invalid.
 Template parse(String source,
 	             {bool lenient : false}) => _parse(source, lenient: lenient);
 
-/// A Template can be used multiple times to [render] content with different values.
+/// A Template can be rendered multiple times with different values.
 abstract class Template {
 	/// [values] can be a combination of Map, List, String. Any non-String object
-	/// will be converted using toString().
+	/// will be converted using toString(). Null values will cause a 
+	/// FormatException, unless lenient module is enabled.
 	String render(values, {bool lenient : false});
 }
 
-/// MustacheFormatException can be used to obtain the line and column numbers
-/// of the token which caused [parse] to fail.
+/// MustacheFormatException is used to obtain the line and column numbers
+/// of the token which caused parse or render to fail.
 class MustacheFormatException implements FormatException {	
 	final String message;
 
diff --git a/lib/scanner.dart b/lib/scanner.dart
index 023d468..0cd1c42 100644
--- a/lib/scanner.dart
+++ b/lib/scanner.dart
@@ -137,7 +137,7 @@
 			// Comment {{! ... }}

 			case _EXCLAIM:

 				_read();

-				_addStringToken(_COMMENT);

+				_addStringToken(_COMMENT); //FIXME hmmm need to think about escaping rules here.

 				break;

 

 			// Partial {{> ... }}

diff --git a/lib/template.dart b/lib/template.dart
index 31102ee..4e9c8f3 100644
--- a/lib/template.dart
+++ b/lib/template.dart
@@ -34,6 +34,9 @@
 

 			stack.removeLast();

 		

+		} else if (t.type == _COMMENT) {

+			// Do nothing

+

 		} else {

 			throw new UnimplementedError();

 		}

@@ -93,6 +96,8 @@
 			case _OPEN_INV_SECTION:

 				_renderInvSection(node);

 				break;

+			case _COMMENT:

+				break; // Do nothing.

 			default:

 				throw new UnimplementedError();

 		}

diff --git a/test/mustache_test.dart b/test/mustache_test.dart
index b284efa..bfe867d 100644
--- a/test/mustache_test.dart
+++ b/test/mustache_test.dart
@@ -11,6 +11,17 @@
 const VALUE_NULL = 'Value was null or missing';
 
 main() {
+	group('Basic', () {
+		test('Variable', () {
+			var output = parse('_{{var}}_')
+				.render({"var": "bob"});
+			expect(output, equals('_bob_'));
+		});
+		test('Comment', () {
+			var output = parse('_{{! i am a comment ! }}_').render({});
+			expect(output, equals('__'));
+		});
+	});
 	group('Section', () {
 		test('Map', () {
 			var output = parse('{{#section}}_{{var}}_{{/section}}')