text: function cmpSubString(str, subStr, offset) {
      for (var i=0; i<subStr.length; ++i) {
          if (str.charCodeAt(offset+i)!==subStr.charCodeAt(i)) {return false}
      }
      return true;
  }
  function StringIterator(string) {
      var that = new StringIterator.$$;
      that.str = string;
      that.index = 0;
      return that;
  }
  StringIterator.$crtmm$=function(){return{nm:'StringIterator',mt:'c',ps:[{nm:'string',$t:{t:$_String}}],pa:1,mod:$CCMM$,d:['$','Iterator']}};
  
  initTypeProto(StringIterator, 'ceylon.language::StringIterator', $init$Basic(), Iterator);
  var StringIterator$proto = StringIterator.$$.prototype;
  StringIterator$proto.$$targs$$={Element$Iterator:{t:Character}, Absent$Iterator:{t:Null}};
  StringIterator$proto.next = function() {
      if (this.index >= this.str.length) { return finished(); }
      var first = this.str.charCodeAt(this.index++);
      if ((first&0xfc00) !== 0xd800 || this.index >= this.str.length) {
          return Character(first);
      }
      return Character((first<<10) + this.str.charCodeAt(this.index++) - 0x35fdc00);
  }
  
  function countCodepoints(str) {
      var count = 0;
      for (var i=0; i<str.length; ++i) {
          ++count;
          if ((str.charCodeAt(i)&0xfc00) === 0xd800) {++i}
      }
      return count;
  }
  function codepointToString(cp) {
      if (cp <= 0xffff) {
          return String.fromCharCode(cp);
      }
      return String.fromCharCode((cp>>10)+0xd7c0, (cp&0x3ff)+0xdc00);
  }
  function codepointFromString(str, index) {
      var first = str.charCodeAt(index);
      if ((first&0xfc00) !== 0xd800) {return first}
      var second = str.charCodeAt(index+1);
      return isNaN(second) ? first : ((first<<10) + second - 0x35fdc00);
  }
  ex$.codepointFromString=codepointFromString;
  
  