whole_func_string: function extractAttributes(attrSet, attrs) {
  		attrSet = require('utils').trim(attrSet);
  		var result = [];
  		
  		/** @type StringStream */
  		var stream = require('stringStream').create(attrSet);
  		stream.eatSpace();
  		
  		while (!stream.eol()) {
  			stream.start = stream.pos;
  			if (stream.eatWhile(reWord)) {
  				var attrName = stream.current();
  				var attrValue = '';
  				if (stream.peek() == '=') {
  					stream.next();
  					stream.start = stream.pos;
  					var quote = stream.peek();
  					
  					if (quote == '"' || quote == "'") {
  						stream.next();
  						if (consumeQuotedValue(stream, quote)) {
  							attrValue = stream.current();
  							// strip quotes
  							attrValue = attrValue.substring(1, attrValue.length - 1);
  						} else {
  							throw 'Invalid attribute value';
  						}
  					} else if (stream.eatWhile(/[^\s\]]/)) {
  						attrValue = stream.current();
  					} else {
  						throw 'Invalid attribute value';
  					}
  				}
  				
  				result.push({
  					name: attrName, 
  					value: attrValue
  				});
  				stream.eatSpace();
  			} else {
  				break;
  			}
  		}
  		
  		return result;
  	}
func_code_string: function extractAttributes(attrSet, attrs) {
  		attrSet = require('utils').trim(attrSet);
  		var result = [];
  		
  		/** @type StringStream */
  		var stream = require('stringStream').create(attrSet);
  		stream.eatSpace();
  		
  		while (!stream.eol()) {
  			stream.start = stream.pos;
  			if (stream.eatWhile(reWord)) {
  				var attrName = stream.current();
  				var attrValue = '';
  				if (stream.peek() == '=') {
  					stream.next();
  					stream.start = stream.pos;
  					var quote = stream.peek();
  					
  					if (quote == '"' || quote == "'") {
  						stream.next();
  						if (consumeQuotedValue(stream, quote)) {
  							attrValue = stream.current();
  							// strip quotes
  							attrValue = attrValue.substring(1, attrValue.length - 1);
  						} else {
  							throw 'Invalid attribute value';
  						}
  					} else if (stream.eatWhile(/[^\s\]]/)) {
  						attrValue = stream.current();
  					} else {
  						throw 'Invalid attribute value';
  					}
  				}
  				
  				result.push({
  					name: attrName, 
  					value: attrValue
  				});
  				stream.eatSpace();
  			} else {
  				break;
  			}
  		}
  		
  		return result;
  	}
func_documentation_string: Extract attributes and their values from attribute set:
  <code>[attr col=3 title="Quoted string"]</code>
  @param {String} attrSet
  @returns {Array}