text: 'use strict';
  
  function $InterpolateProvider(){
    this.$get = ['$parse', function($parse){
      return function(text, templateOnly) {
        var bindings = parseBindings(text);
        if (hasBindings(bindings) || !templateOnly) {
          return compileBindTemplate(text);
        }
      };
    }];
  }
  
  var bindTemplateCache = {};
  function compileBindTemplate(template){
    var fn = bindTemplateCache[template];
    if (!fn) {
      var bindings = [];
      forEach(parseBindings(template), function(text){
        var exp = binding(text);
        bindings.push(exp
          ? function(scope, element) { return scope.$eval(exp); }
          : function() { return text; });
      });
      bindTemplateCache[template] = fn = function(scope, element, prettyPrintJson) {
        var parts = [],
            hadOwnElement = scope.hasOwnProperty('$element'),
            oldElement = scope.$element;
  
        // TODO(misko): get rid of $element
        scope.$element = element;
        try {
          for (var i = 0; i < bindings.length; i++) {
            var value = bindings[i](scope, element);
            if (isElement(value))
              value = '';
            else if (isObject(value))
              value = toJson(value, prettyPrintJson);
            parts.push(value);
          }
          return parts.join('');
        } finally {
          if (hadOwnElement) {
            scope.$element = oldElement;
          } else {
            delete scope.$element;
          }
        }
      };
    }
    return fn;
  }
  
  
  function parseBindings(string) {
    var results = [];
    var lastIndex = 0;
    var index;
    while((index = string.indexOf('{{', lastIndex)) > -1) {
      if (lastIndex < index)
        results.push(string.substr(lastIndex, index - lastIndex));
      lastIndex = index;
  
      index = string.indexOf('}}', index);
      index = index < 0 ? string.length : index + 2;
  
      results.push(string.substr(lastIndex, index - lastIndex));
      lastIndex = index;
    }
    if (lastIndex != string.length)
      results.push(string.substr(lastIndex, string.length - lastIndex));
    return results.length === 0 ? [ string ] : results;
  }
  
  function binding(string) {
    var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/);
    return binding ? binding[1] : null;
  }
  
  function hasBindings(bindings) {
    return bindings.length > 1 || binding(bindings[0]) !== null;
  }
  