[gnome-maps/wip/mlundblad/es6] WIP: Use ES6 classes with GObject extensions



commit 7d4191819ff1bfc69cfbfb14c6d8db81e0acbb52
Author: Marcus Lundblad <ml update uu se>
Date:   Mon Nov 20 21:27:49 2017 +0100

    WIP: Use ES6 classes with GObject extensions

 src/accountListBox.js              |   26 ++---
 src/application.js                 |   88 ++++++++--------
 src/busyMarker.js                  |    8 +-
 src/checkIn.js                     |   55 +++++------
 src/checkInDialog.js               |   58 +++++------
 src/contactPlace.js                |   16 ++--
 src/contextMenu.js                 |   48 ++++-----
 src/exportViewDialog.js            |   40 ++++----
 src/facebookBackend.js             |   52 +++++-----
 src/favoritesPopover.js            |   20 ++--
 src/foursquareBackend.js           |   51 +++++-----
 src/foursquareGoaAuthorizer.js     |   29 +++---
 src/geoJSONShapeLayer.js           |   24 +++--
 src/geoJSONSource.js               |   78 +++++++-------
 src/geoJSONStyle.js                |   13 +--
 src/geoclue.js                     |   26 ++---
 src/geocodeService.js              |   15 +--
 src/gpxShapeLayer.js               |   18 ++--
 src/graphHopper.js                 |   48 ++++-----
 src/http.js                        |   16 ++--
 src/instructionRow.js              |   13 +--
 src/kmlShapeLayer.js               |   19 ++--
 src/layersPopover.js               |   36 +++----
 src/location.js                    |   17 ++--
 src/locationServiceNotification.js |   11 +-
 src/longPrintLayout.js             |   17 ++--
 src/mainWindow.js                  |  129 ++++++++++++------------
 src/mapBubble.js                   |   37 +++----
 src/mapMarker.js                   |   94 ++++++++---------
 src/mapSource.js                   |   17 ++--
 src/mapView.js                     |  138 ++++++++++++-------------
 src/mapWalker.js                   |   37 ++++---
 src/notification.js                |   34 +++----
 src/notificationManager.js         |   20 ++--
 src/openTripPlanner.js             |  197 +++++++++++++++++------------------
 src/osmAccountDialog.js            |   54 +++++-----
 src/osmConnection.js               |  124 +++++++++++------------
 src/osmEdit.js                     |   90 ++++++++---------
 src/osmEditDialog.js               |  112 ++++++++++----------
 src/osmTypeListRow.js              |   19 ++--
 src/osmTypePopover.js              |   20 ++--
 src/osmTypeSearchEntry.js          |   19 ++--
 src/osmTypes.js                    |   23 ++---
 src/overpass.js                    |   36 +++----
 src/place.js                       |   79 +++++++-------
 src/placeBubble.js                 |   59 +++++------
 src/placeEntry.js                  |   41 ++++----
 src/placeFormatter.js              |   26 ++---
 src/placeListRow.js                |   15 ++--
 src/placeMarker.js                 |   17 ++--
 src/placePopover.js                |   50 +++++-----
 src/placeStore.js                  |   74 +++++++-------
 src/printLayout.js                 |   60 +++++------
 src/printOperation.js              |   28 +++---
 src/route.js                       |   47 +++++----
 src/routeEntry.js                  |   20 ++--
 src/routeQuery.js                  |   80 +++++++--------
 src/routingDelegator.js            |   34 +++----
 src/searchPopover.js               |   16 ++--
 src/sendToDialog.js                |   33 +++---
 src/serviceBackend.js              |   44 ++++----
 src/settings.js                    |   24 ++---
 src/shapeLayer.js                  |   38 ++++----
 src/shortPrintLayout.js            |   18 ++--
 src/sidebar.js                     |  118 +++++++++++-----------
 src/socialPlace.js                 |   14 +--
 src/socialPlaceListBox.js          |   46 ++++-----
 src/storedRoute.js                 |   27 +++---
 src/transitArrivalMarker.js        |   14 +--
 src/transitArrivalRow.js           |   18 ++--
 src/transitBoardMarker.js          |   18 ++--
 src/transitItineraryRow.js         |   28 +++---
 src/transitLegRow.js               |   34 +++----
 src/transitMoreRow.js              |   18 ++--
 src/transitOptions.js              |   19 ++--
 src/transitOptionsPanel.js         |   53 +++++-----
 src/transitPlan.js                 |  198 +++++++++++++++++-------------------
 src/transitPrintLayout.js          |   56 +++++-----
 src/transitRouteLabel.js           |   20 ++--
 src/transitStopRow.js              |   14 +--
 src/transitWalkMarker.js           |   14 +--
 src/turnPointMarker.js             |   25 ++---
 src/userLocationBubble.js          |   11 +-
 src/userLocationMarker.js          |   38 ++++----
 src/zoomInNotification.js          |   15 ++--
 85 files changed, 1739 insertions(+), 1904 deletions(-)
---
diff --git a/src/accountListBox.js b/src/accountListBox.js
index e45a21e..e829535 100644
--- a/src/accountListBox.js
+++ b/src/accountListBox.js
@@ -21,25 +21,23 @@
 
 const Gio = imports.gi.Gio;
 const Goa = imports.gi.Goa;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Application = imports.application;
 
-var AccountRow = new Lang.Class({
-    Name: 'AccountRow',
-    Extends: Gtk.ListBoxRow,
+var AccountRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/account-row.ui',
     InternalChildren: [ 'providerLabel',
                         'identityLabel',
                         'providerImage',
                         'attentionNeededImage' ],
-
-    _init: function(params) {
+}, class AccountRow extends Gtk.ListBoxRow {
+    _init(params) {
         this.account = params.account;
         delete params.account;
 
-        this.parent(params);
+        super._init(params);
 
         let account = this.account.get_account();
 
@@ -50,16 +48,14 @@ var AccountRow = new Lang.Class({
     }
 });
 
-var AccountListBox = new Lang.Class({
-    Name: 'AccountListBox',
-    Extends: Gtk.ListBox,
+var AccountListBox = GObject.registerClass({
     Signals: {
         'account-selected': { param_types: [Goa.Object] }
     },
-
-    _init: function(params) {
+}, class AccountListBox extends Gtk.ListBox {
+    _init(params) {
         params.activate_on_single_click = true;
-        this.parent(params);
+        super._init(params);
 
         Application.checkInManager.connect('accounts-refreshed', () => { this.refresh(); });
 
@@ -67,9 +63,9 @@ var AccountListBox = new Lang.Class({
                      (list, row) => { this.emit('account-selected', row.account); });
 
         this.refresh();
-    },
+    }
 
-    refresh: function() {
+    refresh() {
         let accounts = Application.checkInManager.accounts;
 
         this.forall(function(row) {
diff --git a/src/application.js b/src/application.js
index c155ba3..6e2fb9f 100644
--- a/src/application.js
+++ b/src/application.js
@@ -25,7 +25,6 @@ const GObject = imports.gi.GObject;
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
 const GtkClutter = imports.gi.GtkClutter;
-const Lang = imports.lang;
 const WebKit2 = imports.gi.WebKit2;
 
 const CheckIn = imports.checkIn;
@@ -62,9 +61,7 @@ var routeQuery = null;
 const _ensuredTypes = [WebKit2.WebView,
                        OSMTypeSearchEntry.OSMTypeSearchEntry];
 
-var Application = new Lang.Class({
-    Name: 'Application',
-    Extends: Gtk.Application,
+var Application = GObject.registerClass({
     Properties: {
         'connected': GObject.ParamSpec.boolean('connected',
                                                '',
@@ -72,24 +69,25 @@ var Application = new Lang.Class({
                                                GObject.ParamFlags.READABLE |
                                                GObject.ParamFlags.WRITABLE)
     },
+}, class Application extends Gtk.Application {
 
     set connected(p) {
         this._connected = p;
         this.notify('connected');
-    },
+    }
 
     get connected() {
         return this._connected;
-    },
+    }
 
-    _init: function() {
+    _init() {
         /* Translators: This is the program name. */
         GLib.set_application_name(_("Maps"));
 
         /* Needed to be able to use in UI files */
         _ensuredTypes.forEach((type) => { GObject.type_ensure(type); });
 
-        this.parent({ application_id: 'org.gnome.Maps',
+        super._init({ application_id: 'org.gnome.Maps',
                       flags: Gio.ApplicationFlags.HANDLES_OPEN });
         this._connected = false;
 
@@ -118,13 +116,13 @@ var Application = new Lang.Class({
 
             return -1;
         });
-    },
+    }
 
-    _checkNetwork: function() {
+    _checkNetwork() {
         this.connected = networkMonitor.connectivity === Gio.NetworkConnectivity.FULL;
-    },
+    }
 
-    _showContact: function(id) {
+    _showContact(id) {
         contactStore.lookup(id, (contact) => {
             this._mainWindow.markBusy();
             if (!contact) {
@@ -136,9 +134,9 @@ var Application = new Lang.Class({
                 this._mainWindow.mapView.showContact(contact);
             });
         });
-    },
+    }
 
-    _onShowContactActivate: function(action, parameter) {
+    _onShowContactActivate(action, parameter) {
         this._createWindow();
         this._checkNetwork();
         this._mainWindow.present();
@@ -153,20 +151,20 @@ var Application = new Lang.Class({
                     this._showContact(id);
             });
         }
-    },
+    }
 
-    _onQuitActivate: function() {
+    _onQuitActivate() {
         this._mainWindow.destroy();
-    },
+    }
 
-    _onOsmAccountSetupActivate: function() {
+    _onOsmAccountSetupActivate() {
         let dialog = osmEdit.createAccountDialog(this._mainWindow, false);
 
         dialog.show();
         dialog.connect('response', () => { dialog.destroy(); });
-    },
+    }
 
-    _addContacts: function() {
+    _addContacts() {
         contactStore.get_contacts().forEach((contact) => {
             contact.geocode(function() {
                 contact.get_places().forEach((p) => {
@@ -180,9 +178,9 @@ var Application = new Lang.Class({
                 });
             });
         });
-    },
+    }
 
-    _initPlaceStore: function() {
+    _initPlaceStore() {
         placeStore = new PlaceStore.PlaceStore({
             recentPlacesLimit: settings.get('recent-places-limit'),
             recentRoutesLimit: settings.get('recent-routes-limit')
@@ -202,18 +200,18 @@ var Application = new Lang.Class({
                     this._addContacts();
             });
         }
-    },
+    }
 
-    _initAppMenu: function() {
+    _initAppMenu() {
         let builder = new Gtk.Builder();
         builder.add_from_resource('/org/gnome/Maps/ui/app-menu.ui');
 
         let menu = builder.get_object('app-menu');
         this.set_app_menu(menu);
-    },
+    }
 
-    vfunc_startup: function() {
-        this.parent();
+    vfunc_startup() {
+        super.vfunc_startup();
 
         GtkClutter.init(null);
 
@@ -237,9 +235,9 @@ var Application = new Lang.Class({
                                                                              'icons']));
         this._initPlaceStore();
         this._initAppMenu();
-    },
+    }
 
-    _initServices: function() {
+    _initServices() {
         settings         = Settings.getSettings('org.gnome.Maps');
         routeQuery       = new RouteQuery.RouteQuery();
         routingDelegator = new RoutingDelegator.RoutingDelegator({ query: routeQuery });
@@ -252,9 +250,9 @@ var Application = new Lang.Class({
         contactStore = new Maps.ContactStore();
         contactStore.load();
         osmEdit = new OSMEdit.OSMEdit();
-    },
+    }
 
-    _createWindow: function() {
+    _createWindow() {
         if (this._mainWindow)
             return;
 
@@ -268,24 +266,24 @@ var Application = new Lang.Class({
                 log('* focus widget: %s'.format(widget));
             });
         }
-    },
+    }
 
-    vfunc_dbus_register: function(connection, path) {
-        this.parent(connection, path);
+    vfunc_dbus_register(connection, path) {
+        super.vfunc_dbus_register(connection, path);
         return true;
-    },
+    }
 
-    vfunc_dbus_unregister: function(connection, path) {
-        this.parent(connection, path);
-    },
+    vfunc_dbus_unregister(connection, path) {
+        super.vfunc_dbus_register(connection, path);
+    }
 
-    vfunc_activate: function() {
+    vfunc_activate() {
         this._createWindow();
         this._checkNetwork();
         this._mainWindow.present();
-    },
+    }
 
-    _openInternal: function(files) {
+    _openInternal(files) {
         if (!this._mainWindow || !this._mainWindow.mapView.view.realized)
             return;
 
@@ -298,9 +296,9 @@ var Application = new Lang.Class({
         } else {
             this._mainWindow.mapView.openShapeLayers(files);
         }
-    },
+    }
 
-    vfunc_open: function(files) {
+    vfunc_open(files) {
         normalStartup = false;
         this.activate();
 
@@ -310,9 +308,9 @@ var Application = new Lang.Class({
         else
             mapView.view.connect('notify::realized',
                                  this._openInternal.bind(this, files));
-    },
+    }
 
-    _onWindowDestroy: function(window) {
+    _onWindowDestroy(window) {
         this._mainWindow = null;
     }
 });
diff --git a/src/busyMarker.js b/src/busyMarker.js
index b53962d..3f99c3d 100644
--- a/src/busyMarker.js
+++ b/src/busyMarker.js
@@ -18,10 +18,8 @@
  */
 
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
-var BusyMarker = new Lang.Class({
-    Name: 'BusyMarker',
-    Extends: Gtk.Frame,
+var BusyMarker = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/busy-marker.ui'
-});
+}, class BusyMarker extends Gtk.Frame {});
diff --git a/src/checkIn.js b/src/checkIn.js
index d75d492..e314da7 100644
--- a/src/checkIn.js
+++ b/src/checkIn.js
@@ -22,15 +22,12 @@
 const GObject = imports.gi.GObject;
 const Goa = imports.gi.Goa;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const CheckInDialog = imports.checkInDialog;
 const FacebookBackend = imports.facebookBackend;
 const FoursquareBackend = imports.foursquareBackend;
 
-var CheckInManager = new Lang.Class({
-    Name: 'CheckInManager',
-    Extends: GObject.Object,
+var CheckInManager = GObject.registerClass({
     Signals: {
         'accounts-refreshed': { }
     },
@@ -39,10 +36,10 @@ var CheckInManager = new Lang.Class({
                                                 '',
                                                 '',
                                                 GObject.ParamFlags.READABLE)
-    },
-
-    _init: function() {
-        this.parent();
+    }
+}, class CheckInManager extends GObject.Object {
+    _init() {
+        super._init();
 
         try {
             this._goaClient = Goa.Client.new_sync(null);
@@ -66,17 +63,17 @@ var CheckInManager = new Lang.Class({
         }
 
         this._refreshGoaAccounts();
-    },
+    }
 
-    _initBackends: function() {
+    _initBackends() {
         let facebookBackend = new FacebookBackend.FacebookBackend();
         this._backends[facebookBackend.name] = facebookBackend;
 
         let foursquareBackend = new FoursquareBackend.FoursquareBackend();
         this._backends[foursquareBackend.name] = foursquareBackend;
-    },
+    }
 
-    _refreshGoaAccounts: function() {
+    _refreshGoaAccounts() {
         if (!this._goaClient)
             return;
         let accounts = this._goaClient.get_accounts();
@@ -99,39 +96,39 @@ var CheckInManager = new Lang.Class({
 
         this.emit('accounts-refreshed');
         this.notify('hasCheckIn');
-    },
+    }
 
     get client() {
         return this._goaClient;
-    },
+    }
 
     get accounts() {
         return this._accounts;
-    },
+    }
 
     get hasCheckIn() {
         return this._accounts.length > 0;
-    },
+    }
 
-    _getAuthorizer: function(account) {
+    _getAuthorizer(account) {
         return this._authorizers[account.get_account().id];
-    },
+    }
 
-    _getBackend: function(account) {
+    _getBackend(account) {
         return this._backends[account.get_account().provider_type];
-    },
+    }
 
-    performCheckIn: function(account, checkIn, callback, cancellable) {
+    performCheckIn(account, checkIn, callback, cancellable) {
         this._getBackend(account)
             .performCheckIn(this._getAuthorizer(account), checkIn, callback, cancellable);
-    },
+    }
 
-    findPlaces: function(account, latitude, longitude, distance, callback, cancellable) {
+    findPlaces(account, latitude, longitude, distance, callback, cancellable) {
         this._getBackend(account)
             .findPlaces(this._getAuthorizer(account), latitude, longitude, distance, callback, cancellable);
-    },
+    }
 
-    showCheckInDialog: function(parentWindow, place, matchPlace) {
+    showCheckInDialog(parentWindow, place, matchPlace) {
         let dialog = new CheckInDialog.CheckInDialog({ transient_for: parentWindow,
                                                        matchPlace: matchPlace,
                                                        place: place });
@@ -170,14 +167,12 @@ var CheckInManager = new Lang.Class({
     }
 });
 
-var CheckIn = new Lang.Class({
-    Name: 'CheckIn',
-
-    _init: function() {
+var CheckIn = class {
+    _init() {
         this.message = null;
         this.place = null;
         this.privacy = null;
         this.broadcastFacebook = false;
         this.broadcastTwitter = false;
     }
-});
+};
diff --git a/src/checkInDialog.js b/src/checkInDialog.js
index 66dd6e9..371465b 100644
--- a/src/checkInDialog.js
+++ b/src/checkInDialog.js
@@ -20,8 +20,8 @@
  */
 
 const Gio = imports.gi.Gio;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const AccountListBox = imports.accountListBox;
@@ -39,9 +39,7 @@ var Response = {
     FAILURE_CHECKIN_DISABLED: 5
 };
 
-var CheckInDialog = new Lang.Class({
-    Name: 'CheckInDialog',
-    Extends: Gtk.Dialog,
+var CheckInDialog = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/check-in-dialog.ui',
     InternalChildren: [ 'cancelButton',
                         'okButton',
@@ -59,8 +57,8 @@ var CheckInDialog = new Lang.Class({
                         'foursquareOptionsPrivacyComboBox',
                         'foursquareOptionsBroadcastFacebookCheckButton',
                         'foursquareOptionsBroadcastTwitterCheckButton' ],
-
-    _init: function(params) {
+}, class CheckInDialog extends Gtk.Dialog {
+    _init(params) {
         this._place = params.place;
         delete params.place;
 
@@ -70,7 +68,7 @@ var CheckInDialog = new Lang.Class({
         // This is a construct-only property and cannot be set by GtkBuilder
         params.use_header_bar = true;
 
-        this.parent(params);
+        super._init(params);
 
         this._account = null;
         this._checkIn = new CheckIn.CheckIn();
@@ -86,16 +84,16 @@ var CheckInDialog = new Lang.Class({
 
         this._initHeaderBar();
         this._initWidgets();
-    },
+    }
 
-    _initHeaderBar: function() {
+    _initHeaderBar() {
         this._cancelButton.connect('clicked',
                                    () => { this._cancellable.cancel(); });
 
         this._okButton.connect('clicked', () => { this._startCheckInStep(); });
-    },
+    }
 
-    _initWidgets: function() {
+    _initWidgets() {
         // Limitations in Gjs means we can't do this in UI files yet
         this._accountListBox = new AccountListBox.AccountListBox({ visible: true });
         this._accountFrame.add(this._accountListBox);
@@ -128,14 +126,14 @@ var CheckInDialog = new Lang.Class({
             this._checkIn.place = place;
             this._startMessageStep();
         });
-    },
+    }
 
-    vfunc_show: function() {
+    vfunc_show() {
         this._startup();
-        this.parent();
-    },
+        super.vfunc_show();
+    }
 
-    _startup: function() {
+    _startup() {
         let accounts = Application.checkInManager.accounts;
 
         if (accounts.length > 1)
@@ -148,9 +146,9 @@ var CheckInDialog = new Lang.Class({
                 this.response(Response.FAILURE_CHECKIN_DISABLED);
             });
         }
-    },
+    }
 
-    _onAccountRefreshed: function() {
+    _onAccountRefreshed() {
         let accounts = Application.checkInManager.accounts;
 
         if (!Application.checkInManager.hasCheckIn)
@@ -163,14 +161,14 @@ var CheckInDialog = new Lang.Class({
 
             this.response(Response.FAILURE_ACCOUNT_DISABLED);
         }
-    },
+    }
 
-    _startAccountStep: function() {
+    _startAccountStep() {
         this.set_title(_("Select an account"));
         this._stack.set_visible_child_name('account');
-    },
+    }
 
-    _startPlaceStep: function() {
+    _startPlaceStep() {
         this.set_title(_("Loading"));
         this._stack.set_visible_child_name('loading');
 
@@ -180,9 +178,9 @@ var CheckInDialog = new Lang.Class({
                                               100,
                                               this._onFindPlacesFinished.bind(this),
                                               this._cancellable);
-    },
+    }
 
-    _onFindPlacesFinished: function(account, places, error) {
+    _onFindPlacesFinished(account, places, error) {
         if (!error) {
             if (places.length === 0) {
                 this.response(Response.FAILURE_NO_PLACES);
@@ -212,9 +210,9 @@ var CheckInDialog = new Lang.Class({
             this.error = error;
             this.response(Response.FAILURE_GET_PLACES);
         }
-    },
+    }
 
-    _startMessageStep: function() {
+    _startMessageStep() {
         /* Translators: %s is the name of the place to check in.
          */
         this.set_title(_("Check in to %s").format(this._checkIn.place.name));
@@ -240,9 +238,9 @@ var CheckInDialog = new Lang.Class({
                 optionsGrids[provider].show();
             else
                 optionsGrids[provider].hide();
-    },
+    }
 
-    _startCheckInStep: function() {
+    _startCheckInStep() {
         this.set_title(_("Loading"));
         this._stack.set_visible_child_name('loading');
 
@@ -268,9 +266,9 @@ var CheckInDialog = new Lang.Class({
                                                   this._checkIn,
                                                   this._onPerformCheckInFinished.bind(this),
                                                   this._cancellable);
-    },
+    }
 
-    _onPerformCheckInFinished: function (account, data, error) {
+    _onPerformCheckInFinished(account, data, error) {
         if (!error)
             this.response(Response.SUCCESS);
         else {
diff --git a/src/contactPlace.js b/src/contactPlace.js
index b2d8876..6c036c2 100644
--- a/src/contactPlace.js
+++ b/src/contactPlace.js
@@ -19,25 +19,23 @@
  * Author: Jonas Danielsson <jonas threetimestwo org>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Place = imports.place;
 
-var ContactPlace = new Lang.Class({
-    Name: 'ContactPlace',
-    Extends: Place.Place,
-
-    _init: function(params) {
+var ContactPlace = GObject.registerClass(
+class ContactPlace extends Place.Place {
+    _init(params) {
         this._contact = params.contact;
         delete params.contact;
 
         params.store = false;
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
     get icon() {
         return this._contact.icon;
-    },
+    }
 
     get uniqueID() {
         return [this.name,
diff --git a/src/contextMenu.js b/src/contextMenu.js
index c80b42b..d604991 100644
--- a/src/contextMenu.js
+++ b/src/contextMenu.js
@@ -22,12 +22,12 @@
 const Champlain = imports.gi.Champlain;
 const Gdk = imports.gi.Gdk;
 const Geocode = imports.gi.GeocodeGlib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
 const ExportViewDialog = imports.exportViewDialog;
-const Lang = imports.lang;
 const Location = imports.location;
 const OSMAccountDialog = imports.osmAccountDialog;
 const OSMEdit = imports.osmEdit;
@@ -36,24 +36,22 @@ const Place = imports.place;
 const Utils = imports.utils;
 const ZoomInNotification = imports.zoomInNotification;
 
-var ContextMenu = new Lang.Class({
-    Name: 'ContextMenu',
-    Extends: Gtk.Menu,
+var ContextMenu = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/context-menu.ui',
     InternalChildren: [ 'whatsHereItem',
                         'geoURIItem',
                         'exportItem',
                         'addOSMLocationItem',
                         'routeItem' ],
-
-    _init: function(params) {
+}, class ContextMenu extends Gtk.Menu {
+    _init(params) {
         this._mapView = params.mapView;
         delete params.mapView;
 
         this._mainWindow = params.mainWindow;
         delete params.mainWindow;
 
-        this.parent(params);
+        super._init(params);
 
         this._mapView.connect('button-release-event',
                               this._onButtonReleaseEvent.bind(this));
@@ -72,9 +70,9 @@ var ContextMenu = new Lang.Class({
                                        this._routingUpdate.bind(this));
         this._routeItem.visible = false;
         this._routingUpdate();
-    },
+    }
 
-    _onButtonReleaseEvent: function(widget, event) {
+    _onButtonReleaseEvent(widget, event) {
         let [, button] = event.get_button();
         let [, x, y] = event.get_coords();
         this._longitude = this._mapView.view.x_to_longitude(x);
@@ -84,9 +82,9 @@ var ContextMenu = new Lang.Class({
             // Need idle to avoid Clutter dead-lock on re-entrance
             Mainloop.idle_add(() => { this.popup_at_pointer(event); });
         }
-    },
+    }
 
-    _routingUpdate: function() {
+    _routingUpdate() {
         let query = Application.routeQuery;
 
         if (query.points.length === 0)
@@ -100,9 +98,9 @@ var ContextMenu = new Lang.Class({
         } else {
             this._routeItem.label = _("Route to here");
         }
-    },
+    }
 
-    _onRouteActivated: function() {
+    _onRouteActivated() {
         let query = Application.routeQuery;
         let location = new Location.Location({ latitude: this._latitude,
                                                longitude: this._longitude,
@@ -116,9 +114,9 @@ var ContextMenu = new Lang.Class({
         } else {
             query.points[query.points.length - 1].place = place;
         }
-    },
+    }
 
-    _onWhatsHereActivated: function() {
+    _onWhatsHereActivated() {
         let location = new Location.Location({ latitude: this._latitude,
                                                longitude: this._longitude,
                                                accuracy: 0 });
@@ -131,9 +129,9 @@ var ContextMenu = new Lang.Class({
                 Application.notificationManager.showMessage(msg);
             }
         });
-    },
+    }
 
-    _onGeoURIActivated: function() {
+    _onGeoURIActivated() {
         let location = new Location.Location({ latitude: this._latitude,
                                                longitude: this._longitude,
                                                accuracy: 0 });
@@ -142,9 +140,9 @@ var ContextMenu = new Lang.Class({
         let uri = location.to_uri(Geocode.LocationURIScheme.GEO);
 
         clipboard.set_text(uri, uri.length);
-    },
+    }
 
-    _onAddOSMLocationActivated: function() {
+    _onAddOSMLocationActivated() {
         let osmEdit = Application.osmEdit;
         /* if the user is not alread signed in, show the account dialog */
         if (!osmEdit.isSignedIn) {
@@ -161,9 +159,9 @@ var ContextMenu = new Lang.Class({
         }
 
         this._addOSMLocation();
-    },
+    }
 
-    _addOSMLocation: function() {
+    _addOSMLocation() {
         let osmEdit = Application.osmEdit;
 
         if (this._mapView.view.get_zoom_level() < OSMEdit.MIN_ADD_LOCATION_ZOOM_LEVEL) {
@@ -187,9 +185,9 @@ var ContextMenu = new Lang.Class({
                     _("Location was added to the map, note that it may take a while before it shows on the 
map and in search results."));
             }
         });
-    },
+    }
 
-    _activateExport: function() {
+    _activateExport() {
         let view = this._mapView.view;
         let surface = view.to_surface(true);
         let bbox = view.get_bounding_box();
@@ -206,9 +204,9 @@ var ContextMenu = new Lang.Class({
 
         dialog.connect('response', () => { dialog.destroy(); });
         dialog.show_all();
-    },
+    }
 
-    _onExportActivated: function() {
+    _onExportActivated() {
         if (this._mapView.view.state === Champlain.State.DONE) {
             this._activateExport();
         } else {
diff --git a/src/exportViewDialog.js b/src/exportViewDialog.js
index c946563..55295dc 100644
--- a/src/exportViewDialog.js
+++ b/src/exportViewDialog.js
@@ -21,8 +21,8 @@ const Cairo = imports.cairo;
 const Gdk = imports.gi.Gdk;
 const GLib = imports.gi.GLib;
 const Gio = imports.gi.Gio;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Utils = imports.utils;
 
@@ -33,9 +33,7 @@ var Response = {
 
 const _PREVIEW_WIDTH = 150;
 
-var ExportViewDialog = new Lang.Class({
-    Name: 'ExportViewDialog',
-    Extends: Gtk.Dialog,
+var ExportViewDialog = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/export-view-dialog.ui',
     InternalChildren: [ 'exportButton',
                         'cancelButton',
@@ -43,8 +41,8 @@ var ExportViewDialog = new Lang.Class({
                         'fileChooserButton',
                         'previewArea',
                         'layersCheckButton' ],
-
-    _init: function(params) {
+}, class ExportViewDialog extends Gtk.Dialog {
+    _init(params) {
         this._surface = params.surface;
         delete params.surface;
 
@@ -58,7 +56,7 @@ var ExportViewDialog = new Lang.Class({
         delete params.mapView;
 
         params.use_header_bar = true;
-        this.parent(params);
+        super._init(params);
 
         this._cancelButton.connect('clicked', () => { this.response(Response.CANCEL); });
         this._exportButton.connect('clicked', () => { this._exportView(); });
@@ -74,18 +72,18 @@ var ExportViewDialog = new Lang.Class({
         this._filenameEntry.text = this._fileName = this._getName();
         this._fileChooserButton.set_current_folder(this._folder);
         this._setupPreviewArea();
-    },
+    }
 
-    _getName: function() {
+    _getName() {
         /* Translators: This is a format string for a PNG filename for an
          * exported image with coordinates. The .png extension should be kept
          * intact in the translated string.
          */
         return _("Maps at %f, %f.png").format(this._latitude.toFixed(2),
                                               this._longitude.toFixed(2));
-    },
+    }
 
-    _setupPreviewArea: function() {
+    _setupPreviewArea() {
         let [surfaceWidth, surfaceHeight] = this._mapView.view.get_size();
 
         let width = _PREVIEW_WIDTH;
@@ -95,9 +93,9 @@ var ExportViewDialog = new Lang.Class({
         this._previewArea.set_size_request(width, height);
         this._previewArea.connect('draw',
                                   (w, cr) => { this._drawPreview(w, cr); });
-    },
+    }
 
-    _drawPreview: function(widget, cr) {
+    _drawPreview(widget, cr) {
         cr.setOperator(Cairo.Operator.CLEAR);
         cr.paint();
         cr.setOperator(Cairo.Operator.OVER);
@@ -105,9 +103,9 @@ var ExportViewDialog = new Lang.Class({
         cr.scale(this._scaleFactor, this._scaleFactor);
         cr.setSourceSurface(this._surface, 0, 0);
         cr.paint();
-    },
+    }
 
-    _onFileNameChanged: function() {
+    _onFileNameChanged() {
         let name = GLib.filename_from_utf8(this._filenameEntry.text, -1)[0];
         name = name.toString();
         if (!name) {
@@ -122,9 +120,9 @@ var ExportViewDialog = new Lang.Class({
         } catch(e) {
             this._exportButton.sensitive = false;
         }
-    },
+    }
 
-    _onFolderChanged: function() {
+    _onFolderChanged() {
         let folder = this._fileChooserButton.get_filename();
 
         if (!GLib.file_test(folder, GLib.FileTest.IS_DIR)) {
@@ -138,9 +136,9 @@ var ExportViewDialog = new Lang.Class({
 
         this._exportButton.sensitive = true;
         this._folder = folder;
-    },
+    }
 
-    _exportView: function() {
+    _exportView() {
         let [width, height] = this._mapView.view.get_size();
         let pixbuf = Gdk.pixbuf_get_from_surface(this._surface, 0, 0, width, height);
         let path = GLib.build_filenamev([this._folder, this._fileName]);
@@ -174,9 +172,9 @@ var ExportViewDialog = new Lang.Class({
             dialog.connect('response', () => { dialog.destroy(); });
             dialog.show_all();
         }
-    },
+    }
 
-    _includeLayersChanged: function() {
+    _includeLayersChanged() {
         let includeLayers = this._layersCheckButton.get_active();
 
         this._surface = this._mapView.view.to_surface(includeLayers);
diff --git a/src/facebookBackend.js b/src/facebookBackend.js
index c01306f..3df30ad 100644
--- a/src/facebookBackend.js
+++ b/src/facebookBackend.js
@@ -20,43 +20,41 @@
  */
 
 const GFBGraph = imports.gi.GFBGraph;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const ServiceBackend = imports.serviceBackend;
 const SocialPlace = imports.socialPlace;
 
 const _PLACE_LINK_FORMAT = 'https://www.facebook.com/%s';
 
-var FacebookBackend = new Lang.Class({
-    Name: 'SocialServiceFacebookBackend',
-    Extends: ServiceBackend.ServiceBackend,
-
+var FacebookBackend = GObject.registerClass(
+class FacebookBackend extends ServiceBackend.ServiceBackend {
     get name() {
         return 'facebook';
-    },
+    }
 
-    createRestCall: function(authorizer) {
+    createRestCall(authorizer) {
         return GFBGraph.new_rest_call(authorizer);
-    },
+    }
 
-    refreshAuthorization: function(authorizer, cancellable) {
+    refreshAuthorization(authorizer, cancellable) {
         return authorizer.refresh_authorization(cancellable);
-    },
+    }
 
-    getAuthorizerAccount: function(authorizer) {
+    getAuthorizerAccount(authorizer) {
         return authorizer.goa_object;
-    },
+    }
 
-    createAuthorizer: function(account) {
+    createAuthorizer(account) {
         return new GFBGraph.GoaAuthorizer({ goa_object: account });
-    },
+    }
 
-    isTokenInvalid: function(restCall, data) {
+    isTokenInvalid(restCall, data) {
         return data.error &&
                (data.error.code === 2500 || data.error.code === 104 || data.error.code === 190);
-    },
+    }
 
-    isInvalidCall: function(restCall, data) {
+    isInvalidCall(restCall, data) {
         if (!data) {
             return true;
         } else if (data.error) {
@@ -64,21 +62,21 @@ var FacebookBackend = new Lang.Class({
         } else {
             return false;
         }
-    },
+    }
 
-    getCallResultCode: function(restCall, data) {
+    getCallResultCode(restCall, data) {
         return data ?
             (data.error ? data.error.code : null) :
             restCall.get_status_code();
-    },
+    }
 
-    getCallResultMessage: function(restCall, data) {
+    getCallResultMessage(restCall, data) {
         return data ?
             (data.error ? data.error.message : null) :
             restCall.get_status_message();
-    },
+    }
 
-    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) {
+    _realPerformCheckIn(authorizer, checkIn, callback, cancellable) {
         this.callAsync(authorizer,
                        'POST',
                        'me/feed',
@@ -89,9 +87,9 @@ var FacebookBackend = new Lang.Class({
                        },
                        callback,
                        cancellable);
-    },
+    }
 
-    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+    _realFindPlaces(authorizer, latitude, longitude, distance, callback, cancellable) {
         this.callAsync(authorizer,
                        'GET',
                        'search',
@@ -102,9 +100,9 @@ var FacebookBackend = new Lang.Class({
                        },
                        callback,
                        cancellable);
-    },
+    }
 
-    createPlaces: function(rawData) {
+    createPlaces(rawData) {
         return rawData.data.map(function(place) {
             let link = _PLACE_LINK_FORMAT.format(place.id);
 
diff --git a/src/favoritesPopover.js b/src/favoritesPopover.js
index e6a5a0d..34e4ad2 100644
--- a/src/favoritesPopover.js
+++ b/src/favoritesPopover.js
@@ -20,7 +20,6 @@
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const PlaceListRow = imports.placeListRow;
@@ -28,9 +27,7 @@ const PlaceStore = imports.placeStore;
 
 const _N_VISIBLE = 6;
 
-var FavoritesPopover = new Lang.Class({
-    Name: 'FavoritesPopover',
-    Extends: Gtk.Popover,
+var FavoritesPopover = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/favorites-popover.ui',
     InternalChildren: [ 'mainGrid',
                         'revealer',
@@ -44,16 +41,17 @@ var FavoritesPopover = new Lang.Class({
                                         GObject.ParamFlags.READABLE |
                                         GObject.ParamFlags.WRITABLE,
                                         0, GLib.MAXINT32, 0)
-    },
+    }
+}, class FavoritesPopover extends Gtk.Popover {
 
-    _init: function(params) {
+    _init(params) {
         params = params || { };
 
         this._mapView = params.mapView;
         delete params.mapView;
 
         params.transitions_enabled = false;
-        this.parent(params);
+        super._init(params);
 
         this._rows = 0;
 
@@ -92,20 +90,20 @@ var FavoritesPopover = new Lang.Class({
         });
 
         this._updateList();
-    },
+    }
 
     set rows(rows) {
         if (rows !== this._rows) {
             this._rows = rows;
             this.notify('rows');
         }
-    },
+    }
 
     get rows() {
         return this._rows;
-    },
+    }
 
-    _updateList: function() {
+    _updateList() {
         this._list.forall((row) => { row.destroy(); });
 
         let rows = 0;
diff --git a/src/foursquareBackend.js b/src/foursquareBackend.js
index 014c9da..164ddfb 100644
--- a/src/foursquareBackend.js
+++ b/src/foursquareBackend.js
@@ -19,7 +19,7 @@
  * Author: Damián Nohales <damiannohales gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const FoursquareGoaAuthorizer = imports.foursquareGoaAuthorizer;
 const ServiceBackend = imports.serviceBackend;
@@ -27,47 +27,46 @@ const SocialPlace = imports.socialPlace;
 
 const _PLACE_LINK_FORMAT = 'https://foursquare.com/v/foursquare-hq/%s';
 
-var FoursquareBackend = new Lang.Class({
-    Name: 'SocialServiceFoursquareBackend',
-    Extends: ServiceBackend.ServiceBackend,
+var FoursquareBackend = GObject.registerClass(
+class SocialServiceFoursquareBackend extends ServiceBackend.ServiceBackend {
 
     get name() {
         return 'foursquare';
-    },
+    }
 
-    createRestCall: function(authorizer) {
+    createRestCall(authorizer) {
         return FoursquareGoaAuthorizer.newRestCall(authorizer);
-    },
+    }
 
-    refreshAuthorization: function(authorizer, cancellable) {
+    refreshAuthorization(authorizer, cancellable) {
         return authorizer.refreshAuthorization(cancellable);
-    },
+    }
 
-    getAuthorizerAccount: function(authorizer) {
+    getAuthorizerAccount(authorizer) {
         return authorizer.goaObject;
-    },
+    }
 
-    createAuthorizer: function(account) {
+    createAuthorizer(account) {
         return new FoursquareGoaAuthorizer.FoursquareGoaAuthorizer({ goaObject: account });
-    },
+    }
 
-    isTokenInvalid: function(restCall, data) {
+    isTokenInvalid(restCall, data) {
         return data.meta.code === 401 || data.meta.code === 403;
-    },
+    }
 
-    isInvalidCall: function(restCall, data) {
+    isInvalidCall(restCall, data) {
         return !data || data.meta.code !== 200;
-    },
+    }
 
-    getCallResultCode: function(restCall, data) {
+    getCallResultCode(restCall, data) {
         return data ? data.meta.code : restCall.get_status_code();
-    },
+    }
 
-    getCallResultMessage: function(restCall, data) {
+    getCallResultMessage(restCall, data) {
         return data ? data.meta.errorDetail : restCall.get_status_message();
-    },
+    }
 
-    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) {
+    _realPerformCheckIn(authorizer, checkIn, callback, cancellable) {
         let broadcast = checkIn.privacy;
 
         if (checkIn.broadcastFacebook)
@@ -86,9 +85,9 @@ var FoursquareBackend = new Lang.Class({
                        },
                        callback,
                        cancellable);
-    },
+    }
 
-    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+    _realFindPlaces(authorizer, latitude, longitude, distance, callback, cancellable) {
         this.callAsync(authorizer,
                        'GET',
                        'venues/search',
@@ -99,9 +98,9 @@ var FoursquareBackend = new Lang.Class({
                        },
                        callback,
                        cancellable);
-    },
+    }
 
-    createPlaces: function(rawData) {
+    createPlaces(rawData) {
         return rawData.response.venues.map(function(place) {
             let link = _PLACE_LINK_FORMAT.format(place.id);
 
diff --git a/src/foursquareGoaAuthorizer.js b/src/foursquareGoaAuthorizer.js
index ba7538e..71005b7 100644
--- a/src/foursquareGoaAuthorizer.js
+++ b/src/foursquareGoaAuthorizer.js
@@ -20,32 +20,29 @@
  */
 
 const Rest = imports.gi.Rest;
-const Lang = imports.lang;
 
 const _FOURSQUARE_API_VERSION = '20140226';
 
-var FoursquareGoaAuthorizer = new Lang.Class({
-    Name: 'FoursquareGoaAuthorizer',
-
-    _init: function(params) {
+var FoursquareGoaAuthorizer = class FoursquareGoaAuthorizer {
+    _init(params) {
         if (!params.goaObject) {
             logError('FoursquareGoaAuthorizer requires goaObject parameter');
             return;
         }
 
         this.goaObject = params.goaObject;
-    },
+    }
 
     get goaObject() {
         return this._goaObject;
-    },
+    }
 
     set goaObject(object) {
         this._goaObject = object;
         this._accessToken = null;
-    },
+    }
 
-    _refreshAccessToken: function(cancellable) {
+    _refreshAccessToken(cancellable) {
         if (this._accessToken)
             return true;
 
@@ -57,21 +54,21 @@ var FoursquareGoaAuthorizer = new Lang.Class({
         }
 
         return false;
-    },
+    }
 
-    processCall: function(restCall) {
+    processCall(restCall) {
         this._refreshAccessToken(null);
         restCall.add_param('oauth_token', this._accessToken);
         restCall.add_param('v', _FOURSQUARE_API_VERSION);
-    },
+    }
 
-    processMessage: function(soupMessage) {
+    processMessage(soupMessage) {
         this._refreshAccessToken(null);
         let uri = soupMessage.get_uri();
         uri.set_query(uri, 'oauth_token' + this._accessToken + '&v=' + _FOURSQUARE_API_VERSION);
-    },
+    }
 
-    refreshAuthorization: function(cancellable) {
+    refreshAuthorization(cancellable) {
         let ensureCredentialsResult = this.goaObject.get_account().call_ensure_credentials_sync(cancellable);
         if (ensureCredentialsResult[0]) {
             this._accessToken = null;
@@ -80,7 +77,7 @@ var FoursquareGoaAuthorizer = new Lang.Class({
 
         return false;
     }
-});
+};
 
 function newRestCall(authorizer)
 {
diff --git a/src/geoJSONShapeLayer.js b/src/geoJSONShapeLayer.js
index 422f6d3..46dcc47 100644
--- a/src/geoJSONShapeLayer.js
+++ b/src/geoJSONShapeLayer.js
@@ -17,34 +17,33 @@
  * Author: Hashem Nasarat <hashem riseup net>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const GeoJSONSource = imports.geoJSONSource;
 const ShapeLayer = imports.shapeLayer;
 
-var GeoJSONShapeLayer = new Lang.Class({
-    Name: 'GeoJSONShapeLayer',
-    Extends: ShapeLayer.ShapeLayer,
+var GeoJSONShapeLayer = GObject.registerClass(
+class GeoJSONShapeLayer extends ShapeLayer.ShapeLayer {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
 
         this._mapSource = new GeoJSONSource.GeoJSONSource({
             mapView: this._mapView,
             markerLayer: this._markerLayer
         });
-    },
+    }
 
-    getName: function() {
+    getName() {
         /* Special Case since this file extension contains 2 periods */
         let suffix = '.geo.json';
         if (this.filename.endsWith(suffix))
             return this.filename.replace(new RegExp(suffix + '$'), '');
         else
-            return this.parent();
-    },
+            return super.getName();
+    }
 
-    _parseContent: function() {
+    _parseContent() {
         this._mapSource.parse(JSON.parse(this._fileContents));
     }
 });
@@ -53,3 +52,6 @@ GeoJSONShapeLayer.mimeTypes = ['application/vnd.geo+json',
                                'application/geo+json',
                                'application/json'];
 GeoJSONShapeLayer.displayName = 'GeoJSON';
+GeoJSONShapeLayer.createInstance = function(params) {
+    return new GeoJSONShapeLayer(params);
+};
diff --git a/src/geoJSONSource.js b/src/geoJSONSource.js
index 0eef485..91f5aae 100644
--- a/src/geoJSONSource.js
+++ b/src/geoJSONSource.js
@@ -21,7 +21,7 @@
 const Cairo = imports.cairo;
 const Champlain = imports.gi.Champlain;
 const Clutter = imports.gi.Clutter;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 const Mainloop = imports.mainloop;
 
 const Geojsonvt = imports.geojsonvt.geojsonvt;
@@ -39,42 +39,42 @@ const TileFeature = { POINT: 1,
                       LINESTRING: 2,
                       POLYGON: 3 };
 
-var GeoJSONSource = new Lang.Class({
-    Name: 'GeoJSONSource',
-    Extends: Champlain.TileSource,
+var GeoJSONSource = GObject.registerClass(
+class GeoJSONSource extends Champlain.TileSource {
 
-    _init: function(params) {
-        this.parent();
+    _init(params) {
+        super._init();
 
         this._mapView = params.mapView;
         this._markerLayer = params.markerLayer;
         this._bbox = new Champlain.BoundingBox();
-    },
+    }
 
     get bbox() {
         return this._bbox;
-    },
-    vfunc_get_tile_size: function() {
+    }
+
+    vfunc_get_tile_size() {
         return TILE_SIZE;
-    },
+    }
 
-    vfunc_get_max_zoom_level: function() {
+    vfunc_get_max_zoom_level() {
         return 20;
-    },
+    }
 
-    vfunc_get_min_zoom_level: function() {
+    vfunc_get_min_zoom_level() {
         return 0;
-    },
+    }
 
-    vfunc_get_id: function() {
+    vfunc_get_id() {
         return 'GeoJSONSource';
-    },
+    }
 
-    vfunc_get_name: function() {
+    vfunc_get_name() {
         return 'GeoJSONSource';
-    },
+    }
 
-    vfunc_fill_tile: function(tile) {
+    vfunc_fill_tile(tile) {
         if (tile.get_state() === Champlain.State.DONE)
             return;
 
@@ -87,40 +87,40 @@ var GeoJSONSource = new Lang.Class({
         });
 
         Mainloop.idle_add(() => { this._renderTile(tile); });
-    },
+    }
 
-    _validate: function([lon, lat]) {
+    _validate([lon, lat]) {
         if ((-180 <= lon && lon <= 180) &&
             (-90  <= lat && lat <= 90)) {
             return;
         }
 
         throw new Error(_("invalid coordinate"));
-    },
+    }
 
-    _compose: function(coordinates) {
+    _compose(coordinates) {
         coordinates.forEach((coordinate) => {
             this._validate(coordinate);
             this._bbox.extend(coordinate[1], coordinate[0]);
         });
-    },
+    }
 
-    _clampBBox: function() {
+    _clampBBox() {
         this._bbox.top = Math.min(this._bbox.top, MapView.MAX_LATITUDE);
         this._bbox.left = Math.max(this._bbox.left, MapView.MIN_LONGITUDE);
         this._bbox.bottom = Math.max(this._bbox.bottom, MapView.MIN_LATITUDE);
         this._bbox.right = Math.min(this._bbox.right, MapView.MAX_LONGITUDE);
-    },
+    }
 
-    _parseLineString: function(coordinates) {
+    _parseLineString(coordinates) {
         this._compose(coordinates);
-    },
+    }
 
-    _parsePolygon: function(coordinates) {
+    _parsePolygon(coordinates) {
         coordinates.forEach((coordinate) => { this._compose(coordinate); });
-    },
+    }
 
-    _parsePoint: function(coordinates, properties) {
+    _parsePoint(coordinates, properties) {
         let name = null;
         if (properties)
             name = properties.name;
@@ -140,9 +140,9 @@ var GeoJSONSource = new Lang.Class({
         let placeMarker = new PlaceMarker.PlaceMarker({ place: place,
                                                         mapView: this._mapView });
         this._markerLayer.add_marker(placeMarker);
-    },
+    }
 
-    _parseGeometry: function(geometry, properties) {
+    _parseGeometry(geometry, properties) {
         if(!geometry)
             throw new Error(_("parse error"));
 
@@ -180,9 +180,9 @@ var GeoJSONSource = new Lang.Class({
         default:
             throw new Error(_("unknown geometry"));
         }
-    },
+    }
 
-    _parseInternal: function(root) {
+    _parseInternal(root) {
         if (!root || !root.type)
             throw new Error(_("parse error"));
 
@@ -207,16 +207,16 @@ var GeoJSONSource = new Lang.Class({
         default:
             this._parseGeometry(root);
         }
-    },
+    }
 
-    parse: function(json) {
+    parse(json) {
         this._parseInternal(json);
         this._tileIndex = Geojsonvt.geojsonvt(json, { extent: TILE_SIZE,
                                                       maxZoom: 20 });
         this._clampBBox();
-    },
+    }
 
-    _renderTile: function(tile) {
+    _renderTile(tile) {
         let tileJSON = this._tileIndex.getTile(tile.zoom_level, tile.x, tile.y);
         let content = new Clutter.Canvas({ width: TILE_SIZE,
                                            height: TILE_SIZE });
diff --git a/src/geoJSONStyle.js b/src/geoJSONStyle.js
index fce56bb..b4ea97b 100644
--- a/src/geoJSONStyle.js
+++ b/src/geoJSONStyle.js
@@ -18,12 +18,9 @@
  * Author: Alaf Azam <alafazam gmail com>
  */
 
-const Lang = imports.lang;
+var GeoJSONStyle = class GeoJSONStyle {
 
-var GeoJSONStyle = new Lang.Class({
-    Name: 'GeoJSONStyle',
-
-    _init: function(params) {
+    constructor(params) {
 
         if (params.lineWidth || params.lineWidth === 0)
             this.lineWidth = params.lineWidth;
@@ -46,9 +43,9 @@ var GeoJSONStyle = new Lang.Class({
         this.fillColor =  this._hexToColor(params.fillColor) || { red: 0.37,
                                                                   green: 0.62,
                                                                   blue: 0.87 };
-    },
+    }
 
-    _hexToColor: function(colorString) {
+    _hexToColor(colorString) {
         let color = null;
         
         if (!colorString)
@@ -80,7 +77,7 @@ var GeoJSONStyle = new Lang.Class({
 
         return color;
     }
-});
+};
 
 GeoJSONStyle.parseSimpleStyle = function(tags) {
     return  new GeoJSONStyle({ alpha: tags['stroke-opacity'],
diff --git a/src/geoclue.js b/src/geoclue.js
index 66f847b..19d2224 100644
--- a/src/geoclue.js
+++ b/src/geoclue.js
@@ -22,7 +22,6 @@
 const GObject = imports.gi.GObject;
 const GClue = imports.gi.Geoclue;
 const Gio = imports.gi.Gio;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Place = imports.place;
@@ -37,9 +36,7 @@ var State = {
     FAILED: 3
 };
 
-var Geoclue = new Lang.Class({
-    Name: 'Geoclue',
-    Extends: GObject.Object,
+var Geoclue = GObject.registerClass({
     Signals: {
         'location-changed': { }
     },
@@ -53,25 +50,26 @@ var Geoclue = new Lang.Class({
                                        State.FAILED,
                                        State.INITIAL)
     },
+}, class Geoclue extends GObject.Object {
 
     set state(s) {
         this._state = s;
         this.notify('state');
-    },
+    }
 
     get state() {
         return this._state;
-    },
+    }
 
-    _init: function() {
-        this.parent();
+    _init() {
+        super._init();
         this.place = null;
         this._state = State.INITIAL;
 
         this.start(null);
-    },
+    }
 
-    start: function(callback) {
+    start(callback) {
         let id = 'org.gnome.Maps';
         let level = GClue.AccuracyLevel.EXACT;
 
@@ -101,9 +99,9 @@ var Geoclue = new Lang.Class({
             if (callback)
                 callback(true);
         });
-    },
+    }
 
-    _onLocationNotify: function(simple) {
+    _onLocationNotify(simple) {
         let geoclueLocation = simple.get_location();
         let location = new Location.Location({
             latitude: geoclueLocation.latitude,
@@ -113,9 +111,9 @@ var Geoclue = new Lang.Class({
             description: geoclueLocation.description
         });
         this._updateLocation(location);
-    },
+    }
 
-    _updateLocation: function(location) {
+    _updateLocation(location) {
         if (!this.place)
             this.place = new Place.Place({ name: _("Current location") });
 
diff --git a/src/geocodeService.js b/src/geocodeService.js
index 8c90cfb..441925a 100644
--- a/src/geocodeService.js
+++ b/src/geocodeService.js
@@ -22,18 +22,13 @@
  */
 
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const Place = imports.place;
 const Utils = imports.utils;
 
-var GeocodeService = new Lang.Class({
-    Name: 'GeocodeService',
-
-    _init: function() { },
-
-    search: function(string, bbox, cancellable, callback) {
+var GeocodeService = class GeocodeService {
+    search(string, bbox, cancellable, callback) {
         let answerCount = Application.settings.get('max-search-results');
         let forward     = Geocode.Forward.new_for_string(string);
 
@@ -60,9 +55,9 @@ var GeocodeService = new Lang.Class({
                 callback(null);
             }
         });
-    },
+    }
 
-    reverse: function(location, cancellable, callback) {
+    reverse(location, cancellable, callback) {
         let reverse = Geocode.Reverse.new_for_location(location);
 
         Application.application.mark_busy();
@@ -80,4 +75,4 @@ var GeocodeService = new Lang.Class({
             }
         });
     }
-});
+};
diff --git a/src/gpxShapeLayer.js b/src/gpxShapeLayer.js
index f3b6e87..d257b7d 100644
--- a/src/gpxShapeLayer.js
+++ b/src/gpxShapeLayer.js
@@ -17,27 +17,26 @@
  * Author: Hashem Nasarat <hashem riseup net>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const GeoJSONSource = imports.geoJSONSource;
 const ShapeLayer = imports.shapeLayer;
 const Togeojson = imports.togeojson.togeojson;
 const Domparser = imports.xmldom.domparser;
 
-var GpxShapeLayer = new Lang.Class({
-    Name: 'GpxShapeLayer',
-    Extends: ShapeLayer.ShapeLayer,
+var GpxShapeLayer = GObject.registerClass(
+class GpxShapeLayer extends ShapeLayer.ShapeLayer {
 
-    _init: function(params) {
-        this.parent(params);
+    constructor(params) {
+        super.construct(params);
 
         this._mapSource = new GeoJSONSource.GeoJSONSource({
             mapView: this._mapView,
             markerLayer: this._markerLayer
         });
-    },
+    }
 
-    _parseContent: function() {
+    _parseContent() {
         let s = this._fileContents.toString();
         let parser = new Domparser.DOMParser();
         let json = Togeojson.toGeoJSON.gpx(parser.parseFromString(s));
@@ -47,3 +46,6 @@ var GpxShapeLayer = new Lang.Class({
 
 GpxShapeLayer.mimeTypes = ['application/gpx+xml' ];
 GpxShapeLayer.displayName = 'GPX';
+GpxShapeLayer.createInstance = function(params) {
+    return new GpxShapeLayer(params);
+};
diff --git a/src/graphHopper.js b/src/graphHopper.js
index bd1281d..fec2150 100644
--- a/src/graphHopper.js
+++ b/src/graphHopper.js
@@ -21,7 +21,6 @@
 
 const Champlain = imports.gi.Champlain;
 const GLib = imports.gi.GLib;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const Soup = imports.gi.Soup;
 
@@ -32,14 +31,13 @@ const Route = imports.route;
 const RouteQuery = imports.routeQuery;
 const Utils = imports.utils;
 
-var GraphHopper = new Lang.Class({
-    Name: 'GraphHopper',
+var GraphHopper = class GraphHopper {
 
     get route() {
         return this._route;
-    },
+    }
 
-    _init: function(params) {
+    constructor(params) {
         this._session = new Soup.Session({ user_agent : 'gnome-maps/' + pkg.version });
         this._key     = "VCIHrHj0pDKb8INLpT4s5hVadNmJ1Q3vi0J4nJYP";
         this._baseURL = "https://graphhopper.com/api/1/route?";;
@@ -47,11 +45,9 @@ var GraphHopper = new Lang.Class({
         this._route   = new Route.Route();
         this.storedRoute = null;
         this._query = params.query;
-        delete params.query;
-        this.parent(params);
-    },
+    }
 
-    _updateFromStored: function() {
+    _updateFromStored() {
         Mainloop.idle_add(() => {
             if (!this.storedRoute)
                 return;
@@ -63,9 +59,9 @@ var GraphHopper = new Lang.Class({
                                 bbox: this.storedRoute.bbox });
             this.storedRoute = null;
         });
-    },
+    }
 
-    _queryGraphHopper: function(points, transportationType, callback) {
+    _queryGraphHopper(points, transportationType, callback) {
         let url = this._buildURL(points, transportationType);
         let msg = Soup.Message.new('GET', url);
         this._session.queue_message(msg, (session, message) => {
@@ -79,9 +75,9 @@ var GraphHopper = new Lang.Class({
                 callback(null, e);
             }
         });
-    },
+    }
 
-    fetchRoute: function(points, transportationType) {
+    fetchRoute(points, transportationType) {
         if (this.storedRoute) {
             this._updateFromStored();
             return;
@@ -109,9 +105,9 @@ var GraphHopper = new Lang.Class({
                 }
             }
         });
-    },
+    }
 
-    fetchRouteAsync: function(points, transportationType, callback) {
+    fetchRouteAsync(points, transportationType, callback) {
         this._queryGraphHopper(points, transportationType,
                                (result, exception) => {
             if (result) {
@@ -121,9 +117,9 @@ var GraphHopper = new Lang.Class({
                 callback(null, exception);
             }
         });
-    },
+    }
 
-    _buildURL: function(points, transportation) {
+    _buildURL(points, transportation) {
         let locations = points.map(function(point) {
             return [point.place.location.latitude, point.place.location.longitude].join(',');
         });
@@ -138,9 +134,9 @@ var GraphHopper = new Lang.Class({
         let url = this._baseURL + query.toString();
         Utils.debug("Sending route request to: " + url);
         return url;
-    },
+    }
 
-    _parseMessage: function({ status_code, response_body, uri }) {
+    _parseMessage({ status_code, response_body, uri }) {
         if (status_code === 500) {
             log("Internal server error.\n"
                 + "This is most likely a bug in GraphHopper");
@@ -166,9 +162,9 @@ var GraphHopper = new Lang.Class({
         }
 
         return result;
-    },
+    }
 
-    _createRoute: function(route) {
+    _createRoute(route) {
         let path       = EPAF.decode(route.points);
         let turnPoints = this._createTurnPoints(path, route.instructions);
         let bbox       = new Champlain.BoundingBox();
@@ -182,9 +178,9 @@ var GraphHopper = new Lang.Class({
                  distance:   route.distance,
                  time:       route.time,
                  bbox:       bbox };
-    },
+    }
 
-    _createTurnPoints: function(path, instructions) {
+    _createTurnPoints(path, instructions) {
         let via = 0;
         let startPoint = new Route.TurnPoint({
             coordinate:  path[0],
@@ -212,9 +208,9 @@ var GraphHopper = new Lang.Class({
             });
         });
         return [startPoint].concat(rest);
-    },
+    }
 
-    _createTurnPointType: function(sign) {
+    _createTurnPointType(sign) {
         let type = sign + 3;
         let min  = Route.TurnPointType.SHARP_LEFT;
         let max  = Route.TurnPointType.ROUNDABOUT;
@@ -223,4 +219,4 @@ var GraphHopper = new Lang.Class({
         else
             return undefined;
     }
-});
+};
diff --git a/src/http.js b/src/http.js
index 482e3aa..1089ff0 100644
--- a/src/http.js
+++ b/src/http.js
@@ -19,7 +19,6 @@
  * Author: Mattias Bengtsson <mattias jc bengtsson gmail com>
  */
 
-const Lang = imports.lang;
 const Soup = imports.gi.Soup;
 
 function encode(data) {
@@ -29,18 +28,17 @@ function encode(data) {
     return Soup.URI.encode(data.toString(), null);
 }
 
-var Query = new Lang.Class({
-    Name: 'Query',
+var Query = class Query {
 
-    _init: function(obj) {
+    constructor(obj) {
         this._query = {};
         for(let key in obj) {
             this.add(key, obj[key]);
         }
-    },
+    }
 
     // a value === null represents an empty value
-    add: function(key, value) {
+    add(key, value) {
         // Initialize query field if it isn't already
         let queryValue = this._query[key];
         if(!Array.isArray(queryValue))
@@ -50,9 +48,9 @@ var Query = new Lang.Class({
             this._query[key] = this._query[key].concat(value);
         else
             this._query[key].push(value);
-    },
+    }
 
-    toString: function() {
+    toString() {
         let vars = [];
         for(let key in this._query) {
             let values = this._query[key];
@@ -67,4 +65,4 @@ var Query = new Lang.Class({
         }
         return vars.join('&');
     }
-});
+};
diff --git a/src/instructionRow.js b/src/instructionRow.js
index 644e13f..f8f4cdc 100644
--- a/src/instructionRow.js
+++ b/src/instructionRow.js
@@ -20,19 +20,18 @@
  *         Mattias Bengtsson <mattias jc bengtsson gmail com>
  */
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Utils = imports.utils;
 
-var InstructionRow = new Lang.Class({
-    Name: "InstructionRow",
-    Extends: Gtk.ListBoxRow,
+var InstructionRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/instruction-row.ui',
     InternalChildren: [ 'directionImage',
                         'instructionLabel',
-                        'distanceLabel' ],
+                        'distanceLabel' ]
+}, class InstructionRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this.turnPoint = params.turnPoint;
         delete params.turnPoint;
 
@@ -42,7 +41,7 @@ var InstructionRow = new Lang.Class({
         let lines = params.lines;
         delete params.lines;
 
-        this.parent(params);
+        super._init(params);
 
         if (lines)
             this._instructionLabel.lines = lines;
diff --git a/src/kmlShapeLayer.js b/src/kmlShapeLayer.js
index 3de9985..ea13a7f 100644
--- a/src/kmlShapeLayer.js
+++ b/src/kmlShapeLayer.js
@@ -17,27 +17,25 @@
  * Author: Hashem Nasarat <hashem riseup net>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const GeoJSONSource = imports.geoJSONSource;
 const ShapeLayer = imports.shapeLayer;
 const Togeojson = imports.togeojson.togeojson;
 const Domparser = imports.xmldom.domparser;
 
-var KmlShapeLayer = new Lang.Class({
-    Name: 'KmlShapeLayer',
-    Extends: ShapeLayer.ShapeLayer,
-
-    _init: function(params) {
-        this.parent(params);
+var KmlShapeLayer = GObject.registerClass(
+class KmlShapeLayer extends ShapeLayer.ShapeLayer {
+    _init(params) {
+        super._init(params);
 
         this._mapSource = new GeoJSONSource.GeoJSONSource({
             mapView: this._mapView,
             markerLayer: this._markerLayer
         });
-    },
+    }
 
-    _parseContent: function() {
+    _parseContent() {
         let s = this._fileContents.toString();
         let parser = new Domparser.DOMParser();
         let json = Togeojson.toGeoJSON.kml(parser.parseFromString(s));
@@ -47,3 +45,6 @@ var KmlShapeLayer = new Lang.Class({
 
 KmlShapeLayer.mimeTypes = ['application/vnd.google-earth.kml+xml'];
 KmlShapeLayer.displayName = 'KML';
+KmlShapeLayer.createInstance = function(params) {
+    return new KmlShapeLayer(params);
+};
diff --git a/src/layersPopover.js b/src/layersPopover.js
index 8d32a5b..3c9abdb 100644
--- a/src/layersPopover.js
+++ b/src/layersPopover.js
@@ -17,25 +17,24 @@
  * Author: Dario Di Nucci <linkin88mail gmail com>
  */
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const MapView = imports.mapView;
 const ShapeLayer = imports.shapeLayer;
 const Utils = imports.utils;
 
-var ShapeLayerRow = new Lang.Class({
-    Name: 'ShapeLayerRow',
-    Extends: Gtk.ListBoxRow,
+var ShapeLayerRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/shape-layer-row.ui',
     Children: ['closeButton'],
-    InternalChildren: ['layerLabel', 'visibleButton'],
+    InternalChildren: ['layerLabel', 'visibleButton']
+}, class ShapeLayerRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this.shapeLayer = params.shapeLayer;
         delete params.shapeLayer;
 
-        this.parent(params);
+        super._init(params);
 
         this._layerLabel.label = this.shapeLayer.getName();
         this._layerLabel.tooltip_text = this.shapeLayer.file.get_parse_name();
@@ -52,20 +51,19 @@ var ShapeLayerRow = new Lang.Class({
     }
 });
 
-var LayersPopover = new Lang.Class({
-    Name: 'LayersPopover',
-    Extends: Gtk.Popover,
+var LayersPopover = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/layers-popover.ui',
     InternalChildren: [ 'streetLayerButton',
                         'aerialLayerButton',
                         'layersListBox',
-                        'loadLayerButton' ],
+                        'loadLayerButton' ]
+}, class LayersPopover extends Gtk.Popover {
 
-    _init: function(params) {
+    _init(params) {
         this._mapView = params.mapView;
         delete params.mapView;
 
-        this.parent({ width_request: 200,
+        super._init({ width_request: 200,
                       no_show_all: true,
                       transitions_enabled: false,
                       visible: false });
@@ -92,22 +90,22 @@ var LayersPopover = new Lang.Class({
         this._aerialLayerButton.connect('clicked', () => {
             this._mapView.setMapType(MapView.MapType.AERIAL);
         });
-    },
+    }
 
-    setMapType: function(mapType) {
+    setMapType(mapType) {
         if (mapType === MapView.MapType.STREET)
             this._streetLayerButton.active = true;
         else if (mapType === MapView.MapType.AERIAL)
             this._aerialLayerButton.active = true;
-    },
+    }
 
-    _onRemoveClicked: function(row) {
+    _onRemoveClicked(row) {
         this._mapView.removeShapeLayer(row.shapeLayer);
         if (this._layersListBox.get_children().length <= 0)
             this._layersListBox.hide();
-    },
+    }
 
-    _listBoxCreateWidget: function(shapeLayer) {
+    _listBoxCreateWidget(shapeLayer) {
         let row = new ShapeLayerRow({ shapeLayer: shapeLayer });
         row.closeButton.connect('clicked',
                                 () => { this._onRemoveClicked(row); });
diff --git a/src/location.js b/src/location.js
index d4ec63a..88427ab 100644
--- a/src/location.js
+++ b/src/location.js
@@ -22,25 +22,24 @@
  */
 
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 /* Adds heading to Geocode.Location */
-var Location = new Lang.Class({
-    Name: 'Location',
-    Extends: Geocode.Location,
+var Location = GObject.registerClass(
+class Location extends Geocode.Location {
 
-    _init: function(params) {
+    _init(params) {
         this._heading = params.heading;
         delete params.heading;
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
     get heading() {
         return this._heading;
-    },
+    }
 
     set heading(v) {
         this._heading = v;
-    },
+    }
 });
diff --git a/src/locationServiceNotification.js b/src/locationServiceNotification.js
index 9cf6219..385719f 100644
--- a/src/locationServiceNotification.js
+++ b/src/locationServiceNotification.js
@@ -21,7 +21,7 @@
 
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Application = imports.application;
 const Geoclue = imports.geoclue;
@@ -30,12 +30,11 @@ const Utils = imports.utils;
 
 const _PRIVACY_PANEL = 'gnome-privacy-panel.desktop';
 
-var LocationServiceNotification = new Lang.Class({
-    Name: 'LocationServiceNotification',
-    Extends: Notification.Notification,
+var LocationServiceNotification = GObject.registerClass(
+class LocationServiceNotification extends Notification.Notification {
 
-    _init: function() {
-        this.parent();
+    _init() {
+        super._init();
 
         let ui = Utils.getUIObject('location-service-notification',
                                    [ 'button', 'grid' ]);
diff --git a/src/longPrintLayout.js b/src/longPrintLayout.js
index 956a76e..5894d48 100644
--- a/src/longPrintLayout.js
+++ b/src/longPrintLayout.js
@@ -17,7 +17,7 @@
  * Author: Amisha Singla <amishas157 gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const PrintLayout = imports.printLayout;
 const Route = imports.route;
@@ -37,11 +37,10 @@ const _MiniMapView = {
     ZOOM_LEVEL: 18
 };
 
-var LongPrintLayout = new Lang.Class({
-    Name: 'LongPrintLayout',
-    Extends: PrintLayout.PrintLayout,
+var LongPrintLayout = GObject.registerClass(
+class LongPrintLayout extends PrintLayout.PrintLayout {
 
-    _init: function(params) {
+    _init(params) {
         this._route = params.route;
         delete params.route;
 
@@ -55,11 +54,11 @@ var LongPrintLayout = new Lang.Class({
         });
         params.totalSurfaces = totalSurfaces;
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
-    render: function() {
-        this.parent();
+    render() {
+        super.render();
 
         let instructionWidth = _Instruction.SCALE_X * this._pageWidth;
         let instructionHeight = _Instruction.SCALE_Y * this._pageHeight;
diff --git a/src/mainWindow.js b/src/mainWindow.js
index b2bee4a..bf103cb 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -25,7 +25,6 @@ const GObject = imports.gi.GObject;
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -48,13 +47,12 @@ const _CONFIGURE_ID_TIMEOUT = 100; // msecs
 const _WINDOW_MIN_WIDTH = 600;
 const _WINDOW_MIN_HEIGHT = 500;
 
-var ShapeLayerFileChooser = new Lang.Class({
-    Name: 'ShapeLayerFileChooser',
-    Extends: Gtk.FileChooserNative,
-    Template: 'resource:///org/gnome/Maps/ui/shape-layer-file-chooser.ui',
+var ShapeLayerFileChooser = GObject.registerClass({
+    Template: 'resource:///org/gnome/Maps/ui/shape-layer-file-chooser.ui'
+}, class ShapeLayerFileChooser extends Gtk.FileChooserNative {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
         let allFilter = new Gtk.FileFilter();
         allFilter.set_name(_("All Layer Files"));
         this.add_filter(allFilter);
@@ -73,9 +71,7 @@ var ShapeLayerFileChooser = new Lang.Class({
     }
 });
 
-var MainWindow = new Lang.Class({
-    Name: 'MainWindow',
-    Extends: Gtk.ApplicationWindow,
+var MainWindow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/main-window.ui',
     InternalChildren: [ 'headerBar',
                         'grid',
@@ -87,17 +83,18 @@ var MainWindow = new Lang.Class({
                         'favoritesButton',
                         'printRouteButton',
                         'zoomInButton',
-                        'zoomOutButton' ],
+                        'zoomOutButton' ]
+}, class MainWindow extends Gtk.ApplicationWindow {
 
     get mapView() {
         return this._mapView;
-    },
+    }
 
-    _init: function(params) {
+    _init(params) {
         this._overlay = params.overlay;
         delete params.overlay;
 
-        this.parent(params);
+        super._init(params);
 
         this._configureId = 0;
 
@@ -135,9 +132,9 @@ var MainWindow = new Lang.Class({
         this._grid.attach(this._sidebar, 1, 0, 1, 1);
 
         this._grid.show_all();
-    },
+    }
 
-    _createPlaceEntry: function() {
+    _createPlaceEntry() {
         let placeEntry = new PlaceEntry.PlaceEntry({ mapView: this._mapView,
                                                      visible: true,
                                                      margin_start: 35,
@@ -156,9 +153,9 @@ var MainWindow = new Lang.Class({
         popover.connect('selected', () => { this._mapView.grab_focus(); });
         this._mapView.view.connect('button-press-event', () => { popover.hide(); });
         return placeEntry;
-    },
+    }
 
-    _createSidebar: function() {
+    _createSidebar() {
         let sidebar = new Sidebar.Sidebar(this._mapView);
 
         Application.routeQuery.connect('notify', () => { this._setRevealSidebar(true); });
@@ -169,9 +166,9 @@ var MainWindow = new Lang.Class({
                                        sidebar, 'visible',
                                        GObject.BindingFlags.DEFAULT);
         return sidebar;
-    },
+    }
 
-    _initDND: function() {
+    _initDND() {
         this.drag_dest_set(Gtk.DestDefaults.DROP, null, 0);
         this.drag_dest_add_uri_targets();
 
@@ -187,9 +184,9 @@ var MainWindow = new Lang.Class({
             else
                 Gtk.drag_finish(ctx, false, false, time);
         });
-    },
+    }
 
-    _initActions: function() {
+    _initActions() {
         Utils.addActions(this, {
             'close': {
                 onActivate: this.close.bind(this)
@@ -243,9 +240,9 @@ var MainWindow = new Lang.Class({
                 onActivate: this._onOpenShapeLayer.bind(this)
             }
         });
-    },
+    }
 
-    _initSignals: function() {
+    _initSignals() {
         this.connect('delete-event', this._quit.bind(this));
         this.connect('configure-event',
                      this._onConfigureEvent.bind(this));
@@ -305,9 +302,9 @@ var MainWindow = new Lang.Class({
                                    this._updateZoomButtonsSensitivity.bind(this));
         this._mapView.view.connect('notify::min-zoom-level',
                                    this._updateZoomButtonsSensitivity.bind(this));
-    },
+    }
 
-    _updateZoomButtonsSensitivity: function() {
+    _updateZoomButtonsSensitivity() {
         let zoomLevel = this._mapView.view.zoom_level;
         let maxZoomLevel = this._mapView.view.max_zoom_level;
         let minZoomLevel = this._mapView.view.min_zoom_level;
@@ -321,17 +318,17 @@ var MainWindow = new Lang.Class({
             this._zoomOutButton.set_sensitive(false);
         else
             this._zoomOutButton.set_sensitive(true);
-    },
+    }
 
-    _updateLocationSensitivity: function() {
+    _updateLocationSensitivity() {
         let sensitive = (Application.geoclue.state !== Geoclue.State.INITIAL &&
                          (this.application.connected ||
                           this.application.local_tile_path));
 
         this._gotoUserLocationButton.sensitive = sensitive;
-    },
+    }
 
-    _initHeaderbar: function() {
+    _initHeaderbar() {
         this._placeEntry = this._createPlaceEntry();
         this._headerBar.custom_title = this._placeEntry;
 
@@ -357,9 +354,9 @@ var MainWindow = new Lang.Class({
             this._placeEntry.sensitive = app.connected;
             this._printRouteButton.sensitive = app.connected;
         });
-    },
+    }
 
-    _saveWindowGeometry: function() {
+    _saveWindowGeometry() {
         let window = this.get_window();
         let state = window.get_state();
 
@@ -372,9 +369,9 @@ var MainWindow = new Lang.Class({
 
         let position = this.get_position();
         Application.settings.set('window-position', position);
-    },
+    }
 
-    _restoreWindowGeometry: function() {
+    _restoreWindowGeometry() {
         let size = Application.settings.get('window-size');
         if (size.length === 2) {
             let [width, height] = size;
@@ -390,9 +387,9 @@ var MainWindow = new Lang.Class({
 
         if (Application.settings.get('window-maximized'))
             this.maximize();
-    },
+    }
 
-    _onConfigureEvent: function(widget, event) {
+    _onConfigureEvent(widget, event) {
         if (this._configureId !== 0) {
             Mainloop.source_remove(this._configureId);
             this._configureId = 0;
@@ -403,9 +400,9 @@ var MainWindow = new Lang.Class({
             this._configureId = 0;
             return false;
         });
-    },
+    }
 
-    _onWindowStateEvent: function(widget, event) {
+    _onWindowStateEvent(widget, event) {
         let window = widget.get_window();
         let state = window.get_state();
 
@@ -414,9 +411,9 @@ var MainWindow = new Lang.Class({
 
         let maximized = (state & Gdk.WindowState.MAXIMIZED);
         Application.settings.set('window-maximized', maximized);
-    },
+    }
 
-    _quit: function() {
+    _quit() {
         // remove configure event handler if still there
         if (this._configureId !== 0) {
             Mainloop.source_remove(this._configureId);
@@ -427,18 +424,18 @@ var MainWindow = new Lang.Class({
         this._saveWindowGeometry();
 
         return false;
-    },
+    }
 
-    _getLocationServiceNotification: function() {
+    _getLocationServiceNotification() {
         if (!this._locationServiceNotification) {
             this._locationServiceNotification =
                 new LocationServiceNotification.LocationServiceNotification();
         }
 
         return this._locationServiceNotification;
-    },
+    }
 
-    _onGotoUserLocationActivate: function() {
+    _onGotoUserLocationActivate() {
         let message;
 
         if (Application.geoclue.state === Geoclue.State.ON) {
@@ -463,42 +460,42 @@ var MainWindow = new Lang.Class({
                 break;
             }
         });
-    },
+    }
 
-    _printRouteActivate: function() {
+    _printRouteActivate() {
         if (this._mapView.routeShowing) {
             let operation = new PrintOperation.PrintOperation({ mainWindow: this });
         }
-    },
+    }
 
-    _onMapTypeMenuActivate: function(action) {
+    _onMapTypeMenuActivate(action) {
         let state = action.get_state().get_boolean();
         action.set_state(GLib.Variant.new('b', !state));
-    },
+    }
 
-    _onStreetViewActivate: function() {
+    _onStreetViewActivate() {
         this._mapView.setMapType(MapView.MapType.STREET);
         this.layersPopover.setMapType(MapView.MapType.STREET);
-    },
+    }
 
-    _onAerialViewActivate: function() {
+    _onAerialViewActivate() {
         this._mapView.setMapType(MapView.MapType.AERIAL);
         this.layersPopover.setMapType(MapView.MapType.AERIAL);
-    },
+    }
 
-    _onToggleSidebarChangeState: function(action, variant) {
+    _onToggleSidebarChangeState(action, variant) {
         action.set_state(variant);
 
         let reveal = variant.get_boolean();
         this._sidebar.set_reveal_child(reveal);
-    },
+    }
 
-    _setRevealSidebar: function(value) {
+    _setRevealSidebar(value) {
         let action = this.lookup_action('toggle-sidebar');
         action.change_state(GLib.Variant.new_boolean(value));
-    },
+    }
 
-    _onAboutActivate: function() {
+    _onAboutActivate() {
         let aboutDialog = new Gtk.AboutDialog({
             artists: [ 'Jakub Steiner <jimmac gmail com>',
                        'Andreas Nilsson <nisses mail home se>' ],
@@ -535,9 +532,9 @@ var MainWindow = new Lang.Class({
 
         aboutDialog.show();
         aboutDialog.connect('response', () => { aboutDialog.destroy(); });
-    },
+    }
 
-    _getAttribution: function() {
+    _getAttribution() {
         let tileProviderInfo = Service.getService().tileProviderInfo;
         let attribution = _("Map data by %s and contributors").format('<a 
href="https://www.openstreetmap.org";>OpenStreetMap</a>');
 
@@ -559,9 +556,9 @@ var MainWindow = new Lang.Class({
         }
 
         return attribution;
-    },
+    }
 
-    _onOpenShapeLayer: function() {
+    _onOpenShapeLayer() {
         let fileChooser = new ShapeLayerFileChooser({
             transient_for: this,
         });
@@ -574,9 +571,9 @@ var MainWindow = new Lang.Class({
             fileChooser.destroy();
         });
         fileChooser.show();
-    },
+    }
 
-    markBusy: function() {
+    markBusy() {
         if (this._busySignalId !== 0)
             return;
 
@@ -584,9 +581,9 @@ var MainWindow = new Lang.Class({
 
         let stage = this._mapView.view.get_stage();
         this._busySignalId = stage.connect('captured-event', () => { return true; });
-    },
+    }
 
-    unmarkBusy: function() {
+    unmarkBusy() {
         this._busy.hide();
 
         let stage = this._mapView.view.get_stage();
diff --git a/src/mapBubble.js b/src/mapBubble.js
index 130d721..2ca2aa9 100644
--- a/src/mapBubble.js
+++ b/src/mapBubble.js
@@ -23,7 +23,6 @@ const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -40,12 +39,10 @@ var Button = {
     CHECK_IN: 16
 };
 
-var MapBubble = new Lang.Class({
-    Name: "MapBubble",
-    Extends: Gtk.Popover,
-    Abstract: true,
+var MapBubble = GObject.registerClass({ Abstract: true },
+class MapBubble extends Gtk.Popover {
 
-    _init: function(params) {
+    _init(params) {
         this._place = params.place;
         delete params.place;
 
@@ -67,7 +64,7 @@ var MapBubble = new Lang.Class({
 
         params.modal = false;
 
-        this.parent(params);
+        super._init(params);
         let ui = Utils.getUIObject('map-bubble', [ 'bubble-main-grid',
                                                    'bubble-image',
                                                    'bubble-thumbnail',
@@ -98,29 +95,29 @@ var MapBubble = new Lang.Class({
         }
 
         this.add(ui.bubbleMainGrid);
-    },
+    }
 
     get image() {
         return this._image;
-    },
+    }
 
     get thumbnail() {
         return this._thumbnail;
-    },
+    }
 
     get iconStack() {
         return this._iconStack;
-    },
+    }
 
     get place() {
         return this._place;
-    },
+    }
 
     get content() {
         return this._content;
-    },
+    }
 
-    _initFavoriteButton: function(button, image) {
+    _initFavoriteButton(button, image) {
         let placeStore = Application.placeStore;
         button.visible = true;
 
@@ -143,9 +140,9 @@ var MapBubble = new Lang.Class({
                                     PlaceStore.PlaceType.FAVORITE);
             }
         });
-    },
+    }
 
-    _initSendToButton: function(button) {
+    _initSendToButton(button) {
         let dialog = new SendToDialog.SendToDialog({ transient_for: this.get_toplevel(),
                                                      modal: true,
                                                      mapView: this._mapView,
@@ -160,9 +157,9 @@ var MapBubble = new Lang.Class({
             });
             dialog.show_all();
         });
-    },
+    }
 
-    _initRouteButton: function(button, routeFrom) {
+    _initRouteButton(button, routeFrom) {
         let query = Application.routeQuery;
         let from = query.points[0];
         let to = query.points[query.points.length - 1];
@@ -183,9 +180,9 @@ var MapBubble = new Lang.Class({
             this.destroy();
             query.thaw_notify();
         });
-    },
+    }
 
-    _initCheckInButton: function(button, matchPlace) {
+    _initCheckInButton(button, matchPlace) {
         Application.checkInManager.bind_property('hasCheckIn',
                                                  button, 'visible',
                                                  GObject.BindingFlags.DEFAULT |
diff --git a/src/mapMarker.js b/src/mapMarker.js
index 28a40bf..67685db 100644
--- a/src/mapMarker.js
+++ b/src/mapMarker.js
@@ -25,15 +25,12 @@ const Clutter = imports.gi.Clutter;
 const Gdk = imports.gi.Gdk;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const MapWalker = imports.mapWalker;
 const Utils = imports.utils;
 
-var MapMarker = new Lang.Class({
-    Name: 'MapMarker',
-    Extends: Champlain.Marker,
+var MapMarker = GObject.registerClass({
     Implements: [Champlain.Exportable],
     Abstract: true,
     Signals: {
@@ -42,9 +39,10 @@ var MapMarker = new Lang.Class({
     Properties: {
         'surface': GObject.ParamSpec.override('surface',
                                               Champlain.Exportable)
-    },
+    }
+}, class MapMarker extends Champlain.Marker {
 
-    _init: function(params) {
+    _init(params) {
         this._place = params.place;
         delete params.place;
 
@@ -55,7 +53,7 @@ var MapMarker = new Lang.Class({
         params.longitude = this.place.location.longitude;
         params.selectable = true;
 
-        this.parent(params);
+        super._init(params);
 
         this.connect('notify::size', this._translateMarkerPosition.bind(this));
         if (this._mapView) {
@@ -76,25 +74,25 @@ var MapMarker = new Lang.Class({
             this._view.connect('notify::longitude', this._onViewUpdated.bind(this));
             this._view.connect('notify::zoom-level', this._onViewUpdated.bind(this));
         }
-    },
+    }
 
     get surface() {
         return this._surface;
-    },
+    }
 
     set surface(v) {
         this._surface = v;
-    },
+    }
 
-    vfunc_get_surface: function() {
+    vfunc_get_surface() {
         return this._surface;
-    },
+    }
 
-    vfunc_set_surface: function(surface) {
+    vfunc_set_surface(surface) {
         this._surface = surface;
-    },
+    }
 
-    _actorFromIconName: function(name, size, color) {
+    _actorFromIconName(name, size, color) {
         try {
             let theme = Gtk.IconTheme.get_default();
             let pixbuf;
@@ -130,9 +128,9 @@ var MapMarker = new Lang.Class({
             Utils.debug('Failed to load image: %s'.format(e.message));
             return null;
         }
-    },
+    }
 
-    _onButtonPress: function(marker, event) {
+    _onButtonPress(marker, event) {
         // Zoom in on marker on double-click
         if (event.get_click_count() > 1) {
             if (this._view.zoom_level < this._view.max_zoom_level) {
@@ -140,11 +138,11 @@ var MapMarker = new Lang.Class({
                 this._view.center_on(this.latitude, this.longitude);
             }
         }
-    },
+    }
 
-    _translateMarkerPosition: function() {
+    _translateMarkerPosition() {
         this.set_translation(-this.anchor.x, -this.anchor.y, 0);
-    },
+    }
 
     /**
      * Returns: The anchor point for the marker icon, relative to the
@@ -152,29 +150,29 @@ var MapMarker = new Lang.Class({
      */
     get anchor() {
         return { x: 0, y: 0 };
-    },
+    }
 
     get bubbleSpacing() {
         return 0;
-    },
+    }
 
     get place() {
         return this._place;
-    },
+    }
 
     get bubble() {
         if (this._bubble === undefined)
             this._bubble = this._createBubble();
 
         return this._bubble;
-    },
+    }
 
-    _createBubble: function() {
+    _createBubble() {
         // Markers has no associated bubble by default
         return null;
-    },
+    }
 
-    _positionBubble: function(bubble) {
+    _positionBubble(bubble) {
         let [tx, ty, tz] = this.get_translation();
         let x = this._view.longitude_to_x(this.longitude);
         let y = this._view.latitude_to_y(this.latitude);
@@ -200,9 +198,9 @@ var MapMarker = new Lang.Class({
         // Avoid bubble to cover header bar if the marker is close to the top map edge
         else if (pos.y - bubbleSize.height <= 0)
             bubble.position = Gtk.PositionType.BOTTOM;
-    },
+    }
 
-    _hideBubbleOn: function(signal, duration) {
+    _hideBubbleOn(signal, duration) {
         let sourceId = null;
         let signalId = this._view.connect(signal, () => {
             if (sourceId)
@@ -236,9 +234,9 @@ var MapMarker = new Lang.Class({
                 this._view.disconnect(signalId);
             }
         });
-    },
+    }
 
-    _initBubbleSignals: function() {
+    _initBubbleSignals() {
         this._hideBubbleOn('notify::zoom-level', 500);
         this._hideBubbleOn('notify::size');
 
@@ -278,9 +276,9 @@ var MapMarker = new Lang.Class({
             this._bubble.destroy();
             delete this._bubble;
         });
-    },
+    }
 
-    _isInsideView: function() {
+    _isInsideView() {
         let [tx, ty, tz] = this.get_translation();
         let x = this._view.longitude_to_x(this.longitude);
         let y = this._view.latitude_to_y(this.latitude);
@@ -288,53 +286,53 @@ var MapMarker = new Lang.Class({
 
         return x + tx + this.width > 0 && x + tx < mapSize.width &&
                y + ty + this.height > 0 && y + ty < mapSize.height;
-    },
+    }
 
-    _onViewUpdated: function() {
+    _onViewUpdated() {
         if (this.bubble) {
             if (this._isInsideView())
                 this._positionBubble(this.bubble);
             else
                 this.bubble.hide();
         }
-    },
+    }
 
-    showBubble: function() {
+    showBubble() {
         if (this.bubble && !this.bubble.visible && this._isInsideView()) {
             this._initBubbleSignals();
             this.bubble.show();
             this._positionBubble(this.bubble);
         }
-    },
+    }
 
-    hideBubble: function() {
+    hideBubble() {
         if (this._bubble)
             this._bubble.hide();
-    },
+    }
 
     get walker() {
         if (this._walker === undefined)
             this._walker = new MapWalker.MapWalker(this.place, this._mapView);
 
         return this._walker;
-    },
+    }
 
-    zoomToFit: function() {
+    zoomToFit() {
         this.walker.zoomToFit();
-    },
+    }
 
-    goTo: function(animate) {
+    goTo(animate) {
         Utils.once(this.walker, 'gone-to', () => { this.emit('gone-to'); });
         this.walker.goTo(animate);
-    },
+    }
 
-    goToAndSelect: function(animate) {
+    goToAndSelect(animate) {
         Utils.once(this, 'gone-to', () => { this.selected = true; });
 
         this.goTo(animate);
-    },
+    }
 
-    _onMarkerSelected: function() {
+    _onMarkerSelected() {
         if (this.selected)
             this.showBubble();
         else
diff --git a/src/mapSource.js b/src/mapSource.js
index 430c99f..5d79e7e 100644
--- a/src/mapSource.js
+++ b/src/mapSource.js
@@ -22,9 +22,9 @@ const Clutter = imports.gi.Clutter;
 const GdkPixbuf = imports.gi.GdkPixbuf;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const GtkClutter = imports.gi.GtkClutter;
-const Lang = imports.lang;
 const System = imports.system;
 
 const Service = imports.service;
@@ -38,12 +38,11 @@ const _MEMORY_CACHE_SIZE_LIMIT = 100; /* number of tiles */
 const _LOGO_PADDING_X = 10;
 const _LOGO_PADDING_Y = 25;
 
-var AttributionLogo = new Lang.Class({
-    Name: 'AttributionLogo',
-        Extends: GtkClutter.Actor,
+var AttributionLogo = GObject.registerClass({},
+class AttributionLogo extends GtkClutter.Actor {
 
-    _init: function(view) {
-        this.parent();
+    _init(view) {
+        super._init();
 
         if (_attributionImage)
             this.contents = _attributionImage;
@@ -54,15 +53,15 @@ var AttributionLogo = new Lang.Class({
         view.connect('notify::height', () => { this._updatePosition(view); });
 
         this._updatePosition(view);
-    },
+    }
 
-    _updatePosition: function(view) {
+    _updatePosition(view) {
         let width = _attributionImage.pixbuf.width;
         let height = _attributionImage.pixbuf.height;
 
         this.set_position(view.width  - width  - _LOGO_PADDING_X,
                           view.height - height - _LOGO_PADDING_Y);
-    },
+    }
 });
 
 function _updateAttributionImage(source) {
diff --git a/src/mapView.js b/src/mapView.js
index 02d9527..5985667 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -25,7 +25,6 @@ const GObject = imports.gi.GObject;
 const Geocode = imports.gi.GeocodeGlib;
 const Gio = imports.gi.Gio;
 const GtkChamplain = imports.gi.GtkChamplain;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -86,9 +85,7 @@ const DASHED_ROUTE_LINE_FILLED_LENGTH = 5;
 // length of gaps of dashed lines used for walking legs of transit itineraries
 const DASHED_ROUTE_LINE_GAP_LENGTH = 5;
 
-var MapView = new Lang.Class({
-    Name: 'MapView',
-    Extends: GtkChamplain.Embed,
+var MapView = GObject.registerClass({
     Properties: {
         // this property is true when the routing sidebar is active
         'routingOpen': GObject.ParamSpec.boolean('routingOpen',
@@ -113,10 +110,11 @@ var MapView = new Lang.Class({
         'view-moved': {},
         'marker-selected': { param_types: [Champlain.Marker] }
     },
+}, class MapView extends GtkChamplain.Embed {
 
     get routingOpen() {
         return this._routingOpen || this._instructionMarkerLayer.visible;
-    },
+    }
 
     set routingOpen(value) {
         let isValid = Application.routeQuery.isValid();
@@ -129,19 +127,19 @@ var MapView = new Lang.Class({
         if (!value)
             this.routeShowing = false;
         this.notify('routingOpen');
-    },
+    }
 
     get routeShowing() {
         return this._routeShowing;
-    },
+    }
 
     set routeShowing(value) {
         this._routeShowing = value;
         this.notify('routeShowing');
-    },
+    }
 
-    _init: function(params) {
-        this.parent();
+    _init(params) {
+        super._init();
 
         let mapType = params.mapType || MapType.STREET;
         delete params.mapType;
@@ -159,9 +157,9 @@ var MapView = new Lang.Class({
                                     this._updateUserLocation.bind(this));
         this._storeId = 0;
         this._connectRouteSignals();
-    },
+    }
 
-    _initScale: function(view) {
+    _initScale(view) {
         this._scale = new Champlain.Scale({ visible: true });
         this._scale.connect_view(view);
 
@@ -175,9 +173,9 @@ var MapView = new Lang.Class({
         this._scale.set_x_align(Clutter.ActorAlign.START);
         this._scale.set_y_align(Clutter.ActorAlign.END);
         view.add_child(this._scale);
-    },
+    }
 
-    _initView: function() {
+    _initView() {
         let view = this.get_view();
         view.zoom_level = 3;
         view.min_zoom_level = MapMinZoom;
@@ -198,10 +196,10 @@ var MapView = new Lang.Class({
 
         this._initScale(view);
         return view;
-    },
+    }
 
     /* create and store a route layer, pass true to get a dashed line */
-    _createRouteLayer: function(dashed, lineColor, width) {
+    _createRouteLayer(dashed, lineColor, width) {
         let red = Color.parseColor(lineColor, 0);
         let green = Color.parseColor(lineColor, 1);
         let blue = Color.parseColor(lineColor, 2);
@@ -220,9 +218,9 @@ var MapView = new Lang.Class({
         this.view.add_layer(routeLayer);
 
         return routeLayer;
-    },
+    }
 
-    _clearRouteLayers: function() {
+    _clearRouteLayers() {
         this._routeLayers.forEach((routeLayer) => {
             routeLayer.remove_all();
             routeLayer.visible = false;
@@ -230,9 +228,9 @@ var MapView = new Lang.Class({
         });
 
         this._routeLayers = [];
-    },
+    }
 
-    _initLayers: function() {
+    _initLayers() {
         let mode = Champlain.SelectionMode.SINGLE;
 
         this._userLocationLayer = new Champlain.MarkerLayer({ selection_mode: mode });
@@ -252,14 +250,14 @@ var MapView = new Lang.Class({
         ShapeLayer.SUPPORTED_TYPES.push(GpxShapeLayer.GpxShapeLayer);
 
         this._routeLayers = [];
-    },
+    }
 
-    _ensureInstructionLayerAboveRouteLayers: function() {
+    _ensureInstructionLayerAboveRouteLayers() {
         this.view.remove_layer(this._instructionMarkerLayer);
         this.view.add_layer(this._instructionMarkerLayer);
-    },
+    }
 
-    _connectRouteSignals: function() {
+    _connectRouteSignals() {
         let route = Application.routingDelegator.graphHopper.route;
         let transitPlan = Application.routingDelegator.openTripPlanner.plan;
         let query = Application.routeQuery;
@@ -290,9 +288,9 @@ var MapView = new Lang.Class({
         });
 
         query.connect('notify', () => { this.routingOpen = query.isValid(); });
-    },
+    }
 
-    setMapType: function(mapType) {
+    setMapType(mapType) {
         if (this._mapType && this._mapType === mapType)
             return;
 
@@ -334,13 +332,13 @@ var MapView = new Lang.Class({
         overlay_sources.forEach((source) => {
             this.view.add_overlay_source(source, 255);
         });
-    },
+    }
 
-    toggleScale: function() {
+    toggleScale() {
         this._scale.visible = !this._scale.visible;
-    },
+    }
 
-    openShapeLayers: function(files) {
+    openShapeLayers(files) {
         let bbox = new Champlain.BoundingBox();
         let ret = true;
         files.forEach((file) => {
@@ -365,22 +363,22 @@ var MapView = new Lang.Class({
 
         this.gotoBBox(bbox);
         return ret;
-    },
+    }
 
-    removeShapeLayer: function(shapeLayer) {
+    removeShapeLayer(shapeLayer) {
         shapeLayer.unload();
         let i = this._findShapeLayerIndex(shapeLayer.file);
         this.shapeLayerStore.remove(i);
-    },
+    }
 
-    _findShapeLayerIndex: function(file) {
+    _findShapeLayerIndex(file) {
         for (let i = 0; i < this.shapeLayerStore.get_n_items(); i++)
             if (this.shapeLayerStore.get_item(i).file.equal(file))
                 return i;
         return -1;
-    },
+    }
 
-    goToGeoURI: function(uri) {
+    goToGeoURI(uri) {
         try {
             let location = new Location.Location({ heading: -1 });
             location.set_from_uri(uri);
@@ -397,9 +395,9 @@ var MapView = new Lang.Class({
             Application.notificationManager.showMessage(msg);
             Utils.debug("failed to open GeoURI: %s".format(e.message));
         }
-    },
+    }
 
-    gotoUserLocation: function(animate) {
+    gotoUserLocation(animate) {
         if (!this._userLocation)
             return;
 
@@ -408,15 +406,15 @@ var MapView = new Lang.Class({
             this.emit('gone-to-user-location');
         });
         this._userLocation.goTo(animate);
-    },
+    }
 
-    userLocationVisible: function() {
+    userLocationVisible() {
         let box = this.view.get_bounding_box();
 
         return box.covers(this._userLocation.latitude, this._userLocation.longitude);
-    },
+    }
 
-    _updateUserLocation: function() {
+    _updateUserLocation() {
         if (!Application.geoclue.place)
             return;
 
@@ -440,15 +438,15 @@ var MapView = new Lang.Class({
         this._userLocation.selected = previousSelected;
 
         this.emit('user-location-changed');
-    },
+    }
 
-    _storeLocation: function() {
+    _storeLocation() {
         let box = this.view.get_bounding_box();
         let lastViewedLocation = [box.top, box.bottom, box.left, box.right];
         Application.settings.set('last-viewed-location', lastViewedLocation);
-    },
+    }
 
-    _goToStoredLocation: function() {
+    _goToStoredLocation() {
         if (!this.view.realized)
             return;
 
@@ -458,9 +456,9 @@ var MapView = new Lang.Class({
                                                        left: box[2],
                                                        right: box[3] });
         this.gotoBBox(bounding_box, true);
-    },
+    }
 
-    gotoBBox: function(bbox, linear) {
+    gotoBBox(bbox, linear) {
         if (!bbox.is_valid()) {
             Utils.debug('Bounding box is invalid');
             return;
@@ -476,9 +474,9 @@ var MapView = new Lang.Class({
                                                     right  : bbox.right })
         });
         new MapWalker.MapWalker(place, this).goTo(true, linear);
-    },
+    }
 
-    showTurnPoint: function(turnPoint) {
+    showTurnPoint(turnPoint) {
         if (this._turnPointMarker)
             this._turnPointMarker.destroy();
 
@@ -489,9 +487,9 @@ var MapView = new Lang.Class({
                                                                       mapView: this });
         this._instructionMarkerLayer.add_marker(this._turnPointMarker);
         this._turnPointMarker.goTo();
-    },
+    }
 
-    showTransitStop: function(transitStop, transitLeg) {
+    showTransitStop(transitStop, transitLeg) {
         if (this._turnPointMarker)
             this._turnPointMarker.destroy();
 
@@ -500,9 +498,9 @@ var MapView = new Lang.Class({
                                                                       mapView: this });
         this._instructionMarkerLayer.add_marker(this._turnPointMarker);
         this._turnPointMarker.goTo();
-    },
+    }
 
-    showContact: function(contact) {
+    showContact(contact) {
         let places = contact.get_places();
         if (places.length === 0)
             return;
@@ -520,9 +518,9 @@ var MapView = new Lang.Class({
             this.gotoBBox(contact.bounding_box);
         else
             new MapWalker.MapWalker(places[0], this).goTo(true);
-    },
+    }
 
-    _showStoredRoute: function(stored) {
+    _showStoredRoute(stored) {
         let query = Application.routeQuery;
         let route = Application.routingDelegator.graphHopper.route;
 
@@ -545,9 +543,9 @@ var MapView = new Lang.Class({
             query.thaw_notify();
         });
         route.reset();
-    },
+    }
 
-    showPlace: function(place, animation) {
+    showPlace(place, animation) {
         this._placeLayer.remove_all();
 
         if (place instanceof StoredRoute.StoredRoute) {
@@ -561,9 +559,9 @@ var MapView = new Lang.Class({
 
         this._placeLayer.add_marker(placeMarker);
         placeMarker.goToAndSelect(animation);
-    },
+    }
 
-    showRoute: function(route) {
+    showRoute(route) {
         let routeLayer;
 
         this._clearRouteLayers();
@@ -578,9 +576,9 @@ var MapView = new Lang.Class({
 
         this._showDestinationTurnpoints();
         this.gotoBBox(route.bbox);
-    },
+    }
 
-    _showDestinationTurnpoints: function() {
+    _showDestinationTurnpoints() {
         let route = Application.routingDelegator.graphHopper.route;
         let query = Application.routeQuery;
         let pointIndex = 0;
@@ -596,9 +594,9 @@ var MapView = new Lang.Class({
                 pointIndex++;
             }
         }, this);
-    },
+    }
 
-    _showTransitItinerary: function(itinerary) {
+    _showTransitItinerary(itinerary) {
         this.gotoBBox(itinerary.bbox);
         this._clearRouteLayers();
         this._placeLayer.remove_all();
@@ -676,13 +674,13 @@ var MapView = new Lang.Class({
         this._instructionMarkerLayer.add_marker(arrival);
 
         this.routingOpen = true;
-    },
+    }
 
-    _showTransitPlan: function(plan) {
+    _showTransitPlan(plan) {
         this.gotoBBox(plan.bbox);
-    },
+    }
 
-    _onViewMoved: function() {
+    _onViewMoved() {
         this.emit('view-moved');
         if (this._storeId !== 0)
             return;
@@ -691,9 +689,9 @@ var MapView = new Lang.Class({
             this._storeId = 0;
             this._storeLocation();
         });
-    },
+    }
 
-    onSetMarkerSelected: function(selectedMarker) {
+    onSetMarkerSelected(selectedMarker) {
         this.emit('marker-selected', selectedMarker);
     }
 });
diff --git a/src/mapWalker.js b/src/mapWalker.js
index 06a03ec..d433abb 100644
--- a/src/mapWalker.js
+++ b/src/mapWalker.js
@@ -24,7 +24,7 @@
 const Champlain = imports.gi.Champlain;
 const Clutter = imports.gi.Clutter;
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Location = imports.location;
 const Utils = imports.utils;
@@ -33,17 +33,21 @@ const _MAX_DISTANCE = 19850; // half of Earth's circumference (km)
 const _MIN_ANIMATION_DURATION = 2000; // msec
 const _MAX_ANIMATION_DURATION = 5000; // msec
 
-var MapWalker = new Lang.Class({
-    Name: 'MapWalker',
+var MapWalker = GObject.registerClass({
+    Signals: {
+        'gone-to': { }
+    }
+}, class MapWalker extends GObject.Object {
 
-    _init: function(place, mapView) {
+    _init(place, mapView) {
         this.place = place;
         this._mapView = mapView;
         this._view = mapView.view;
         this._boundingBox = this._createBoundingBox(this.place);
-    },
+        super._init();
+    }
 
-    _createBoundingBox: function(place) {
+    _createBoundingBox(place) {
         if (place.bounding_box !== null) {
             return new Champlain.BoundingBox({ top: place.bounding_box.top,
                                                bottom: place.bounding_box.bottom,
@@ -51,10 +55,10 @@ var MapWalker = new Lang.Class({
                                                right: place.bounding_box.right });
         } else
             return null;
-    },
+    }
 
     // Zoom to the maximal zoom-level that fits the place type
-    zoomToFit: function() {
+    zoomToFit() {
         let zoom;
         if (this._boundingBox !== null && this._boundingBox.is_valid()) {
             this._view.zoom_level = this._view.max_zoom_level;
@@ -81,9 +85,9 @@ var MapWalker = new Lang.Class({
             this._view.center_on(this.place.location.latitude,
                                  this.place.location.longitude);
         }
-    },
+    }
 
-    goTo: function(animate, linear) {
+    goTo(animate, linear) {
         Utils.debug('Going to ' + [this.place.name,
                     this.place.location.latitude,
                     this.place.location.longitude].join(' '));
@@ -129,9 +133,9 @@ var MapWalker = new Lang.Class({
                 });
             });
         }
-    },
+    }
 
-    _ensureVisible: function(fromLocation) {
+    _ensureVisible(fromLocation) {
         let visibleBox = null;
 
         if (this._boundingBox !== null && this._boundingBox.is_valid()) {
@@ -153,9 +157,9 @@ var MapWalker = new Lang.Class({
         }
 
         this._view.ensure_visible(visibleBox, true);
-    },
+    }
 
-    _boxCovers: function(coverBox) {
+    _boxCovers(coverBox) {
         if (this._boundingBox === null)
             return false;
 
@@ -172,9 +176,9 @@ var MapWalker = new Lang.Class({
             return false;
 
         return true;
-    },
+    }
 
-    _updateGoToDuration: function(fromLocation) {
+    _updateGoToDuration(fromLocation) {
         let toLocation = this.place.location;
 
         let distance = fromLocation.get_distance_from(toLocation);
@@ -189,4 +193,3 @@ var MapWalker = new Lang.Class({
         this._view.goto_animation_duration = duration / 2;
     }
 });
-Utils.addSignalMethods(MapWalker.prototype);
diff --git a/src/notification.js b/src/notification.js
index e78a331..a1fd790 100644
--- a/src/notification.js
+++ b/src/notification.js
@@ -19,23 +19,22 @@
  * Author: Mattias Bengtsson <mattias jc bengtsson gmail com>
  */
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Utils = imports.utils;
 
-var Notification = new Lang.Class({
-    Name: 'Notification',
-    Extends: Gtk.Revealer,
+var Notification = GObject.registerClass({
     Signals: {
         'revealed': { },
         'dismissed': { }
     },
-    Abstract: true,
+    Abstract: true
+}, class Notification extends Gtk.Revealer {
 
-    _init: function() {
-        this.parent({ visible: true,
+    _init() {
+        super._init({ visible: true,
                       halign: Gtk.Align.CENTER,
                       valign: Gtk.Align.START });
 
@@ -45,17 +44,17 @@ var Notification = new Lang.Class({
 
         this._ui.dismissButton.connect('clicked', this.dismiss.bind(this));
         this.add(this._ui.frame);
-    },
+    }
 
-    reveal: function() {
+    reveal() {
         this._setRevealAndEmit(true, 'revealed');
-    },
+    }
 
-    dismiss: function() {
+    dismiss() {
         this._setRevealAndEmit(false, 'dismissed');
-    },
+    }
 
-    _setRevealAndEmit: function(state, signal) {
+    _setRevealAndEmit(state, signal) {
         // We only want to send a dismissed / shown -signal
         // if there is an actual change in revealed state.
         if (state !== this.child_revealed) {
@@ -68,12 +67,11 @@ var Notification = new Lang.Class({
     }
 });
 
-var Plain = new Lang.Class({
-    Name: 'Plain',
-    Extends: Notification,
+var Plain = GObject.registerClass(
+class Plain extends Notification {
 
-    _init: function(msg) {
-        this.parent();
+    _init(msg) {
+        super._init();
         let label = new Gtk.Label({ visible : true,
                                     hexpand : true,
                                     halign  : Gtk.Align.START,
diff --git a/src/notificationManager.js b/src/notificationManager.js
index ba2fae1..3622d4b 100644
--- a/src/notificationManager.js
+++ b/src/notificationManager.js
@@ -20,21 +20,19 @@
  *         Jonas Danielsson <jonas threetimestwo org>
  */
 
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Notification = imports.notification;
 
 const _TIMEOUT = 5000; /* ms */
 
-var NotificationManager = new Lang.Class({
-    Name: 'NotificationManager',
+var NotificationManager = class NotificationManager {
 
-    _init: function(overlay) {
+    constructor(overlay) {
         this._overlay = overlay;
-    },
+    }
 
-    _add: function(notification) {
+    _add(notification) {
         this._current = notification;
         if (!(notification instanceof Notification.Plain)) {
             let dismissId = notification.connect('dismissed', () => {
@@ -46,18 +44,18 @@ var NotificationManager = new Lang.Class({
         this._overlay.add_overlay(notification);
         Mainloop.timeout_add(_TIMEOUT, notification.dismiss.bind(notification));
         notification.reveal();
-    },
+    }
 
-    showMessage: function (msg) {
+    showMessage(msg) {
         let notification = new Notification.Plain(msg);
         notification.connect('dismissed', () => {
             this._current = null;
             notification.destroy();
         });
         this.showNotification(notification);
-    },
+    }
 
-    showNotification: function(notification) {
+    showNotification(notification) {
         if(notification.get_parent() === this._overlay)
             return;
         if (!this._current) {
@@ -68,4 +66,4 @@ var NotificationManager = new Lang.Class({
                                  this._add.bind(this, notification));
         }
     }
-});
+};
diff --git a/src/openTripPlanner.js b/src/openTripPlanner.js
index 58254b8..f1b8ad2 100644
--- a/src/openTripPlanner.js
+++ b/src/openTripPlanner.js
@@ -19,8 +19,6 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Champlain = imports.gi.Champlain;
 const GLib = imports.gi.GLib;
 const Soup = imports.gi.Soup;
@@ -122,46 +120,41 @@ const NUM_STOPS_TO_TRY = 5;
 // gap to use when fetching additional routes
 const GAP_BEFORE_MORE_RESULTS = 120;
 
-var OpenTripPlanner = new Lang.Class({
-    Name: 'OpenTripPlanner',
+var OpenTripPlanner = class OpenTripPlanner {
 
-    _init: function(params) {
+    constructor(params) {
         this._session = new Soup.Session();
         /* initially set routers as updated far back in the past to force
          * a download when first request
          */
         this._routersUpdatedTimestamp = 0;
         this._query = params.query;
-        delete params.query;
         this._graphHopper = params.graphHopper;
-        delete params.graphHopper;
         this._plan = new TransitPlan.Plan();
         this._baseUrl = this._getBaseUrl();
         this._walkingRoutes = [];
         this._extendPrevious = false;
-
-        this.parent(params);
-    },
+    }
 
     get plan() {
         return this._plan;
-    },
+    }
 
     get enabled() {
         return this._baseUrl !== null;
-    },
+    }
 
-    fetchFirstResults: function() {
+    fetchFirstResults() {
         this._extendPrevious = false;
         this._fetchRoute();
-    },
+    }
 
-    fetchMoreResults: function() {
+    fetchMoreResults() {
         this._extendPrevious = true;
         this._fetchRoute();
-    },
+    }
 
-    _getBaseUrl: function() {
+    _getBaseUrl() {
         let debugUrl = GLib.getenv('OTP_BASE_URL');
 
         if (debugUrl) {
@@ -176,16 +169,16 @@ var OpenTripPlanner = new Lang.Class({
                 return null;
             }
         }
-    },
+    }
 
-    _getRouterUrl: function(router) {
+    _getRouterUrl(router) {
         if (!router || router.length === 0)
             router = 'default';
 
         return this._baseUrl + '/routers/' + router;
-    },
+    }
 
-    _fetchRouters: function(callback) {
+    _fetchRouters(callback) {
         let currentTime = (new Date()).getTime();
 
         if (currentTime - this._routersUpdatedTimestamp < ROUTERS_TIMEOUT) {
@@ -211,9 +204,9 @@ var OpenTripPlanner = new Lang.Class({
                 }
             });
         }
-    },
+    }
 
-    _getRoutersForPlace: function(place) {
+    _getRoutersForPlace(place) {
         let routers = [];
 
         this._routers.routerInfo.forEach((routerInfo) => {
@@ -231,19 +224,19 @@ var OpenTripPlanner = new Lang.Class({
         });
 
         return routers;
-    },
+    }
 
     /* Note: this is theoretically slow (O(n*m)), but we will have filtered
      * possible routers for the starting and ending query point, so they should
      * be short (in many cases just one element)
      */
-    _routerIntersection: function(routers1, routers2) {
+    _routerIntersection(routers1, routers2) {
         return routers1.filter(function(n) {
             return routers2.indexOf(n) != -1;
         });
-    },
+    }
 
-    _getMode: function(routeType) {
+    _getMode(routeType) {
         switch (routeType) {
         case TransitPlan.RouteType.TRAM:
             return 'TRAM';
@@ -258,17 +251,17 @@ var OpenTripPlanner = new Lang.Class({
         default:
             throw new Error('unhandled route type');
         }
-    },
+    }
 
-    _getModes: function(options) {
+    _getModes(options) {
         let modes = options.transitTypes.map((transitType) => {
             return this._getMode(transitType);
         });
 
         return modes.join(',');
-    },
+    }
 
-    _selectBestStopRecursive: function(stops, index, stopIndex, callback) {
+    _selectBestStopRecursive(stops, index, stopIndex, callback) {
         if (index < stops.length) {
             let points = this._query.filledPoints;
             let stop = stops[index];
@@ -311,20 +304,20 @@ var OpenTripPlanner = new Lang.Class({
             stops.forEach((stop) => { Utils.debug(JSON.stringify(stop, '', 2)); });
             callback(stops[0]);
         }
-    },
+    }
 
     /* stopIndex here is the index of stop (i.e. starting point, intermediate
      * stop, final stop
      */
-    _selectBestStop: function(stops, stopIndex, callback) {
+    _selectBestStop(stops, stopIndex, callback) {
         this._selectBestStopRecursive(stops, 0, stopIndex, callback);
-    },
+    }
 
-    _sortTransitStops: function(s1, s2) {
+    _sortTransitStops(s1, s2) {
         return s1.dist > s2.dist;
-    },
+    }
 
-    _fetchRoutesForStop: function(router, stop, callback) {
+    _fetchRoutesForStop(router, stop, callback) {
         let query = new HTTP.Query();
         let uri = new Soup.URI(this._getRouterUrl(router) +
                                '/index/stops/' + stop.id + '/routes');
@@ -342,9 +335,9 @@ var OpenTripPlanner = new Lang.Class({
                 callback(routes);
             }
         });
-    },
+    }
 
-    _routeMatchesSelectedModes: function(route) {
+    _routeMatchesSelectedModes(route) {
         let desiredTransitTypes = this._query.transitOptions.transitTypes;
 
         for (let i = 0; i < desiredTransitTypes.length; i++) {
@@ -364,9 +357,9 @@ var OpenTripPlanner = new Lang.Class({
         }
 
         return false;
-    },
+    }
 
-    _filterStopsRecursive: function(router, stops, index, filteredStops, callback) {
+    _filterStopsRecursive(router, stops, index, filteredStops, callback) {
         if (index < stops.length) {
             let stop = stops[index];
 
@@ -385,13 +378,13 @@ var OpenTripPlanner = new Lang.Class({
         } else {
             callback(filteredStops);
         }
-    },
+    }
 
-    _filterStops: function(router, stops, callback) {
+    _filterStops(router, stops, callback) {
         this._filterStopsRecursive(router, stops, 0, [], callback);
-    },
+    }
 
-    _fetchTransitStopsRecursive: function(router, index, result, callback) {
+    _fetchTransitStopsRecursive(router, index, result, callback) {
         let points = this._query.filledPoints;
 
         if (index < points.length) {
@@ -451,30 +444,30 @@ var OpenTripPlanner = new Lang.Class({
         } else {
             callback(result);
         }
-    },
+    }
 
-    _fetchTransitStops: function(router, callback) {
+    _fetchTransitStops(router, callback) {
         this._fetchTransitStopsRecursive(router, 0, [], callback);
-    },
+    }
 
     // get a time suitably formatted for the OpenTripPlanner query param
-    _formatTime: function(time, offset) {
+    _formatTime(time, offset) {
         let utcTimeWithOffset = (time + offset) / 1000;
         let date = GLib.DateTime.new_from_unix_utc(utcTimeWithOffset);
 
         return date.format('%R');
-    },
+    }
 
     // get a date suitably formatted for the OpenTripPlanner query param
-    _formatDate: function(time, offset) {
+    _formatDate(time, offset) {
         let utcTimeWithOffset = (time + offset) / 1000;
         let date = GLib.DateTime.new_from_unix_utc(utcTimeWithOffset);
 
         return date.format('%F');
-    },
+    }
 
     // create parameter map for the request, given query and options
-    _createParams: function(stops) {
+    _createParams(stops) {
         let params = { fromPlace: stops[0].id,
                        toPlace: stops.last().id };
         let intermediatePlaces = [];
@@ -539,9 +532,9 @@ var OpenTripPlanner = new Lang.Class({
             params.mode = this._getModes(options);
 
         return params;
-    },
+    }
 
-    _fetchRoutesForRouter: function(router, callback) {
+    _fetchRoutesForRouter(router, callback) {
         this._fetchTransitStops(router, (stops) => {
             let points = this._query.filledPoints;
 
@@ -578,9 +571,9 @@ var OpenTripPlanner = new Lang.Class({
                 }
             });
         });
-    },
+    }
 
-    _fetchRoutesRecursive: function(routers, index, result, callback) {
+    _fetchRoutesRecursive(routers, index, result, callback) {
         if (index < routers.length) {
             let router = routers[index];
 
@@ -595,26 +588,26 @@ var OpenTripPlanner = new Lang.Class({
         } else {
             callback(result);
         }
-    },
+    }
 
-    _fetchRoutes: function(routers, callback) {
+    _fetchRoutes(routers, callback) {
         this._fetchRoutesRecursive(routers, 0, [], callback);
-    },
+    }
 
-    _reset: function() {
+    _reset() {
         this._extendPrevious = false;
         if (this._query.latest)
             this._query.latest.place = null;
         else
             this.plan.reset();
-    },
+    }
 
     /* Indicate that no routes where found, either shows the "No route found"
      * notification, or in case of loading additional (later/earlier) results,
      * indicate no such where found, so that the sidebar can disable the
      * "load more" functionallity as appropriate.
      */
-    _noRouteFound: function() {
+    _noRouteFound() {
         if (this._extendPrevious) {
             let message = this._query.arriveBy ?
                           _("No earlier alternatives found.") :
@@ -626,9 +619,9 @@ var OpenTripPlanner = new Lang.Class({
             Application.notificationManager.showMessage(_("No route found."));
             this._reset();
         }
-    },
+    }
 
-    _fetchRoute: function() {
+    _fetchRoute() {
         this._fetchRouters((success) => {
             if (success) {
                 let points = this._query.filledPoints;
@@ -664,13 +657,13 @@ var OpenTripPlanner = new Lang.Class({
                 this._reset();
             }
         });
-    },
+    }
 
-    _isOnlyWalkingItinerary: function(itinerary) {
+    _isOnlyWalkingItinerary(itinerary) {
         return itinerary.legs.length === 1 && !itinerary.legs[0].transit;
-    },
+    }
 
-    _recalculateItineraries: function(itineraries) {
+    _recalculateItineraries(itineraries) {
         // filter out itineraries with only walking
         let newItineraries = [];
 
@@ -683,9 +676,9 @@ var OpenTripPlanner = new Lang.Class({
          * top if the total distance is below some threashhold?
          */
         this._recalculateItinerariesRecursive(newItineraries, 0);
-    },
+    }
 
-    _isItineraryRealistic: function(itinerary) {
+    _isItineraryRealistic(itinerary) {
         for (let i = 0; i < itinerary.legs.length; i++) {
             let leg = itinerary.legs[i];
 
@@ -711,9 +704,9 @@ var OpenTripPlanner = new Lang.Class({
         }
 
         return true;
-    },
+    }
 
-    _recalculateItinerariesRecursive: function(itineraries, index) {
+    _recalculateItinerariesRecursive(itineraries, index) {
         if (index < itineraries.length) {
             this._recalculateItinerary(itineraries[index], (itinerary) => {
                 itineraries[index] = itinerary;
@@ -759,21 +752,21 @@ var OpenTripPlanner = new Lang.Class({
                 this._noRouteFound();
             }
         }
-    },
+    }
 
     // create a straight-line "as the crow flies" polyline between two places
-    _createStraightPolyline: function(fromLoc, toLoc) {
+    _createStraightPolyline(fromLoc, toLoc) {
         return [new Champlain.Coordinate({ latitude: fromLoc.latitude,
                                            longitude: fromLoc.longitude }),
                 new Champlain.Coordinate({ latitude: toLoc.latitude,
                                            longitude: toLoc.longitude })];
-    },
+    }
 
     /* Creates a new walking leg given start and end places, and a route
      * obtained from GraphHopper. If the route is undefined (which happens if
      * GraphHopper failed to obtain a walking route, approximate it with a
      * straight line. */
-    _createWalkingLeg: function(from, to, fromName, toName, route) {
+    _createWalkingLeg(from, to, fromName, toName, route) {
         let fromLocation = from.place.location;
         let toLocation = to.place.location;
         let fromCoordinate = [fromLocation.latitude, fromLocation.longitude];
@@ -796,12 +789,12 @@ var OpenTripPlanner = new Lang.Class({
                                      duration: duration,
                                      distance: distance,
                                      walkingInstructions: walkingInstructions });
-    },
+    }
 
     /* fetches walking route and stores the route for the given coordinate
      * pair to avoid requesting the same route over and over from GraphHopper
      */
-    _fetchWalkingRoute: function(points, callback) {
+    _fetchWalkingRoute(points, callback) {
         let index = points[0].place.location.latitude + ',' +
                     points[0].place.location.longitude + ';' +
                     points[1].place.location.latitude + ',' +
@@ -818,9 +811,9 @@ var OpenTripPlanner = new Lang.Class({
         } else {
             callback(route);
         }
-    },
+    }
 
-    _recalculateItinerary: function(itinerary, callback) {
+    _recalculateItinerary(itinerary, callback) {
         let from = this._query.filledPoints[0];
         let to = this._query.filledPoints.last();
 
@@ -892,9 +885,9 @@ var OpenTripPlanner = new Lang.Class({
              */
             this._recalculateItineraryRecursive(itinerary, 0, callback);
         }
-    },
+    }
 
-    _createQueryPointForCoord: function(coord) {
+    _createQueryPointForCoord(coord) {
         let location = new Location.Location({ latitude: coord[0],
                                                longitude: coord[1],
                                                accuracy: 0 });
@@ -903,9 +896,9 @@ var OpenTripPlanner = new Lang.Class({
 
         point.place = place;
         return point;
-    },
+    }
 
-    _recalculateItineraryRecursive: function(itinerary, index, callback) {
+    _recalculateItineraryRecursive(itinerary, index, callback) {
         if (index < itinerary.legs.length) {
             let leg = itinerary.legs[index];
             if (index === 0) {
@@ -1103,9 +1096,9 @@ var OpenTripPlanner = new Lang.Class({
         } else {
             callback(itinerary);
         }
-    },
+    }
 
-    _getRoutersForPoints: function(points) {
+    _getRoutersForPoints(points) {
         let startRouters = this._getRoutersForPlace(points[0].place);
         let endRouters =
             this._getRoutersForPlace(points.last().place);
@@ -1114,27 +1107,27 @@ var OpenTripPlanner = new Lang.Class({
             this._routerIntersection(startRouters, endRouters);
 
         return intersectingRouters;
-    },
+    }
 
-    _createItineraries: function(itineraries) {
+    _createItineraries(itineraries) {
         return itineraries.map((itinerary) => { return this._createItinerary(itinerary); });
-    },
+    }
 
-    _createItinerary: function(itinerary) {
+    _createItinerary(itinerary) {
         let legs = this._createLegs(itinerary.legs);
         return new TransitPlan.Itinerary({ duration:  itinerary.duration,
                                            transfers: itinerary.transfers,
                                            departure: itinerary.startTime,
                                            arrival:   itinerary.endTime,
                                            legs:      legs});
-    },
+    }
 
-    _createLegs: function(legs) {
+    _createLegs(legs) {
         return legs.map((leg) => { return this._createLeg(leg); });
-    },
+    }
 
     /* check if a string is a valid hex RGB string */
-    _isValidHexColor: function(string) {
+    _isValidHexColor(string) {
         if (string && string.length === 6) {
             let regex = /^[A-Fa-f0-9]/;
 
@@ -1142,9 +1135,9 @@ var OpenTripPlanner = new Lang.Class({
         }
 
         return false;
-    },
+    }
 
-    _createLeg: function(leg) {
+    _createLeg(leg) {
         let polyline = EPAF.decode(leg.legGeometry.points);
         let intermediateStops =
             this._createIntermediateStops(leg);
@@ -1184,18 +1177,18 @@ var OpenTripPlanner = new Lang.Class({
                                      color:                color,
                                      textColor:            textColor,
                                      tripShortName:        leg.tripShortName });
-    },
+    }
 
-    _createIntermediateStops: function(leg) {
+    _createIntermediateStops(leg) {
         let stops = leg.intermediateStops;
         return stops.map((stop) => { return this._createIntermediateStop(stop, leg); });
-    },
+    }
 
-    _createIntermediateStop: function(stop, leg) {
+    _createIntermediateStop(stop, leg) {
         return new TransitPlan.Stop({ name:       stop.name,
                                       arrival:    stop.arrival,
                                       departure:  stop.departure,
                                       agencyTimezoneOffset: leg.agencyTimeZoneOffset,
                                       coordinate: [stop.lat, stop.lon] });
     }
-});
+};
diff --git a/src/osmAccountDialog.js b/src/osmAccountDialog.js
index c9ce704..56a6b98 100644
--- a/src/osmAccountDialog.js
+++ b/src/osmAccountDialog.js
@@ -22,7 +22,6 @@
 
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const WebKit2 = imports.gi.WebKit2;
 
 const Application = imports.application;
@@ -31,9 +30,7 @@ var Response = {
     SIGNED_IN: 0
 };
 
-var OSMAccountDialog = new Lang.Class({
-    Name: 'OSMAccountDialog',
-    Extends: Gtk.Dialog,
+var OSMAccountDialog = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/osm-account-dialog.ui',
     InternalChildren: ['stack',
                        'emailEntry',
@@ -48,15 +45,16 @@ var OSMAccountDialog = new Lang.Class({
                        'verificationFailedLabel',
                        'signedInUserLabel',
                        'signOutButton'],
+}, class OSMAccountDialog extends Gtk.Dialog {
 
-    _init: function(params) {
+    _init(params) {
         /* This is a construct-only property and cannot be set by GtkBuilder */
         params.use_header_bar = true;
 
         this._closeOnSignIn = params.closeOnSignIn;
         delete params.closeOnSignIn;
 
-        this.parent(params);
+        super._init(params);
 
         this._emailEntry.connect('changed',
                                  this._onCredentialsChanged.bind(this));
@@ -80,31 +78,31 @@ var OSMAccountDialog = new Lang.Class({
             this._signedInUserLabel.label = Application.osmEdit.username;
             this._stack.visible_child_name = 'logged-in';
         }
-    },
+    }
 
-    _onCredentialsChanged: function() {
+    _onCredentialsChanged() {
         let email = this._emailEntry.text;
         let password = this._passwordEntry.text;
 
         // make sign in button sensitive if credential have been entered
         this._signInButton.sensitive =
             email && email.length > 0 && password && password.length > 0;
-    },
+    }
 
-    _onSignInButtonClicked: function() {
+    _onSignInButtonClicked() {
         this._performSignIn();
-    },
+    }
 
-    _onPasswordActivated: function() {
+    _onPasswordActivated() {
         /* if username and password was entered, proceed with sign-in */
         let email = this._emailEntry.text;
         let password = this._passwordEntry.text;
 
         if (email && email.length > 0 && password && password.length > 0)
             this._performSignIn();
-    },
+    }
 
-    _performSignIn: function() {
+    _performSignIn() {
         /* turn on signing in spinner and desensisize credential entries */
         this._signInSpinner.visible = true;
         this._signInButton.sensitive = false;
@@ -115,9 +113,9 @@ var OSMAccountDialog = new Lang.Class({
         Application.osmEdit.performOAuthSignIn(this._emailEntry.text,
                                                this._passwordEntry.text,
                                                this._onOAuthSignInPerformed.bind(this));
-    },
+    }
 
-    _onOAuthSignInPerformed: function(success, verificationPage) {
+    _onOAuthSignInPerformed(success, verificationPage) {
         if (success) {
             /* switch to the verification view and show the verification
                page */
@@ -135,13 +133,13 @@ var OSMAccountDialog = new Lang.Class({
         /* re-sensisize credential entries */
         this._emailEntry.sensitive = true;
         this._passwordEntry.sensitive = true;
-    },
+    }
 
-    _onVerifyButtonClicked: function() {
+    _onVerifyButtonClicked() {
         this._performVerification();
-    },
+    }
 
-    _performVerification: function() {
+    _performVerification() {
         /* allow copying the leading space between the "The verification is"
            label and the code */
         let verificationCode = this._verificationEntry.text.trim();
@@ -155,23 +153,23 @@ var OSMAccountDialog = new Lang.Class({
 
         Application.osmEdit.requestOAuthAccessToken(verificationCode,
                                                     this._onOAuthAccessTokenRequested.bind(this));
-    },
+    }
 
-    _onVerificationEntryChanged: function() {
+    _onVerificationEntryChanged() {
         this._verifyButton.sensitive =
             this._verificationEntry.text &&
             this._verificationEntry.text.length > 0;
-    },
+    }
 
-    _onVerificationEntryActivated: function() {
+    _onVerificationEntryActivated() {
         /* proceed with verfication if a code has been entered */
         let verificationCode = this._verificationEntry.text;
 
         if (verificationCode && verificationCode.length > 0)
             this._performVerification();
-    },
+    }
 
-    _onOAuthAccessTokenRequested: function(success) {
+    _onOAuthAccessTokenRequested(success) {
         if (success) {
             /* update the username label */
             this._signedInUserLabel.label = Application.osmEdit.username;
@@ -197,9 +195,9 @@ var OSMAccountDialog = new Lang.Class({
         }
         /* reset verification code entry */
         this._verificationEntry.text = '';
-    },
+    }
 
-    _onSignOutButtonClicked: function() {
+    _onSignOutButtonClicked() {
         Application.osmEdit.signOut();
         this._stack.visible_child_name = 'sign-in';
     }
diff --git a/src/osmConnection.js b/src/osmConnection.js
index d858ceb..6b3b7ac 100644
--- a/src/osmConnection.js
+++ b/src/osmConnection.js
@@ -22,7 +22,6 @@
 
 const _ = imports.gettext.gettext;
 
-const Lang = imports.lang;
 const Maps = imports.gi.GnomeMaps;
 const Rest = imports.gi.Rest;
 const Secret = imports.gi.Secret;
@@ -45,10 +44,9 @@ const SECRET_SCHEMA = new Secret.Schema("org.gnome.Maps",
     }
 );
 
-var OSMConnection = new Lang.Class({
-    Name: 'OSMConnection',
+var OSMConnection = class OSMConnection {
 
-    _init: function(params) {
+    constructor() {
         this._session = new Soup.Session();
 
         /* OAuth proxy used for making OSM uploads */
@@ -56,9 +54,9 @@ var OSMConnection = new Lang.Class({
                                               BASE_URL + '/' + API_VERSION,
                                               false);
         Maps.osm_init();
-    },
+    }
 
-    getOSMObject: function(type, id, callback, cancellable) {
+    getOSMObject(type, id, callback, cancellable) {
         let url = this._getQueryUrl(type, id);
         let uri = new Soup.URI(url);
         let request = new Soup.Message({ method: 'GET', uri: uri });
@@ -82,13 +80,13 @@ var OSMConnection = new Lang.Class({
                 callback(false, message.status_code, null, type, e);
             }
         });
-    },
+    }
 
-    _getQueryUrl: function(type, id) {
+    _getQueryUrl(type, id) {
         return BASE_URL + '/' + API_VERSION + '/' + type + '/' + id;
-    },
+    }
 
-    openChangeset: function(comment, callback) {
+    openChangeset(comment, callback) {
         /* we assume that this would only be called if there's already been an
            OAuth access token enrolled, so, if the currently instanciated
            proxy instance doesn't have a token set, we could safely count on
@@ -102,9 +100,9 @@ var OSMConnection = new Lang.Class({
         } else {
             this._doOpenChangeset(comment, callback);
         }
-    },
+    }
 
-    _onPasswordLookedUp: function(result, comment, callback) {
+    _onPasswordLookedUp(result, comment, callback) {
         let password = Secret.password_lookup_finish(result);
 
         if (password) {
@@ -117,9 +115,9 @@ var OSMConnection = new Lang.Class({
         } else {
             callback(false, null, null);
         }
-    },
+    }
 
-    _doOpenChangeset: function(comment, callback) {
+    _doOpenChangeset(comment, callback) {
         let changeset =
             Maps.OSMChangeset.new(comment, 'gnome-maps ' + pkg.version);
         let xml = changeset.serialize();
@@ -130,9 +128,9 @@ var OSMConnection = new Lang.Class({
 
         call.invoke_async(null, (call, res, userdata) =>
                                 { this._onChangesetOpened(call, callback); });
-    },
+    }
 
-    _onChangesetOpened: function(call, callback) {
+    _onChangesetOpened(call, callback) {
         if (call.get_status_code() !== Soup.Status.OK) {
             callback(false, call.get_status_code(), null);
             return;
@@ -140,9 +138,9 @@ var OSMConnection = new Lang.Class({
 
         let changesetId = parseInt(call.get_payload());
         callback(true, call.get_status_code(), changesetId);
-    },
+    }
 
-    uploadObject: function(object, type, changeset, callback) {
+    uploadObject(object, type, changeset, callback) {
         object.changeset = changeset;
 
         let xml = object.serialize();
@@ -153,18 +151,18 @@ var OSMConnection = new Lang.Class({
 
         call.invoke_async(null, (call, res, userdata) =>
                                 { this._onObjectUploaded(call, callback); });
-    },
+    }
 
-    _onObjectUploaded: function(call, callback) {
+    _onObjectUploaded(call, callback) {
         if (call.get_status_code() !== Soup.Status.OK) {
             callback(false, call.get_status_code(), null);
             return;
         }
 
         callback(true, call.get_status_code(), call.get_payload());
-    },
+    }
 
-    deleteObject: function(object, type, changeset, callback) {
+    deleteObject(object, type, changeset, callback) {
         object.changeset = changeset;
 
         let xml = object.serialize();
@@ -175,60 +173,60 @@ var OSMConnection = new Lang.Class({
 
         call.invoke_async(null, (call, res, userdata) =>
                                 { this._onObjectDeleted(call, callback); });
-    },
+    }
 
-    _onObjectDeleted: function(call, callback) {
+    _onObjectDeleted(call, callback) {
         if (call.get_status_code() !== Soup.Status.OK) {
             callback(false, call.get_status_code(), null);
             return;
         }
 
         callback(true, call.get_status_code(), call.get_payload());
-    },
+    }
 
-    closeChangeset: function(changesetId, callback) {
+    closeChangeset(changesetId, callback) {
         let call = this._callProxy.new_call();
         call.set_method('PUT');
         call.set_function(this._getCloseChangesetFunction(changesetId));
 
         call.invoke_async(null, (call, res, userdata) =>
                                 { this._onChangesetClosed(call, callback); });
-    },
+    }
 
-    _onChangesetClosed: function(call, callback) {
+    _onChangesetClosed(call, callback) {
         if (call.get_status_code() !== Soup.Status.OK) {
             callback(false, call.get_status_code(), null);
             return;
         }
 
         callback(true, call.get_status_code(), call.get_payload());
-    },
+    }
 
-    _getCloseChangesetFunction: function(changesetId) {
+    _getCloseChangesetFunction(changesetId) {
         return '/changeset/' + changesetId + '/close';
-    },
+    }
 
-    _getCreateOrUpdateFunction: function(object, type) {
+    _getCreateOrUpdateFunction(object, type) {
         if (object.id)
             return type + '/' + object.id;
         else
             return type + '/create';
-    },
+    }
 
-    _getDeleteFunction: function(object, type) {
+    _getDeleteFunction(object, type) {
         return type + '/' + id;
-    },
+    }
 
-    requestOAuthToken: function(callback) {
+    requestOAuthToken(callback) {
         /* OAuth proxy used for enrolling access tokens */
         this._oauthProxy = Rest.OAuthProxy.new(CONSUMER_KEY, CONSUMER_SECRET,
                                                OAUTH_ENDPOINT_URL, false);
         this._oauthProxy.request_token_async('request_token', 'oob', (p, error, w, u) => {
             this._onRequestOAuthToken(error, callback);
         }, this._oauthProxy, callback);
-    },
+    }
 
-    _onRequestOAuthToken: function(error, callback) {
+    _onRequestOAuthToken(error, callback) {
         if (error) {
             Utils.debug(error);
             callback(false);
@@ -238,9 +236,9 @@ var OSMConnection = new Lang.Class({
         this._oauthToken = this._oauthProxy.get_token();
         this._oauthTokenSecret = this._oauthProxy.get_token_secret();
         callback(true);
-    },
+    }
 
-    authorizeOAuthToken: function(username, password, callback) {
+    authorizeOAuthToken(username, password, callback) {
         /* get login session ID */
         let loginUrl = LOGIN_URL + '?cookie_test=true';
         let uri = new Soup.URI(loginUrl);
@@ -249,9 +247,9 @@ var OSMConnection = new Lang.Class({
         this._session.queue_message(msg, (obj, message) => {
             this._onLoginFormReceived(message, username, password, callback);
         });
-    },
+    }
 
-    _onLoginFormReceived: function(message, username, password, callback) {
+    _onLoginFormReceived(message, username, password, callback) {
         if (message.status_code !== Soup.Status.OK) {
             callback(false);
             return;
@@ -268,9 +266,9 @@ var OSMConnection = new Lang.Class({
         }
 
         this._login(username, password, osmSessionID, osmSessionToken, callback);
-    },
+    }
 
-    _login: function(username, password, sessionId, token, callback) {
+    _login(username, password, sessionId, token, callback) {
         /* post login form */
         let msg = Soup.form_request_new_from_hash('POST', LOGIN_URL,
                                                   {username: username,
@@ -292,9 +290,9 @@ var OSMConnection = new Lang.Class({
                 callback(false, null);
         });
 
-    },
+    }
 
-    _fetchAuthorizeForm: function(username, sessionId, callback) {
+    _fetchAuthorizeForm(username, sessionId, callback) {
         let auth = '/authorize?oauth_token=';
         let authorizeUrl = OAUTH_ENDPOINT_URL + auth + this._oauthToken;
         let uri = new Soup.URI(authorizeUrl);
@@ -311,9 +309,9 @@ var OSMConnection = new Lang.Class({
                 callback(false, null);
             }
         });
-    },
+    }
 
-    _postAuthorizeForm: function(username, sessionId, token, callback) {
+    _postAuthorizeForm(username, sessionId, token, callback) {
         let authorizeUrl = OAUTH_ENDPOINT_URL + '/authorize';
         let msg = Soup.form_request_new_from_hash('POST', authorizeUrl, {
             oauth_token: this._oauthToken,
@@ -336,15 +334,15 @@ var OSMConnection = new Lang.Class({
             } else
                 callback(false, null);
         });
-    },
+    }
 
-    requestOAuthAccessToken: function(code, callback) {
+    requestOAuthAccessToken(code, callback) {
         this._oauthProxy.access_token_async('access_token', code, (p, error, w, data) => {
             this._onAccessOAuthToken(error, callback);
         }, this._oauthProxy, callback);
-    },
+    }
 
-    _onAccessOAuthToken: function(error, callback) {
+    _onAccessOAuthToken(error, callback) {
         if (error) {
             callback(false);
             return;
@@ -362,16 +360,16 @@ var OSMConnection = new Lang.Class({
                               (source, result, userData) => {
                                 this._onPasswordStored(result, callback);
                               });
-    },
+    }
 
-    _onPasswordStored: function(result, callback) {
+    _onPasswordStored(result, callback) {
         let res = false;
         if (result)
             res = Secret.password_store_finish(result);
         callback(res);
-    },
+    }
 
-    signOut: function() {
+    signOut() {
         /* clear token on call proxy, so it will use a new token if the user
            signs in again (with a new access token) during this running
            session */
@@ -380,14 +378,14 @@ var OSMConnection = new Lang.Class({
 
         Secret.password_clear(SECRET_SCHEMA, {}, null,
             this._onPasswordCleared.bind(this));
-    },
+    }
 
-    _onPasswordCleared: function(source, result) {
+    _onPasswordCleared(source, result) {
         Secret.password_clear_finish(result);
-    },
+    }
 
     /* extract the session ID from the login form response headers */
-    _extractOSMSessionID: function(responseHeaders) {
+    _extractOSMSessionID(responseHeaders) {
         let cookie = responseHeaders.get('Set-Cookie');
 
         if (cookie === null)
@@ -406,11 +404,11 @@ var OSMConnection = new Lang.Class({
         }
 
         return null;
-    },
+    }
 
     /* extract the authenticity token from the hidden input field of the login
        form */
-    _extractToken: function(messageBody) {
+    _extractToken(messageBody) {
         let regex = /.*authenticity_token.*value=\"([^\"]+)\".*/;
         let lines = messageBody.split('\n');
 
@@ -423,7 +421,7 @@ var OSMConnection = new Lang.Class({
 
         return null;
     }
-});
+};
 
 /*
  * Gets a status message (usually for an error case)
diff --git a/src/osmEdit.js b/src/osmEdit.js
index d74209b..cfb9206 100644
--- a/src/osmEdit.js
+++ b/src/osmEdit.js
@@ -20,9 +20,6 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const GObject = imports.gi.GObject;
-const Lang = imports.lang;
-
 const Application = imports.application;
 const OSMAccountDialog = imports.osmAccountDialog;
 const OSMEditDialog = imports.osmEditDialog;
@@ -32,22 +29,20 @@ const Utils = imports.utils;
 /* minimum zoom level at which to offer adding a location */
 var MIN_ADD_LOCATION_ZOOM_LEVEL = 16;
 
-var OSMEdit = new Lang.Class({
-    Name: 'OSMEdit',
-    Extends: GObject.Object,
+var OSMEdit = class OSMEdit {
 
-    _init: function() {
+    constructor() {
         this._osmConnection = new OSMConnection.OSMConnection();
         this._osmObject = null; // currently edited object
         this._username = Application.settings.get('osm-username');
         this._isSignedIn = this._username !== null && this._username.length > 0;
-    },
+    }
 
     get object() {
         return this._osmObject;
-    },
+    }
 
-    createEditDialog: function(parentWindow, place) {
+    createEditDialog(parentWindow, place) {
         let dialog = new OSMEditDialog.OSMEditDialog({
             transient_for: parentWindow,
             modal: true,
@@ -55,9 +50,9 @@ var OSMEdit = new Lang.Class({
         });
 
         return dialog;
-    },
+    }
 
-    createEditNewDialog: function(parentWindow, latitude, longitude) {
+    createEditNewDialog(parentWindow, latitude, longitude) {
         let dialog = new OSMEditDialog.OSMEditDialog({
             transient_for: parentWindow,
             modal: true,
@@ -67,9 +62,9 @@ var OSMEdit = new Lang.Class({
         });
 
         return dialog;
-    },
+    }
 
-    createAccountDialog: function(parentWindow, closeOnSignIn) {
+    createAccountDialog(parentWindow, closeOnSignIn) {
         let dialog = new OSMAccountDialog.OSMAccountDialog({
             transient_for: parentWindow,
             modal: true,
@@ -77,9 +72,9 @@ var OSMEdit = new Lang.Class({
         });
 
         return dialog;
-    },
+    }
 
-    fetchObject: function(place, callback, cancellable) {
+    fetchObject(place, callback, cancellable) {
         let osmType = Utils.osmTypeToString(place.osmType);
 
         /* reset currenly edited object */
@@ -88,88 +83,87 @@ var OSMEdit = new Lang.Class({
                      (function(success, status, osmObject, osmType) {
                          callback(success, status, osmObject, osmType);
                      }), cancellable);
-    },
+    }
 
-    uploadObject: function(object, type, comment, callback) {
+    uploadObject(object, type, comment, callback) {
         this._openChangeset(object, type, comment,
                             this._uploadObject.bind(this), callback);
-    },
+    }
 
-    _onChangesetOpened: function(success, status, changesetId, object, type,
-                                 action, callback) {
+    _onChangesetOpened(success, status, changesetId, object, type, action, callback) {
         if (success) {
             let osmType = Utils.osmTypeToString(type);
             action(object, osmType, changesetId, callback);
         } else {
             callback(false, status);
         }
-    },
+    }
 
-    _openChangeset: function(object, type, comment, action, callback) {
+    _openChangeset(object, type, comment, action, callback) {
         this._osmConnection.openChangeset(comment, (success, status, changesetId) => {
             this._onChangesetOpened(success, status, changesetId, object, type, action, callback);
         });
-    },
+    }
 
-    _onObjectUploaded: function(success, status, response, changesetId, callback) {
+    _onObjectUploaded(success, status, response, changesetId, callback) {
         if (success)
             this._closeChangeset(changesetId, callback);
         else
             callback(false, status);
-    },
+    }
 
-    _uploadObject: function(object, type, changesetId, callback) {
+    _uploadObject(object, type, changesetId, callback) {
         this._osmObject = object;
         this._osmConnection.uploadObject(object, type, changesetId, (success, status, response) => {
             this._onObjectUploaded(success, status, response, changesetId, callback);
         });
-    },
+    }
 
-    deleteObject: function(object, type, comment, callback) {
+    deleteObject(object, type, comment, callback) {
         this._openChangeset(object, type, comment,
                             this._deleteObject.bind(this), callback);
-    },
+    }
 
-    _onObjectDeleted: function(success, status, response, changesetId, callback) {
+    _onObjectDeleted(success, status, response, changesetId, callback) {
         if (success)
             this._closeChangeset(changesetId, callback);
         else
             callback(false, status);
-    },
+    }
 
-    _deleteObject: function(object, type, changesetId, callback) {
+    _deleteObject(object, type, changesetId, callback) {
         this._osmObject = object;
         this._osmConnection.deleteObject(object, type, changesetId, (success, status, response) => {
             this._onObjectDeleted(success, status, response, changesetId, callback);
         });
-    },
+    }
 
-    _closeChangeset: function(changesetId, callback) {
+    _closeChangeset(changesetId, callback) {
         this._osmConnection.closeChangeset(changesetId, callback);
-    },
+    }
 
-    performOAuthSignIn: function(username, password, callback) {
+    performOAuthSignIn(username, password, callback) {
         this._osmConnection.requestOAuthToken((success) => {
             if (success)
                 this._onOAuthTokenRequested(username, password, callback);
             else
                 callback(false, null);
         });
-    },
+    }
 
-    _onOAuthTokenRequested: function(username, password, callback) {
+    _onOAuthTokenRequested(username, password, callback) {
         /* keep track of authorizing username */
         this._username = username;
         this._osmConnection.authorizeOAuthToken(username, password, callback);
-    },
+    }
 
-    requestOAuthAccessToken: function(code, callback) {
+    requestOAuthAccessToken(code, callback) {
         this._osmConnection.requestOAuthAccessToken(code, (success, token) => {
             this._onOAuthAccessTokenRequested(success, callback);
         });
-    },
+    }
 
-    _onOAuthAccessTokenRequested: function(success, callback) {
+    _onOAuthAccessTokenRequested(success, callback) {
         if (success) {
             this._isSignedIn = true;
             Application.settings.set('osm-username', this._username);
@@ -179,21 +173,21 @@ var OSMEdit = new Lang.Class({
         }
 
         callback(success);
-    },
+    }
 
-    signOut: function() {
+    signOut() {
         this._username = null;
         this._isSignedIn = false;
 
         Application.settings.set('osm-username', '');
         this._osmConnection.signOut();
-    },
+    }
 
     get isSignedIn() {
         return this._isSignedIn;
-    },
+    }
 
     get username() {
         return this._username;
     }
-});
+};
diff --git a/src/osmEditDialog.js b/src/osmEditDialog.js
index bba8e65..b8d5bf6 100644
--- a/src/osmEditDialog.js
+++ b/src/osmEditDialog.js
@@ -25,8 +25,8 @@ const _ = imports.gettext.gettext;
 const Geocode = imports.gi.GeocodeGlib;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Soup = imports.gi.Soup;
 
 const Application = imports.application;
@@ -220,16 +220,15 @@ const OSM_FIELDS = [
         hint: _("Information used to inform other mappers about non-obvious information about an element, 
the author’s intent when creating it, or hints for further improvement.")
     }];
 
-const OSMEditAddress = new Lang.Class({
-    Name: 'OSMEditAddress',
-    Extends: Gtk.Grid,
+const OSMEditAddress = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/osm-edit-address.ui',
     Children: [ 'street',
                 'number',
                 'post',
                 'city' ],
+}, class OSMEditAddress extends Gtk.Grid {
 
-    _init: function(params) {
+    _init(params) {
         let street = params.street;
         delete params.street;
 
@@ -242,7 +241,7 @@ const OSMEditAddress = new Lang.Class({
         let city = params.city;
         delete params.city;
 
-        this.parent(params);
+        super._init(params);
 
         if (street)
             this.street.text = street;
@@ -259,9 +258,7 @@ const OSMEditAddress = new Lang.Class({
 });
 
 
-var OSMEditDialog = new Lang.Class({
-    Name: 'OSMEditDialog',
-    Extends: Gtk.Dialog,
+var OSMEditDialog = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/osm-edit-dialog.ui',
     InternalChildren: [ 'cancelButton',
                         'backButton',
@@ -280,8 +277,9 @@ var OSMEditDialog = new Lang.Class({
                         'hintPopover',
                         'hintLabel',
                         'headerBar'],
+}, class OSMEditDialog extends Gtk.Dialog {
 
-    _init: function(params) {
+    _init(params) {
         this._place = params.place;
         delete params.place;
 
@@ -297,7 +295,7 @@ var OSMEditDialog = new Lang.Class({
         /* This is a construct-only property and cannot be set by GtkBuilder */
         params.use_header_bar = true;
 
-        this.parent(params);
+        super._init(params);
 
         /* I could not get this widget working from within the widget template
          * this results in a segfault. The widget definition is left in-place,
@@ -355,9 +353,9 @@ var OSMEditDialog = new Lang.Class({
         this._recentTypesListBox.connect('row-activated', (listbox, row) => {
             this._onTypeSelected(null, row._key, row._value, row._title);
         });
-    },
+    }
 
-    _onNextClicked: function() {
+    _onNextClicked() {
         if (this._isEditing) {
             this._switchToUpload();
         } else {
@@ -370,17 +368,17 @@ var OSMEditDialog = new Lang.Class({
                                              this._osmType, comment,
                                              this._onObjectUploaded.bind(this));
         }
-    },
+    }
 
-    _onTypeClicked: function() {
+    _onTypeClicked() {
         this._cancelButton.visible = false;
         this._backButton.visible = true;
         this._nextButton.visible = false;
         this._headerBar.title = _("Select Type");
         this._stack.visible_child_name = 'select-type';
-    },
+    }
 
-    _onTypeSelected: function(popover, key, value, title) {
+    _onTypeSelected(popover, key, value, title) {
         this._typeValueLabel.label = title;
         this._updateType(key, value);
 
@@ -405,18 +403,18 @@ var OSMEditDialog = new Lang.Class({
         this._nextButton.sensitive = true;
 
         this._updateRecentTypesList();
-    },
+    }
 
-    _updateType: function(key, value) {
+    _updateType(key, value) {
         /* clear out any previous type-related OSM tags */
         OSMTypes.OSM_TYPE_TAGS.forEach((tag) => { this._osmObject.delete_tag(tag); });
 
         this._osmObject.set_tag(key, value);
-    },
+    }
 
     /* update visibility and enable the type selection button if the object has
      * a well-known type (based on a known set of tags) */
-    _updateTypeButton: function() {
+    _updateTypeButton() {
         let numTypeTags = 0;
         let lastTypeTag = null;
 
@@ -447,9 +445,9 @@ var OSMEditDialog = new Lang.Class({
                 this._typeButton.visible = true;
             }
         }
-    },
+    }
 
-    _updateRecentTypesList: function() {
+    _updateRecentTypesList() {
         let recentTypes = OSMTypes.recentTypesStore.recentTypes;
 
         if (recentTypes.length > 0) {
@@ -489,9 +487,9 @@ var OSMEditDialog = new Lang.Class({
             this._recentTypesLabel.visible = false;
             this._recentTypesListBox.visible = false;
         }
-    },
+    }
 
-    _switchToUpload: function() {
+    _switchToUpload() {
         this._stack.set_visible_child_name('upload');
         this._nextButton.label = _("Done");
         this._cancelButton.visible = false;
@@ -499,13 +497,13 @@ var OSMEditDialog = new Lang.Class({
         this._cancelButton.visible = false;
         this._isEditing = false;
         this._commentTextView.grab_focus();
-    },
+    }
 
-    _onCancelClicked: function() {
+    _onCancelClicked() {
         this.response(Response.CANCELLED);
-    },
+    }
 
-    _onBackClicked: function() {
+    _onBackClicked() {
         this._backButton.visible = false;
         this._cancelButton.visible = true;
         this._nextButton.visible = true;
@@ -515,27 +513,27 @@ var OSMEditDialog = new Lang.Class({
         this._commentTextView.buffer.text = '';
         this._typeSearch.text = '';
         this._headerBar.title = this._originalTitle;
-    },
+    }
 
-    _onObjectFetched: function(success, status, osmObject, osmType, error) {
+    _onObjectFetched(success, status, osmObject, osmType, error) {
         if (success) {
             this._isEditing = true;
             this._loadOSMData(osmObject);
         } else {
             this._showError(status, error);
         }
-    },
+    }
 
-    _onObjectUploaded: function(success, status) {
+    _onObjectUploaded(success, status) {
         if (success) {
             this.response(Response.UPLOADED);
         } else {
             this._showError(status);
             this.response(Response.ERROR);
         }
-    },
+    }
 
-    _showError: function(status, error) {
+    _showError(status, error) {
         /* set error message from specific error if available, otherwise use
          * a generic error message for the HTTP status code */
         let statusMessage =
@@ -552,10 +550,10 @@ var OSMEditDialog = new Lang.Class({
         messageDialog.run();
         messageDialog.destroy();
         this.response(Response.ERROR);
-    },
+    }
 
     /* GtkContainer.child_get_property doesn't seem to be usable from GJS */
-    _getRowOfDeleteButton: function(button) {
+    _getRowOfDeleteButton(button) {
         for (let row = 1; row < this._currentRow; row++) {
             let label = this._editorGrid.get_child_at(0, row);
             let deleteButton = this._editorGrid.get_child_at(2, row);
@@ -565,9 +563,9 @@ var OSMEditDialog = new Lang.Class({
         }
 
         return -1;
-    },
+    }
 
-    _addOSMEditDeleteButton: function(fieldSpec) {
+    _addOSMEditDeleteButton(fieldSpec) {
         let deleteButton = Gtk.Button.new_from_icon_name('user-trash-symbolic',
                                                          Gtk.IconSize.BUTTON);
         let styleContext = deleteButton.get_style_context();
@@ -593,9 +591,9 @@ var OSMEditDialog = new Lang.Class({
         });
 
         deleteButton.show();
-    },
+    }
 
-    _addOSMEditLabel: function(fieldSpec) {
+    _addOSMEditLabel(fieldSpec) {
         let text = fieldSpec.name;
         if (fieldSpec.includeHelp) {
             let link = _WIKI_BASE + fieldSpec.tag;
@@ -607,9 +605,9 @@ var OSMEditDialog = new Lang.Class({
         label.get_style_context().add_class('dim-label');
         this._editorGrid.attach(label, 0, this._currentRow, 1, 1);
         label.show();
-    },
+    }
 
-    _showHintPopover: function(entry, hint) {
+    _showHintPopover(entry, hint) {
         if (this._hintPopover.visible) {
             this._hintPopover.popdown();
         } else {
@@ -617,9 +615,9 @@ var OSMEditDialog = new Lang.Class({
             this._hintLabel.label = hint;
             this._hintPopover.popup();
         }
-    },
+    }
 
-    _addOSMEditTextEntry: function(fieldSpec, value) {
+    _addOSMEditTextEntry(fieldSpec, value) {
         this._addOSMEditLabel(fieldSpec);
 
         let entry = new Gtk.Entry();
@@ -650,9 +648,9 @@ var OSMEditDialog = new Lang.Class({
         this._addOSMEditDeleteButton(fieldSpec);
 
         this._currentRow++;
-    },
+    }
 
-    _addOSMEditIntegerEntry: function(fieldSpec, value) {
+    _addOSMEditIntegerEntry(fieldSpec, value) {
         this._addOSMEditLabel(fieldSpec);
 
         let spinbutton = Gtk.SpinButton.new_with_range(0, 1e9, 1);
@@ -677,9 +675,9 @@ var OSMEditDialog = new Lang.Class({
 
         this._addOSMEditDeleteButton(fieldSpec);
         this._currentRow++;
-    },
+    }
 
-    _addOSMEditComboEntry: function(fieldSpec, value) {
+    _addOSMEditComboEntry(fieldSpec, value) {
         this._addOSMEditLabel(fieldSpec);
 
         let combobox = new Gtk.ComboBoxText();
@@ -700,9 +698,9 @@ var OSMEditDialog = new Lang.Class({
 
         this._addOSMEditDeleteButton(fieldSpec);
         this._currentRow++;
-    },
+    }
 
-    _addOSMEditAddressEntry: function(fieldSpec, value) {
+    _addOSMEditAddressEntry(fieldSpec, value) {
         this._addOSMEditLabel(fieldSpec);
 
         let addr = new OSMEditAddress({ street: value[0],
@@ -724,10 +722,10 @@ var OSMEditDialog = new Lang.Class({
         addr.street.grab_focus();
         this._addOSMEditDeleteButton(fieldSpec);
         this._currentRow += rows;
-    },
+    }
 
     /* update visible items in the "Add Field" popover */
-    _updateAddFieldMenu: function() {
+    _updateAddFieldMenu() {
         /* clear old items */
         let children = this._addFieldPopoverGrid.get_children();
         let hasAllFields = true;
@@ -783,9 +781,9 @@ var OSMEditDialog = new Lang.Class({
         }
 
         this._addFieldButton.sensitive = !hasAllFields;
-    },
+    }
 
-    _addOSMField: function(fieldSpec, value) {
+    _addOSMField(fieldSpec, value) {
         switch (fieldSpec.type) {
         case EditFieldType.TEXT:
             this._addOSMEditTextEntry(fieldSpec, value);
@@ -800,9 +798,9 @@ var OSMEditDialog = new Lang.Class({
             this._addOSMEditAddressEntry(fieldSpec, value);
             break;
         }
-    },
+    }
 
-    _loadOSMData: function(osmObject) {
+    _loadOSMData(osmObject) {
         this._osmObject = osmObject;
 
         /* keeps track of the current insertion row in the grid for editing
diff --git a/src/osmTypeListRow.js b/src/osmTypeListRow.js
index 56229cc..795d203 100644
--- a/src/osmTypeListRow.js
+++ b/src/osmTypeListRow.js
@@ -19,31 +19,30 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
-var OSMTypeListRow = new Lang.Class({
-    Name: 'OSMTypeListRow',
-    Extends: Gtk.ListBoxRow,
+var OSMTypeListRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/osm-type-list-row.ui',
-    InternalChildren: [ 'name' ],
+    InternalChildren: [ 'name' ]
+}, class OSMTypeListRow extends Gtk.ListBoxRow {
 
-    _init: function(props) {
+    _init(props) {
         this._type = props.type;
         delete props.type;
 
-        this.parent(props);
+        super._init(props);
 
         this._name.label = this._type.title;
-    },
+    }
 
     get key() {
         return this._type.key;
-    },
+    }
 
     get value() {
         return this._type.value;
-    },
+    }
 
     get title() {
         return this._type.title;
diff --git a/src/osmTypePopover.js b/src/osmTypePopover.js
index 787e0b4..c4e53de 100644
--- a/src/osmTypePopover.js
+++ b/src/osmTypePopover.js
@@ -21,14 +21,11 @@
 
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const OSMTypeListRow = imports.osmTypeListRow;
 const SearchPopover = imports.searchPopover;
 
-var OSMTypePopover = new Lang.Class({
-    Name: 'OSMTypePopover',
-    Extends: SearchPopover.SearchPopover,
+var OSMTypePopover = GObject.registerClass({
     InternalChildren: ['list'],
     Template: 'resource:///org/gnome/Maps/ui/osm-type-popover.ui',
     Signals : {
@@ -37,25 +34,26 @@ var OSMTypePopover = new Lang.Class({
         'selected' : { param_types: [ GObject.TYPE_STRING,
                                       GObject.TYPE_STRING,
                                       GObject.TYPE_STRING ] }
-    },
+    }
+}, class OSMTypePopover extends SearchPopover.SearchPopover {
 
-    _init: function(props) {
-        this.parent(props);
+    _init(props) {
+        super._init(props);
 
         this._list.connect('row-activated', (list, row) => {
             if (row)
                 this.emit('selected', row.key, row.value, row.title);
         });
-    },
+    }
 
-    showMatches: function(matches) {
+    showMatches(matches) {
         this._list.forall((row) => { row.destroy(); });
 
         matches.forEach((type) => { this._addRow(type); });
         this.show();
-    },
+    }
 
-    _addRow: function(type) {
+    _addRow(type) {
         let row = new OSMTypeListRow.OSMTypeListRow({ type: type,
                                                       can_focus: true });
         this._list.add(row);
diff --git a/src/osmTypeSearchEntry.js b/src/osmTypeSearchEntry.js
index af6a1c3..eae9235 100644
--- a/src/osmTypeSearchEntry.js
+++ b/src/osmTypeSearchEntry.js
@@ -19,8 +19,8 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const OSMTypePopover = imports.osmTypePopover;
 const OSMTypes = imports.osmTypes;
@@ -28,13 +28,12 @@ const Utils = imports.utils;
 
 const MAX_MATCHES = 10;
 
-var OSMTypeSearchEntry = new Lang.Class({
-    Name: 'OSMTypeSearchEntry',
-    Extends: Gtk.SearchEntry,
-    Template: 'resource:///org/gnome/Maps/ui/osm-type-search-entry.ui',
+var OSMTypeSearchEntry = GObject.registerClass({
+    Template: 'resource:///org/gnome/Maps/ui/osm-type-search-entry.ui'
+}, class OSMTypeSearchEntry extends Gtk.SearchEntry {
 
-    _init: function(props) {
-        this.parent(props);
+    _init(props) {
+        super._init(props);
 
         this._popover =
             new OSMTypePopover.OSMTypePopover({relative_to: this});
@@ -47,13 +46,13 @@ var OSMTypeSearchEntry = new Lang.Class({
 
         this.connect('search-changed', this._onSearchChanged.bind(this));
         this.connect('activate', this._onSearchChanged.bind(this));
-    },
+    }
 
     get popover() {
         return this._popover;
-    },
+    }
 
-    _onSearchChanged: function() {
+    _onSearchChanged() {
         if (this.text.length === 0) {
             this._popover.hide();
             return;
diff --git a/src/osmTypes.js b/src/osmTypes.js
index 53ca49c..40980c6 100644
--- a/src/osmTypes.js
+++ b/src/osmTypes.js
@@ -21,7 +21,6 @@
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
-const Lang = imports.lang;
 
 const Utils = imports.utils;
 
@@ -105,21 +104,19 @@ function lookupType(key, value) {
         return null;
 }
 
-var RecentTypesStore = new Lang.Class({
-    Name: 'RecentTypesStore',
+var RecentTypesStore = class RecentTypesStore {
 
-    _init: function() {
-        this.parent();
+    constructor() {
         this._filename = GLib.build_filenamev([GLib.get_user_data_dir(),
                                               _RECENT_TYPES_STORE_FILE]);
         this._load();
-    },
+    }
 
     get recentTypes() {
         return this._recentTypes;
-    },
+    }
 
-    _load: function() {
+    _load() {
         if (!GLib.file_test(this._filename, GLib.FileTest.EXISTS)) {
             this._recentTypes = [];
             return;
@@ -132,16 +129,16 @@ var RecentTypesStore = new Lang.Class({
         }
 
         this._recentTypes = JSON.parse(buffer);
-    },
+    }
 
-    _save: function() {
+    _save() {
         let buffer = JSON.stringify(this._recentTypes);
         if (!Utils.writeFile(this._filename, buffer))
             log('Failed to write recent types file!');
-    },
+    }
 
     /* push a type key/value as the most recently used type */
-    pushType: function(key, value) {
+    pushType(key, value) {
         /* find out if the type is already stored */
         let pos = -1;
         for (let i = 0; i < this._recentTypes.length; i++) {
@@ -163,6 +160,6 @@ var RecentTypesStore = new Lang.Class({
 
         this._save();
     }
-});
+};
 
 var recentTypesStore = new RecentTypesStore();
diff --git a/src/overpass.js b/src/overpass.js
index c8c0851..b8307ca 100644
--- a/src/overpass.js
+++ b/src/overpass.js
@@ -19,7 +19,6 @@
 
 const Format = imports.format;
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
 const Soup = imports.gi.Soup;
 
 const Place = imports.place;
@@ -34,10 +33,9 @@ const _DEFAULT_OUTPUT_SORT_ORDER = 'qt';
 
 const BASE_URL = 'https://overpass-api.de/api/interpreter';
 
-var Overpass = new Lang.Class({
-    Name: 'Overpass',
+var Overpass = class Overpass {
 
-    _init: function(params) {
+    constructor(params) {
         params = params || { };
 
         // maximum allowed runtime for the query in seconds
@@ -60,9 +58,9 @@ var Overpass = new Lang.Class({
 
         // HTTP Session Variables
         this._session = new Soup.Session();
-    },
+    }
 
-    addInfo: function(place, callback) {
+    addInfo(place, callback) {
         let url = this._getQueryUrl(place);
         let uri = new Soup.URI(url);
         let request = new Soup.Message({ method: 'GET',
@@ -82,9 +80,9 @@ var Overpass = new Lang.Class({
                 callback(false, message.status_code);
             }
         });
-    },
+    }
 
-    _populatePlace: function(place, overpassData) {
+    _populatePlace(place, overpassData) {
         let element = overpassData.elements[0];
 
         if (!(element && element.tags && element.tags.name))
@@ -114,35 +112,35 @@ var Overpass = new Lang.Class({
             place.toilets = element.tags.toilets;
         if (element.tags.note)
             place.note = element.tags.note;
-    },
+    }
 
-    _getQueryUrl: function(place) {
+    _getQueryUrl(place) {
         return Format.vprintf('%s?data=%s', [ BASE_URL,
                                               this._generateOverpassQuery(place) ]);
-    },
+    }
 
-    _generateOverpassQuery: function(place) {
+    _generateOverpassQuery(place) {
         return Format.vprintf('%s%s%s;%s;%s;',
                               [ this._getKeyValue('timeout', this.timeout),
                                 this._getKeyValue('out', this.outputFormat),
                                 this._getKeyValue('maxsize', this.maxsize),
                                 this._getData(place),
                                 this._getOutput() ]);
-    },
+    }
 
-    _getKeyValue: function(key, value) {
+    _getKeyValue(key, value) {
         return Format.vprintf('[%s:%s]', [ key,
                                            value ]);
-    },
+    }
 
-    _getData: function(place) {
+    _getData(place) {
         return Format.vprintf('%s(%s)', [Utils.osmTypeToString(place.osm_type),
                                          place.osm_id]);
-    },
+    }
 
-    _getOutput: function() {
+    _getOutput() {
         return Format.vprintf('out %s %s %s', [ this.outputInfo,
                                                 this.outputSortOrder,
                                                 this.outputCount ]);
     }
-});
+};
diff --git a/src/place.js b/src/place.js
index 5fbf19e..b5c8277 100644
--- a/src/place.js
+++ b/src/place.js
@@ -21,7 +21,7 @@
 
 const Geocode = imports.gi.GeocodeGlib;
 const GLib = imports.gi.GLib;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 const Location = imports.location;
 const Translations = imports.translations;
 const Utils = imports.utils;
@@ -29,11 +29,10 @@ const Utils = imports.utils;
 // Matches coordinates string with the format "<lat>, <long>"
 const COORDINATES_REGEX = /^\s*(\-?\d+(?:\.\d+)?)\s*,\s*(\-?\d+(?:\.\d+)?)\s*$/;
 
-var Place = new Lang.Class({
-    Name: 'Place',
-    Extends: Geocode.Place,
+var Place = GObject.registerClass(
+class Place extends Geocode.Place {
 
-    _init: function(params) {
+    _init(params) {
         this._population = params.population;
         delete params.population;
 
@@ -96,122 +95,122 @@ var Place = new Lang.Class({
             if (!params[prop])
                 delete params[prop];
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
     set store(v) {
         this._store = v;
-    },
+    }
 
     get store() {
         return this._store;
-    },
+    }
 
     get uniqueID() {
         return this.osm_type + '-' + this.osm_id;
-    },
+    }
 
     set population(v) {
         this._population = v;
-    },
+    }
 
     get population() {
         return this._population;
-    },
+    }
 
     set website(v) {
         this._website = v;
-    },
+    }
 
     get website() {
         return this._website;
-    },
+    }
 
     set phone(v) {
         this._phone = v;
-    },
+    }
 
     get phone() {
         return this._phone;
-    },
+    }
 
     set wiki(v) {
         this._wiki = v;
-    },
+    }
 
     get wiki() {
         return this._wiki;
-    },
+    }
 
     set openingHours(v) {
         this._openingHours = v;
-    },
+    }
 
     get openingHours() {
         return this._openingHours;
-    },
+    }
 
     set internetAccess(v) {
         this._internetAccess = v;
-    },
+    }
 
     get openingHoursTranslated() {
         return Translations.translateOpeningHours(this._openingHours);
-    },
+    }
 
     get internetAccess() {
         return this._internetAccess;
-    },
+    }
 
     get internetAccessTranslated() {
         return Translations.translateInternetAccess(this._internetAccess);
-    },
+    }
 
     set religion(v) {
         this._religion = v;
-    },
+    }
 
     get religion() {
         return this._religion;
-    },
+    }
 
     get religionTranslated() {
         return Translations.translateReligion(this._religion);
-    },
+    }
 
     set toilets(v) {
         this._toilets = v;
-    },
+    }
 
     get toilets() {
         return this._toilets;
-    },
+    }
 
     get toiletsTranslated() {
         return Translations.translateYesNo(this._toilets);
-    },
+    }
 
     set note(v) {
         this._note = v;
-    },
+    }
 
     get note() {
         return this._note;
-    },
+    }
 
     set wheelchair(v) {
         this._wheelchair = v;
-    },
+    }
 
     get wheelchair() {
         return this._wheelchair;
-    },
+    }
 
     get wheelchairTranslated() {
         return this._translateWheelchair(this._wheelchair);
-    },
+    }
 
-    _translateWheelchair: function(string) {
+    _translateWheelchair(string) {
         switch(string) {
             /* Translators:
              * This means wheelchairs have full unrestricted access.
@@ -240,10 +239,10 @@ var Place = new Lang.Class({
 
             default: return null;
         }
-    },
+    }
 
 
-    toJSON: function() {
+    toJSON() {
         let bounding_box = null;
 
         if (this.bounding_box) {
@@ -286,9 +285,9 @@ var Place = new Lang.Class({
                  religion: this.religion,
                  toilets: this.toilets,
                  note: this.note };
-    },
+    }
 
-    match: function(searchString) {
+    match(searchString) {
         let name = this.name;
         if (!name)
             return false;
diff --git a/src/placeBubble.js b/src/placeBubble.js
index f8fee0b..22fe5fa 100644
--- a/src/placeBubble.js
+++ b/src/placeBubble.js
@@ -21,9 +21,9 @@
 
 const GdkPixbuf = imports.gi.GdkPixbuf;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const Format = imports.format;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const ContactPlace = imports.contactPlace;
@@ -43,11 +43,10 @@ const THUMBNAIL_FETCH_SIZE = 128;
 // final scaled size of cropped thumnail
 const THUMBNAIL_FINAL_SIZE = 70;
 
-var PlaceBubble = new Lang.Class({
-    Name: 'PlaceBubble',
-    Extends: MapBubble.MapBubble,
+var PlaceBubble = GObject.registerClass(
+class PlaceBubble extends MapBubble.MapBubble {
 
-    _init: function(params) {
+    _init(params) {
         let ui = Utils.getUIObject('place-bubble', [ 'stack',
                                                      'box-content',
                                                      'grid-content',
@@ -62,7 +61,7 @@ var PlaceBubble = new Lang.Class({
         if (params.place.store)
             params.buttons |= MapBubble.Button.FAVORITE;
 
-        this.parent(params);
+        super._init(params);
 
         Utils.load_icon(this.place.icon, 48, (pixbuf) => { this.image.pixbuf = pixbuf; });
 
@@ -106,20 +105,20 @@ var PlaceBubble = new Lang.Class({
             this._initEditButton();
 
         this._initExpandButton();
-    },
+    }
 
-    _formatWikiLink: function(wiki) {
+    _formatWikiLink(wiki) {
         let lang = Wikipedia.getLanguage(wiki);
         let article = Wikipedia.getArticle(wiki);
 
         return Format.vprintf('https://%s.wikipedia.org/wiki/%s', [ lang, article ]);
-    },
+    }
 
     /*
      * Create an array of all content to be showed when expanding the place
      * bubble
      */
-    _createExpandedContent: function(place) {
+    _createExpandedContent(place) {
         let expandedContent = [];
 
         if (place.population) {
@@ -176,9 +175,9 @@ var PlaceBubble = new Lang.Class({
         }
 
         return expandedContent;
-    },
+    }
 
-    _attachContent: function(content, expandedContent) {
+    _attachContent(content, expandedContent) {
         content.forEach((info) => {
             let label = new Gtk.Label({ label: info,
                                         visible: true,
@@ -221,9 +220,9 @@ var PlaceBubble = new Lang.Class({
                 // Expand over both columns if this row has no label
                 this._expandedContent.attach(widget, 0, row, 2, 1);
         });
-    },
+    }
 
-    _populate: function(place) {
+    _populate(place) {
         let formatter = new PlaceFormatter.PlaceFormatter(place);
 
         let content = formatter.rows.map((row) => {
@@ -248,22 +247,22 @@ var PlaceBubble = new Lang.Class({
 
         if (place.wiki)
             this._requestWikipediaThumbnail(place.wiki);
-    },
+    }
 
-    _requestWikipediaThumbnail: function(wiki) {
+    _requestWikipediaThumbnail(wiki) {
         Wikipedia.fetchArticleThumbnail(wiki, THUMBNAIL_FETCH_SIZE,
                                         this._onThumbnailComplete.bind(this));
-    },
+    }
 
-    _onThumbnailComplete: function(thumbnail) {
+    _onThumbnailComplete(thumbnail) {
         if (thumbnail) {
             this.thumbnail.pixbuf = this._cropAndScaleThumbnail(thumbnail);
             this.iconStack.visible_child_name = 'thumbnail';
         }
-    },
+    }
 
     // returns a cropped square-shaped thumbnail
-    _cropAndScaleThumbnail: function(thumbnail) {
+    _cropAndScaleThumbnail(thumbnail) {
         let width = thumbnail.get_width();
         let height = thumbnail.get_height();
         let croppedThumbnail;
@@ -279,28 +278,28 @@ var PlaceBubble = new Lang.Class({
         return croppedThumbnail.scale_simple(THUMBNAIL_FINAL_SIZE,
                                              THUMBNAIL_FINAL_SIZE,
                                              GdkPixbuf.InterpType.BILINEAR);
-    },
+    }
 
     // clear the view widgets to be able to re-populate an updated place
-    _clearView: function() {
+    _clearView() {
         this._boxContent.get_children().forEach((child) => { child.destroy(); });
         this._expandedContent.get_children().forEach((child) => { child.destroy(); });
-    },
+    }
 
-    _initEditButton: function() {
+    _initEditButton() {
         this._editButton.visible = true;
         this._editButton.connect('clicked', this._onEditClicked.bind(this));
-    },
+    }
 
-    _initExpandButton: function() {
+    _initExpandButton() {
         let image = this._expandButton.get_child();
 
         this._expandButton.connect('clicked', (function() {
             this._revealer.reveal_child = !this._revealer.child_revealed;
         }).bind(this));
-    },
+    }
 
-    _onEditClicked: function() {
+    _onEditClicked() {
         let osmEdit = Application.osmEdit;
         /* if the user is not alread signed in, show the account dialog */
         if (!osmEdit.isSignedIn) {
@@ -317,9 +316,9 @@ var PlaceBubble = new Lang.Class({
         }
 
         this._edit();
-    },
+    }
 
-    _edit: function() {
+    _edit() {
         let osmEdit = Application.osmEdit;
         let dialog = osmEdit.createEditDialog(this.get_toplevel(), this._place);
 
diff --git a/src/placeEntry.js b/src/placeEntry.js
index 83eb454..35e663e 100644
--- a/src/placeEntry.js
+++ b/src/placeEntry.js
@@ -34,9 +34,7 @@ const PlaceStore = imports.placeStore;
 const PlacePopover = imports.placePopover;
 const Utils = imports.utils;
 
-var PlaceEntry = new Lang.Class({
-    Name: 'PlaceEntry',
-    Extends: Gtk.SearchEntry,
+var PlaceEntry = GObject.registerClass({
     Properties: {
         'place': GObject.ParamSpec.object('place',
                                           'Place',
@@ -44,7 +42,8 @@ var PlaceEntry = new Lang.Class({
                                           GObject.ParamFlags.READABLE |
                                           GObject.ParamFlags.WRITABLE,
                                           Geocode.Place)
-    },
+    }
+}, class PlaceEntry extends Gtk.SearchEntry {
 
     set place(p) {
         if (!this._place && !p)
@@ -63,17 +62,17 @@ var PlaceEntry = new Lang.Class({
 
         this._place = p;
         this.notify('place');
-    },
+    }
 
     get place() {
         return this._place;
-    },
+    }
 
     get popover() {
         return this._popover;
-    },
+    }
 
-    _init: function(props) {
+    _init(props) {
         let numVisible = props.num_visible || 6;
         delete props.num_visible;
         this._mapView = props.mapView;
@@ -92,7 +91,7 @@ var PlaceEntry = new Lang.Class({
         this._matchRoute = props.matchRoute || false;
         delete props.matchRoute;
 
-        this.parent(props);
+        super._init(props);
 
         this._filter = new Gtk.TreeModelFilter({ child_model: Application.placeStore });
         this._filter.set_visible_func(this._completionVisibleFunc.bind(this));
@@ -124,17 +123,17 @@ var PlaceEntry = new Lang.Class({
                 return false;
             });
         }
-    },
+    }
 
-    _locEquals: function(placeA, placeB) {
+    _locEquals(placeA, placeB) {
         if (!placeA.location || !placeB.location)
             return false;
 
         return (placeA.location.latitude === placeB.location.latitude &&
                 placeA.location.longitude === placeB.location.longitude);
-    },
+    }
 
-    _createPopover: function(numVisible, maxChars) {
+    _createPopover(numVisible, maxChars) {
         let popover = new PlacePopover.PlacePopover({ num_visible:   numVisible,
                                                       relative_to:   this,
                                                       maxChars:      maxChars});
@@ -151,15 +150,15 @@ var PlaceEntry = new Lang.Class({
         });
 
         return popover;
-    },
+    }
 
-    _refreshFilter: function() {
+    _refreshFilter() {
         /* Filter model based on input text */
         this._filter.refilter();
         this._popover.updateCompletion(this._filter, this.text);
-    },
+    }
 
-    _completionVisibleFunc: function(model, iter) {
+    _completionVisibleFunc(model, iter) {
         let place = model.get_value(iter, PlaceStore.Columns.PLACE);
         let type = model.get_value(iter, PlaceStore.Columns.TYPE);
 
@@ -170,9 +169,9 @@ var PlaceEntry = new Lang.Class({
             return place.match(this.text);
         else
             return false;
-    },
+    }
 
-    _parse: function() {
+    _parse() {
         if (this.text.length === 0) {
             this.place = null;
             return true;
@@ -199,9 +198,9 @@ var PlaceEntry = new Lang.Class({
         }
 
         return false;
-    },
+    }
 
-    _onActivate: function() {
+    _onActivate() {
         if (this._parse())
             return;
 
diff --git a/src/placeFormatter.js b/src/placeFormatter.js
index f5ff7e4..6c5b8cf 100644
--- a/src/placeFormatter.js
+++ b/src/placeFormatter.js
@@ -20,24 +20,22 @@
  */
 
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
 
 const StoredRoute = imports.storedRoute;
 
-var PlaceFormatter = new Lang.Class({
-    Name: "PlaceFormatter",
+var PlaceFormatter = class PlaceFormatter {
 
-    _init: function(place) {
+    constructor(place) {
         this._place = place;
         this._rows = [];
         this._titleProperty = 'name';
 
         this._update();
-    },
+    }
 
     get place() {
         return this._place;
-    },
+    }
 
     get title() {
         let title;
@@ -50,13 +48,13 @@ var PlaceFormatter = new Lang.Class({
             title = this.place[this._titleProperty];
 
         return title;
-    },
+    }
 
     get rows() {
         return this._rows;
-    },
+    }
 
-    getDetailsString: function() {
+    getDetailsString() {
         if (this._place instanceof StoredRoute.StoredRoute)
             return this._place.viaString;
 
@@ -65,9 +63,9 @@ var PlaceFormatter = new Lang.Class({
                 return this._place[prop];
             }).join(', ');
         }).join(', ');
-    },
+    }
 
-    _update: function() {
+    _update() {
         switch (this._place.place_type) {
         case Geocode.PlaceType.COUNTRY:
             if (this._place.country)
@@ -108,12 +106,12 @@ var PlaceFormatter = new Lang.Class({
                 this._addRow(['postal_code', 'town']);
             break;
         }
-    },
+    }
 
-    _addRow: function(properties) {
+    _addRow(properties) {
         properties = properties.filter((prop) => { return this._place[prop] ? true : false; });
 
         if (properties.length > 0)
             this._rows.push(properties);
     }
-});
+};
diff --git a/src/placeListRow.js b/src/placeListRow.js
index 377dca4..da19041 100644
--- a/src/placeListRow.js
+++ b/src/placeListRow.js
@@ -18,8 +18,8 @@
  */
 
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const PlaceFormatter = imports.placeFormatter;
 const PlaceStore = imports.placeStore;
@@ -27,16 +27,15 @@ const Utils = imports.utils;
 
 var ROW_HEIGHT = 55;
 
-var PlaceListRow = new Lang.Class({
-    Name: 'PlaceListRow',
-    Extends: Gtk.ListBoxRow,
+var PlaceListRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/place-list-row.ui',
     InternalChildren: [ 'icon',
                         'name',
                         'details',
                         'typeIcon' ],
+}, class PlaceListRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this.place = params.place;
         delete params.place;
 
@@ -50,7 +49,7 @@ var PlaceListRow = new Lang.Class({
         delete params.type;
 
         params.height_request = ROW_HEIGHT;
-        this.parent(params);
+        super._init(params);
 
         let formatter = new PlaceFormatter.PlaceFormatter(this.place);
         this.title = formatter.title;
@@ -69,9 +68,9 @@ var PlaceListRow = new Lang.Class({
         else if (type === PlaceStore.PlaceType.CONTACT)
             this._typeIcon.icon_name = 'avatar-default-symbolic';
 
-    },
+    }
 
-    _boldMatch: function(title, string) {
+    _boldMatch(title, string) {
         let canonicalString = Utils.normalizeString(string).toLowerCase();
         let canonicalTitle = Utils.normalizeString(title).toLowerCase();
 
diff --git a/src/placeMarker.js b/src/placeMarker.js
index 6bbca8d..86e068c 100644
--- a/src/placeMarker.js
+++ b/src/placeMarker.js
@@ -19,27 +19,26 @@
  * Author: Damián Nohales <damiannohales gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const MapMarker = imports.mapMarker;
 const PlaceBubble = imports.placeBubble;
 
-var PlaceMarker = new Lang.Class({
-    Name: 'PlaceMarker',
-    Extends: MapMarker.MapMarker,
+var PlaceMarker = GObject.registerClass(
+class PlaceMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
 
         this.add_actor(this._actorFromIconName('mark-location', 32));
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2),
                  y: this.height - 3 };
-    },
+    }
 
-    _createBubble: function() {
+    _createBubble() {
         if (this.place.name) {
             return new PlaceBubble.PlaceBubble({ place: this.place,
                                                  mapView: this._mapView });
diff --git a/src/placePopover.js b/src/placePopover.js
index ce9d350..6a20481 100644
--- a/src/placePopover.js
+++ b/src/placePopover.js
@@ -19,7 +19,6 @@
 
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const PlaceListRow = imports.placeListRow;
@@ -35,9 +34,7 @@ const Mode = {
     RESULT: 3 // We are displaying results
 };
 
-var PlacePopover = new Lang.Class({
-    Name: 'PlacePopover',
-    Extends: SearchPopover.SearchPopover,
+var PlacePopover = GObject.registerClass({
     Signals : {
         'selected' : { param_types: [ GObject.TYPE_OBJECT ] }
     },
@@ -48,8 +45,9 @@ var PlacePopover = new Lang.Class({
                         'spinner',
                         'list',
                         'noResultsLabel' ],
+}, class PlacePopover extends SearchPopover.SearchPopover {
 
-    _init: function(props) {
+    _init(props) {
         let numVisible = props.num_visible;
         delete props.num_visible;
 
@@ -57,12 +55,12 @@ var PlacePopover = new Lang.Class({
         delete props.maxChars;
 
         props.transitions_enabled = false;
-        this.parent(props);
+        super._init(props);
 
         this._entry = this.relative_to;
         this._entry.connect('notify::place', () => { this._mode = Mode.ACTIVATED; });
 
-        Application.routingDelegator.graphHopper.route.connect('updated', () => {
+        Application.routingDelegator.graphHopper.route.connect('update', () => {
             this._mode = Mode.ACTIVATED;
         });
 
@@ -93,18 +91,18 @@ var PlacePopover = new Lang.Class({
         // This silents warning at Maps exit about this widget being
         // visible but not mapped.
         this.connect('unmap', (popover) => { popover.hide(); });
-    },
+    }
 
-    showSpinner: function() {
+    showSpinner() {
         this._spinner.start();
         this._stack.visible_child = this._spinner;
         this._updateHint();
 
         if (!this.visible)
             this.show();
-    },
+    }
 
-    showResult: function() {
+    showResult() {
         this._mode = Mode.RESULT;
 
         if (this._spinner.active)
@@ -118,18 +116,18 @@ var PlacePopover = new Lang.Class({
 
         if (!this.visible)
             this.show();
-    },
+    }
 
-    showNoResult: function() {
+    showNoResult() {
         this._mode = Mode.IDLE;
 
         if (this._spinner.active)
             this._spinner.stop();
 
         this._stack.visible_child = this._noResultsLabel;
-    },
+    }
 
-    showCompletion: function() {
+    showCompletion() {
         if (this._mode === undefined || this._mode === Mode.ACTIVATED) {
             this._mode = Mode.IDLE;
             return;
@@ -141,14 +139,14 @@ var PlacePopover = new Lang.Class({
 
         if (!this.visible)
             this.show();
-    },
+    }
 
-    vfunc_hide: function() {
+    vfunc_hide() {
         this._hintRevealer.reveal_child = false;
-        this.parent();
-    },
+        super.vfunc_hide();
+    }
 
-    updateResult: function(places, searchString) {
+    updateResult(places, searchString) {
         this._list.forall((row) => { row.destroy(); });
 
         places.forEach((place) => {
@@ -157,9 +155,9 @@ var PlacePopover = new Lang.Class({
 
             this._addRow(place, null, searchString);
         });
-    },
+    }
 
-    updateCompletion: function(filter, searchString) {
+    updateCompletion(filter, searchString) {
         this._list.forall((row) => { row.destroy(); });
 
         filter.foreach((model, path, iter) => {
@@ -167,18 +165,18 @@ var PlacePopover = new Lang.Class({
             let type = model.get_value(iter, PlaceStore.Columns.TYPE);
             this._addRow(place, type, searchString);
         });
-    },
+    }
 
-    _addRow: function(place, type, searchString) {
+    _addRow(place, type, searchString) {
         let row = new PlaceListRow.PlaceListRow({ place: place,
                                                   searchString: searchString,
                                                   type: type,
                                                   maxChars: this._maxChars,
                                                   can_focus: true });
         this._list.add(row);
-    },
+    }
 
-    _updateHint: function() {
+    _updateHint() {
         if (this._stack.visible_child === this._spinner) {
             this._hintRevealer.reveal_child = false;
             return;
diff --git a/src/placeStore.js b/src/placeStore.js
index 77577d7..7b3abc7 100644
--- a/src/placeStore.js
+++ b/src/placeStore.js
@@ -22,7 +22,6 @@ const GObject = imports.gi.GObject;
 const GdkPixbuf = imports.gi.GdkPixbuf;
 const Geocode = imports.gi.GeocodeGlib;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const ContactPlace = imports.contactPlace;
 const Place = imports.place;
@@ -50,11 +49,10 @@ var Columns = {
     ADDED: 4
 };
 
-var PlaceStore = new Lang.Class({
-    Name: 'PlaceStore',
-    Extends: Gtk.ListStore,
+var PlaceStore = GObject.registerClass(
+class PlaceStore extends Gtk.ListStore {
 
-    _init: function(params) {
+    _init(params) {
         this._recentPlacesLimit = params.recentPlacesLimit;
         delete params.recentPlacesLimit;
 
@@ -67,7 +65,7 @@ var PlaceStore = new Lang.Class({
                                               _PLACES_STORE_FILE]);
         this._typeTable = {};
 
-        this.parent();
+        super._init(params);
         this.set_column_types([GdkPixbuf.Pixbuf,
                                GObject.TYPE_OBJECT,
                                GObject.TYPE_STRING,
@@ -75,22 +73,22 @@ var PlaceStore = new Lang.Class({
                                GObject.TYPE_DOUBLE]);
 
         this.set_sort_column_id(Columns.ADDED, Gtk.SortType.ASCENDING);
-    },
+    }
 
-    _addPlace: function(place, type) {
+    _addPlace(place, type) {
         this._setPlace(this.append(), place, type, new Date().getTime());
         this._store();
-    },
+    }
 
-    _addContact: function(place) {
+    _addContact(place) {
         if (this.exists(place, PlaceType.CONTACT)) {
             return;
         }
 
         this._addPlace(place, PlaceType.CONTACT);
-    },
+    }
 
-    _addFavorite: function(place) {
+    _addFavorite(place) {
         if (!place.store)
             return;
 
@@ -105,9 +103,9 @@ var PlaceStore = new Lang.Class({
             }, true);
         }
         this._addPlace(place, PlaceType.FAVORITE);
-    },
+    }
 
-    _addRecent: function(place) {
+    _addRecent(place) {
         if (!place.store)
             return;
 
@@ -133,9 +131,9 @@ var PlaceStore = new Lang.Class({
         }
         this._addPlace(place, PlaceType.RECENT);
         this._numRecentPlaces++;
-    },
+    }
 
-    _addRecentRoute: function(stored) {
+    _addRecentRoute(stored) {
         if (this.exists(stored, PlaceType.RECENT_ROUTE))
             return;
 
@@ -157,9 +155,9 @@ var PlaceStore = new Lang.Class({
         }
         this._addPlace(stored, PlaceType.RECENT_ROUTE);
         this._numRecentRoutes++;
-    },
+    }
 
-    load: function() {
+    load() {
         if (!GLib.file_test(this.filename, GLib.FileTest.EXISTS))
             return;
 
@@ -191,9 +189,9 @@ var PlaceStore = new Lang.Class({
         } catch (e) {
             throw new Error('failed to parse places file');
         }
-    },
+    }
 
-    addPlace: function(place, type) {
+    addPlace(place, type) {
         if (type === PlaceType.FAVORITE)
             this._addFavorite(place, type);
         else if (type === PlaceType.RECENT)
@@ -202,9 +200,9 @@ var PlaceStore = new Lang.Class({
             this._addContact(place, type);
         else if (type === PlaceType.RECENT_ROUTE)
             this._addRecentRoute(place);
-    },
+    }
 
-    removePlace: function(place, placeType) {
+    removePlace(place, placeType) {
         if (!this.exists(place, placeType))
             return;
 
@@ -217,9 +215,9 @@ var PlaceStore = new Lang.Class({
             return false;
         }, true);
         this._store();
-    },
+    }
 
-    getModelForPlaceType: function(placeType) {
+    getModelForPlaceType(placeType) {
         let filter = new Gtk.TreeModelFilter({ child_model: this });
 
         filter.set_visible_func((model, iter) => {
@@ -228,9 +226,9 @@ var PlaceStore = new Lang.Class({
         });
 
         return filter;
-    },
+    }
 
-    _store: function() {
+    _store() {
         let jsonArray = [];
         this.foreach((model, path, iter) => {
             let place = model.get_value(iter, Columns.PLACE);
@@ -249,9 +247,9 @@ var PlaceStore = new Lang.Class({
         let buffer = JSON.stringify(jsonArray);
         if (!Utils.writeFile(this.filename, buffer))
             log('Failed to write places file!');
-    },
+    }
 
-    _setPlace: function(iter, place, type, added) {
+    _setPlace(iter, place, type, added) {
         this.set(iter,
                  [Columns.PLACE,
                   Columns.NAME,
@@ -268,9 +266,9 @@ var PlaceStore = new Lang.Class({
             });
         }
         this._typeTable[place.uniqueID] = type;
-    },
+    }
 
-    get: function(place) {
+    get(place) {
         let storedPlace = null;
 
         this.foreach((model, path, iter) => {
@@ -282,9 +280,9 @@ var PlaceStore = new Lang.Class({
             return false;
         });
         return storedPlace;
-    },
+    }
 
-    isStale: function(place) {
+    isStale(place) {
         if (!this.exists(place, null))
             return false;
 
@@ -302,16 +300,16 @@ var PlaceStore = new Lang.Class({
         let days = Math.abs(now - added) / _ONE_DAY;
 
         return (days >= _STALE_THRESHOLD);
-    },
+    }
 
-    exists: function(place, type) {
+    exists(place, type) {
         if (type !== undefined && type !== null && this._typeTable[place.uniqueID] !== undefined)
             return this._typeTable[place.uniqueID] === type;
         else
             return this._typeTable[place.uniqueID] !== undefined;
-    },
+    }
 
-    _removeIf: function(evalFunc, stop) {
+    _removeIf(evalFunc, stop) {
         this.foreach((model, path, iter) => {
             if (evalFunc(model, iter)) {
                 this.remove(iter);
@@ -320,9 +318,9 @@ var PlaceStore = new Lang.Class({
             }
             return false;
         });
-    },
+    }
 
-    updatePlace: function(place) {
+    updatePlace(place) {
         this.foreach((model, path, iter) => {
             let p = model.get_value(iter, Columns.PLACE);
 
diff --git a/src/printLayout.js b/src/printLayout.js
index b25c028..0a93f3e 100644
--- a/src/printLayout.js
+++ b/src/printLayout.js
@@ -22,7 +22,6 @@ const Champlain = imports.gi.Champlain;
 const Clutter = imports.gi.Clutter;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Pango = imports.gi.Pango;
 const PangoCairo = imports.gi.PangoCairo;
 
@@ -74,15 +73,14 @@ function newFromRoute(route, pageWidth, pageHeight) {
     }
 }
 
-var PrintLayout = new Lang.Class({
-    Name: 'PrintLayout',
-    Extends: GObject.Object,
+var PrintLayout = GObject.registerClass({
     Abstract: true,
     Signals: {
         'render-complete': { }
-    },
+    }
+}, class PrintLayout extends GObject.Object {
 
-    _init: function(params) {
+    _init(params) {
         this._pageWidth = params.pageWidth;
         delete params.pageWidth;
 
@@ -92,16 +90,16 @@ var PrintLayout = new Lang.Class({
         this._totalSurfaces = params.totalSurfaces;
         delete params.totalSurfaces;
 
-        this.parent();
+        super._init(params);
 
         this.numPages = 0;
         this.surfaceObjects = [];
         this._surfacesRendered = 0;
         this.renderFinished = false;
         this._initSignals();
-    },
+    }
 
-    render: function() {
+    render() {
         let headerWidth = _Header.SCALE_X * this._pageWidth;
         let headerHeight = _Header.SCALE_Y * this._pageHeight;
         let headerMargin = _Header.SCALE_MARGIN * this._pageHeight;
@@ -130,20 +128,20 @@ var PrintLayout = new Lang.Class({
         this._drawMapView(mapViewWidth, mapViewHeight,
                           mapViewZoomLevel, allTurnPoints);
         this._cursorY += dy;
-    },
+    }
 
-    _initSignals: function() {
+    _initSignals() {
         this.connect('render-complete', () => { this.renderFinished = true; });
-    },
+    }
 
-    _createMarker: function(turnPoint) {
+    _createMarker(turnPoint) {
         return new TurnPointMarker.TurnPointMarker({
             turnPoint: turnPoint,
             queryPoint: {}
         });
-    },
+    }
 
-    _drawMapView: function(width, height, zoomLevel, turnPoints) {
+    _drawMapView(width, height, zoomLevel, turnPoints) {
         let pageNum = this.numPages - 1;
         let x = this._cursorX;
         let y = this._cursorY;
@@ -180,24 +178,24 @@ var PrintLayout = new Lang.Class({
             if (surface)
                 this._addSurface(surface, x, y, pageNum);
         }
-    },
+    }
 
-    _createTurnPointArray: function(startIndex, endIndex) {
+    _createTurnPointArray(startIndex, endIndex) {
         let turnPointArray = [];
         for (let i = startIndex; i < endIndex; i++) {
             turnPointArray.push(this._route.turnPoints[i]);
         }
         return turnPointArray;
-    },
+    }
 
-    _addRouteLayer: function(view) {
+    _addRouteLayer(view) {
         let routeLayer = new Champlain.PathLayer({ stroke_width: _STROKE_WIDTH,
                                                    stroke_color: _STROKE_COLOR });
         view.add_layer(routeLayer);
         this._route.path.forEach((node) => { routeLayer.add_node(node); });
-    },
+    }
 
-    _drawInstruction: function(width, height, turnPoint) {
+    _drawInstruction(width, height, turnPoint) {
         let pageNum = this.numPages - 1;
         let x = this._cursorX;
         let y = this._cursorY;
@@ -228,9 +226,9 @@ var PrintLayout = new Lang.Class({
             let surface = widget.get_surface();
             this._addSurface(surface, x, y, pageNum);
         });
-    },
+    }
 
-    _drawHeader: function(width, height) {
+    _drawHeader(width, height) {
         let pageNum = this.numPages - 1;
         let x = this._cursorX;
         let y = this._cursorY;
@@ -252,28 +250,28 @@ var PrintLayout = new Lang.Class({
         cr.fill();
 
         this._addSurface(surface, x, y, pageNum);
-    },
+    }
 
-    _addSurface: function(surface, x, y, pageNum) {
+    _addSurface(surface, x, y, pageNum) {
         this.surfaceObjects[pageNum].push({ surface: surface, x: x, y: y });
         this._surfacesRendered++;
         if (this._surfacesRendered === this._totalSurfaces)
             this.emit('render-complete');
-    },
+    }
 
-    _adjustPage: function(dy) {
+    _adjustPage(dy) {
         if (this._cursorY + dy > this._pageHeight)
             this._createNewPage();
-    },
+    }
 
-    _createNewPage: function() {
+    _createNewPage() {
         this.numPages++;
         this.surfaceObjects[this.numPages - 1] = [];
         this._cursorX = 0;
         this._cursorY = 0;
-    },
+    }
 
-    _formatQueryPlaceName: function(index) {
+    _formatQueryPlaceName(index) {
         let query = Application.routeQuery;
         if (index === -1)
             index = query.filledPoints.length - 1;
diff --git a/src/printOperation.js b/src/printOperation.js
index 7b89c2f..60399ff 100644
--- a/src/printOperation.js
+++ b/src/printOperation.js
@@ -18,7 +18,6 @@
  */
 
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -28,10 +27,9 @@ const Utils = imports.utils;
 
 const _MIN_TIME_TO_ABORT = 3000;
 
-var PrintOperation = new Lang.Class({
-    Name: 'PrintOperation',
+var PrintOperation = class PrintOperation {
 
-    _init: function(params) {
+    constructor(params) {
         this._mainWindow = params.mainWindow;
         delete params.mainWindow;
 
@@ -54,9 +52,9 @@ var PrintOperation = new Lang.Class({
                                                      this.onAbortDialogResponse.bind(this));
 
         this._runPrintOperation();
-    },
+    }
 
-    _beginPrint: function(operation, context, data) {
+    _beginPrint(operation, context, data) {
         let route = Application.routingDelegator.graphHopper.route;
         let selectedTransitItinerary =
             Application.routingDelegator.openTripPlanner.plan.selectedItinerary;
@@ -79,34 +77,34 @@ var PrintOperation = new Lang.Class({
             this._layout = PrintLayout.newFromRoute(route, width, height);
         }
         this._layout.render();
-    },
+    }
 
-    onAbortDialogResponse: function(dialog, response) {
+    onAbortDialogResponse(dialog, response) {
         if (response === Gtk.ResponseType.DELETE_EVENT ||
             response === Gtk.ResponseType.CANCEL) {
             this._abortDialog.disconnect(this._responseId);
             this._operation.cancel();
             this._abortDialog.close();
         }
-    },
+    }
 
-    _paginate: function(operation, context) {
+    _paginate(operation, context) {
         if (this._layout.renderFinished) {
             operation.set_n_pages(this._layout.numPages);
             this._abortDialog.close();
         }
         return this._layout.renderFinished;
-    },
+    }
 
-    _drawPage: function(operation, context, page_num, data) {
+    _drawPage(operation, context, page_num, data) {
         let cr = context.get_cairo_context();
         this._layout.surfaceObjects[page_num].forEach((so) => {
             cr.setSourceSurface(so.surface, so.x, so.y);
             cr.paint();
         });
-    },
+    }
 
-    _runPrintOperation: function() {
+    _runPrintOperation() {
         try {
             let result = this._operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
                                              this._mainWindow);
@@ -118,4 +116,4 @@ var PrintOperation = new Lang.Class({
             Utils.debug('Failed to print: %s'.format(e.message));
         }
     }
-});
+};
diff --git a/src/route.js b/src/route.js
index 2f16711..ec4121f 100644
--- a/src/route.js
+++ b/src/route.js
@@ -20,7 +20,7 @@
  */
 
 const Champlain = imports.gi.Champlain;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Utils = imports.utils;
 
@@ -41,14 +41,19 @@ var TurnPointType = {
     START:         10000
 };
 
-var Route = new Lang.Class({
-    Name: 'Route',
+var Route = GObject.registerClass({
+    Signals: {
+        'update': {},
+        'reset': {}
+    }
+}, class Route extends GObject.Object {
 
-    _init: function() {
+    _init() {
+        super._init();
         this.reset();
-    },
+    }
 
-    update: function({ path, turnPoints, distance, time, bbox }) {
+    update({ path, turnPoints, distance, time, bbox }) {
         this.path = path;
         this.turnPoints = turnPoints;
         this.distance = distance;
@@ -56,18 +61,18 @@ var Route = new Lang.Class({
         this.bbox = bbox || this.createBBox(path);
 
         this.emit('update');
-    },
+    }
 
-    reset: function() {
+    reset() {
         this.path = [];
         this.turnPoints = [];
         this.distance = 0;
         this.time = 0;
         this.bbox = null;
         this.emit('reset');
-    },
+    }
 
-    createBBox: function(coordinates) {
+    createBBox(coordinates) {
         let bbox = new Champlain.BoundingBox();
         coordinates.forEach(function({ latitude, longitude }) {
             bbox.extend(latitude, longitude);
@@ -75,30 +80,28 @@ var Route = new Lang.Class({
         return bbox;
     }
 });
-Utils.addSignalMethods(Route.prototype);
 
-var TurnPoint = new Lang.Class({
-    Name: 'TurnPoint',
+var TurnPoint = class TurnPoint {
 
-    _init: function({ coordinate, type, distance, instruction, turnAngle }) {
+    constructor({ coordinate, type, distance, instruction, turnAngle }) {
         this.coordinate = coordinate;
         this._type = type;
         this.distance = distance;
         this.instruction = instruction;
         this.iconName = this._getIconName(turnAngle);
-    },
+    }
 
     get type() {
         return this._type;
-    },
+    }
 
-    isStop: function() {
+    isStop() {
         return this._type === TurnPointType.START
             || this._type === TurnPointType.VIA
             || this._type === TurnPointType.END;
-    },
+    }
 
-    _getIconName: function(turnAngle) {
+    _getIconName(turnAngle) {
         switch(this._type) {
         case TurnPointType.SHARP_LEFT:   return 'maps-direction-sharpleft-symbolic';
         case TurnPointType.LEFT:         return 'maps-direction-left-symbolic';
@@ -113,9 +116,9 @@ var TurnPoint = new Lang.Class({
         case TurnPointType.ROUNDABOUT:   return this._getRoundaboutIconName(turnAngle);
         default:                         return '';
         }
-    },
+    }
 
-    _getRoundaboutIconName: function(turnAngle) {
+    _getRoundaboutIconName(turnAngle) {
         /*
          * To map turnAngle with closest roundabout
          * turning angle symbol available. The Algorithm
@@ -139,4 +142,4 @@ var TurnPoint = new Lang.Class({
         }
         return 'maps-direction-roundabout-' + angle + '-symbolic';
     }
-});
+};
diff --git a/src/routeEntry.js b/src/routeEntry.js
index 812ef37..3dd1df3 100644
--- a/src/routeEntry.js
+++ b/src/routeEntry.js
@@ -20,7 +20,6 @@
 const Gdk = imports.gi.Gdk;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const PlaceEntry = imports.placeEntry;
@@ -31,17 +30,16 @@ var Type = {
     VIA: 2
 };
 
-var RouteEntry = new Lang.Class({
-    Name: 'RouteEntry',
-    Extends: Gtk.Grid,
+var RouteEntry = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/route-entry.ui',
     Children: [ 'iconEventBox' ],
     InternalChildren: [ 'entryGrid',
                         'icon',
                         'button',
-                        'buttonImage' ],
+                        'buttonImage' ]
+}, class RouteEntry extends Gtk.Grid {
 
-    _init: function(params) {
+    _init(params) {
         this._type = params.type;
         delete params.type;
 
@@ -51,7 +49,7 @@ var RouteEntry = new Lang.Class({
         this._mapView = params.mapView || null;
         delete params.mapView;
 
-        this.parent(params);
+        super._init(params);
 
         this.entry = this._createEntry();
         this._entryGrid.add(this.entry);
@@ -78,17 +76,17 @@ var RouteEntry = new Lang.Class({
             this._icon.icon_name = 'maps-point-end-symbolic';
             break;
         }
-    },
+    }
 
     get button() {
         return this._button;
-    },
+    }
 
     get point() {
         return this._point;
-    },
+    }
 
-    _createEntry: function() {
+    _createEntry() {
         let entry = new PlaceEntry.PlaceEntry({ visible: true,
                                                 can_focus: true,
                                                 hexpand: true,
diff --git a/src/routeQuery.js b/src/routeQuery.js
index cd3b4b2..f2bf1c0 100644
--- a/src/routeQuery.js
+++ b/src/routeQuery.js
@@ -21,7 +21,6 @@
 
 const GObject = imports.gi.GObject;
 const Geocode = imports.gi.GeocodeGlib;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const PlaceStore = imports.placeStore;
@@ -44,9 +43,7 @@ var Transportation = {
     }
 };
 
-var QueryPoint = new Lang.Class({
-    Name: 'QueryPoint',
-    Extends: GObject.Object,
+var QueryPoint = GObject.registerClass({
     Properties: {
         'place': GObject.ParamSpec.object('place',
                                           '',
@@ -54,26 +51,25 @@ var QueryPoint = new Lang.Class({
                                           GObject.ParamFlags.READABLE |
                                           GObject.ParamFlags.WRITABLE,
                                           Geocode.Place)
-    },
+    }
+}, class QueryPoint extends GObject.Object {
 
-    _init: function() {
+    _init() {
         this._place = null;
-        this.parent();
-    },
+        super._init();
+    }
 
     set place(p) {
         this._place = p;
         this.notify('place');
-    },
+    }
 
     get place() {
         return this._place;
     }
 });
 
-var RouteQuery = new Lang.Class({
-    Name: 'RouteQuery',
-    Extends: GObject.Object,
+var RouteQuery = GObject.registerClass({
     Signals: {
         'reset': { },
         'point-added': { param_types: [GObject.TYPE_OBJECT, GObject.TYPE_INT] },
@@ -95,40 +91,41 @@ var RouteQuery = new Lang.Class({
                                                 Transportation.PEDESTRIAN,
                                                 Transportation.CAR,
                                                 Transportation.TRANSIT)
-    },
+    }
+}, class RouteQuery extends GObject.Object {
 
     get points() {
         return this._points;
-    },
+    }
 
     set points(points) {
         this._points = points;
         this.notify('points');
-    },
+    }
 
     get filledPoints() {
         return this.points.filter(function(point) {
             return point.place;
         });
-    },
+    }
 
     get latest() {
         return this._latest;
-    },
+    }
 
     get time() {
         return this._time;
-    },
+    }
 
     /* time to leave or arrive, null implies "Leave now" */
     set time(time) {
         this._time = time;
         this.notify('points');
-    },
+    }
 
     get date() {
         return this._date;
-    },
+    }
 
     /* date to leave or arrive */
     set date(date) {
@@ -138,11 +135,11 @@ var RouteQuery = new Lang.Class({
          * triggering an update */
         if (date)
             this.notify('points');
-    },
+    }
 
     get arriveBy() {
         return this._arriveBy;
-    },
+    }
 
     /* when set to true, the set time and date means arrive by the specified
      * time */
@@ -150,19 +147,19 @@ var RouteQuery = new Lang.Class({
         this._arriveBy = arriveBy;
         if (this._time)
             this.notify('points');
-    },
+    }
 
     get transitOptions() {
         return this._transitOptions;
-    },
+    }
 
     set transitOptions(options) {
         this._transitOptions = options;
         this.notify('points');
-    },
+    }
 
-    _init: function(args) {
-        this.parent(args);
+    _init(args) {
+        super._init(args);
         this._points = [];
         this._time = null;
         this._date = null;
@@ -170,15 +167,15 @@ var RouteQuery = new Lang.Class({
         this._transitOptions = new TransitOptions.TransitOptions();
         this._initTransportation();
         this.reset();
-    },
+    }
 
-    _initTransportation: function() {
+    _initTransportation() {
         let transportationType = Application.settings.get_enum('transportation-type');
 
         this.transportation = transportationType;
-    },
+    }
 
-    addPoint: function(index) {
+    addPoint(index) {
         let point = new QueryPoint();
 
         if (index === -1)
@@ -200,9 +197,9 @@ var RouteQuery = new Lang.Class({
         this.notify('points');
         this.emit('point-added', point, index);
         return point;
-    },
+    }
 
-    removePoint: function(index) {
+    removePoint(index) {
         let removedPoints = this._points.splice(index, 1);
         let point = removedPoints ? removedPoints[0] : null;
         if (point === this._latest)
@@ -212,19 +209,20 @@ var RouteQuery = new Lang.Class({
             this.notify('points');
             this.emit('point-removed', point, index);
         }
-    },
+    }
 
     set transportation(transportation) {
         Application.settings.set_enum('transportation-type', transportation);
         this._transportation = transportation;
         this.notify('transportation');
         this.notify('points');
-    },
+    }
+
     get transportation() {
         return this._transportation;
-    },
+    }
 
-    reset: function() {
+    reset() {
         this.freeze_notify();
         this._points.forEach(function(point) {
             point.place = null;
@@ -232,16 +230,16 @@ var RouteQuery = new Lang.Class({
         this._latest = null;
         this.thaw_notify();
         this.emit('reset');
-    },
+    }
 
-    isValid: function() {
+    isValid() {
         if (this.filledPoints.length >= 2)
             return true;
         else
             return false;
-    },
+    }
 
-    toString: function() {
+    toString() {
         return "\nPoints: " + this.points +
                "\nTransportation: " + this.transportation;
     }
diff --git a/src/routingDelegator.js b/src/routingDelegator.js
index b03417b..6e02b21 100644
--- a/src/routingDelegator.js
+++ b/src/routingDelegator.js
@@ -19,22 +19,16 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
- const Lang = imports.lang;
+const GraphHopper = imports.graphHopper;
+const OpenTripPlanner = imports.openTripPlanner;
+const RouteQuery = imports.routeQuery;
 
- const GraphHopper = imports.graphHopper;
- const OpenTripPlanner = imports.openTripPlanner;
- const RouteQuery = imports.routeQuery;
+const _FALLBACK_TRANSPORTATION = RouteQuery.Transportation.PEDESTRIAN;
 
- const _FALLBACK_TRANSPORTATION = RouteQuery.Transportation.PEDESTRIAN;
+var RoutingDelegator = class RoutingDelegator {
 
- var RoutingDelegator = new Lang.Class({
-    Name: 'RoutingDelegator',
-
-    _init: function(params) {
+    constructor(params) {
         this._query = params.query;
-        delete params.query;
-
-        this.parent(params);
 
         this._transitRouting = false;
         this._graphHopper = new GraphHopper.GraphHopper({ query: this._query });
@@ -50,28 +44,28 @@
             !this._openTripPlanner.enabled) {
             this._query.transportation = _FALLBACK_TRANSPORTATION;
         }
-    },
+    }
 
     get graphHopper() {
         return this._graphHopper;
-    },
+    }
 
     get openTripPlanner() {
         return this._openTripPlanner;
-    },
+    }
 
     set useTransit(useTransit) {
         this._transitRouting = useTransit;
-    },
+    }
 
-    reset: function() {
+    reset() {
         if (this._transitRouting)
             this._openTripPlanner.plan.reset();
         else
             this._graphHopper.route.reset();
-    },
+    }
 
-    _onQueryChanged: function() {
+    _onQueryChanged() {
         if (this._query.isValid()) {
             if (this._transitRouting) {
                 this._openTripPlanner.fetchFirstResults();
@@ -81,4 +75,4 @@
             }
         }
     }
- });
+};
diff --git a/src/searchPopover.js b/src/searchPopover.js
index 8f676de..d99b754 100644
--- a/src/searchPopover.js
+++ b/src/searchPopover.js
@@ -23,17 +23,15 @@
 const Gdk = imports.gi.Gdk;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 /* Abstract search result popover that progagates keypress events from a
    focus-taking internal widget to the spawning search entry widget */
-var SearchPopover = new Lang.Class({
-    Name: 'SearchPopover',
-    Extends: Gtk.Popover,
-    Abstract: true,
+var SearchPopover = GObject.registerClass({
+    Abstract: true
+}, class SearchPopover extends Gtk.Popover {
 
-    _init: function(props) {
-        this.parent(props);
+    _init(props) {
+        super._init(props);
 
         this._entry = this.relative_to;
 
@@ -43,9 +41,9 @@ var SearchPopover = new Lang.Class({
         this._entry.connect('key-press-event',
                             this._propagateKeys.bind(this));
         this._entry.connect('button-press-event', () => { this._list.unselect_all(); });
-    },
+    }
 
-    _propagateKeys: function(entry, event) {
+    _propagateKeys(entry, event) {
         let row;
 
         if (this.visible) {
diff --git a/src/sendToDialog.js b/src/sendToDialog.js
index cd07b25..4366261 100644
--- a/src/sendToDialog.js
+++ b/src/sendToDialog.js
@@ -20,9 +20,9 @@
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const GWeather = imports.gi.GWeather;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const Utils = imports.utils;
@@ -37,9 +37,7 @@ var Response = {
 
 const _NUM_VISIBLE = 6;
 
-var SendToDialog = new Lang.Class({
-    Name: 'SendToDialog',
-    Extends: Gtk.Dialog,
+var SendToDialog = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/send-to-dialog.ui',
     InternalChildren: [ 'list',
                         'weatherRow',
@@ -54,9 +52,10 @@ var SendToDialog = new Lang.Class({
                         'headerBar',
                         'cancelButton',
                         'chooseButton',
-                        'scrolledWindow' ],
+                        'scrolledWindow' ]
+}, class SendToDialog extends Gtk.Dialog {
 
-    _init: function(params) {
+    _init(params) {
         this._place = params.place;
         delete params.place;
 
@@ -64,7 +63,7 @@ var SendToDialog = new Lang.Class({
         delete params.mapView;
 
         params.use_header_bar = true;
-        this.parent(params);
+        super._init(params);
 
         this._scrolledWindow.min_content_height = 40 * _NUM_VISIBLE;
         this._headerBar.subtitle = this._place.name;
@@ -87,9 +86,9 @@ var SendToDialog = new Lang.Class({
             else
                 row.set_header(null);
         });
-    },
+    }
 
-    ensureApplications: function() {
+    ensureApplications() {
         let weatherInfo = Gio.DesktopAppInfo.new(_WEATHER_APPID + '.desktop');
         let clocksInfo = Gio.DesktopAppInfo.new(_CLOCKS_APPID + '.desktop');
         let browserInfo = Gio.AppInfo.get_default_for_uri_scheme('https');
@@ -122,9 +121,9 @@ var SendToDialog = new Lang.Class({
         }
 
         return appWeather || appClocks || browserInfo;
-    },
+    }
 
-    _getOSMURI: function() {
+    _getOSMURI() {
         let view = this._mapView.view;
         let place = this._place;
 
@@ -139,9 +138,9 @@ var SendToDialog = new Lang.Class({
                                                      place.location.longitude,
                                                      view.zoom_level);
         }
-    },
+    }
 
-    _activateRow: function(row) {
+    _activateRow(row) {
         let timestamp = Gtk.get_current_event_time();
 
         if (row === this._weatherRow || row === this._clocksRow) {
@@ -180,13 +179,13 @@ var SendToDialog = new Lang.Class({
             }
         }
         this.response(Response.SUCCESS);
-    },
+    }
 
-    _checkWeather: function(appInfo) {
+    _checkWeather(appInfo) {
         return (GWeather !== null && appInfo !== null);
-    },
+    }
 
-    _checkClocks: function(appInfo) {
+    _checkClocks(appInfo) {
         return (GWeather !== null && appInfo !== null);
     }
 });
diff --git a/src/serviceBackend.js b/src/serviceBackend.js
index bbe7165..edcfdeb 100644
--- a/src/serviceBackend.js
+++ b/src/serviceBackend.js
@@ -19,42 +19,42 @@
  * Author: Damián Nohales <damiannohales gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Utils = imports.utils;
 
-var ServiceBackend = new Lang.Class({
-    Name: 'SocialServiceServiceBackend',
-    Abstract: true,
+var ServiceBackend = GObject.registerClass({
+    Abstract: true
+}, class ServiceBackend extends GObject.Object {
 
     //Abstract
-    get name() { },
+    get name() { }
 
     //Abstract
-    createRestCall: function(authorizer) { },
+    createRestCall(authorizer) { }
 
     //Abstract
-    refreshAuthorization: function(authorizer, cancellable) { },
+    refreshAuthorization(authorizer, cancellable) { }
 
     //Abstract
-    getAuthorizerAccount: function(authorizer) { },
+    getAuthorizerAccount(authorizer) { }
 
     //Abstract
-    createAuthorizer: function(account) { },
+    createAuthorizer(account) { }
 
     //Abstract
-    isTokenInvalid: function(restCall, parsedPayload) { },
+    isTokenInvalid(restCall, parsedPayload) { }
 
     //Abstract
-    isInvalidCall: function(restCall, parsedPayload) { },
+    isInvalidCall(restCall, parsedPayload) { }
 
     //Abstract
-    getCallResultCode: function(restCall, parsedPayload) { },
+    getCallResultCode(restCall, parsedPayload) { }
 
     //Abstract
-    getCallResultMessage: function(restCall, parsedPayload) { },
+    getCallResultMessage(restCall, parsedPayload) { }
 
-    callAsync: function(authorizer, method, func, params, callback, cancellable, mustRefreshToken) {
+    callAsync(authorizer, method, func, params, callback, cancellable, mustRefreshToken) {
         mustRefreshToken = mustRefreshToken || true;
         cancellable = cancellable || null;
 
@@ -94,17 +94,17 @@ var ServiceBackend = new Lang.Class({
             else
                 callback(account, data, null);
         });
-    },
+    }
 
-    performCheckIn: function(authorizer, checkIn, callback, cancellable) {
+    performCheckIn(authorizer, checkIn, callback, cancellable) {
         callback = callback || function() {};
         this._realPerformCheckIn(authorizer, checkIn, callback, cancellable);
-    },
+    }
 
     //Abstract
-    _realPerformCheckIn: function(authorizer, checkIn, callback, cancellable) { },
+    _realPerformCheckIn(authorizer, checkIn, callback, cancellable) { }
 
-    findPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) {
+    findPlaces(authorizer, latitude, longitude, distance, callback, cancellable) {
         callback = callback || function() {};
         this._realFindPlaces(authorizer,
                              latitude,
@@ -117,11 +117,11 @@ var ServiceBackend = new Lang.Class({
                                      callback(account, [], error);
                              },
                              cancellable);
-    },
+    }
 
     //Abstract
-    _realFindPlaces: function(authorizer, latitude, longitude, distance, callback, cancellable) { },
+    _realFindPlaces(authorizer, latitude, longitude, distance, callback, cancellable) { }
 
     //Abstract
-    createPlaces: function(rawData) { }
+    createPlaces(rawData) { }
 });
diff --git a/src/settings.js b/src/settings.js
index 10827c3..fa2478a 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -21,30 +21,28 @@
 
 const GLib = imports.gi.GLib;
 const Gio = imports.gi.Gio;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 const System = imports.system;
 
-var Settings = new Lang.Class({
-    Name: "Settings",
-    Extends: Gio.Settings,
+var Settings = GObject.registerClass(
+class Settings extends Gio.Settings {
 
-    // The GVariant types of the settings
-    _keyTypes: {},
-
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
+        // The GVariant types of the settings
+        this._keyTypes = {};
         this.list_keys().forEach((key) => {
             this._keyTypes[key] = this.get_value(key)
                                       .get_type()
                                       .dup_string();
         });
-    },
+    }
 
-    get: function(name) {
+    get(name) {
         return this.get_value(name).deep_unpack();
-    },
+    }
 
-    set: function(name, value) {
+    set(name, value) {
         this.set_value(name, GLib.Variant.new (this._keyTypes[name], value));
     }
 });
diff --git a/src/shapeLayer.js b/src/shapeLayer.js
index 9dd5107..dccc789 100644
--- a/src/shapeLayer.js
+++ b/src/shapeLayer.js
@@ -22,26 +22,26 @@ const Gio = imports.gi.Gio;
 const GObject = imports.gi.GObject;
 const Lang = imports.lang;
 
+const GeoJSONShapeLayer = imports.geoJSONShapeLayer;
+
 var SUPPORTED_TYPES = [];
 
 function newFromFile(file, mapView) {
     let contentType = Gio.content_type_guess(file.get_uri(), null)[0];
     for (let layerClass of SUPPORTED_TYPES) {
         if (layerClass.mimeTypes.indexOf(contentType) > -1) {
-            return new layerClass({ file: file, mapView: mapView });
+            return layerClass.createInstance({ file: file, mapView: mapView });
         }
     }
     return null;
 }
 
-var ShapeLayer = new Lang.Class({
-    Name: 'ShapeLayer',
-    Extends: GObject.Object,
-    Abstract: true,
-
-    _init: function(params) {
-        this.parent();
+var ShapeLayer = GObject.registerClass({
+    Abstract: true
+}, class ShapeLayer extends GObject.Object {
 
+    _init(params) {
+        super._init();
         this._visible = true;
         this._mapView = params.mapView;
         this.file = params.file;
@@ -56,15 +56,15 @@ var ShapeLayer = new Lang.Class({
             selection_mode: Champlain.SelectionMode.SINGLE
         });
         this._mapSource = null;
-    },
+    }
 
     get bbox() {
         return this._mapSource.bbox;
-    },
+    }
 
     get visible() {
         return this._visible;
-    },
+    }
 
     set visible(v) {
         if (v && !this._visible) {
@@ -75,17 +75,17 @@ var ShapeLayer = new Lang.Class({
             this._markerLayer.hide_all_markers();
         }
         this._visible = v;
-    },
+    }
 
-    getName: function() {
+    getName() {
         /*
          * Remove file extension and use that in lieu of a fileformat-specific
          * display name.
          */
         return this.filename.replace(/\.[^\.]+$/, '');
-    },
+    }
 
-    load: function() {
+    load() {
         let [status, buffer] = this.file.load_contents(null);
         this._fileContents = buffer;
         if (!status)
@@ -93,14 +93,14 @@ var ShapeLayer = new Lang.Class({
         this._parseContent();
         this._mapView.view.add_layer(this._markerLayer);
         this._mapView.view.add_overlay_source(this._mapSource, 255);
-    },
+    }
 
 
-    _parseContent: function() {
+    _parseContent() {
         /* Unimplemented */
-    },
+    }
 
-    unload: function() {
+    unload() {
         this._mapView.view.remove_layer(this._markerLayer);
         this._mapView.view.remove_overlay_source(this._mapSource);
     }
diff --git a/src/shortPrintLayout.js b/src/shortPrintLayout.js
index 35010b9..c0595ac 100644
--- a/src/shortPrintLayout.js
+++ b/src/shortPrintLayout.js
@@ -17,7 +17,7 @@
  * Author: Amisha Singla <amishas157 gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const PrintLayout = imports.printLayout;
 
@@ -28,11 +28,9 @@ const _Instruction = {
     SCALE_MARGIN: 0.01
 };
 
-var ShortPrintLayout = new Lang.Class({
-    Name: 'ShortPrintLayout',
-    Extends: PrintLayout.PrintLayout,
-
-    _init: function(params) {
+var ShortPrintLayout = GObject.registerClass(
+class ShortPrintLayout extends PrintLayout.PrintLayout {
+    _init(params) {
         this._route = params.route;
         delete params.route;
 
@@ -40,11 +38,11 @@ var ShortPrintLayout = new Lang.Class({
         let totalSurfaces = 2 + this._route.turnPoints.length;
         params.totalSurfaces = totalSurfaces;
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
-    render: function() {
-        this.parent();
+    render() {
+        super.render();
 
         let instructionWidth = _Instruction.SCALE_X * this._pageWidth;
         let instructionHeight = _Instruction.SCALE_Y * this._pageHeight;
diff --git a/src/sidebar.js b/src/sidebar.js
index 2348c46..56c6a7b 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -24,7 +24,6 @@ const Cairo = imports.cairo;
 const Gdk = imports.gi.Gdk;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -40,9 +39,7 @@ const TransitMoreRow = imports.transitMoreRow;
 const TransitOptionsPanel = imports.transitOptionsPanel;
 const Utils = imports.utils;
 
-var Sidebar = new Lang.Class({
-    Name: 'Sidebar',
-    Extends: Gtk.Revealer,
+var Sidebar = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/sidebar.ui',
     InternalChildren: [ 'distanceInfo',
                         'entryList',
@@ -66,10 +63,11 @@ var Sidebar = new Lang.Class({
                         'transitItineraryListBox',
                         'transitItineraryBackButton',
                         'transitItineraryTimeLabel',
-                        'transitItineraryDurationLabel'],
+                        'transitItineraryDurationLabel']
+}, class Sidebar extends Gtk.Revealer {
 
-    _init: function(mapView) {
-        this.parent({ transition_type: Gtk.RevealerTransitionType.SLIDE_LEFT });
+    _init(mapView) {
+        super._init({ transition_type: Gtk.RevealerTransitionType.SLIDE_LEFT });
 
         this._mapView = mapView;
 
@@ -104,9 +102,9 @@ var Sidebar = new Lang.Class({
          */
         if (!Application.routingDelegator.openTripPlanner.enabled)
             this._modeTransitToggle.destroy();
-    },
+    }
 
-    _initTransportationToggles: function(pedestrian, bike, car, transit) {
+    _initTransportationToggles(pedestrian, bike, car, transit) {
         let transport = RouteQuery.Transportation;
 
         let onToggle = function(mode, button) {
@@ -143,9 +141,9 @@ var Sidebar = new Lang.Class({
 
         setToggles.bind(this)();
         this._query.connect('notify::transportation', setToggles.bind(this));
-    },
+    }
 
-    _switchRoutingMode: function(mode) {
+    _switchRoutingMode(mode) {
         if (mode === RouteQuery.Transportation.TRANSIT) {
             Application.routingDelegator.useTransit = true;
             this._linkButtonStack.visible_child_name = 'openTripPlanner';
@@ -158,9 +156,9 @@ var Sidebar = new Lang.Class({
             this._transitRevealer.reveal_child = false;
             Application.routingDelegator.openTripPlanner.plan.deselectItinerary();
         }
-    },
+    }
 
-    _initQuerySignals: function() {
+    _initQuerySignals() {
         this._query.connect('point-added', (obj, point, index) => {
             this._createRouteEntry(index, point);
         });
@@ -169,14 +167,14 @@ var Sidebar = new Lang.Class({
             let row = this._entryList.get_row_at_index(index);
             row.destroy();
         });
-    },
+    }
 
-    _cancelStore: function() {
+    _cancelStore() {
         Mainloop.source_remove(this._storeRouteTimeoutId);
         this._storeRouteTimeoutId = 0;
-    },
+    }
 
-    _createRouteEntry: function(index, point) {
+    _createRouteEntry(index, point) {
         let type;
         if (index === 0)
             type = RouteEntry.Type.FROM;
@@ -210,9 +208,9 @@ var Sidebar = new Lang.Class({
         }
 
         this._initRouteDragAndDrop(routeEntry);
-    },
+    }
 
-    _initInstructionList: function() {
+    _initInstructionList() {
         let route = Application.routingDelegator.graphHopper.route;
         let transitPlan = Application.routingDelegator.openTripPlanner.plan;
 
@@ -316,36 +314,36 @@ var Sidebar = new Lang.Class({
         this._transitItineraryBackButton.connect('clicked',
                                                  this._showTransitOverview.bind(this));
 
-    },
+    }
 
-    _clearTransitOverview: function() {
+    _clearTransitOverview() {
         let listBox = this._transitOverviewListBox;
         listBox.forall(listBox.remove.bind(listBox));
 
         this._instructionStack.visible_child = this._transitWindow;
         this._timeInfo.label = '';
         this._distanceInfo.label = '';
-    },
+    }
 
-    _clearTransitItinerary: function() {
+    _clearTransitItinerary() {
         let listBox = this._transitItineraryListBox;
         listBox.forall(listBox.remove.bind(listBox));
-    },
+    }
 
-    _showTransitOverview: function() {
+    _showTransitOverview() {
         let plan = Application.routingDelegator.openTripPlanner.plan;
 
         this._transitListStack.visible_child_name = 'overview';
         this._transitHeader.visible_child_name = 'options';
         plan.deselectItinerary();
-    },
+    }
 
-    _showTransitItineraryView: function() {
+    _showTransitItineraryView() {
         this._transitListStack.visible_child_name = 'itinerary';
         this._transitHeader.visible_child_name = 'itinerary-header';
-    },
+    }
 
-    _populateTransitItineraryOverview: function() {
+    _populateTransitItineraryOverview() {
         let plan = Application.routingDelegator.openTripPlanner.plan;
 
         plan.itineraries.forEach((itinerary) => {
@@ -360,31 +358,31 @@ var Sidebar = new Lang.Class({
 
         /* add an empty list row to get a final separator */
         this._transitOverviewListBox.add(new Gtk.ListBoxRow({ visible: true }));
-    },
+    }
 
-    _onItineraryActivated: function(itinerary) {
+    _onItineraryActivated(itinerary) {
         let plan = Application.routingDelegator.openTripPlanner.plan;
 
         this._populateTransitItinerary(itinerary);
         this._showTransitItineraryView();
         plan.selectItinerary(itinerary);
-    },
+    }
 
-    _onMoreActivated: function(row) {
+    _onMoreActivated(row) {
         row.startLoading();
         Application.routingDelegator.openTripPlanner.fetchMoreResults();
-    },
+    }
 
-    _onItineraryOverviewRowActivated: function(listBox, row) {
+    _onItineraryOverviewRowActivated(listBox, row) {
         this._transitOverviewListBox.unselect_all();
 
         if (row.itinerary)
             this._onItineraryActivated(row.itinerary);
         else
             this._onMoreActivated(row);
-    },
+    }
 
-    _populateTransitItinerary: function(itinerary) {
+    _populateTransitItinerary(itinerary) {
         this._transitItineraryTimeLabel.label =
             itinerary.prettyPrintTimeInterval();
         this._transitItineraryDurationLabel.label =
@@ -403,20 +401,20 @@ var Sidebar = new Lang.Class({
         this._transitItineraryListBox.add(
             new TransitArrivalRow.TransitArrivalRow({ itinerary: itinerary,
                                                       mapView: this._mapView }));
-    },
+    }
 
 
-    _clearInstructions: function() {
+    _clearInstructions() {
         let listBox = this._instructionList;
         listBox.forall(listBox.remove.bind(listBox));
 
         this._instructionStack.visible_child = this._instructionWindow;
         this._timeInfo.label = '';
         this._distanceInfo.label = '';
-    },
+    }
 
     // Iterate over points and establish the new order of places
-    _reorderRoutePoints: function(srcIndex, destIndex) {
+    _reorderRoutePoints(srcIndex, destIndex) {
         let points = this._query.points;
         let srcPlace = this._draggedPoint.place;
 
@@ -433,13 +431,13 @@ var Sidebar = new Lang.Class({
         }
 
         this._query.thaw_notify();
-    },
+    }
 
     /* The reason we don't just use the array .reverse() function is that we
      * need to update the place parameters on the actual point objects in the
      * array to fire the query notify signal that will iniate an update.
      */
-    _reverseRoutePoints: function() {
+    _reverseRoutePoints() {
         let points = this._query.points;
         let length = points.length;
 
@@ -452,28 +450,28 @@ var Sidebar = new Lang.Class({
             points[length - i - 1].place = p1;
         }
         this._query.thaw_notify();
-    },
+    }
 
-    _onDragDrop: function(row, context, x, y, time) {
+    _onDragDrop(row, context, x, y, time) {
         let srcIndex = this._query.points.indexOf(this._draggedPoint);
         let destIndex = row.get_index();
 
         this._reorderRoutePoints(srcIndex, destIndex);
         Gtk.drag_finish(context, true, false, time);
         return true;
-    },
+    }
 
-    _dragHighlightRow: function(row) {
+    _dragHighlightRow(row) {
         row.opacity = 0.6;
-    },
+    }
 
-    _dragUnhighlightRow: function(row) {
+    _dragUnhighlightRow(row) {
         row.opacity = 1.0;
-    },
+    }
 
     // Set the opacity of the row we are currently dragging above
     // to semi transparent.
-    _onDragMotion: function(row, context, x, y, time) {
+    _onDragMotion(row, context, x, y, time) {
         let routeEntry = row.get_child();
 
         if (this._draggedPoint && this._draggedPoint !== routeEntry.point) {
@@ -482,19 +480,19 @@ var Sidebar = new Lang.Class({
         } else
             Gdk.drag_status(context, 0, time);
         return true;
-    },
+    }
 
     // Drag ends, show the dragged row again.
-    _onDragEnd: function(context, row) {
+    _onDragEnd(context, row) {
         this._draggedPoint = null;
 
         // Restore to natural height
         row.height_request = -1;
         row.get_child().show();
-    },
+    }
 
     // Drag begins, set the correct drag icon and hide the dragged row.
-    _onDragBegin: function(context, row) {
+    _onDragBegin(context, row) {
         let routeEntry = row.get_child();
         let dragEntry = this._dragWidget.get_child();
 
@@ -509,12 +507,12 @@ var Sidebar = new Lang.Class({
         dragEntry.entry.text = routeEntry.entry.text;
         Gtk.drag_set_icon_surface(context,
                                   this._dragWidget.get_surface(), 0, 0);
-    },
+    }
 
     // We add RouteEntry to an OffscreenWindow and paint the background
     // of the entry to be transparent. We can later use the GtkOffscreenWindow
     // method get_surface to generate our drag icon.
-    _initDragWidget: function() {
+    _initDragWidget() {
         let dragEntry = new RouteEntry.RouteEntry({ type: RouteEntry.Type.TO,
                                                     name: 'dragged-entry',
                                                     app_paintable: true });
@@ -528,12 +526,12 @@ var Sidebar = new Lang.Class({
         });
 
         this._dragWidget.add(dragEntry);
-    },
+    }
 
     // Set up drag and drop between RouteEntrys. The drag source is from a
     // GtkEventBox that contains the start/end icon next in the entry. And
     // the drag destination is the ListBox row.
-    _initRouteDragAndDrop: function(routeEntry) {
+    _initRouteDragAndDrop(routeEntry) {
         let dragIcon = routeEntry.iconEventBox;
         let row = routeEntry.get_parent();
 
@@ -556,4 +554,4 @@ var Sidebar = new Lang.Class({
 
         this._initDragWidget();
     }
-})
+});
diff --git a/src/socialPlace.js b/src/socialPlace.js
index 46f0ae0..8ee1e8d 100644
--- a/src/socialPlace.js
+++ b/src/socialPlace.js
@@ -19,17 +19,13 @@
  * Author: Damián Nohales <damiannohales gmail com>
  */
 
-const Geocode = imports.gi.GeocodeGlib;
 const GObject = imports.gi.GObject;
-const Lang = imports.lang;
 const Location = imports.location;
 
-var SocialPlace = new Lang.Class({
-    Name: 'SocialServiceSocialPlace',
-    Extends: GObject.Object,
-
-    _init: function(params) {
-        this.parent();
+var SocialPlace = GObject.registerClass(
+class SocialPlace extends GObject.Object {
+    _init(params) {
+        super._init();
 
         this.id = params.id;
         this.name = params.name;
@@ -38,7 +34,7 @@ var SocialPlace = new Lang.Class({
         this.category = params.category;
         this.link = params.link;
         this.originalData = params.originalData;
-    },
+    }
 
     get location() {
         return new Location.Location({ latitude: parseFloat(this.latitude),
diff --git a/src/socialPlaceListBox.js b/src/socialPlaceListBox.js
index 13514fb..cb70fec 100644
--- a/src/socialPlaceListBox.js
+++ b/src/socialPlaceListBox.js
@@ -21,21 +21,18 @@
 
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
-const Mainloop = imports.mainloop;
 
-var SocialPlaceRow = new Lang.Class({
-    Name: 'SocialPlaceRow',
-    Extends: Gtk.ListBoxRow,
+var SocialPlaceRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/social-place-row.ui',
     InternalChildren: [ 'nameLabel',
-                        'categoryLabel' ],
+                        'categoryLabel' ]
+}, class SocialPlaceRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this.place = params.place;
         delete params.place;
 
-        this.parent(params);
+        super._init(params);
 
         this._nameLabel.label = this.place.name;
         if (this.place.category)
@@ -45,22 +42,19 @@ var SocialPlaceRow = new Lang.Class({
     }
 });
 
-var SocialPlaceMoreResultsRow = new Lang.Class({
-    Name: 'SocialPlaceMoreResultsRow',
-    Extends: Gtk.ListBoxRow,
+var SocialPlaceMoreResultsRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/social-place-more-results-row.ui'
-});
+}, class SocialPlaceMoreResultsRow extends Gtk.ListBoxRow {});
 
-var SocialPlaceListBox = new Lang.Class({
-    Name: 'SocialPlaceListBox',
-    Extends: Gtk.ListBox,
+var SocialPlaceListBox = GObject.registerClass({
     Signals: {
         'place-selected': { param_types: [GObject.TYPE_OBJECT] }
-    },
+    }
+}, class SocialPlaceListBox extends Gtk.ListBox {
 
-    _init: function(params) {
+    _init(params) {
         params.activate_on_single_click = true;
-        this.parent(params);
+        super._init(params);
 
         this.connect('row-activated', (list, row) => {
             if (!row.place) {
@@ -70,11 +64,11 @@ var SocialPlaceListBox = new Lang.Class({
             } else
                 this.emit('place-selected', row.place);
         });
-    },
+    }
 
     get matches() {
         return this._matches;
-    },
+    }
 
     set matches(matches) {
         this.forall(function(row) {
@@ -93,17 +87,17 @@ var SocialPlaceListBox = new Lang.Class({
             if (this._matches.badMatches.length > 0)
                 this._addMoreResults();
         }
-    },
+    }
 
-    _showBadMatches: function() {
+    _showBadMatches() {
         this._matches.badMatches.forEach(this._addPlace.bind(this));
-    },
+    }
 
-    _addPlace: function(place) {
+    _addPlace(place) {
         this.add(new SocialPlaceRow({ place: place }));
-    },
+    }
 
-    _addMoreResults: function() {
+    _addMoreResults() {
         this.add(new SocialPlaceMoreResultsRow({}));
     }
 });
diff --git a/src/storedRoute.js b/src/storedRoute.js
index 3d18dc8..ba0c26b 100644
--- a/src/storedRoute.js
+++ b/src/storedRoute.js
@@ -22,8 +22,8 @@
 
 const Champlain = imports.gi.Champlain;
 const Gio = imports.gi.Gio;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Place = imports.place;
 const Route = imports.route;
@@ -33,11 +33,10 @@ const RouteQuery = imports.routeQuery;
 const _RLM = '\u200F';
 const _LRM = '\u200E';
 
-var StoredRoute = new Lang.Class({
-    Name: 'StoredRoute',
-    Extends: Place.Place,
+var StoredRoute = GObject.registerClass(
+class StoredRoute extends Place.Place {
 
-    _init: function(params) {
+    _init(params) {
         let route = params.route;
         delete params.route;
 
@@ -78,8 +77,8 @@ var StoredRoute = new Lang.Class({
             this.places.push(new Place.Place({ place: place }));
         });
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
     get viaString() {
         let directionMarker = this._rtl ? _RLM : _LRM;
@@ -87,11 +86,11 @@ var StoredRoute = new Lang.Class({
         return this.places.map(function(place) {
             return directionMarker + place.name;
         }).join(directionMarker + arrow);
-    },
+    }
 
     get transportation() {
         return this._transportation;
-    },
+    }
 
     get icon() {
         let transport = RouteQuery.Transportation;
@@ -110,17 +109,17 @@ var StoredRoute = new Lang.Class({
         }
 
         return icon;
-    },
+    }
 
     get uniqueID() {
         return this._transportation + '-' + this.places.map(function(place) {
             return [place.osm_type, place.osm_id].join('-');
         }).join('-');
-    },
+    }
 
     get containsCurrentLocation() {
         return this._containsCurrentLocation;
-    },
+    }
 
     get containsNull() {
         let hasNull = false;
@@ -132,9 +131,9 @@ var StoredRoute = new Lang.Class({
             }
         }
         return hasNull;
-    },
+    }
 
-    toJSON: function() {
+    toJSON() {
         let turnPoints = this.route.turnPoints.map(function(turnPoint) {
             let coordinate = { latitude: turnPoint.coordinate.latitude,
                                longitude: turnPoint.coordinate.longitude };
diff --git a/src/transitArrivalMarker.js b/src/transitArrivalMarker.js
index 4a401ea..6254740 100644
--- a/src/transitArrivalMarker.js
+++ b/src/transitArrivalMarker.js
@@ -19,20 +19,18 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
 
 const Color = imports.color;
 const Location = imports.location;
 const MapMarker = imports.mapMarker;
 const Place = imports.place;
 
-var TransitArrivalMarker = new Lang.Class({
-    Name: 'TransitArrivalMarker',
-    Extends: MapMarker.MapMarker,
+var TransitArrivalMarker = GObject.registerClass(
+class TransitArrivalMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
+    _init(params) {
         let lastPoint = params.leg.polyline[params.leg.polyline.length - 1];
         let location =
             new Location.Location({ latitude: lastPoint.latitude,
@@ -44,7 +42,7 @@ var TransitArrivalMarker = new Lang.Class({
         delete params.leg;
         params.place = new Place.Place({ location: location });
 
-        this.parent(params);
+        super._init(params);
 
         let bgRed = Color.parseColor(bgColor, 0);
         let bgGreen = Color.parseColor(bgColor, 1);
@@ -58,7 +56,7 @@ var TransitArrivalMarker = new Lang.Class({
             this._actorFromIconName('maps-point-end-symbolic', 0, color);
 
         this.add_actor(actor);
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2) - 1,
diff --git a/src/transitArrivalRow.js b/src/transitArrivalRow.js
index b2b903a..311089c 100644
--- a/src/transitArrivalRow.js
+++ b/src/transitArrivalRow.js
@@ -19,23 +19,21 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const _ = imports.gettext.gettext;
 
 const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
-var TransitArrivalRow = new Lang.Class({
-    Name: 'TransitArrivalRow',
-    Extends: Gtk.ListBoxRow,
+var TransitArrivalRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-arrival-row.ui',
     InternalChildren: ['arrivalLabel',
                        'timeLabel',
                        'eventBox',
-                       'separator'],
+                       'separator']
+}, class TransitArrivalRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this._itinerary = params.itinerary;
         delete params.itinerary;
 
@@ -45,7 +43,7 @@ var TransitArrivalRow = new Lang.Class({
         this._print = params.print;
         delete params.print;
 
-        this.parent(params);
+        super._init(params);
 
         let lastLeg = this._itinerary.legs[this._itinerary.legs.length - 1];
 
@@ -69,9 +67,9 @@ var TransitArrivalRow = new Lang.Class({
             this._onEvent(event, lastLeg.toCoordinate);
             return true;
         });
-    },
+    }
 
-    _onEvent: function(event, coord) {
+    _onEvent(event, coord) {
         let [isButton, button] = event.get_button();
         let type = event.get_event_type();
 
diff --git a/src/transitBoardMarker.js b/src/transitBoardMarker.js
index cb5483b..2bd3302 100644
--- a/src/transitBoardMarker.js
+++ b/src/transitBoardMarker.js
@@ -19,11 +19,10 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Cairo = imports.cairo;
 const Clutter = imports.gi.Clutter;
 const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
 const Color = imports.color;
@@ -41,11 +40,10 @@ const ACTOR_SIZE = 20;
  */
 const OUTLINE_LUMINANCE_THREASHHOLD = 0.9;
 
-var TransitBoardMarker = new Lang.Class({
-    Name: 'TransitBoardMarker',
-    Extends: MapMarker.MapMarker,
+var TransitBoardMarker = GObject.registerClass(
+class TransitBoardMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
+    _init(params) {
         let firstPoint = params.leg.polyline[0];
         let location = new Location.Location({ latitude: firstPoint.latitude,
                                                longitude: firstPoint.longitude
@@ -54,10 +52,10 @@ var TransitBoardMarker = new Lang.Class({
 
         delete params.leg;
         params.place = new Place.Place({ location: location });
-        this.parent(params);
+        super._init(params);
 
         this.add_actor(this._createActor(leg));
-    },
+    }
 
     /* Creates a Clutter actor for the given transit leg, showing the
      * corresponding transit type icon and rendered inside a circle using the
@@ -68,7 +66,7 @@ var TransitBoardMarker = new Lang.Class({
      * background color above a threashold to improve readability against the
      * map background.
      */
-    _createActor: function(leg) {
+    _createActor(leg) {
         try {
             let bgColor = leg.color ? leg.color : TransitPlan.DEFAULT_ROUTE_COLOR;
             let fgColor =
@@ -131,7 +129,7 @@ var TransitBoardMarker = new Lang.Class({
             Utils.debug('Failed to load image: %s'.format(e.message));
             return null;
         }
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2) - 1,
diff --git a/src/transitItineraryRow.js b/src/transitItineraryRow.js
index 16acfae..b4b1878 100644
--- a/src/transitItineraryRow.js
+++ b/src/transitItineraryRow.js
@@ -19,37 +19,35 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
 const TransitRouteLabel = imports.transitRouteLabel;
 
-var TransitItineraryRow = new Lang.Class({
-    Name: 'TransitItineraryRow',
-    Extends: Gtk.ListBoxRow,
+var TransitItineraryRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-itinerary-row.ui',
     InternalChildren: ['timeLabel',
                        'durationLabel',
-                       'summaryGrid'],
+                       'summaryGrid']
+}, class TransitItineraryRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this._itinerary = params.itinerary;
         delete params.itinerary;
 
-        this.parent(params);
+        super._init(params);
 
         this._timeLabel.label = this._itinerary.prettyPrintTimeInterval();
         this._durationLabel.label = this._itinerary.prettyPrintDuration();
 
         this._populateSummary();
-    },
+    }
 
     get itinerary() {
         return this._itinerary;
-    },
+    }
 
-    _populateSummary: function() {
+    _populateSummary() {
         let length = this._itinerary.legs.length;
         /* use compacted route labels when more than 2 legs, to avoid
          * overflowing the sidebar width
@@ -68,7 +66,7 @@ var TransitItineraryRow = new Lang.Class({
                 this._summaryGrid.add(new Gtk.Label({ visible: true,
                                                       label: '-' }));
         });
-    },
+    }
 
     /* calculate an estimated relative space-consuption for rendering,
      * this is done based on route label character lengths and a fixed
@@ -76,7 +74,7 @@ var TransitItineraryRow = new Lang.Class({
      * exact pixel-correct calculation would be hard depeding on fonts and
      * themes
      */
-    _calculateEstimatedSpace: function() {
+    _calculateEstimatedSpace() {
         let length = this._itinerary.legs.length;
         /* assume mode icons and the separators consume about twice the space of
          * characters
@@ -89,9 +87,9 @@ var TransitItineraryRow = new Lang.Class({
         });
 
         return space;
-    },
+    }
 
-    _createLeg: function(leg, useCompact, useContractedLabels) {
+    _createLeg(leg, useCompact, useContractedLabels) {
         let icon = new Gtk.Image({ icon_name: leg.iconName, visible: true });
 
         icon.get_style_context().add_class('sidebar-icon');
diff --git a/src/transitLegRow.js b/src/transitLegRow.js
index 9b8530d..e0f6c3f 100644
--- a/src/transitLegRow.js
+++ b/src/transitLegRow.js
@@ -19,12 +19,11 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const _ = imports.gettext.gettext;
 
 const Gdk = imports.gi.Gdk;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 const Pango = imports.gi.Pango;
 
@@ -33,9 +32,7 @@ const TransitRouteLabel = imports.transitRouteLabel;
 const TransitStopRow = imports.transitStopRow;
 const Utils = imports.utils;
 
-var TransitLegRow = new Lang.Class({
-    Name: 'TransitLegRow',
-    Extends: Gtk.ListBoxRow,
+var TransitLegRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-leg-row.ui',
     InternalChildren: ['modeImage',
                        'fromLabel',
@@ -47,9 +44,10 @@ var TransitLegRow = new Lang.Class({
                        'agencyLabel',
                        'collapsButton',
                        'instructionList',
-                       'eventBox'],
+                       'eventBox']
+}, class TransitLegRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this._leg = params.leg;
         delete params.leg;
 
@@ -62,7 +60,7 @@ var TransitLegRow = new Lang.Class({
         this._print = params.print;
         delete params.print;
 
-        this.parent(params);
+        super._init(params);
 
         this._modeImage.icon_name = this._leg.iconName;
         if (this._start) {
@@ -172,10 +170,10 @@ var TransitLegRow = new Lang.Class({
         // allow more space for the departure label when printing
         if (this._print)
             this._fromLabel.max_width_chars = -1;
-    },
+    }
 
     // Handle events received on the EventBox for expanding when clicking
-    _handleEventBox: function(event) {
+    _handleEventBox(event) {
         let [isButton, button] = event.get_button();
         let type = event.get_event_type();
 
@@ -190,9 +188,9 @@ var TransitLegRow = new Lang.Class({
                     this._expand();
             }
         }
-    },
+    }
 
-    _expand: function() {
+    _expand() {
         this._footerStack.visible_child_name = 'separator';
         this._detailsRevealer.reveal_child = true;
         /* collaps the time label down to just show the start time when
@@ -201,20 +199,20 @@ var TransitLegRow = new Lang.Class({
          */
         this._timeLabel.label = this._leg.prettyPrintDepartureTime();
         this._isExpanded = true;
-    },
+    }
 
-    _collaps: function() {
+    _collaps() {
         this._footerStack.visible_child_name = 'expander';
         this._detailsRevealer.reveal_child = false;
         this._timeLabel.label = this._leg.prettyPrintTime({ isStart: this._start });
         this._isExpanded = false;
-    },
+    }
 
-    _hasIntructions: function() {
+    _hasIntructions() {
         return this._leg.transit || this._leg.walkingInstructions;
-    },
+    }
 
-    _populateInstructions: function() {
+    _populateInstructions() {
         if (this._leg.transit) {
             let stops = this._leg.intermediateStops;
             for (let index = 0; index < stops.length; index++) {
diff --git a/src/transitMoreRow.js b/src/transitMoreRow.js
index 25d75df..0b0ed55 100644
--- a/src/transitMoreRow.js
+++ b/src/transitMoreRow.js
@@ -19,31 +19,29 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const _ = imports.gettext.gettext;
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
 const Application = imports.application;
 
-var TransitMoreRow = new Lang.Class({
-    Name: 'TransitMoreRow',
-    Extends: Gtk.ListBoxRow,
+var TransitMoreRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-more-row.ui',
     InternalChildren: ['stack',
-                       'label'],
+                       'label']
+}, class TransitMoreRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
 
         if (Application.routeQuery.arriveBy)
             this._label.label = _("Load earlier alternatives");
         else
             this._label.label = _("Load later alternatives");
-    },
+    }
 
-    startLoading: function() {
+    startLoading() {
         this._stack.visible_child_name = 'spinner';
     }
 });
diff --git a/src/transitOptions.js b/src/transitOptions.js
index 80c0bc4..0a964ee 100644
--- a/src/transitOptions.js
+++ b/src/transitOptions.js
@@ -19,19 +19,16 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
+var TransitOptions = class TransitOptions {
 
-var TransitOptions = new Lang.Class({
-    Name: 'TransitOptions',
-
-    _init: function() {
+    constructor() {
         this._showAllTransitTypes = true;
         this._transitTypes = [];
-    },
+    }
 
     get showAllTransitTypes() {
         return this._showAllTransitTypes;
-    },
+    }
 
     /* When set to true, show any mode of transportation, else only show modes
      * added with addTransitType()
@@ -39,19 +36,19 @@ var TransitOptions = new Lang.Class({
     set showAllTransitTypes(showAllTransitTypes) {
         this._showAllTransitTypes = showAllTransitTypes;
         this._transitTypes = [];
-    },
+    }
 
     /* Add an explicit transport mode to show
      */
-    addTransitType: function(transitType) {
+    addTransitType(transitType) {
         this._showAllTransitTypes = false;
         this._transitTypes.push(transitType);
-    },
+    }
 
     get transitTypes() {
         return this._transitTypes;
     }
-});
+};
 
 /* return true if the passed in options objects are equal, either both
  * accept any transit type, or both contains the same set of types, otherwise
diff --git a/src/transitOptionsPanel.js b/src/transitOptionsPanel.js
index bd71e4b..daa8b31 100644
--- a/src/transitOptionsPanel.js
+++ b/src/transitOptionsPanel.js
@@ -21,8 +21,8 @@
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
 
 const Application = imports.application;
 const Time = imports.time;
@@ -35,9 +35,7 @@ const CLOCK_FORMAT_KEY = 'clock-format';
 let _desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 let clockFormat = _desktopSettings.get_string(CLOCK_FORMAT_KEY);
 
-var TransitOptionsPanel = new Lang.Class({
-    Name: 'TransitOptionsPanel',
-    Extends: Gtk.Grid,
+var TransitOptionsPanel = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-options-panel.ui',
     InternalChildren: ['transitTimeOptionsComboBox',
                        'transitTimeEntry',
@@ -48,15 +46,16 @@ var TransitOptionsPanel = new Lang.Class({
                        'tramCheckButton',
                        'trainCheckButton',
                        'subwayCheckButton',
-                       'ferryCheckButton'],
+                       'ferryCheckButton']
+}, class TransitOptionsPanel extends Gtk.Grid {
 
-    _init: function(params) {
+    _init(params) {
         this._query = Application.routeQuery;
-        this.parent(params);
+        super._init(params);
         this._initTransitOptions();
-    },
+    }
 
-    reset: function() {
+    reset() {
         /* reset to indicate departure now and forget any previous manually
          * set time and date
          */
@@ -64,9 +63,9 @@ var TransitOptionsPanel = new Lang.Class({
         this._timeSelected = false;
         this._dateSelected = false;
         this._lastOptions = new TransitOptions.TransitOptions();
-    },
+    }
 
-    _initTransitOptions: function() {
+    _initTransitOptions() {
         this._transitTimeOptionsComboBox.connect('changed',
             this._onTransitTimeOptionsComboboxChanged.bind(this));
         this._transitTimeEntry.connect('activate',
@@ -82,9 +81,9 @@ var TransitOptionsPanel = new Lang.Class({
             this._onTransitDateButtonToogled.bind(this));
         this._transitParametersMenuButton.connect('toggled',
             this._onTransitParametersToggled.bind(this))
-    },
+    }
 
-    _onTransitTimeOptionsComboboxChanged: function() {
+    _onTransitTimeOptionsComboboxChanged() {
         if (this._transitTimeOptionsComboBox.active_id === 'leaveNow') {
             this._transitTimeEntry.visible = false;
             this._transitDateButton.visible = false;
@@ -109,16 +108,16 @@ var TransitOptionsPanel = new Lang.Class({
                 this._query.arriveBy = false;
             }
         }
-    },
+    }
 
-    _updateTransitTimeEntry: function(time) {
+    _updateTransitTimeEntry(time) {
         if (clockFormat === '24h')
             this._transitTimeEntry.text = time.format('%R');
         else
             this._transitTimeEntry.text = time.format('%r');
-    },
+    }
 
-    _onTransitTimeEntryActivated: function() {
+    _onTransitTimeEntryActivated() {
         let timeString = this._transitTimeEntry.text;
 
         if (timeString && timeString.length > 0) {
@@ -131,18 +130,18 @@ var TransitOptionsPanel = new Lang.Class({
                 this._timeSelected = timeString;
             }
         }
-    },
+    }
 
-    _updateTransitDateButton: function(date) {
+    _updateTransitDateButton(date) {
         this._transitDateButton.label =
             /*
              * Translators: this is a format string giving the equivalent to
              * "may 29" according to the current locale's convensions.
              */
             date.format(C_("month-day-date", "%b %e"));
-    },
+    }
 
-    _onTransitDateCalenderDaySelected: function() {
+    _onTransitDateCalenderDaySelected() {
         let calendar = this._transitDateButton.popover.get_child();
         let year = calendar.year;
         let month = calendar.month + 1;
@@ -158,14 +157,14 @@ var TransitOptionsPanel = new Lang.Class({
             /* remember that the user has already selected a date */
             this._dateSelected = date;
         }
-    },
+    }
 
-    _onTransitDateButtonToogled: function() {
+    _onTransitDateButtonToogled() {
         if (!this._transitDateButton.active)
             this._onTransitDateCalenderDaySelected();
-    },
+    }
 
-    _createTransitOptions: function() {
+    _createTransitOptions() {
         let options = new TransitOptions.TransitOptions();
         let busSelected = this._busCheckButton.active;
         let tramSelected = this._tramCheckButton.active;
@@ -190,9 +189,9 @@ var TransitOptionsPanel = new Lang.Class({
         }
 
         return options;
-    },
+    }
 
-    _onTransitParametersToggled: function() {
+    _onTransitParametersToggled() {
         if (!this._transitParametersMenuButton.active) {
             let options = this._createTransitOptions();
 
diff --git a/src/transitPlan.js b/src/transitPlan.js
index d9cd573..4470660 100644
--- a/src/transitPlan.js
+++ b/src/transitPlan.js
@@ -19,8 +19,6 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const _ = imports.gettext.gettext;
 const ngettext = imports.gettext.ngettext;
 
@@ -84,58 +82,57 @@ function _printTimeWithTZOffset(time, offset) {
 var DEFAULT_ROUTE_COLOR = '4c4c4c';
 var DEFAULT_ROUTE_TEXT_COLOR = 'ffffff';
 
-var Plan = new Lang.Class({
-    Name: 'Plan',
-    Extends: GObject.Object,
+var Plan = GObject.registerClass({
     Signals: {
         'update': {},
         'reset': {},
         'no-more-results': {},
         'itinerary-selected': { param_types: [GObject.TYPE_OBJECT] },
         'itinerary-deselected': {}
-    },
+    }
+}, class Plan extends GObject.Object {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
         this.reset();
-    },
+    }
 
     get itineraries() {
         return this._itineraries;
-    },
+    }
 
     get selectedItinerary() {
         return this._selectedItinerary;
-    },
+    }
 
-    update: function(itineraries) {
+    update(itineraries) {
         this._itineraries = itineraries;
         this.bbox = this._createBBox();
         this.emit('update');
-    },
+    }
 
-    reset: function() {
+    reset() {
         this._itineraries = [];
         this.bbox = null;
         this._selectedItinerary = null;
         this.emit('reset');
-    },
+    }
 
-    noMoreResults: function() {
+    noMoreResults() {
         this.emit('no-more-results');
-    },
+    }
 
-    selectItinerary: function(itinerary) {
+    selectItinerary(itinerary) {
         this._selectedItinerary = itinerary;
         this.emit('itinerary-selected', itinerary);
-    },
+    }
 
-    deselectItinerary: function() {
+    deselectItinerary() {
         this._selectedItinerary = null;
         this.emit('itinerary-deselected');
-    },
+    }
 
-    _createBBox: function() {
+    _createBBox() {
         let bbox = new Champlain.BoundingBox();
         this._itineraries.forEach(function(itinerary) {
             bbox.compose(itinerary.bbox);
@@ -144,11 +141,10 @@ var Plan = new Lang.Class({
     }
 });
 
-var Itinerary = new Lang.Class({
-    Name: 'Itinerary',
-    Extends: GObject.Object,
+var Itinerary = GObject.registerClass(
+class Itinerary extends GObject.Object {
 
-    _init: function(params) {
+    _init(params) {
         this._duration = params.duration;
         delete params.duration;
 
@@ -164,36 +160,36 @@ var Itinerary = new Lang.Class({
         this._legs = params.legs;
         delete params.legs;
 
-        this.parent(params);
+        super._init(params);
 
         this.bbox = this._createBBox();
-    },
+    }
 
     get duration() {
         return this._duration;
-    },
+    }
 
     get departure() {
         return this._departure;
-    },
+    }
 
     get arrival() {
         return this._arrival;
-    },
+    }
 
     get transfers() {
         return this._transfers;
-    },
+    }
 
     get legs() {
         return this._legs;
-    },
+    }
 
     /* adjust timings of the legs of the itinerary, using the real duration of
      * walking legs, also sets the timezone offsets according to adjacent
      * transit legs
      */
-    _adjustLegTimings: function() {
+    _adjustLegTimings() {
         if (this.legs.length === 1 && !this.legs[0].transit) {
             /* if there is only one leg, and it's a walking one, just need to
              * adjust the arrival time
@@ -232,9 +228,9 @@ var Itinerary = new Lang.Class({
                 }
             }
         }
-    },
+    }
 
-    _createBBox: function() {
+    _createBBox() {
         let bbox = new Champlain.BoundingBox();
 
         this._legs.forEach(function(leg) {
@@ -242,9 +238,9 @@ var Itinerary = new Lang.Class({
         });
 
         return bbox;
-    },
+    }
 
-    prettyPrintTimeInterval: function() {
+    prettyPrintTimeInterval() {
         /* Translators: this is a format string for showing a departure and
          * arrival time, like:
          * "12:00 – 13:03" where the placeholder %s are the actual times,
@@ -252,24 +248,24 @@ var Itinerary = new Lang.Class({
          */
         return _("%s \u2013 %s").format(this._getDepartureTime(),
                                         this._getArrivalTime());
-    },
+    }
 
-    _getDepartureTime: function() {
+    _getDepartureTime() {
         /* take the itinerary departure time and offset using the timezone
          * offset of the first leg */
         return _printTimeWithTZOffset(this.departure,
                                       this.legs[0].agencyTimezoneOffset);
-    },
+    }
 
-    _getArrivalTime: function() {
+    _getArrivalTime() {
         /* take the itinerary departure time and offset using the timezone
          * offset of the last leg */
         let lastLeg = this.legs[this.legs.length - 1];
         return _printTimeWithTZOffset(this.arrival,
                                       lastLeg.agencyTimezoneOffset);
-    },
+    }
 
-    prettyPrintDuration: function() {
+    prettyPrintDuration() {
         let mins = this.duration / 60;
 
         if (mins < 60) {
@@ -297,16 +293,16 @@ var Itinerary = new Lang.Class({
                 return ngettext("%d:%02d hour", "%d:%02d hours", hours).format(hours, mins);
             }
         }
-    },
+    }
 
-    adjustTimings: function() {
+    adjustTimings() {
         this._adjustLegTimings();
         this._departure = this._legs[0].departure;
         this._arrival = this._legs[this._legs.length - 1].arrival;
         this._duration = (this._arrival - this._departure) / 1000;
-    },
+    }
 
-    _getTransitDepartureLeg: function() {
+    _getTransitDepartureLeg() {
         for (let i = 0; i < this._legs.length; i++) {
             let leg = this._legs[i];
 
@@ -315,9 +311,9 @@ var Itinerary = new Lang.Class({
         }
 
         throw new Error('no transit leg found');
-    },
+    }
 
-    _getTransitArrivalLeg: function() {
+    _getTransitArrivalLeg() {
         for (let i = this._legs.length - 1; i >= 0; i--) {
             let leg = this._legs[i];
 
@@ -326,22 +322,22 @@ var Itinerary = new Lang.Class({
         }
 
         throw new Error('no transit leg found');
-    },
+    }
 
     /* gets the departure time of the first transit leg */
     get transitDepartureTime() {
         return this._getTransitDepartureLeg().departure;
-    },
+    }
 
     /* gets the timezone offset of the first transit leg */
     get transitDepartureTimezoneOffset() {
         return this._getTransitDepartureLeg().timezoneOffset;
-    },
+    }
 
     /* gets the arrival time of the final transit leg */
     get transitArrivalTime() {
         return this._getTransitArrivalLeg().arrival;
-    },
+    }
 
     /* gets the timezone offset of the final transit leg */
     get transitArrivalTimezoneOffset() {
@@ -349,10 +345,9 @@ var Itinerary = new Lang.Class({
     }
 });
 
-var Leg = new Lang.Class({
-    Name: 'Leg',
+var Leg = class Leg {
 
-    _init: function(params) {
+    constructor(params) {
         this._route = params.route;
         delete params.route;
 
@@ -416,16 +411,14 @@ var Leg = new Lang.Class({
         this._tripShortName = params.tripShortName;
         delete params.tripShortName;
 
-        this.parent(params);
-
         this.bbox = this._createBBox();
 
         this._compactRoute = null;
-    },
+    }
 
     get route() {
         return this._route;
-    },
+    }
 
     // try to get a shortened route name, suitable for overview rendering
     get compactRoute() {
@@ -456,101 +449,101 @@ var Leg = new Lang.Class({
         }
 
         return this._compactRoute;
-    },
+    }
 
     get routeType() {
         return this._routeType;
-    },
+    }
 
     get departure() {
         return this._departure;
-    },
+    }
 
     set departure(departure) {
         this._departure = departure;
-    },
+    }
 
     get arrival() {
         return this._arrival;
-    },
+    }
 
     get timezoneOffset() {
         return this._agencyTimezoneOffset;
-    },
+    }
 
     set arrival(arrival) {
         this._arrival = arrival;
-    },
+    }
 
     get polyline() {
         return this._polyline;
-    },
+    }
 
     get fromCoordinate() {
         return this._fromCoordinate;
-    },
+    }
 
     get toCoordinate() {
         return this._toCoordinate;
-    },
+    }
 
     get from() {
         return this._from;
-    },
+    }
 
     get to() {
         return this._to;
-    },
+    }
 
     get intermediateStops() {
         return this._intermediateStops;
-    },
+    }
 
     get headsign() {
         return this._headsign;
-    },
+    }
 
     get transit() {
         return this._isTransit;
-    },
+    }
 
     get distance() {
         return this._distance;
-    },
+    }
 
     get duration() {
         return this._duration;
-    },
+    }
 
     get agencyName() {
         return this._agencyName;
-    },
+    }
 
     get agencyUrl() {
         return this._agencyUrl;
-    },
+    }
 
     get agencyTimezoneOffset() {
         return this._agencyTimezoneOffset;
-    },
+    }
 
     set agencyTimezoneOffset(tzOffset) {
         this._agencyTimezoneOffset = tzOffset;
-    },
+    }
 
     get color() {
         return this._color || DEFAULT_ROUTE_COLOR;
-    },
+    }
 
     get textColor() {
         return this._textColor || DEFAULT_ROUTE_TEXT_COLOR;
-    },
+    }
 
     get tripShortName() {
         return this._tripShortName;
-    },
+    }
 
-    _createBBox: function() {
+    _createBBox() {
         let bbox = new Champlain.BoundingBox();
 
         this.polyline.forEach(function({ latitude, longitude }) {
@@ -558,7 +551,7 @@ var Leg = new Lang.Class({
         });
 
         return bbox;
-    },
+    }
 
     get iconName() {
         if (this._isTransit) {
@@ -624,11 +617,11 @@ var Leg = new Lang.Class({
         } else {
             return 'route-pedestrian-symbolic';
         }
-    },
+    }
 
     get walkingInstructions() {
         return this._walkingInstructions;
-    },
+    }
 
     /* Pretty print timing for a transit leg, set params.isStart: true when
      * printing for the starting leg of an itinerary.
@@ -636,7 +629,7 @@ var Leg = new Lang.Class({
      * otherwise the departure and arrival time of the leg (i.e. transit ride
      * or an in-between walking section) will be printed.
      */
-    prettyPrintTime: function(params) {
+    prettyPrintTime(params) {
         if (!this.transit && params.isStart) {
             return this.prettyPrintDepartureTime();
         } else {
@@ -649,27 +642,26 @@ var Leg = new Lang.Class({
             return _("%s\u2013%s").format(this.prettyPrintDepartureTime(),
                                           this.prettyPrintArrivalTime());
         }
-    },
+    }
 
-    prettyPrintDepartureTime: function() {
+    prettyPrintDepartureTime() {
         /* take the itinerary departure time and offset using the timezone
          * offset of the first leg
          */
         return _printTimeWithTZOffset(this.departure, this.agencyTimezoneOffset);
-    },
+    }
 
-    prettyPrintArrivalTime: function() {
+    prettyPrintArrivalTime() {
         /* take the itinerary departure time and offset using the timezone
          * offset of the last leg
          */
         return _printTimeWithTZOffset(this.arrival, this.agencyTimezoneOffset);
     }
-});
+};
 
-var Stop = new Lang.Class({
-    Name: 'Stop',
+var Stop = class Stop {
 
-    _init: function(params) {
+    constructor(params) {
         this._name = params.name;
         delete params.name;
 
@@ -684,17 +676,17 @@ var Stop = new Lang.Class({
 
         this._coordinate = params.coordinate;
         delete params.coordinate;
-    },
+    }
 
     get name() {
         return this._name;
-    },
+    }
 
     get coordinate() {
         return this._coordinate;
-    },
+    }
 
-    prettyPrint: function(params) {
+    prettyPrint(params) {
         if (params.isFinal) {
             /* take the stop arrival time and offset using the timezone
              * offset of the last leg
@@ -709,7 +701,7 @@ var Stop = new Lang.Class({
                                           this._agencyTimezoneOffset);
         }
     }
-});
+};
 
 function sortItinerariesByDepartureAsc(first, second) {
     return first.departure > second.departure;
diff --git a/src/transitPrintLayout.js b/src/transitPrintLayout.js
index 6bf3609..9d4de27 100644
--- a/src/transitPrintLayout.js
+++ b/src/transitPrintLayout.js
@@ -19,12 +19,11 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Cairo = imports.cairo;
 const Champlain = imports.gi.Champlain;
 const Clutter = imports.gi.Clutter;
 const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
 const MapSource = imports.mapSource;
@@ -60,20 +59,19 @@ const _Instruction = {
     SCALE_MARGIN: 0.01
 };
 
-var TransitPrintLayout = new Lang.Class({
-    Name: 'TransitPrintLayout',
-    Extends: PrintLayout.PrintLayout,
+var TransitPrintLayout = GObject.registerClass(
+class TransitPrintLayout extends PrintLayout.PrintLayout {
 
-    _init: function(params) {
+    _init(params) {
         this._itinerary = params.itinerary;
         delete params.itinerary;
 
         params.totalSurfaces = this._getNumberOfSurfaces();
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
-    _getNumberOfSurfaces: function() {
+    _getNumberOfSurfaces() {
         // always one fixed surface for the title label
         let numSurfaces = 1;
 
@@ -88,9 +86,9 @@ var TransitPrintLayout = new Lang.Class({
         numSurfaces++;
 
         return numSurfaces;
-    },
+    }
 
-    _drawMapView: function(width, height, zoomLevel, index) {
+    _drawMapView(width, height, zoomLevel, index) {
         let pageNum = this.numPages - 1;
         let x = this._cursorX;
         let y = this._cursorY;
@@ -138,22 +136,22 @@ var TransitPrintLayout = new Lang.Class({
             if (surface)
                 this._addSurface(surface, x, y, pageNum);
         }
-    },
+    }
 
-    _createStartMarker: function(leg, previousLeg) {
+    _createStartMarker(leg, previousLeg) {
         return new TransitWalkMarker.TransitWalkMarker({ leg: leg,
                                                          previousLeg: previousLeg });
-    },
+    }
 
-    _createBoardMarker: function(leg) {
+    _createBoardMarker(leg) {
         return new TransitBoardMarker.TransitBoardMarker({ leg: leg });
-    },
+    }
 
-    _createArrivalMarker: function(leg) {
+    _createArrivalMarker(leg) {
         return new TransitArrivalMarker.TransitArrivalMarker({ leg: leg });
-    },
+    }
 
-    _addRouteLayer: function(view, index) {
+    _addRouteLayer(view, index) {
         let routeLayer = new Champlain.PathLayer({ stroke_width: _STROKE_WIDTH,
                                                    stroke_color: _STROKE_COLOR });
         let leg = this._itinerary.legs[index];
@@ -184,9 +182,9 @@ var TransitPrintLayout = new Lang.Class({
 
             routeLayer.add_node(firstPoint);
         }
-    },
+    }
 
-    _renderWidget: function(widget, width, height) {
+    _renderWidget(widget, width, height) {
         let pageNum = this.numPages - 1;
         let x = this._cursorX;
         let y = this._cursorY;
@@ -213,9 +211,9 @@ var TransitPrintLayout = new Lang.Class({
             let surface = widget.get_surface();
             this._addSurface(surface, x, y, pageNum);
         });
-    },
+    }
 
-    _drawInstruction: function(width, height, leg, start) {
+    _drawInstruction(width, height, leg, start) {
         let legRow = new TransitLegRow.TransitLegRow({
             visible: true,
             leg: leg,
@@ -224,9 +222,9 @@ var TransitPrintLayout = new Lang.Class({
         });
 
         this._renderWidget(legRow, width, height);
-    },
+    }
 
-    _drawArrival: function(width, height) {
+    _drawArrival(width, height) {
         let arrivalRow = new TransitArrivalRow.TransitArrivalRow({
             visible: true,
             itinerary: this._itinerary,
@@ -234,14 +232,14 @@ var TransitPrintLayout = new Lang.Class({
         });
 
         this._renderWidget(arrivalRow, width, height);
-    },
+    }
 
-    _legHasMiniMap: function(index) {
+    _legHasMiniMap(index) {
         let leg = this._itinerary.legs[index];
         return !leg.transit;
-    },
+    }
 
-    render: function() {
+    render() {
         let headerWidth = _Header.SCALE_X * this._pageWidth;
         let headerHeight = _Header.SCALE_Y * this._pageHeight;
         let headerMargin = _Header.SCALE_MARGIN * this._pageHeight;
diff --git a/src/transitRouteLabel.js b/src/transitRouteLabel.js
index 16efa36..c13bd99 100644
--- a/src/transitRouteLabel.js
+++ b/src/transitRouteLabel.js
@@ -19,10 +19,9 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Cairo = imports.cairo;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
 const Color = imports.color;
@@ -41,12 +40,11 @@ const DARK_OUTLINE_LUMINANCE_THREASHHOLD = 0.1;
 const HIGH_CONTRAST_COLOR = '000000';
 const HIGH_CONTRAST_TEXT_COLOR = 'ffffff';
 
-var TransitRouteLabel = new Lang.Class({
-    Name: 'TransitRouteLabel',
-    Extends: Gtk.Label,
+var TransitRouteLabel = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-route-label.ui',
+}, class TransitRouteLabel extends Gtk.Label {
 
-    _init: function(params) {
+    _init(params) {
         let leg = params.leg;
         let compact = params.compact;
         let print = params.print;
@@ -54,13 +52,13 @@ var TransitRouteLabel = new Lang.Class({
         delete params.leg;
         delete params.compact;
         delete params.print;
-        this.parent(params);
+        super._init(params);
 
         this._setLabel(leg, compact, print);
         this.connect('draw', this._onDraw.bind(this));
-    },
+    }
 
-    _setLabel: function(leg, compact, print) {
+    _setLabel(leg, compact, print) {
         let color = leg.color;
         let textColor = leg.textColor;
         let label = leg.route;
@@ -111,13 +109,13 @@ var TransitRouteLabel = new Lang.Class({
         this.label = '<span foreground="#%s">%s</span>'.format(
                                         textColor,
                                         GLib.markup_escape_text(label, -1));
-    },
+    }
 
     /* I didn't find any easy/obvious way to override widget background color
      * and getting rounded corner just using CSS styles, so doing a custom
      * Cairo drawing of a "roundrect"
      */
-    _onDraw: function(widget, cr) {
+    _onDraw(widget, cr) {
         let width = widget.get_allocated_width();
         let height = widget.get_allocated_height();
         let radius = this._hasOutline ? 5 : 3;
diff --git a/src/transitStopRow.js b/src/transitStopRow.js
index c8ebef6..f3cbe79 100644
--- a/src/transitStopRow.js
+++ b/src/transitStopRow.js
@@ -19,27 +19,25 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const _ = imports.gettext.gettext;
 
+const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
 
-var TransitStopRow = new Lang.Class({
-    Name: 'TransitStopRow',
-    Extends: Gtk.ListBoxRow,
+var TransitStopRow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/transit-stop-row.ui',
     InternalChildren: [ 'nameLabel',
-                        'timeLabel' ],
+                        'timeLabel' ]
+}, class TransitStopRow extends Gtk.ListBoxRow {
 
-    _init: function(params) {
+    _init(params) {
         this.stop = params.stop;
         delete params.stop;
 
         this._final = params.final;
         delete params.final;
 
-        this.parent(params);
+        super._init(params);
 
         this._nameLabel.label = this.stop.name;
         this._timeLabel.label = this.stop.prettyPrint({ isFinal: this._final });
diff --git a/src/transitWalkMarker.js b/src/transitWalkMarker.js
index fca04cc..93c642b 100644
--- a/src/transitWalkMarker.js
+++ b/src/transitWalkMarker.js
@@ -19,20 +19,18 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
-
 const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
 
 const Color = imports.color;
 const Location = imports.location;
 const MapMarker = imports.mapMarker;
 const Place = imports.place;
 
-var TransitWalkMarker = new Lang.Class({
-    Name: 'TransitWalkMarker',
-    Extends: MapMarker.MapMarker,
+var TransitWalkMarker = GObject.registerClass(
+class TransitWalkMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
+    _init(params) {
         /* if there is a preceeding leg, put the marker at the end of that leg
          * to avoid gaps, since we will "fill out" the walking leg path line
          * since sometimes the walking route might not reach exactly to the
@@ -56,7 +54,7 @@ var TransitWalkMarker = new Lang.Class({
 
         params.place = new Place.Place({ location: location });
 
-        this.parent(params);
+        super._init(params);
 
         let bgRed = Color.parseColor(bgColor, 0);
         let bgGreen = Color.parseColor(bgColor, 1);
@@ -70,7 +68,7 @@ var TransitWalkMarker = new Lang.Class({
             this._actorFromIconName('maps-point-start-symbolic', 0, color);
 
         this.add_actor(actor);
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2) - 1,
diff --git a/src/turnPointMarker.js b/src/turnPointMarker.js
index aa69fbf..e6c624e 100644
--- a/src/turnPointMarker.js
+++ b/src/turnPointMarker.js
@@ -21,7 +21,7 @@
 
 const Clutter = imports.gi.Clutter;
 const Gdk = imports.gi.Gdk;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -31,11 +31,10 @@ const MapMarker = imports.mapMarker;
 const Place = imports.place;
 const Utils = imports.utils;
 
-var TurnPointMarker = new Lang.Class({
-    Name: 'TurnPointMarker',
-    Extends: MapMarker.MapMarker,
+var TurnPointMarker = GObject.registerClass(
+class TurnPointMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
+    _init(params) {
         this._queryPoint = params.queryPoint;
         delete params.queryPoint;
 
@@ -62,7 +61,7 @@ var TurnPointMarker = new Lang.Class({
         params.place = new Place.Place({
             location: new Location.Location({ latitude: latitude,
                                               longitude: longitude }) });
-        this.parent(params);
+        super._init(params);
 
         let actor;
         if (this._queryPoint) {
@@ -76,9 +75,9 @@ var TurnPointMarker = new Lang.Class({
                                             color);
         }
         this.add_actor(actor);
-    },
+    }
 
-    _getColor: function() {
+    _getColor() {
         /* Use the route color from the transit leg when representing part of
          * a transit trip, otherwise let the fallback functionallity of the
          * utility function use a GNOMEish blue color for turn-by-turn routing.
@@ -89,14 +88,14 @@ var TurnPointMarker = new Lang.Class({
                               green: Color.parseColor(color, 1, 93 / 255),
                               blue: Color.parseColor(color, 2, 155 / 255),
                               alpha: 255 });
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2) - 1,
                  y: Math.floor(this.height / 2) - 1 };
-    },
+    }
 
-    goTo: function() {
+    goTo() {
         let view = this._mapView.view;
         let turnPointZoomLevel = 15;
 
@@ -110,9 +109,9 @@ var TurnPointMarker = new Lang.Class({
         });
 
         view.go_to(this.latitude, this.longitude);
-    },
+    }
 
-    _onMarkerDrag: function() {
+    _onMarkerDrag() {
         let query = Application.routeQuery;
         let place = new Place.Place({
             location: new Location.Location({ latitude: this.latitude.toFixed(5),
diff --git a/src/userLocationBubble.js b/src/userLocationBubble.js
index b2847c1..75e2c5d 100644
--- a/src/userLocationBubble.js
+++ b/src/userLocationBubble.js
@@ -19,16 +19,15 @@
  * Author: Damián Nohales <damiannohales gmail com>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const MapBubble = imports.mapBubble;
 const Utils = imports.utils;
 
-var UserLocationBubble = new Lang.Class({
-    Name: "UserLocationBubble",
-    Extends: MapBubble.MapBubble,
+var UserLocationBubble = GObject.registerClass(
+class UserLocationBubble extends MapBubble.MapBubble {
 
-    _init: function(params) {
+    _init(params) {
         let ui = Utils.getUIObject('user-location-bubble', [ 'grid-content',
                                                              'label-accuracy',
                                                              'label-coordinates' ]);
@@ -38,7 +37,7 @@ var UserLocationBubble = new Lang.Class({
         params.routeFrom = true;
         params.checkInMatchPlace = false;
 
-        this.parent(params);
+        super._init(params);
 
         this.image.icon_name = 'find-location-symbolic';
         this.image.pixel_size = 48;
diff --git a/src/userLocationMarker.js b/src/userLocationMarker.js
index f4b7529..a66c07d 100644
--- a/src/userLocationMarker.js
+++ b/src/userLocationMarker.js
@@ -21,16 +21,15 @@
 
 const Champlain = imports.gi.Champlain;
 const Clutter = imports.gi.Clutter;
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const MapMarker = imports.mapMarker;
 const UserLocationBubble = imports.userLocationBubble;
 
-var AccuracyCircleMarker = new Lang.Class({
-    Name: 'AccuracyCircleMarker',
-    Extends: Champlain.Point,
+var AccuracyCircleMarker = GObject.registerClass(
+class AccuracyCirleMarker extends Champlain.Point {
 
-    _init: function(params) {
+    _init(params) {
         this.place = params.place;
         delete params.place;
 
@@ -42,10 +41,10 @@ var AccuracyCircleMarker = new Lang.Class({
         params.longitude = this.place.location.longitude;
         params.reactive = false;
 
-        this.parent(params);
-    },
+        super._init(params);
+    }
 
-    refreshGeometry: function(view) {
+    refreshGeometry(view) {
         let zoom = view.zoom_level;
         let source = view.map_source;
         let metersPerPixel = source.get_meters_per_pixel(zoom,
@@ -62,12 +61,11 @@ var AccuracyCircleMarker = new Lang.Class({
     }
 });
 
-var UserLocationMarker = new Lang.Class({
-    Name: 'UserLocationMarker',
-    Extends: MapMarker.MapMarker,
+var UserLocationMarker = GObject.registerClass(
+class UserLocationMarker extends MapMarker.MapMarker {
 
-    _init: function(params) {
-        this.parent(params);
+    _init(params) {
+        super._init(params);
 
         if (this.place.location.heading > -1) {
             let actor = this._actorFromIconName('user-location-compass', 0);
@@ -84,26 +82,26 @@ var UserLocationMarker = new Lang.Class({
             this._zoomLevelId = this._view.connect('notify::zoom-level',
                                                    
this._accuracyMarker.refreshGeometry.bind(this._accuracyMarker));
         }
-    },
+    }
 
     get anchor() {
         return { x: Math.floor(this.width / 2),
                  y: Math.floor(this.height / 2) };
-    },
+    }
 
-    _createBubble: function() {
+    _createBubble() {
         return new UserLocationBubble.UserLocationBubble({ place: this.place,
                                                            mapView: this._mapView });
-    },
+    }
 
-    addToLayer: function(layer) {
+    addToLayer(layer) {
         if (this._accuracyMarker)
             layer.add_marker(this._accuracyMarker);
 
         layer.add_marker(this);
-    },
+    }
 
-    disconnectView: function() {
+    disconnectView() {
         if (this._zoomLevelId)
             this._view.disconnect(this._zoomLevelId);
     }
diff --git a/src/zoomInNotification.js b/src/zoomInNotification.js
index 382ecf3..3661c5b 100644
--- a/src/zoomInNotification.js
+++ b/src/zoomInNotification.js
@@ -19,31 +19,30 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
-const Lang = imports.lang;
+const GObject = imports.gi.GObject;
 
 const Application = imports.application;
 const Notification = imports.notification;
 const OSMEdit = imports.osmEdit;
 const Utils = imports.utils;
 
-var ZoomInNotification = Lang.Class({
-    Name: 'ZoomInNotification',
-    Extends: Notification.Notification,
+var ZoomInNotification = GObject.registerClass(
+class ZoomInNotification extends Notification.Notification {
 
-    _init: function(props) {
+    _init(props) {
         this._latitude = props.latitude;
         this._longitude = props.longitude;
         this._view = props.view;
-        this.parent();
+        super._init();
 
         let ui = Utils.getUIObject('zoom-in-notification', [ 'grid',
                                                              'okButton' ]);
 
         ui.okButton.connect('clicked', this._onZoomIn.bind(this));
         this._ui.body.add(ui.grid);
-    },
+    }
 
-    _onZoomIn: function() {
+    _onZoomIn() {
         this._view.zoom_level = OSMEdit.MIN_ADD_LOCATION_ZOOM_LEVEL;
 
         /* center on the position first selected */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]