func (m *Machine) UpdateLogin(newlogin string) {
	m.Login = newlogin
	updateTokenValue(m.logintoken, newlogin)
}
UpdateLogin sets the login for the Machine m.
package netrc
import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"sync"
	"unicode"
	"unicode/utf8"
)
type tkType int
const (
	tkMachine tkType = iota
	tkDefault
	tkLogin
	tkPassword
	tkAccount
	tkMacdef
	tkComment
	tkWhitespace
)
var keywords = map[string]tkType{
	"machine":  tkMachine,
	"default":  tkDefault,
	"login":    tkLogin,
	"password": tkPassword,
	"account":  tkAccount,
	"macdef":   tkMacdef,
	"#":        tkComment,
}
type Netrc struct {
	tokens     []*token
	machines   []*Machine
	macros     Macros
	updateLock sync.Mutex
}
func (n *Netrc) FindMachine(name string) (m *Machine) {
	var def *Machine
	for _, m = range n.machines {
		if m.Name == name {
			return m
		}
		if m.IsDefault() {
			def = m
		}
	}
	if def == nil {
		return nil
	}
	return def
}
func (n *Netrc) MarshalText() (text []byte, err error) {
	for i := range n.tokens {
		switch n.tokens[i].kind {
		case tkComment, tkDefault, tkWhitespace:  
			text = append(text, n.tokens[i].rawkind...)
		default:
			if n.tokens[i].value != "" {  
				text = append(text, n.tokens[i].rawkind...)
			}
		}
		if n.tokens[i].kind == tkMacdef {
			text = append(text, ' ')
			text = append(text, n.tokens[i].macroName...)
		}
		text = append(text, n.tokens[i].rawvalue...)
	}
	return
}
func (n *Netrc) NewMachine(name, login, password, account string) *Machine {
	n.updateLock.Lock()
	defer n.updateLock.Unlock()
	prefix := "\n"
	if len(n.tokens) == 0 {
		prefix = ""
	}
	m := &Machine{
		Name:     name,
		Login:    login,
		Password: password,
		Account:  account,
		nametoken: &token{
			kind:     tkMachine,
			rawkind:  []byte(prefix + "machine"),
			value:    name,
			rawvalue: []byte(" " + name),
		},
		logintoken: &token{
			kind:     tkLogin,
			rawkind:  []byte("\n\tlogin"),
			value:    login,
			rawvalue: []byte(" " + login),
		},
		passtoken: &token{
			kind:     tkPassword,
			rawkind:  []byte("\n\tpassword"),
			value:    password,
			rawvalue: []byte(" " + password),
		},
		accounttoken: &token{
			kind:     tkAccount,
			rawkind:  []byte("\n\taccount"),
			value:    account,
			rawvalue: []byte(" " + account),
		},
	}
	n.insertMachineTokensBeforeDefault(m)
	for i := range n.machines {
		if n.machines[i].IsDefault() {
			n.machines = append(append(n.machines[:i], m), n.machines[i:]...)
			return m
		}
	}
	n.machines = append(n.machines, m)
	return m
}
func (n *Netrc) insertMachineTokensBeforeDefault(m *Machine) {
	newtokens := []*token{m.nametoken}
	if m.logintoken.value != "" {
		newtokens = append(newtokens, m.logintoken)
	}
	if m.passtoken.value != "" {
		newtokens = append(newtokens, m.passtoken)
	}
	if m.accounttoken.value != "" {
		newtokens = append(newtokens, m.accounttoken)
	}
	for i := range n.tokens {
		if n.tokens[i].kind == tkDefault {
			n.tokens = append(n.tokens[:i], append(newtokens, n.tokens[i:]...)...)
			return
		}
	}
	n.tokens = append(n.tokens, newtokens...)
	return
}
func (n *Netrc) RemoveMachine(name string) {
	n.updateLock.Lock()
	defer n.updateLock.Unlock()
	for i := range n.machines {
		if n.machines[i] != nil && n.machines[i].Name == name {
			m := n.machines[i]
			for _, t := range []*token{
				m.nametoken, m.logintoken, m.passtoken, m.accounttoken,
			} {
				n.removeToken(t)
			}
			n.machines = append(n.machines[:i], n.machines[i+1:]...)
			return
		}
	}
}
func (n *Netrc) removeToken(t *token) {
	if t != nil {
		for i := range n.tokens {
			if n.tokens[i] == t {
				n.tokens = append(n.tokens[:i], n.tokens[i+1:]...)
				return
			}
		}
	}
}
type Machine struct {
	Name     string
	Login    string
	Password string
	Account  string
	nametoken    *token
	logintoken   *token
	passtoken    *token
	accounttoken *token
}
func (m *Machine) IsDefault() bool {
	return m.Name == ""
}
func (m *Machine) UpdatePassword(newpass string) {
	m.Password = newpass
	updateTokenValue(m.passtoken, newpass)
}