docs: function bind(html, data, map) {
        if (Array.isArray(data)) {
          var output = '';
  
          for (var i = 0, l = data.length; i<l; i++) {
            output += this.bind(html, data[i], map);
          }
  
          return output;
        }
  
        html = (html || '').toString();
        data = data || {};
  
        var that = this;
  
        var openers = 0,
            remove = 0,
            components,
            attributes,
            mappings = map && compileMappings(map.mappings),
            intag = false,
            tagname = '',
            isClosing = false,
            isSelfClosing = false,
            selfClosing = false,
            matchmode = false,
            createAttribute = map && map.conf && map.conf.create,
            closing,
            tagbody;
  
        var c,
            buffer = '',
            left;
  
        for (var i = 0, l = html.length; i < l; i++) {
          c = html.charAt(i);
  
          //
          // Figure out which part of the HTML we are currently processing. And if
          // we have queued up enough HTML to process it's data.
          //
          if (c === '!' && intag && !matchmode) {
            intag = false;
            buffer += html.slice(left, i + 1);
          } else if (c === '<' && !intag) {
            closing = true;
            intag = true;
            left = i;
          } else if (c === '>' && intag) {
            intag = false;
            tagbody = html.slice(left, i + 1);
            components = this.tag.exec(tagbody);
  
            if(!components) {
              intag = true;
              continue;
            }
  
            isClosing = components[1];
            tagname = components[2];
            attributes = components[3];
            selfClosing = components[4];
            isSelfClosing = this.selfClosing.test(tagname);
  
            if (matchmode) {
              //
              // and its a closing.
              //
              if (!!isClosing) {
                if (openers <= 0) {
                  matchmode = false;
                } else {
                  --openers;
                }
              } else if (!isSelfClosing) {
                //
                // and its not a self-closing tag
                //
                ++openers;
              }
            }
  
            if (!isClosing && !matchmode) {
              //
              // if there is a match in progress and
              //
              if (mappings && mappings.length > 0) {
                for (var ii = mappings.length - 1; ii >= 0; ii--) {
                  var setAttribute = false
                    , mapping = mappings[ii]
                    , shouldSetAttribute = mapping.re && attributes.match(mapping.re);
  
                  //
                  // check if we are targetting a element only or attributes
                  //
                  if ('tag' in mapping && !this.attr.test(tagbody) && mapping.tag === tagname) {
                    tagbody = tagbody + fetch(data, mapping, '', tagbody);
                    continue;
                  }
  
                  tagbody = tagbody.replace(this.attr, function(str, key, q, value, a) {
                    var newdata;
  
                    if (shouldSetAttribute && mapping.replace !== key || remove) {
                      return str;
                    } else if (shouldSetAttribute || typeof mapping.replacePartial1 !== 'undefined') {
                      setAttribute = true;
  
                      //
                      // determine if we should use the replace argument or some value from the data object.
                      //
                      if (typeof mapping.replacePartial2 !== 'undefined') {
                        newdata = value.replace(mapping.replacePartial1, mapping.replacePartial2);
                      } else if (typeof mapping.replacePartial1 !== 'undefined' && mapping.dataKey) {
                        newdata = value.replace(mapping.replacePartial1, fetch(data, mapping, value, tagbody, key));
                      } else {
                        newdata = fetch(data, mapping, value, tagbody, key);
                      }
  
                      return key + '="' + (newdata || '') + '"';
                    } else if (!mapping.replace && mapping.attribute === key) {
                      if (
                        mapping.value === value ||
                        that.hasClass(value, mapping.value ||
                        mappings.conf.where === key) ||
                        (_toString.call(mapping.value) === '[object RegExp]' &&
                          mapping.value.exec(value) !== null)
                      ) {
                        if (mapping.remove) {
                          //
                          // only increase the remove counter if it's not a self
                          // closing element. As matchmode is suffectient to
                          // remove tose
                          //
                          if (!isSelfClosing) remove++;
                          matchmode = true;
                        } else if (mapping.plates) {
                          var partial = that.bind(
                              mapping.plates
                            , typeof mapping.data === 'string' ? fetch(data, { dataKey: mapping.data }) : mapping.data || data
                            , mapping.mapper
                          );
  
                          buffer += tagbody + that.iterate(html, partial, components, tagname, undefined, map);
                          matchmode = true;
                        } else {
                          var v = newdata = fetch(data, mapping, value, tagbody, key);
                          newdata = tagbody + newdata;
  
                          if (Array.isArray(v)) {
                            newdata = that.iterate(html, v, components, tagname, value, map);
                            // If the item is an array, then we need to tell
                            // Plates that we're dealing with nests
                            that.nest.push(tagname);
                          } else if (typeof v === 'object') {
                            newdata = tagbody + that.iterate(html, v, components, tagname, value, map);
                          }
  
                          buffer += newdata || '';
                          matchmode = true;
                        }
                      }
                    }
  
                    return str;
                  });
  
                  //
                  // Do we need to create the attributes if they don't exist.
                  //
                  if (createAttribute && shouldSetAttribute && !setAttribute) {
                    var spliced = selfClosing ? 2 : 1
                      , close = selfClosing ? '/>': '>'
                      , left = tagbody.substr(0, tagbody.length - spliced);
  
                    if (left[left.length - 1] === ' ') {
                      left = left.substr(0, left.length - 1);
  
                      if (selfClosing) {
                        close = ' ' + close;
                      }
                    }
  
                    tagbody = [
                      left,
                      ' ',
                      mapping.replace,
                      '="',
                      fetch(data, mapping),
                      '"',
                      close
                    ].join('');
                  }
                }
              } else {
                //
                // if there is no map, we are just looking to match
                // the specified id to a data key in the data object.
                //
                tagbody.replace(this.attr, function (attr, key, q, value, idx) {
                  if (key === map && map.conf.where || 'id' && data[value]) {
                    var v = data[value],
                        nest = Array.isArray(v),
                        output = nest || typeof v === 'object'
                          ? that.iterate(html.substr(left), v, components, tagname, value, map)
                          : v;
  
                    // If the item is an array, then we need to tell
                    // Plates that we're dealing with nests
                    if (nest) { that.nest.push(tagname); }
  
                    buffer += nest ? output : tagbody + output;
                    matchmode = true;
                  }
                });
              }
            }
  
            //
            // if there is currently no match in progress
            // just write the tagbody to the buffer.
            //
            if (!matchmode && that.nest.length === 0) {
              if (!remove) buffer += tagbody;
  
              if (remove && !!isClosing) --remove;
            } else if (!matchmode && that.nest.length) {
                this.nest.pop();
            }
          } else if (!intag && !matchmode) {
            //
            // currently not inside a tag and there is no
            // match in progress, we can write the char to
            // the buffer.
            //
            if (!remove) buffer += c;
          }
        }
        return buffer;
      }