diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index c8d0a0a0f7..d39ebd6c0a 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -149,19 +149,32 @@ function textForRoomAliasesEvent(ev) {
     if (addedAliases.length && !removedAliases.length) {
         return _t('%(senderName)s added %(addedAddresses)s as addresses for this room.', {
             senderName: senderName,
+            count: addedAliases.length,
             addedAddresses: addedAliases.join(', '),
         });
     } else if (!addedAliases.length && removedAliases.length) {
-        return _t('%(senderName)s removed %(addresses)s as addresses for this room.', {
+        return _t('%(senderName)s removed %(removedAddresses)s as addresses for this room.', {
             senderName: senderName,
+            count: removedAliases.length,
             removedAddresses: removedAliases.join(', '),
         });
     } else {
-        return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.', {
+        const args = {
             senderName: senderName,
             addedAddresses: addedAliases.join(', '),
             removedAddresses: removedAliases.join(', '),
-        });
+        };
+        /* eslint-disable max-len */
+        if (addedAliases.length === 1 && removedAliases.length === 1) {
+            return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|one,one', args);
+        } else if (addedAliases.length !== 1 && removedAliases.length === 1) {
+            return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|other,one', args);
+        } else if (addedAliases.length === 1 && removedAliases.length !== 1) {
+            return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|one,other', args);
+        } else {
+            return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|other,other', args);
+        }
+        /* eslint-enable max-len */
     }
 }
 
diff --git a/src/components/views/messages/RoomAliasesEvent.js b/src/components/views/messages/RoomAliasesEvent.js
new file mode 100644
index 0000000000..7d9b2e6795
--- /dev/null
+++ b/src/components/views/messages/RoomAliasesEvent.js
@@ -0,0 +1,161 @@
+/*
+Michael Telatynski <7t3chguy@gmail.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import { _t } from '../../../languageHandler';
+
+export class GenericEventListSummary extends React.Component {
+    static propTypes = {
+        // An summary to display when collapsed
+        summary: PropTypes.string.isRequired,
+        // whether to show summary whilst children are expanded
+        alwaysShowSummary: PropTypes.bool,
+        // An array of EventTiles to render when expanded
+        children: PropTypes.array.isRequired,
+        // Called when the GELS expansion is toggled
+        onToggle: PropTypes.func,
+        // how many children should cause GELS to act
+        threshold: PropTypes.number.isRequired,
+    };
+
+    static defaultProps = {
+        threshold: 1,
+    };
+
+    constructor(props, context) {
+        super(props, context);
+        this._toggleSummary = this._toggleSummary.bind(this);
+    }
+
+    state = {
+        expanded: false,
+    };
+
+    _toggleSummary() {
+        this.setState({expanded: !this.state.expanded});
+        this.props.onToggle();
+    }
+
+    render() {
+        const fewEvents = this.props.children.length < this.props.threshold;
+        const expanded = this.state.expanded || fewEvents;
+        const showSummary = !expanded || this.props.alwaysShowSummary;
+
+        let expandedEvents = null;
+        if (expanded) {
+            expandedEvents = this.props.children;
+        }
+
+        if (fewEvents) {
+            return <div className="mx_MemberEventListSummary">{ expandedEvents }</div>;
+        }
+
+        let summaryContainer = null;
+        if (showSummary) {
+            summaryContainer = (
+                <div className="mx_EventTile_line">
+                    <div className="mx_EventTile_info">
+                        {this.props.summary}
+                    </div>
+                </div>
+            );
+        }
+        let toggleButton = null;
+        if (!fewEvents) {
+            toggleButton = <div className={"mx_MemberEventListSummary_toggle"} onClick={this._toggleSummary}>
+                {expanded ? 'collapse' : 'expand'}
+            </div>;
+        }
+
+        return (
+            <div className="mx_MemberEventListSummary">
+                {toggleButton}
+                {summaryContainer}
+                {/*{showSummary ? <div className="mx_MemberEventListSummary_line">&nbsp;</div> : null}*/}
+                {expandedEvents}
+            </div>
+        );
+    }
+}
+
+export default class RoomAliasesEvent extends React.Component {
+    static PropTypes = {
+        /* the MatrixEvent to show */
+        mxEvent: PropTypes.object.isRequired,
+
+        /* the shsape of the tile, used */
+        tileShape: PropTypes.string,
+    };
+
+    getEventTileOps() {
+        return this.refs.body && this.refs.body.getEventTileOps ? this.refs.body.getEventTileOps() : null;
+    }
+
+    render() {
+        const senderName = this.props.mxEvent.sender ? this.props.mxEvent.sender.name : this.props.mxEvent.getSender();
+        const oldAliases = this.props.mxEvent.getPrevContent().aliases || [];
+        const newAliases = this.props.mxEvent.getContent().aliases || [];
+
+        const addedAliases = newAliases.filter((x) => !oldAliases.includes(x));
+        const removedAliases = oldAliases.filter((x) => !newAliases.includes(x));
+
+        if (!addedAliases.length && !removedAliases.length) {
+            return '';
+        }
+
+        if (addedAliases.length && !removedAliases.length) {
+            return <div>{_t('%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.', {
+                senderName: senderName,
+                count: addedAliases.length,
+                addedAddresses: addedAliases.join(', '),
+            })}</div>;
+        } else if (!addedAliases.length && removedAliases.length) {
+            return <div>{_t('%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.', {
+                senderName: senderName,
+                count: removedAliases.length,
+                removedAddresses: removedAliases.join(', '),
+            })}</div>;
+        } else {
+            // const args = {
+            //     senderName: senderName,
+            //     addedAddresses: addedAliases.join(', '),
+            //     removedAddresses: removedAliases.join(', '),
+            // };
+
+            const changes = [];
+            addedAliases.forEach((alias) => {
+                changes.push(<div key={'+' + alias}>Added {alias}</div>);
+            });
+            removedAliases.forEach((alias) => {
+                changes.push(<div key={'-' + alias}>Removed {alias}</div>);
+            });
+
+            const summary = _t('%(senderName)s changed the addresses of this room.', {senderName});
+            return <GenericEventListSummary alwaysShowSummary={true} summary={summary}>
+                {changes}
+            </GenericEventListSummary>;
+        }
+
+        // return <BodyType ref="body" mxEvent={this.props.mxEvent} highlights={this.props.highlights}
+        //             highlightLink={this.props.highlightLink}
+        //             showUrlPreview={this.props.showUrlPreview}
+        //             tileShape={this.props.tileShape}
+        //             onWidgetLoad={this.props.onWidgetLoad} />;
+    }
+}
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index 647b8a0f5d..10f0b85936 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -33,7 +33,7 @@ var ObjectUtils = require('../../../ObjectUtils');
 
 var eventTileTypes = {
     'm.room.message': 'messages.MessageEvent',
-    'm.room.aliases': 'messages.TextualEvent',
+    'm.room.aliases': 'messages.RoomAliasesEvent',
     'm.room.member' : 'messages.TextualEvent',
     'm.call.invite' : 'messages.TextualEvent',
     'm.call.answer' : 'messages.TextualEvent',
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index de0b8e9ebb..5ee29b6314 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -853,5 +853,10 @@
     "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
     "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
     "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
-    "Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>"
+    "Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s added %(addedAddresses)s as an address for this room.",
+    "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s added %(addedAddresses)s as addresses for this room.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s removed %(removedAddresses)s as an address for this room.",
+    "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s removed %(removedAddresses)s as addresses for this room.",
+    "%(senderName)s changed the addresses of this room.": "%(senderName)s changed the addresses of this room."
 }