func (s *Store) VisitMailboxes(f func([]storage.Message) (cont bool)) error {
	s.Lock()
	boxNames := make([]string, 0, len(s.boxes))
	for k := range s.boxes {
		boxNames = append(boxNames, k)
	}
	s.Unlock()
	for _, mailbox := range boxNames {
		ms, _ := s.GetMessages(mailbox)
		if !f(ms) {
			break
		}
	}
	return nil
}
VisitMailboxes visits each mailbox in the store.
package mem
import (
	"fmt"
	"io/ioutil"
	"sort"
	"strconv"
	"sync"
	"github.com/inbucket/inbucket/pkg/config"
	"github.com/inbucket/inbucket/pkg/storage"
)
type Store struct {
	sync.Mutex
	boxes    map[string]*mbox
	cap      int            
	incoming chan *msgDone  
	remove   chan *msgDone  
}
type mbox struct {
	sync.RWMutex
	name     string
	last     int
	first    int
	messages map[string]*Message
}
var _ storage.Store = &Store{}
func New(cfg config.Storage) (storage.Store, error) {
	s := &Store{
		boxes: make(map[string]*mbox),
		cap:   cfg.MailboxMsgCap,
	}
	if str, ok := cfg.Params["maxkb"]; ok {
		maxKB, err := strconv.ParseInt(str, 10, 64)
		if err != nil {
			return nil, fmt.Errorf("failed to parse maxkb: %v", err)
		}
		if maxKB > 0 {
			s.incoming = make(chan *msgDone)
			s.remove = make(chan *msgDone)
			go s.maxSizeEnforcer(maxKB * 1024)
		}
	}
	return s, nil
}
func (s *Store) AddMessage(message storage.Message) (id string, err error) {
	r, ierr := message.Source()
	if ierr != nil {
		err = ierr
		return
	}
	source, ierr := ioutil.ReadAll(r)
	if ierr != nil {
		err = ierr
		return
	}
	m := &Message{
		mailbox: message.Mailbox(),
		from:    message.From(),
		to:      message.To(),
		date:    message.Date(),
		subject: message.Subject(),
	}
	s.withMailbox(message.Mailbox(), true, func(mb *mbox) {
		mb.last++
		m.index = mb.last
		id = strconv.Itoa(mb.last)
		m.id = id
		m.source = source
		mb.messages[id] = m
		if s.cap > 0 {
			for len(mb.messages) > s.cap {
				delete(mb.messages, strconv.Itoa(mb.first))
				mb.first++
			}
		}
	})
	s.enforcerDeliver(m)
	return id, err
}
func (s *Store) GetMessage(mailbox, id string) (m storage.Message, err error) {
	if id == "latest" {
		ms, err := s.GetMessages(mailbox)
		if err != nil {
			return nil, err
		}
		count := len(ms)
		if count == 0 {
			return nil, nil
		}
		return ms[count-1], nil
	}
	s.withMailbox(mailbox, false, func(mb *mbox) {
		var ok bool
		m, ok = mb.messages[id]
		if !ok {
			m = nil
		}
	})
	return m, err
}
func (s *Store) GetMessages(mailbox string) (ms []storage.Message, err error) {
	s.withMailbox(mailbox, false, func(mb *mbox) {
		ms = make([]storage.Message, 0, len(mb.messages))
		for _, v := range mb.messages {
			ms = append(ms, v)
		}
		sort.Slice(ms, func(i, j int) bool {
			return ms[i].(*Message).index < ms[j].(*Message).index
		})
	})
	return ms, err
}
func (s *Store) MarkSeen(mailbox, id string) error {
	s.withMailbox(mailbox, true, func(mb *mbox) {
		m := mb.messages[id]
		if m != nil {
			m.seen = true
		}
	})
	return nil
}
func (s *Store) PurgeMessages(mailbox string) error {
	var messages map[string]*Message
	s.withMailbox(mailbox, true, func(mb *mbox) {
		messages = mb.messages
		mb.messages = make(map[string]*Message)
	})
	if len(messages) > 0 && s.remove != nil {
		for _, m := range messages {
			s.enforcerRemove(m)
		}
	}
	return nil
}
func (s *Store) removeMessage(mailbox, id string) *Message {
	var m *Message
	s.withMailbox(mailbox, true, func(mb *mbox) {
		m = mb.messages[id]
		if m != nil {
			delete(mb.messages, id)
		}
	})
	return m
}
func (s *Store) RemoveMessage(mailbox, id string) error {
	m := s.removeMessage(mailbox, id)
	if m != nil {
		s.enforcerRemove(m)
	}
	return nil
}