diff --git a/discord/channel.py b/discord/channel.py
index a3ba99dc9..70b0b0b39 100644
--- a/discord/channel.py
+++ b/discord/channel.py
@@ -355,7 +355,8 @@ class TextChannel(abc.MessageChannel, CommonGuildChannel):
 
         Edits the channel.
 
-        You must have the Manage Channel permission to use this.
+        You must have the :attr:`Permissions.manage_channel` permission to
+        use this.
 
         Parameters
         ----------
@@ -446,7 +447,8 @@ class VoiceChannel(CommonGuildChannel):
 
         Edits the channel.
 
-        You must have the Manage Channel permission to use this.
+        You must have the :attr:`Permissions.manage_channel` permission to
+        use this.
 
         Parameters
         ----------
diff --git a/discord/emoji.py b/discord/emoji.py
index 9e90bff66..1f06c7e45 100644
--- a/discord/emoji.py
+++ b/discord/emoji.py
@@ -24,6 +24,8 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
 
+import asyncio
+
 from . import utils
 from .mixins import Hashable
 
@@ -107,3 +109,51 @@ class Emoji(Hashable):
     def url(self):
         """Returns a URL version of the emoji."""
         return "https://discordapp.com/api/emojis/{0.id}.png".format(self)
+
+
+    @asyncio.coroutine
+    def delete(self):
+        """|coro|
+
+        Deletes the custom emoji.
+
+        You must have :attr:`Permissions.manage_emojis` permission to
+        do this.
+
+        Guild local emotes can only be deleted by user bots.
+
+        Raises
+        -------
+        Forbidden
+            You are not allowed to delete emojis.
+        HTTPException
+            An error occurred deleting the emoji.
+        """
+
+        yield from self._state.http.delete_custom_emoji(self.guild.id, self.id)
+
+    @asyncio.coroutine
+    def edit(self, *, name):
+        """|coro|
+
+        Edits the custom emoji.
+
+        You must have :attr:`Permissions.manage_emojis` permission to
+        do this.
+
+        Guild local emotes can only be edited by user bots.
+
+        Parameters
+        -----------
+        name: str
+            The new emoji name.
+
+        Raises
+        -------
+        Forbidden
+            You are not allowed to edit emojis.
+        HTTPException
+            An error occurred editing the emoji.
+        """
+
+        yield from self._state.http.edit_custom_emoji(self.guild.id, self.id, name=name)
diff --git a/discord/guild.py b/discord/guild.py
index 6e37c3ab8..3ed07b200 100644
--- a/discord/guild.py
+++ b/discord/guild.py
@@ -680,3 +680,81 @@ class Guild(Hashable):
 
         # TODO: add to cache
         return role
+
+    @asyncio.coroutine
+    def kick(self, user):
+        """|coro|
+
+        Kicks a user from the guild.
+
+        The user must meet the :class:`abc.Snowflake` abc.
+
+        You must have :attr:`Permissions.kick_members` permissions to
+        do this.
+
+        Parameters
+        -----------
+        user: :class:`abc.Snowflake`
+            The user to kick from their guild.
+
+        Raises
+        -------
+        Forbidden
+            You do not have the proper permissions to kick.
+        HTTPException
+            Kicking failed.
+        """
+        yield from self._state.http.kick(user.id, self.id)
+
+    @asyncio.coroutine
+    def ban(self, user, *, delete_message_days=1):
+        """|coro|
+
+        Bans a user from the guild.
+
+        The user must meet the :class:`abc.Snowflake` abc.
+
+        You must have :attr:`Permissions.ban_members` permissions to
+        do this.
+
+        Parameters
+        -----------
+        user: :class:`abc.Snowflake`
+            The user to ban from their guild.
+        delete_message_days: int
+            The number of days worth of messages to delete from the user
+            in the guild. The minimum is 0 and the maximum is 7.
+
+        Raises
+        -------
+        Forbidden
+            You do not have the proper permissions to ban.
+        HTTPException
+            Banning failed.
+        """
+        yield from self._state.http.ban(user.id, self.id, delete_message_days)
+
+    @asyncio.coroutine
+    def unban(self, user):
+        """|coro|
+
+        Unbans a user from the guild.
+
+        The user must meet the :class:`abc.Snowflake` abc.
+
+        You must have :attr:`Permissions.ban_members` permissions to
+        do this.
+
+        Parameters
+        -----------
+        user: :class:`abc.Snowflake`
+            The user to unban.
+
+        Raises
+        -------
+        Forbidden
+            You do not have the proper permissions to unban.
+        HTTPException
+            Unbanning failed.
+        """
+        yield from self._state.http.unban(user.id, self.id)
diff --git a/discord/http.py b/discord/http.py
index 3b957a16e..ecb9cd9f8 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -383,6 +383,11 @@ class HTTPClient:
         bucket = 'members:{}'.format(guild_id)
         return self.patch(url, json=payload, bucket=bucket)
 
