Add mirrors support back
diff --git a/lib/mustache.dart b/lib/mustache.dart
index 7a5b0d2..8ac1af6 100644
--- a/lib/mustache.dart
+++ b/lib/mustache.dart
@@ -1,12 +1,13 @@
 library mustache;
 
-part 'char_reader.dart';
-part 'scanner.dart';
-part 'template.dart';
+import 'dart:mirrors';
+
+part 'src/char_reader.dart';
+part 'src/scanner.dart';
+part 'src/template.dart';
 
 /// [Mustache template documentation](http://mustache.github.com/mustache.5.html)
 
-
 /// Use new Template(source) instead.
 @deprecated
 Template parse(String source, {bool lenient : false})
@@ -25,8 +26,7 @@
       {bool lenient,
        bool htmlEscapeValues,
        String name,
-       PartialResolver partialResolver,
-       PropertyResolver propertyResolver}) = _Template.source;
+       PartialResolver partialResolver}) = _Template.source;
   
 	/// [values] can be a combination of Map, List, String. Any non-String object
 	/// will be converted using toString(). Null values will cause a 
@@ -86,13 +86,3 @@
 //TODO does this require some sort of context to find partials nested in subdirs?
 typedef Template PartialResolver(String templateName);
 
-//Allows pluggable property lookup. This is so code using mirrors can be
-// plugged in without requiring the mirrors dependency in the core library.
-typedef Object PropertyResolver(Object obj, String name);
-
-// Useful for handing partials
-abstract class TemplateRenderer {
-  String renderString(String templateName, values);
-  void render(String templateName, values, StringSink sink);
-}
-
diff --git a/lib/char_reader.dart b/lib/src/char_reader.dart
similarity index 100%
rename from lib/char_reader.dart
rename to lib/src/char_reader.dart
diff --git a/lib/scanner.dart b/lib/src/scanner.dart
similarity index 95%
rename from lib/scanner.dart
rename to lib/src/scanner.dart
index b144b3a..32b03dc 100644
--- a/lib/scanner.dart
+++ b/lib/src/scanner.dart
@@ -1,9 +1,5 @@
 part of mustache;

 

-//FIXME Temporarily made public for testing.

-//List<_Token> scan(String source, bool lenient) => _scan(source, lenient);

-//List<_Token> trim(List<_Token> tokens) => _trim(tokens);

-

 List<_Token> _scan(String source, bool lenient) => _trim(new _Scanner(source).scan());

 

 const int _TEXT = 1;

@@ -18,7 +14,7 @@
 const int _LINE_END = 10; // Should be filtered out, before returned by scan.

 

 //FIXME make private

-tokenTypeString(int type) => [

+_tokenTypeString(int type) => [

 	'?', 

 	'Text',

 	'Var',

@@ -137,7 +133,7 @@
 	final String value;

 	final int line;

 	final int column;

-	toString() => "${tokenTypeString(type)}: \"${value.replaceAll('\n', '\\n')}\" $line:$column";

+	toString() => "${_tokenTypeString(type)}: \"${value.replaceAll('\n', '\\n')}\" $line:$column";

 }

 

 class _Scanner {

diff --git a/lib/template.dart b/lib/src/template.dart
similarity index 84%
rename from lib/template.dart
rename to lib/src/template.dart
index cce5c2e..18b6a20 100644
--- a/lib/template.dart
+++ b/lib/src/template.dart
@@ -1,6 +1,6 @@
 part of mustache;

 

-const Object _NO_SUCH_PROPERTY = const Object();

+const Object _noSuchProperty = const Object();

 

 final RegExp _validTag = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');

 final RegExp _integerTag = new RegExp(r'^[0-9]+$');

@@ -64,34 +64,29 @@
        {bool lenient: false,

         bool htmlEscapeValues : true,

         String name,

-        PartialResolver partialResolver,

-        PropertyResolver propertyResolver})

+        PartialResolver partialResolver})

        :  _root = _parse(source, lenient, name),

           _lenient = lenient,

           _htmlEscapeValues = htmlEscapeValues,

           _name = name,

-          _partialResolver = partialResolver,

-          _propertyResolver = propertyResolver;

+          _partialResolver = partialResolver;

   

   // TODO share impl with _Template.source;

   _Template.root(this._root, 

       {bool lenient: false,

        bool htmlEscapeValues : true,

        String name,

-       PartialResolver partialResolver,

-       PropertyResolver propertyResolver})

+       PartialResolver partialResolver})

       :  _lenient = lenient,

          _htmlEscapeValues = htmlEscapeValues,

          _name = name,

-         _partialResolver = partialResolver,

-         _propertyResolver = propertyResolver;

+         _partialResolver = partialResolver;

     

   final _Node _root;

   final bool _lenient;

   final bool _htmlEscapeValues;

   final String _name;

   final PartialResolver _partialResolver;

-  final PropertyResolver _propertyResolver;

   

   String renderString(values) {

     var buf = new StringBuffer();

@@ -101,7 +96,7 @@
 

   void render(values, StringSink sink) {

     var renderer = new _Renderer(_root, sink, values, [values],

-        _lenient, _htmlEscapeValues, _partialResolver, _propertyResolver, _name);

+        _lenient, _htmlEscapeValues, _partialResolver, _name);

     renderer.render();

   }

 }

