/* vim:set ts=2 sw=2 sts=2 expandtab */
/*jshint asi: true undef: true es5: true node: true browser: true devel: true
         forin: true latedef: false globalstrict: true */

'use strict';

var Name = require('name')
var Method = require('method')

var core = require('./core'),
    convert = core.convert, accumulate = core.accumulate

var queued = Name()
var input = Name()
var forward = Name()
var state = Name()

function drain(buffer, next, result) {
  var values = buffer[queued]
  while (values.length) result = next(values.shift(), result)
  buffer[queued] = null
  return result
}

function isDrained(buffer) {
  return buffer[queued] === null
}

function buffer(source) {
  var self = convert(source, buffer.accumulate)
  self[state] = null
  self[input] = source
  self[queued] = []
  self[forward] = function(value) {
    self[queued].push(value)
  }
  accumulate(source, function(value) {
    self[state] = self[forward](value, self[state])
  })
  return self
}
buffer.accumulate = function(buffer, next, initial) {
  if (isDrained(buffer)) return accumulate(buffer[input], next, initial)
  buffer[state] = drain(buffer, next, initial)
  buffer[forward] = next
  return buffer
}

module.exports = buffer

@@ -673,24 +673,694 @@
 r(source) %7B%0A
+  /**%0A  Buffer a reducible, saving items from reducible in-memory until a consumer%0A  reduces the buffer.%0A%0A  Reducibles are not required to expose a data container for the sequence they%0A  represent, meaning items in the reducible may not be represented in-memory%0A  at all. This is great for representing potentially infinite data structures%0A  like %22mouse clicks over time%22, or %22data streamed from server%22. However,%0A  sometimes it's important to reduce all items in the reducible, even if the%0A  item was emitted at a point in the past. This is where buffer comes in handy.%0A  It stores a backlog of previously emitted items in-memory until you're%0A  ready to consume.%0A  **/%0A
   var self =

Add docstring for buffer function