func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) {
	if s == nil {
		return nil, ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}
	s.RLock()
	defer s.RUnlock()
	for _, e := range guild.Emojis {
		if e.ID == emojiID {
			return e, nil
		}
	}
	return nil, ErrStateNotFound
}
Emoji returns an emoji for a guild and emoji id.
package discordgo
import (
	"errors"
	"sort"
	"sync"
)
var ErrNilState = errors.New("state not instantiated, please use discordgo.New() or assign Session.State")
var ErrStateNotFound = errors.New("state cache not found")
var ErrMessageIncompletePermissions = errors.New("message incomplete, unable to determine permissions")
type State struct {
	sync.RWMutex
	Ready
	MaxMessageCount int
	TrackChannels   bool
	TrackEmojis     bool
	TrackMembers    bool
	TrackRoles      bool
	TrackVoice      bool
	TrackPresences  bool
	guildMap   map[string]*Guild
	channelMap map[string]*Channel
	memberMap  map[string]map[string]*Member
}
func NewState() *State {
	return &State{
		Ready: Ready{
			PrivateChannels: []*Channel{},
			Guilds:          []*Guild{},
		},
		TrackChannels:  true,
		TrackEmojis:    true,
		TrackMembers:   true,
		TrackRoles:     true,
		TrackVoice:     true,
		TrackPresences: true,
		guildMap:       make(map[string]*Guild),
		channelMap:     make(map[string]*Channel),
		memberMap:      make(map[string]map[string]*Member),
	}
}
func (s *State) createMemberMap(guild *Guild) {
	members := make(map[string]*Member)
	for _, m := range guild.Members {
		members[m.User.ID] = m
	}
	s.memberMap[guild.ID] = members
}
func (s *State) GuildAdd(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}
	s.Lock()
	defer s.Unlock()
	for _, c := range guild.Channels {
		s.channelMap[c.ID] = c
	}
	if guild.Members != nil {
		s.createMemberMap(guild)
	} else if _, ok := s.memberMap[guild.ID]; !ok {
		s.memberMap[guild.ID] = make(map[string]*Member)
	}
	if g, ok := s.guildMap[guild.ID]; ok {
		if guild.MemberCount == 0 {
			guild.MemberCount = g.MemberCount
		}
		if guild.Roles == nil {
			guild.Roles = g.Roles
		}
		if guild.Emojis == nil {
			guild.Emojis = g.Emojis
		}
		if guild.Members == nil {
			guild.Members = g.Members
		}
		if guild.Presences == nil {
			guild.Presences = g.Presences
		}
		if guild.Channels == nil {
			guild.Channels = g.Channels
		}
		if guild.VoiceStates == nil {
			guild.VoiceStates = g.VoiceStates
		}
		*g = *guild
		return nil
	}
	s.Guilds = append(s.Guilds, guild)
	s.guildMap[guild.ID] = guild
	return nil
}
func (s *State) GuildRemove(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}
	_, err := s.Guild(guild.ID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	delete(s.guildMap, guild.ID)
	for i, g := range s.Guilds {
		if g.ID == guild.ID {
			s.Guilds = append(s.Guilds[:i], s.Guilds[i+1:]...)
			return nil
		}
	}
	return nil
}
func (s *State) Guild(guildID string) (*Guild, error) {
	if s == nil {
		return nil, ErrNilState
	}
	s.RLock()
	defer s.RUnlock()
	if g, ok := s.guildMap[guildID]; ok {
		return g, nil
	}
	return nil, ErrStateNotFound
}
func (s *State) PresenceAdd(guildID string, presence *Presence) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	for i, p := range guild.Presences {
		if p.User.ID == presence.User.ID {
			guild.Presences[i].Activities = presence.Activities
			if presence.Status != "" {
				guild.Presences[i].Status = presence.Status
			}
			guild.Presences[i].User.ID = presence.User.ID
			if presence.User.Avatar != "" {
				guild.Presences[i].User.Avatar = presence.User.Avatar
			}
			if presence.User.Discriminator != "" {
				guild.Presences[i].User.Discriminator = presence.User.Discriminator
			}
			if presence.User.Email != "" {
				guild.Presences[i].User.Email = presence.User.Email
			}
			if presence.User.Token != "" {
				guild.Presences[i].User.Token = presence.User.Token
			}
			if presence.User.Username != "" {
				guild.Presences[i].User.Username = presence.User.Username
			}
			return nil
		}
	}
	guild.Presences = append(guild.Presences, presence)
	return nil
}
func (s *State) PresenceRemove(guildID string, presence *Presence) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	for i, p := range guild.Presences {
		if p.User.ID == presence.User.ID {
			guild.Presences = append(guild.Presences[:i], guild.Presences[i+1:]...)
			return nil
		}
	}
	return ErrStateNotFound
}
func (s *State) Presence(guildID, userID string) (*Presence, error) {
	if s == nil {
		return nil, ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}
	for _, p := range guild.Presences {
		if p.User.ID == userID {
			return p, nil
		}
	}
	return nil, ErrStateNotFound
}
func (s *State) MemberAdd(member *Member) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	members, ok := s.memberMap[member.GuildID]
	if !ok {
		return ErrStateNotFound
	}
	m, ok := members[member.User.ID]
	if !ok {
		members[member.User.ID] = member
		guild.Members = append(guild.Members, member)
	} else {
		if member.JoinedAt == "" {
			member.JoinedAt = m.JoinedAt
		}
		*m = *member
	}
	return nil
}
func (s *State) MemberRemove(member *Member) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	members, ok := s.memberMap[member.GuildID]
	if !ok {
		return ErrStateNotFound
	}
	_, ok = members[member.User.ID]
	if !ok {
		return ErrStateNotFound
	}
	delete(members, member.User.ID)
	for i, m := range guild.Members {
		if m.User.ID == member.User.ID {
			guild.Members = append(guild.Members[:i], guild.Members[i+1:]...)
			return nil
		}
	}
	return ErrStateNotFound
}
func (s *State) Member(guildID, userID string) (*Member, error) {
	if s == nil {
		return nil, ErrNilState
	}
	s.RLock()
	defer s.RUnlock()
	members, ok := s.memberMap[guildID]
	if !ok {
		return nil, ErrStateNotFound
	}
	m, ok := members[userID]
	if ok {
		return m, nil
	}
	return nil, ErrStateNotFound
}
func (s *State) RoleAdd(guildID string, role *Role) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	for i, r := range guild.Roles {
		if r.ID == role.ID {
			guild.Roles[i] = role
			return nil
		}
	}
	guild.Roles = append(guild.Roles, role)
	return nil
}
func (s *State) RoleRemove(guildID, roleID string) error {
	if s == nil {
		return ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}
	s.Lock()
	defer s.Unlock()
	for i, r := range guild.Roles {
		if r.ID == roleID {
			guild.Roles = append(guild.Roles[:i], guild.Roles[i+1:]...)
			return nil
		}
	}
	return ErrStateNotFound
}
func (s *State) Role(guildID, roleID string) (*Role, error) {
	if s == nil {
		return nil, ErrNilState
	}
	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}
	s.RLock()
	defer s.RUnlock()
	for _, r := range guild.Roles {
		if r.ID == roleID {
			return r, nil
		}
	}
	return nil, ErrStateNotFound
}
func (s *State) ChannelAdd(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}
	s.Lock()
	defer s.Unlock()
	if c, ok := s.channelMap[channel.ID]; ok {
		if channel.Messages == nil {
			channel.Messages = c.Messages
		}
		if channel.PermissionOverwrites == nil {
			channel.PermissionOverwrites = c.PermissionOverwrites
		}
		*c = *channel
		return nil
	}
	if channel.Type == ChannelTypeDM || channel.Type == ChannelTypeGroupDM {
		s.PrivateChannels = append(s.PrivateChannels, channel)
	} else {
		guild, ok := s.guildMap[channel.GuildID]
		if !ok {
			return ErrStateNotFound
		}
		guild.Channels = append(guild.Channels, channel)
	}
	s.channelMap[channel.ID] = channel
	return nil
}
func (s *State) ChannelRemove(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}
	_, err := s.Channel(channel.ID)
	if err != nil {
		return err
	}
	if channel.Type == ChannelTypeDM || channel.Type == ChannelTypeGroupDM {
		s.Lock()
		defer s.Unlock()
		for i, c := range s.PrivateChannels {
			if c.ID == channel.ID {
				s.PrivateChannels = append(s.PrivateChannels[:i], s.PrivateChannels[i+1:]...)
				break
			}
		}
	} else {
		guild, err := s.Guild(channel.GuildID)
		if err != nil {
			return err
		}
		s.Lock()
		defer s.Unlock()
		for i, c := range guild.Channels {
			if c.ID == channel.ID {
				guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
				break
			}
		}
	}
	delete(s.channelMap, channel.ID)
	return nil
}
func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) {
	return s.Channel(channelID)
}
func (s *State) PrivateChannel(channelID string) (*Channel, error) {
	return s.Channel(channelID)
}
func (s *State) Channel(channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}
	s.RLock()
	defer s.RUnlock()
	if c, ok := s.channelMap[channelID]; ok {
		return c, nil
	}
	return nil, ErrStateNotFound
}