@@ -116,7 +111,6 @@
 	    this._lenient,

 	    this._htmlEscapeValues,

 	    this._partialResolver,

-	    this._propertyResolver,

 	    this._templateName)

     : _stack = new List.from(stack); 

 	

@@ -128,7 +122,6 @@
           renderer._lenient,

           renderer._htmlEscapeValues,

           renderer._partialResolver,

-          renderer._propertyResolver,

           renderer._templateName);

 

 	 _Renderer.subtree(_Renderer renderer, _Node node, StringSink sink)

@@ -139,7 +132,6 @@
            renderer._lenient,

            renderer._htmlEscapeValues,

            renderer._partialResolver,

-           renderer._propertyResolver,

            renderer._templateName);

 	

 	final _Node _root;

@@ -149,7 +141,6 @@
 	final bool _lenient;

 	final bool _htmlEscapeValues;

 	final PartialResolver _partialResolver;

-	final PropertyResolver _propertyResolver;

 	final String _templateName;

 

 	void render() {

@@ -196,16 +187,16 @@
 			return _stack.last;

 		}

 		var parts = name.split('.');

-		var object = _NO_SUCH_PROPERTY;

+		var object = _noSuchProperty;

 		for (var o in _stack.reversed) {

 			object = _getNamedProperty(o, parts[0]);

-			if (object != _NO_SUCH_PROPERTY) {

+			if (object != _noSuchProperty) {

 				break;

 			}

 		}

 		for (int i = 1; i < parts.length; i++) {

-			if (object == null || object == _NO_SUCH_PROPERTY) {

-				return _NO_SUCH_PROPERTY;

+			if (object == null || object == _noSuchProperty) {

+				return _noSuchProperty;

 			}

 			object = _getNamedProperty(object, parts[i]);

 		}

@@ -215,11 +206,9 @@
 	// Returns the property of the given object by name. For a map,

 	// which contains the key name, this is object[name]. For other

 	// objects, this is object.name or object.name(). If no property

-	// by the given name exists, this method returns _NO_SUCH_PROPERTY.

+	// by the given name exists, this method returns noSuchProperty.

 	_getNamedProperty(object, name) {

 	  

-	  if (_propertyResolver != null) return _propertyResolver(object, name);

-	  

 		var property = null;

 		if (object is Map && object.containsKey(name))

 		  return object[name];

@@ -228,23 +217,22 @@
 		  return object[int.parse(name)];

 		

 		if (_lenient && !_validTag.hasMatch(name))

-			return _NO_SUCH_PROPERTY;

+			return _noSuchProperty;

 		

-// Move mirrors code into another library.

-//		var instance = reflect(object);

-//		var field = instance.type.instanceMembers[new Symbol(name)];

-//		if (field == null) return _NO_SUCH_PROPERTY;

-//		

-//		var invocation = null;

-//		if ((field is VariableMirror) || ((field is MethodMirror) && (field.isGetter))) {

-//			invocation = instance.getField(field.simpleName);

-//		} else if ((field is MethodMirror) && (field.parameters.length == 0)) {

-//			invocation = instance.invoke(field.simpleName, []);

-//		}

-//		if (invocation == null) {

-//			return _NO_SUCH_PROPERTY;

-//		}

-//		return invocation.reflectee;

+		var instance = reflect(object);

+		var field = instance.type.instanceMembers[new Symbol(name)];

+		if (field == null) return _noSuchProperty;

+		

+		var invocation = null;

+		if ((field is VariableMirror) || ((field is MethodMirror) && (field.isGetter))) {

+			invocation = instance.getField(field.simpleName);

+		} else if ((field is MethodMirror) && (field.parameters.length == 0)) {

+			invocation = instance.invoke(field.simpleName, []);

+		}

+		if (invocation == null) {

+			return _noSuchProperty;

+		}

+		return invocation.reflectee;

 	}

 

 	_renderVariable(node, {bool escape : true}) {

@@ -252,7 +240,7 @@
 		

 		if (value is Function) value = value('');

 		

-		if (value == _NO_SUCH_PROPERTY) {

+		if (value == _noSuchProperty) {

 			if (!_lenient)

 				throw new TemplateException(

 				  'Value was missing, variable: ${node.value}',

@@ -297,7 +285,7 @@
 		} else if (value == false) {

 			// Do nothing.

 		

-		} else if (value == _NO_SUCH_PROPERTY) {

+		} else if (value == _noSuchProperty) {

 			if (!_lenient)

 				throw new TemplateException(

 				  'Value was missing, section: ${node.value}',

@@ -328,7 +316,7 @@
 		} else if (value == true || value is Map || value is Iterable) {

 			// Do nothing.

 		

-		} else if (value == _NO_SUCH_PROPERTY) {

+		} else if (value == _noSuchProperty) {

 			if (_lenient) {

 				_renderSectionWithValue(node, null);

 			} else {

@@ -422,5 +410,5 @@
 	final int line;

 	final int column;

 	final List<_Node> children = new List<_Node>();

-	String toString() => '_Node: ${tokenTypeString(type)}';

+	String toString() => '_Node: ${_tokenTypeString(type)}';

 }