+    def edit_member(self, guild_id, user_id, **fields):
+        url = '{0.GUILDS}/{1}/members/{2}'.format(self, guild_id, user_id)
+        bucket = 'members:%s' % guild_id
+        return self.patch(url, json=fields, bucket=bucket)
+
     # Channel management
 
     def edit_channel(self, channel_id, **options):
diff --git a/discord/member.py b/discord/member.py
index f9c5fa669..5584d0bc8 100644
--- a/discord/member.py
+++ b/discord/member.py
@@ -24,6 +24,8 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
 
+import asyncio
+
 from .user import User
 from .game import Game
 from .permissions import Permissions
@@ -161,16 +163,19 @@ class Member:
     def __hash__(self):
         return hash(self._user.id)
 
-    def _update(self, data, user):
-        self._user.name = user['username']
-        self._user.discriminator = user['discriminator']
-        self._user.avatar = user['avatar']
-        self._user.bot = user.get('bot', False)
+    def _update(self, data, user=None):
+        if user:
+            self._user.name = user['username']
+            self._user.discriminator = user['discriminator']
+            self._user.avatar = user['avatar']
+            self._user.bot = user.get('bot', False)
 
         # the nickname change is optional,
         # if it isn't in the payload then it didn't change
-        if 'nick' in data:
+        try:
             self.nick = data['nick']
+        except KeyError:
+            pass
 
         # update the roles
         self.roles = [self.guild.default_role]
@@ -283,3 +288,187 @@ class Member:
     def voice(self):
         """Optional[:class:`VoiceState`]: Returns the member's current voice state."""
         return self.guild._voice_state_for(self._user.id)
