whole_func_string: function (str, callback, additionalData) {
              var root, error = null, globalVars, modifyVars, ignored, preText = '';
  
              globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + '\n' : '';
              modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + Parser.serializeVars(additionalData.modifyVars) : '';
  
              if (context.pluginManager) {
                  var preProcessors = context.pluginManager.getPreProcessors();
                  for (var i = 0; i < preProcessors.length; i++) {
                      str = preProcessors[i].process(str, { context: context, imports: imports, fileInfo: fileInfo });
                  }
              }
  
              if (globalVars || (additionalData && additionalData.banner)) {
                  preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;
                  ignored = imports.contentsIgnoredChars;
                  ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
                  ignored[fileInfo.filename] += preText.length;
              }
  
              str = str.replace(/\r\n?/g, '\n');
              // Remove potential UTF Byte Order Mark
              str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
              imports.contents[fileInfo.filename] = str;
  
              // Start with the primary rule.
              // The whole syntax tree is held under a Ruleset node,
              // with the `root` property set to true, so no `{}` are
              // output. The callback is called when the input is parsed.
              try {
                  parserInput.start(str, context.chunkInput, function fail(msg, index) {
                      throw new LessError({
                          index: index,
                          type: 'Parse',
                          message: msg,
                          filename: fileInfo.filename
                      }, imports);
                  });
  
                  tree.Node.prototype.parse = this;
                  root = new tree.Ruleset(null, this.parsers.primary());
                  tree.Node.prototype.rootNode = root;
                  root.root = true;
                  root.firstRoot = true;
                  root.functionRegistry = functionRegistry.inherit();
                  
              } catch (e) {
                  return callback(new LessError(e, imports, fileInfo.filename));
              }
  
              // If `i` is smaller than the `input.length - 1`,
              // it means the parser wasn't able to parse the whole
              // string, so we've got a parsing error.
              //
              // We try to extract a \n delimited string,
              // showing the line where the parse error occurred.
              // We split it up into two parts (the part which parsed,
              // and the part which didn't), so we can color them differently.
              var endInfo = parserInput.end();
              if (!endInfo.isFinished) {
  
                  var message = endInfo.furthestPossibleErrorMessage;
  
                  if (!message) {
                      message = 'Unrecognised input';
                      if (endInfo.furthestChar === '}') {
                          message += '. Possibly missing opening \'{\'';
                      } else if (endInfo.furthestChar === ')') {
                          message += '. Possibly missing opening \'(\'';
                      } else if (endInfo.furthestReachedEnd) {
                          message += '. Possibly missing something';
                      }
                  }
  
                  error = new LessError({
                      type: 'Parse',
                      message: message,
                      index: endInfo.furthest,
                      filename: fileInfo.filename
                  }, imports);
              }
  
              var finish = function (e) {
                  e = error || e || imports.error;
  
                  if (e) {
                      if (!(e instanceof LessError)) {
                          e = new LessError(e, imports, fileInfo.filename);
                      }
  
                      return callback(e);
                  }
                  else {
                      return callback(null, root);
                  }
              };
  
              if (context.processImports !== false) {
                  new visitors.ImportVisitor(imports, finish)
                      .run(root);
              } else {
                  return finish();
              }
          }
func_code_string: function (str, callback, additionalData) {
              var root, error = null, globalVars, modifyVars, ignored, preText = '';
  
              globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + '\n' : '';
              modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + Parser.serializeVars(additionalData.modifyVars) : '';
  
              if (context.pluginManager) {
                  var preProcessors = context.pluginManager.getPreProcessors();
                  for (var i = 0; i < preProcessors.length; i++) {
                      str = preProcessors[i].process(str, { context: context, imports: imports, fileInfo: fileInfo });
                  }
              }
  
              if (globalVars || (additionalData && additionalData.banner)) {
                  preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;
                  ignored = imports.contentsIgnoredChars;
                  ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
                  ignored[fileInfo.filename] += preText.length;
              }
  
              str = str.replace(/\r\n?/g, '\n');
              // Remove potential UTF Byte Order Mark
              str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
              imports.contents[fileInfo.filename] = str;
  
              // Start with the primary rule.
              // The whole syntax tree is held under a Ruleset node,
              // with the `root` property set to true, so no `{}` are
              // output. The callback is called when the input is parsed.
              try {
                  parserInput.start(str, context.chunkInput, function fail(msg, index) {
                      throw new LessError({
                          index: index,
                          type: 'Parse',
                          message: msg,
                          filename: fileInfo.filename
                      }, imports);
                  });
  
                  tree.Node.prototype.parse = this;
                  root = new tree.Ruleset(null, this.parsers.primary());
                  tree.Node.prototype.rootNode = root;
                  root.root = true;
                  root.firstRoot = true;
                  root.functionRegistry = functionRegistry.inherit();
                  
              } catch (e) {
                  return callback(new LessError(e, imports, fileInfo.filename));
              }
  
              // If `i` is smaller than the `input.length - 1`,
              // it means the parser wasn't able to parse the whole
              // string, so we've got a parsing error.
              //
              // We try to extract a \n delimited string,
              // showing the line where the parse error occurred.
              // We split it up into two parts (the part which parsed,
              // and the part which didn't), so we can color them differently.
              var endInfo = parserInput.end();
              if (!endInfo.isFinished) {
  
                  var message = endInfo.furthestPossibleErrorMessage;
  
                  if (!message) {
                      message = 'Unrecognised input';
                      if (endInfo.furthestChar === '}') {
                          message += '. Possibly missing opening \'{\'';
                      } else if (endInfo.furthestChar === ')') {
                          message += '. Possibly missing opening \'(\'';
                      } else if (endInfo.furthestReachedEnd) {
                          message += '. Possibly missing something';
                      }
                  }
  
                  error = new LessError({
                      type: 'Parse',
                      message: message,
                      index: endInfo.furthest,
                      filename: fileInfo.filename
                  }, imports);
              }
  
              var finish = function (e) {
                  e = error || e || imports.error;
  
                  if (e) {
                      if (!(e instanceof LessError)) {
                          e = new LessError(e, imports, fileInfo.filename);
                      }
  
                      return callback(e);
                  }
                  else {
                      return callback(null, root);
                  }
              };
  
              if (context.processImports !== false) {
                  new visitors.ImportVisitor(imports, finish)
                      .run(root);
              } else {
                  return finish();
              }
          }
func_documentation_string: Parse an input string into an abstract syntax tree, @param str A string containing 'less' markup @param callback call `callback` when done. @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply