function LabelHelper(sessionId) {
    var self = this;
    self.labels = [];
    var conn = new jsforce.Connection({ accessToken: sessionId });
    var promise = conn.metadata.list({type: "CustomLabel"}, "37.0")
        .then(function(res) {
            for (var i = 0; i < res.length; i++) {
                // only include NC or unpackaged labels
                var pieces = res[i].fullName.split("__");
                if (pieces.length === 1 || pieces[0] === "NC") {
                    self.labels.push(pieces[pieces.length - 1]); // exclude namespace
                }
            }
            self.labels.sort();
        }, function(err) {
            console.error(err);
        });

    function popupCenter(url, title, w, h) {
        // http://stackoverflow.com/a/16861050
        // Fixes dual-screen position                         Most browsers      Firefox
        var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
        var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
        var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
        var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
        var left = ((width / 2) - (w / 2)) + dualScreenLeft;
        var top = ((height / 2) - (h / 2)) + dualScreenTop;
        var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
        // Puts focus on the newWindow
        if (window.focus) {
            newWindow.focus();
        }
        return newWindow;
    }

    function openLabelEdit(name) {
        popupCenter("/apex/EditLabel?name=" + name, "_blank", 650, 400);
    }

    function enhanceInputs() {
        var elements = $(".label-autocomplete")
            .removeClass("label-autocomplete")
            .each(function() {
            var self = $(this);
            var addLink = $("<span title=\"Add\" class=\"inline-icon fa fa-plus\">");
            var editLink = $("<span title=\"Edit\" class=\"inline-icon fa fa-pencil\">");

            addLink.click(function() {
                var pageName = getPageName();
                var win = popupCenter("/apex/EditLabel?p=" + pageName, "_blank", 650, 400);
                win.onload = function() {
                    win.callback = function(x) {
                        self.val(x);
                        editLink.removeClass('inline-icon-disabled');
                    };
                };
            });

            editLink.click(function() {
                if (!$(this).hasClass('inline-icon-disabled')) {
                    openLabelEdit(self.val());
                }
            });

            self.on('input', function() {
                editLink.toggleClass('inline-icon-disabled', !$.trim($(this).val()));
            });

            if (!$.trim(self.val())) {
                editLink.addClass('inline-icon-disabled');
            }

            self.parent().append(addLink, editLink);
        });
        promise.then(function() {
            elements.autocomplete({
                source: function(req, res) {
                    res($.ui.autocomplete.filter(self.labels, req.term).slice(0, 20));
                }
            });
        });
    }

    function enhanceLinks() {
        $(".label-link")
            .removeClass('label-link')
            .children("span")
            .wrap(function() {
            var self = $(this);
            return $("<a href=\"\">").click(function() {
                openLabelEdit(self.text());
                return false;
            });
        });
    }

    self.enhance = function() {
        enhanceInputs();
        enhanceLinks();
    };

    // Gets query param value for 'p'
    function getPageName() {
        var results = new RegExp('[\?&]p=([^&#]*)').exec(window.location.href);
        if (results === null){
           return $('input[id$="PageNameInput"]').val();
        } else {
           return results[1] || "";
        }
    }
}