+
+    @asyncio.coroutine
+    def ban(self):
+        """|coro|
+
+        Bans this member. Equivalent to :meth:`Guild.ban`
+        """
+        yield from self.guild.ban(self)
+
+    @asyncio.coroutine
+    def unban(self):
+        """|coro|
+
+        Unbans this member. Equivalent to :meth:`Guild.unban`
+        """
+        yield from self.guild.unban(self)
+
+    @asyncio.coroutine
+    def kick(self):
+        """|coro|
+
+        Kicks this member. Equivalent to :meth:`Guild.kick`
+        """
+        yield from self.guild.kick(self)
+
+    @asyncio.coroutine
+    def edit(self, **fields):
+        """|coro|
+
+        Edits the member's data.
+
+        Depending on the parameter passed, this requires different permissions listed below:
+
+        +---------------+--------------------------------------+
+        |   Parameter   |              Permission              |
+        +---------------+--------------------------------------+
+        | nick          | :attr:`Permissions.manage_nicknames` |
+        +---------------+--------------------------------------+
+        | mute          | :attr:`Permissions.mute_members`     |
+        +---------------+--------------------------------------+
+        | deafen        | :attr:`Permissions.deafen_members`   |
+        +---------------+--------------------------------------+
+        | roles         | :attr:`Permissions.manage_roles`     |
+        +---------------+--------------------------------------+
+        | voice_channel | :attr:`Permissions.move_members`     |
+        +---------------+--------------------------------------+
+
+        All parameters are optional.
+
+        Parameters
+        -----------
+        nick: str
+            The member's new nickname. Use ``None`` to remove the nickname.
+        mute: bool
+            Indicates if the member should be guild muted or un-muted.
+        deafen: bool
+            Indicates if the member should be guild deafened or un-deafened.
+        roles: List[:class:`Roles`]
+            The member's new list of roles. This *replaces* the roles.
+        voice_channel: :class:`VoiceChannel`
+            The voice channel to move the member to.
+
+        Raises
+        -------
+        Forbidden
+            You do not have the proper permissions to the action requested.
+        HTTPException
+            The operation failed.
+        """
+        http = self._state.http
+        guild_id = self.guild.id
+        payload = {}
+
+        try:
+            nick = fields['nick']
+        except KeyError:
+            # nick not present so...
+            pass
+        else:
+            nick = nick if nick else ''
+            if self._state.self_id == self.id:
+                yield from http.change_my_nickname(guild_id, nick)
+            else:
+                payload['nick'] = nick
+
+        deafen = fields.get('deafen')
+        if deafen is not None:
+            payload['deaf'] = deafen
+
+        mute = fields.get('mute')
+        if mute is not None:
+            payload['mute'] = mute
+
+        try:
+            vc = fields['voice_channel']
+        except KeyError:
+            pass
+        else:
+            payload['channel_id'] = vc.id
+
+        try:
+            roles = fields['roles']
+        except KeyError:
+            pass
+        else:
+            payload['roles'] = tuple(r.id for r in roles)
+
+        yield from http.edit_member(guild_id, self.id, **payload)
+
+        # TODO: wait for WS event for modify-in-place behaviour
+
+    @asyncio.coroutine
+    def move_to(self, channel):
+        """|coro|
+
+        Moves a member to a new voice channel (they must be connected first).
+
+        You must have the :attr:`Permissions.move_members` permission to
+        use this.
+
+        This raises the same exceptions as :meth:`edit`.
+
+        Parameters
+        -----------
+        channel: :class:`VoiceChannel`
+            The new voice channel to move the member to.
+        """
+        yield from self.edit(voice_channel=channel)
+
+    @asyncio.coroutine
+    def add_roles(self, *roles):
+        """|coro|
+
+        Gives the member a number of :class:`Role`\s.
+
+        You must have the :attr:`Permissions.manage_roles` permission to
+        use this.
+
+        Parameters
+        -----------
+        \*roles
+            An argument list of :class:`Role`\s to give the member.
+
+        Raises
+        -------
+        Forbidden
+            You do not have permissions to add these roles.
+        HTTPException
+            Adding roles failed.
+        """
+
+        new_roles = utils._unique(r for s in (self.roles[1:], roles) for r in s)
+        yield from self.edit(roles=new_roles)
+
+    @asyncio.coroutine
+    def remove_roles(self, *roles):
+        """|coro|
+
+        Removes :class:`Role`\s from this member.
+
+        You must have the :attr:`Permissions.manage_roles` permission to
+        use this.
+
+        Parameters
+        -----------
+        \*roles
+            An argument list of :class:`Role`\s to remove from the member.
+
+        Raises
+        -------
+        Forbidden
+            You do not have permissions to remove these roles.
+        HTTPException
+            Removing the roles failed.
+        """
+
+        new_roles = self.roles[1:] # remove @everyone
+        for role in roles:
+            try:
+                new_roles.remove(role)
+            except ValueError:
+                pass
+
+        yield from self.edit(roles=new_roles)
diff --git a/discord/state.py b/discord/state.py
index 0cf0e9559..e6e551fd4 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -47,7 +47,7 @@ class ListenerType(enum.Enum):
     chunk = 0
 
 Listener = namedtuple('Listener', ('type', 'future', 'predicate'))
-StateContext = namedtuple('StateContext', 'try_insert_user http')
+StateContext = namedtuple('StateContext', 'try_insert_user http self_id')
 log = logging.getLogger(__name__)
 ReadyState = namedtuple('ReadyState', ('launch', 'guilds'))
 
@@ -60,7 +60,7 @@ class ConnectionState:
         self.syncer = syncer
         self.is_bot = None
         self._listeners = []
-        self.ctx = StateContext(try_insert_user=self.try_insert_user, http=http)
+        self.ctx = StateContext(try_insert_user=self.try_insert_user, http=http, self_id=None)
         self.clear()
 
     def clear(self):
@@ -220,6 +220,7 @@ class ConnectionState:
     def parse_ready(self, data):
         self._ready_state = ReadyState(launch=asyncio.Event(), guilds=[])
         self.user = self.try_insert_user(data['user'])
+        self.ctx.self_id = self.user.id
         guilds = data.get('guilds')
 
         guilds = self._ready_state.guilds