function resultPrinter(options, source, removedNodes) {
  // Options
  var pretty = Boolean(options && options.pretty);

  return {
    toString: function () {
      if (!removedNodes || removedNodes.length === 0) {
        return source;
      }

      var result = '';
      var lastPos = 0;

      // Step through the removed nodes, building up the resulting string.
      for (var i = 0; i < removedNodes.length; i++) {
        var node = removedNodes[i];
        result += source.slice(lastPos, node.start);
        lastPos = node.end;
        if (!pretty) {
          var toReplace = source.slice(node.start, node.end);
          if (!node.loc || node.loc.start.line === node.loc.end.line) {
            result += space(toReplace.length);
          } else {
            var toReplaceLines = toReplace.split(LINE_RX);
            result += space(toReplaceLines[0].length);
            for (var j = 1; j < toReplaceLines.length; j += 2) {
              result += toReplaceLines[j] + space(toReplaceLines[j + 1].length);
            }
          }
        }
      }

      return result += source.slice(lastPos);
    },
    generateMap: function () {
      return {
        version: 3,
        sources: [ 'source.js' ],
        names: [],
        mappings: pretty ? generateSourceMappings(removedNodes) : ''
      };
    }
  }
}
Given a string JavaScript source which contains Flow types, return a string
which has removed those types.

Options:

  - all: (default: false)
    If true, bypasses looking for an @flow pragma comment before parsing.

  - pretty: (default: false)
    If true, removes types completely rather than replacing with spaces.
    This may require using source maps.

Returns an object with two methods:

  - .toString()
    Returns the transformed source code.

  - .generateMap()
    Returns a v3 source map.