docs: function set(key, value, lineno, child) {
    // keys can be passed as buffers
    // we need a string
    key = '' + key;
    //console.error('%s=%s', key, value);
  
    var typedef = Types[key]
      , exists = this._data[key]
      , val = exists || {value: null, lineno: !child ? lineno : undefined}
      , changed = false;
  
    if(!lineno && !child) {
      changed = !exists || exists && exists.value !== value;
    }
  
    if(typedef && typedef.repeats) {
      // repeatable values always trigger a change
      // as they are created or appended
      if(!lineno && !child) changed = true;
      if(!exists) {
        val.value = [value];
        this._data[key] = val;
      }else{
        exists.value.push(value);
      }
    }else{
      val.value = value;
      this._data[key] = val;
    }
  
    if(lineno === undefined && !child) {
      // keep track of new keys, repeatable keys that are arrays
      // are always appended to the end of the file
      if(typedef.repeats || !exists) {
        if(!Object.keys(this._added).length) {
          this._lines.push(GENERATED);
        }
        this._added[key] = value;
  
        // add a line with the encoded value
        this._lines.push(this.encode(key, value));
      }
  
      // keep track of modified data for config rewrite (must come after added)
      if(exists && !this._added[key]) {
        this._modified[exists.lineno] = key;
        // line numbers are one-based but the array is zero
        this._lines[exists.lineno - 1] = this.encode(key, value);
      }
    }
  
    if(changed) {
      // emit change event with key, newval, oldval, newentry, oldentry
      this.emit('change',
        key, value, (exists ? exists.value : undefined), val, exists);
  
      // emit by key also, easier to consume
      this.emit(key,
        key, value, (exists ? exists.value : undefined), val, exists);
    }
  
    // merge include files synchronously
    // as we encounter them
    if(key === Types.INCLUDE && value) {
      this.emit('include', value, this._file, lineno);
    }
  }