diff --git a/examples/demo-object-as-source.html b/examples/demo-object-as-source.html
new file mode 100644
index 000000000..a4095903f
--- /dev/null
+++ b/examples/demo-object-as-source.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html lang="en" ng-app="demo">
+<head>
+  <meta charset="utf-8">
+  <title>AngularJS ui-select</title>
+
+  <!--
+    IE8 support, see AngularJS Internet Explorer Compatibility http://docs.angularjs.org/guide/ie
+    For Firefox 3.6, you will also need to include jQuery and ECMAScript 5 shim
+  -->
+  <!--[if lt IE 9]>
+    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
+    <script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/2.2.0/es5-shim.js"></script>
+    <script>
+      document.createElement('ui-select');
+      document.createElement('ui-select-match');
+      document.createElement('ui-select-choices');
+    </script>
+  <![endif]-->
+
+  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
+  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
+  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">
+
+  <!-- ui-select files -->
+  <script src="../dist/select.js"></script>
+  <link rel="stylesheet" href="../dist/select.css">
+
+  <script src="demo.js"></script>
+
+  <!-- Select2 theme -->
+  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">
+
+  <!--
+    Selectize theme
+    Less versions are available at https://github.com/brianreavis/selectize.js/tree/master/dist/less
+  -->
+  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">
+  <!-- <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.bootstrap2.css"> -->
+  <!-- <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.bootstrap3.css"> -->
+
+  <style>
+    body {
+      padding: 15px;
+    }
+
+    .select2 > .select2-choice.ui-select-match {
+      /* Because of the inclusion of Bootstrap */
+      height: 29px;
+    }
+
+    .selectize-control > .selectize-dropdown {
+      top: 36px;
+    }
+  </style>
+</head>
+
+<body ng-controller="DemoCtrl">
+
+  <button class="btn btn-default btn-xs" ng-click="enable()">Enable ui-select</button>
+  <button class="btn btn-default btn-xs" ng-click="disable()">Disable ui-select</button>
+  <button class="btn btn-default btn-xs" ng-click="clear()">Clear ng-model</button>
+
+  <h1>(key, value) format</h1>
+
+  <h2>Using value for binding</h2>
+
+  <p>Selected: {{person.selectedValue}}</p>
+  <ui-select ng-model="person.selectedValue" theme="select2" ng-disabled="disabled" style="min-width: 300px;" title="Choose a person">
+    <ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
+    <ui-select-choices repeat="person.value as (key, person) in peopleObj | filter: {'value':$select.search}">
+      <div ng-bind-html="person.value.name | highlight: $select.search"></div>
+      <small>
+        email: {{person.value.email}}
+        age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
+      </small>
+    </ui-select-choices>
+  </ui-select>
+
+  <h2>Using single property for binding</h2>
+  <p>Selected: {{person.selectedSingle}}</p>
+  <ui-select ng-model="person.selectedSingle" theme="select2" ng-disabled="disabled" style="min-width: 300px;" title="Choose a person">
+    <ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
+    <ui-select-choices repeat="person.value.name as (key, person) in peopleObj | filter: {'value':$select.search}">
+      <div ng-bind-html="person.value.name | highlight: $select.search"></div>
+      <small>
+        email: {{person.value.email}}
+        age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
+      </small>
+    </ui-select-choices>
+  </ui-select>
+
+  <h2>Using key for binding</h2>
+  <p>Selected: {{person.selectedSingleKey}}</p>
+  <ui-select ng-model="person.selectedSingleKey" theme="select2" ng-disabled="disabled" style="min-width: 300px;" title="Choose a person">
+    <ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
+    <ui-select-choices repeat="person.key as (key, person) in peopleObj | filter: {'value':$select.search}">
+      <div ng-bind-html="person.value.name | highlight: $select.search"></div>
+      <small>
+        email: {{person.value.email}}
+        age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
+      </small>
+    </ui-select-choices>
+  </ui-select>
+
+</body>
+</html>
diff --git a/examples/demo.js b/examples/demo.js
index 759917531..d53204914 100644
--- a/examples/demo.js
+++ b/examples/demo.js
@@ -46,7 +46,7 @@ app.controller('DemoCtrl', function($scope, $http, $timeout, $interval) {
 
   $scope.setInputFocus = function (){
     $scope.$broadcast('UiSelectDemo1');
-  }
+  };
 
   $scope.enable = function() {
     $scope.disabled = false;
@@ -58,11 +58,11 @@ app.controller('DemoCtrl', function($scope, $http, $timeout, $interval) {
 
   $scope.enableSearch = function() {
     $scope.searchEnabled = true;
-  }
+  };
 
   $scope.disableSearch = function() {
     $scope.searchEnabled = false;
-  }
+  };
 
   $scope.clear = function() {
     $scope.person.selected = undefined;
@@ -130,7 +130,25 @@ app.controller('DemoCtrl', function($scope, $http, $timeout, $interval) {
     return item;
   };
 
+  $scope.peopleObj = {
+    '1' : { name: 'Adam',      email: 'adam@email.com',      age: 12, country: 'United States' },
+    '2' : { name: 'Amalie',    email: 'amalie@email.com',    age: 12, country: 'Argentina' },
+    '3' : { name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
+    '4' : { name: 'Adrian',    email: 'adrian@email.com',    age: 21, country: 'Ecuador' },
+    '5' : { name: 'Wladimir',  email: 'wladimir@email.com',  age: 30, country: 'Ecuador' },
+    '6' : { name: 'Samantha',  email: 'samantha@email.com',  age: 30, country: 'United States' },
+    '7' : { name: 'Nicole',    email: 'nicole@email.com',    age: 43, country: 'Colombia' },
+    '8' : { name: 'Natasha',   email: 'natasha@email.com',   age: 54, country: 'Ecuador' },
+    '9' : { name: 'Michael',   email: 'michael@email.com',   age: 15, country: 'Colombia' },
+    '10' : { name: 'Nicolás',   email: 'nicolas@email.com',    age: 43, country: 'Colombia' }
+  };
+
   $scope.person = {};
+
+  $scope.person.selectedValue = $scope.peopleObj[3];
+  $scope.person.selectedSingle = 'Samantha';
+  $scope.person.selectedSingleKey = '5';
+
   $scope.people = [
     { name: 'Adam',      email: 'adam@email.com',      age: 12, country: 'United States' },
     { name: 'Amalie',    email: 'amalie@email.com',    age: 12, country: 'Argentina' },
diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js
index 69e29b6cc..0b4f8a562 100644
--- a/src/uiSelectChoicesDirective.js
+++ b/src/uiSelectChoicesDirective.js
@@ -39,7 +39,7 @@ uis.directive('uiSelectChoices',
           throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row but got '{0}'.", choices.length);
         }
 
-        choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp))
+        choices.attr('ng-repeat', $select.parserResult.repeatExpression(groupByExp))
             .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed
             .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')')
             .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)');
diff --git a/src/uiSelectController.js b/src/uiSelectController.js
index 486c245a2..a1b786168 100644
--- a/src/uiSelectController.js
+++ b/src/uiSelectController.js
@@ -5,8 +5,8 @@
  * put as much logic in the controller (instead of the link functions) as possible so it can be easily tested.
  */
 uis.controller('uiSelectCtrl',
-  ['$scope', '$element', '$timeout', '$filter', 'uisRepeatParser', 'uiSelectMinErr', 'uiSelectConfig',
-  function($scope, $element, $timeout, $filter, RepeatParser, uiSelectMinErr, uiSelectConfig) {
+  ['$scope', '$element', '$timeout', '$filter', 'uisRepeatParser', 'uiSelectMinErr', 'uiSelectConfig', '$parse',
+  function($scope, $element, $timeout, $filter, RepeatParser, uiSelectMinErr, uiSelectConfig, $parse) {
 
   var ctrl = this;
 
@@ -92,6 +92,9 @@ uis.controller('uiSelectCtrl',
       $timeout(function() {
         ctrl.search = initSearchValue || ctrl.search;
         ctrl.searchInput[0].focus();
+        if(!ctrl.tagging.isActivated && ctrl.items.length > 1) {
+          _ensureHighlightVisible();
+        }
       });
     }
   };
@@ -141,6 +144,28 @@ uis.controller('uiSelectCtrl',
     ctrl.isGrouped = !!groupByExp;
     ctrl.itemProperty = ctrl.parserResult.itemName;
 
+    //If collection is an Object, convert it to Array
+
+    var originalSource = ctrl.parserResult.source;
+    
+    //When an object is used as source, we better create an array and use it as 'source'
+    var createArrayFromObject = function(){
+      $scope.$uisSource = Object.keys(originalSource($scope)).map(function(v){
+        var result = {};
+        result[ctrl.parserResult.keyName] = v;
+        result.value = $scope.peopleObj[v];
+        return result;
+      });
+    };
+
+    if (ctrl.parserResult.keyName){ // Check for (key,value) syntax
+      createArrayFromObject();
+      ctrl.parserResult.source = $parse('$uisSource' + ctrl.parserResult.filters);
+      $scope.$watch(originalSource, function(newVal, oldVal){
+        if (newVal !== oldVal) createArrayFromObject();
+      }, true);
+    }
+
     ctrl.refreshItems = function (data){
       data = data || ctrl.parserResult.source($scope);
       var selectedItems = ctrl.selected;
@@ -164,7 +189,7 @@ uis.controller('uiSelectCtrl',
         ctrl.items = [];
       } else {
         if (!angular.isArray(items)) {
-          throw uiSelectMinErr('items', "Expected an array but got '{0}'.", items);
+          throw uiSelectMinErr('items', "Expected an array but got '{0}'.", items);          
         } else {
           //Remove already selected items (ex: while searching)
           //TODO Should add a test
diff --git a/src/uisRepeatParserService.js b/src/uisRepeatParserService.js
index 7ed9955f1..8d343a1e0 100644
--- a/src/uisRepeatParserService.js
+++ b/src/uisRepeatParserService.js
@@ -20,7 +20,9 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE
    */
   self.parse = function(expression) {
 
-    var match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?([\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
+
+    //0000000000000000000000000000000000011111111100000000000000022222222222222003333333333333333333333000044444444444444444400000000000000005555500000666666666666600000000000000000000007777777770000000
+    var match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\w]+)\s*(|\s*[\s\S]+?)?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
 
     if (!match) {
       throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.",
@@ -28,10 +30,20 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE
     }
 
     return {
-      itemName: match[2], // (lhs) Left-hand side,
-      source: $parse(match[3]),
-      trackByExp: match[4],
-      modelMapper: $parse(match[1] || match[2])
+      itemName: match[4] || match[2], // (lhs) Left-hand side,
+      keyName: match[3], //for (key, value) syntax
+      source: $parse(!match[3] ? match[5] + (match[6] || ''): match[5]), //concat source with filters if its an array
+      sourceName: match[5],
+      filters: match[6],
+      trackByExp: match[7],
+      modelMapper: $parse(match[1] || match[4] || match[2]),
+      repeatExpression: function (grouped) {
+        var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items');
+        if (this.trackByExp) {
+          expression += ' track by ' + this.trackByExp;
+        }
+        return expression;
+      } 
     };
 
   };
@@ -40,11 +52,4 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE
     return '$group in $select.groups';
   };
 
-  self.getNgRepeatExpression = function(itemName, source, trackByExp, grouped) {
-    var expression = itemName + ' in ' + (grouped ? '$group.items' : source);
-    if (trackByExp) {
-      expression += ' track by ' + trackByExp;
-    }
-    return expression;
-  };
 }]);
diff --git a/test/select.spec.js b/test/select.spec.js
index 80f953c46..aaeedfacc 100644
--- a/test/select.spec.js
+++ b/test/select.spec.js
@@ -1,7 +1,7 @@
 'use strict';
 
 describe('ui-select tests', function() {
-  var scope, $rootScope, $compile, $timeout, $injector;
+  var scope, $rootScope, $compile, $timeout, $injector, uisRepeatParser;
 
   var Key = {
     Enter: 13,
@@ -48,12 +48,13 @@ describe('ui-select tests', function() {
     });
   });
 
-  beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_, _$injector_) {
+  beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_, _$injector_, _uisRepeatParser_) {
     $rootScope = _$rootScope_;
     scope = $rootScope.$new();
     $compile = _$compile_;
     $timeout = _$timeout_;
     $injector = _$injector_;
+    uisRepeatParser = _uisRepeatParser_;
     scope.selection = {};
 
     scope.getGroupLabel = function(person) {
@@ -77,6 +78,19 @@ describe('ui-select tests', function() {
       { name: 'Nicole',    email: 'nicole@email.com',    group: 'bar', age: 43 },
       { name: 'Natasha',   email: 'natasha@email.com',   group: 'Baz', age: 54 }
     ];
+  
+    scope.peopleObj = {
+      '1' : { name: 'Adam',      email: 'adam@email.com',      age: 12, country: 'United States' },
+      '2' : { name: 'Amalie',    email: 'amalie@email.com',    age: 12, country: 'Argentina' },
+      '3' : { name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
+      '4' : { name: 'Adrian',    email: 'adrian@email.com',    age: 21, country: 'Ecuador' },
+      '5' : { name: 'Wladimir',  email: 'wladimir@email.com',  age: 30, country: 'Ecuador' },
+      '6' : { name: 'Samantha',  email: 'samantha@email.com',  age: 30, country: 'United States' },
+      '7' : { name: 'Nicole',    email: 'nicole@email.com',    age: 43, country: 'Colombia' },
+      '8' : { name: 'Natasha',   email: 'natasha@email.com',   age: 54, country: 'Ecuador' },
+      '9' : { name: 'Michael',   email: 'michael@email.com',   age: 15, country: 'Colombia' },
+      '10' : { name: 'Nicolás',   email: 'nicolas@email.com',    age: 43, country: 'Colombia' }
+    };
 
     scope.someObject = {};
     scope.someObject.people = [
@@ -190,6 +204,86 @@ describe('ui-select tests', function() {
 
 
   // Tests
+  //uisRepeatParser
+
+  it('should parse simple repeat syntax', function() {
+    
+    var locals = {};
+    locals.people = [{name: 'Wladimir'}, {name: 'Samantha'}];
+    locals.person = locals.people[0];
+
+    var parserResult = uisRepeatParser.parse('person in people');
+    expect(parserResult.itemName).toBe('person');
+    expect(parserResult.modelMapper(locals)).toBe(locals.person);
+    expect(parserResult.source(locals)).toBe(locals.people);
+
+    var ngExp = parserResult.repeatExpression(false);
+    expect(ngExp).toBe('person in $select.items');
+
+    var ngExpGrouped = parserResult.repeatExpression(true);
+    expect(ngExpGrouped).toBe('person in $group.items');
+
+  });
+
+  it('should parse simple repeat syntax', function() {
+    
+    var locals = {};
+    locals.people = [{name: 'Wladimir'}, {name: 'Samantha'}];
+    locals.person = locals.people[0];
+
+    var parserResult = uisRepeatParser.parse('person.name as person in people');
+    expect(parserResult.itemName).toBe('person');
+    expect(parserResult.modelMapper(locals)).toBe(locals.person.name);
+    expect(parserResult.source(locals)).toBe(locals.people);
+
+  });
+
+  it('should parse simple property binding repeat syntax', function() {
+    
+    var locals = {};
+    locals.people = [{name: 'Wladimir'}, {name: 'Samantha'}];
+    locals.person = locals.people[0];
+
+    var parserResult = uisRepeatParser.parse('person.name as person in people');
+    expect(parserResult.itemName).toBe('person');
+    expect(parserResult.modelMapper(locals)).toBe(locals.person.name);
+    expect(parserResult.source(locals)).toBe(locals.people);
+
+  });
+
+  it('should parse (key, value) repeat syntax', function() {
+    
+    var locals = {};
+    locals.people = { 'WC' : {name: 'Wladimir'}, 'SH' : {name: 'Samantha'}};
+    locals.person = locals.people[0];
+
+    var parserResult = uisRepeatParser.parse('(key,person) in people');
+    expect(parserResult.itemName).toBe('person');
+    expect(parserResult.keyName).toBe('key');
+    expect(parserResult.modelMapper(locals)).toBe(locals.person);
+    expect(parserResult.source(locals)).toBe(locals.people);
+
+    var ngExp = parserResult.repeatExpression(false);
+    expect(ngExp).toBe('person in $select.items');
+
+    var ngExpGrouped = parserResult.repeatExpression(true);
+    expect(ngExpGrouped).toBe('person in $group.items');
+
+  });
+
+  it('should parse simple property binding with (key, value) repeat syntax', function() {
+    
+    var locals = {};
+    locals.people = { 'WC' : {name: 'Wladimir'}, 'SH' : {name: 'Samantha'}};
+    locals.person = locals.people['WC'];
+
+    var parserResult = uisRepeatParser.parse('person.name as (key, person) in people');
+    expect(parserResult.itemName).toBe('person');
+    expect(parserResult.keyName).toBe('key');
+    expect(parserResult.modelMapper(locals)).toBe(locals.person.name);
+    expect(parserResult.source(locals)).toBe(locals.people);
+
+  });
 
   it('should compile child directives', function() {
     var el = createUiSelect();
@@ -469,6 +563,88 @@ describe('ui-select tests', function() {
     el2.remove();
   });
 
+  it('should bind model correctly (with object as source)', function() {
+    var el = compileTemplate(
+      '<ui-select ng-model="selection.selected"> \
+        <ui-select-match placeholder="Pick one...">{{$select.selected.value.name}}</ui-select-match> \
+        <ui-select-choices repeat="person.value as (key,person) in peopleObj | filter: $select.search"> \
+          <div ng-bind-html="person.value.name | highlight: $select.search"></div> \
+          <div ng-bind-html="person.value.email | highlight: $select.search"></div> \
+        </ui-select-choices> \
+      </ui-select>'
+    );
+    // scope.selection.selected = 'Samantha';
+
+    clickItem(el, 'Samantha');
+    scope.$digest();
+    expect(getMatchLabel(el)).toEqual('Samantha');
+    expect(scope.selection.selected).toBe(scope.peopleObj[6]);
+
+  });
+
+  it('should bind model correctly (with object as source) using a single property', function() {
+    var el = compileTemplate(
+      '<ui-select ng-model="selection.selected"> \
+        <ui-select-match placeholder="Pick one...">{{$select.selected.value.name}}</ui-select-match> \
+        <ui-select-choices repeat="person.value.name as (key,person) in peopleObj | filter: $select.search"> \
+          <div ng-bind-html="person.value.name | highlight: $select.search"></div> \
+          <div ng-bind-html="person.value.email | highlight: $select.search"></div> \
+        </ui-select-choices> \
+      </ui-select>'
+    );
+    // scope.selection.selected = 'Samantha';
+
+    clickItem(el, 'Samantha');
+    scope.$digest();
+    expect(getMatchLabel(el)).toEqual('Samantha');
+    expect(scope.selection.selected).toBe('Samantha');
+
+  });
+
+  it('should update choices when original source changes (with object as source)', function() {
+    var el = compileTemplate(
+      '<ui-select ng-model="selection.selected"> \
+        <ui-select-match placeholder="Pick one...">{{$select.selected.value.name}}</ui-select-match> \
+        <ui-select-choices repeat="person.value.name as (key,person) in peopleObj | filter: $select.search"> \
+          <div ng-bind-html="person.value.name | highlight: $select.search"></div> \
+          <div ng-bind-html="person.value.email | highlight: $select.search"></div> \
+        </ui-select-choices> \
+      </ui-select>'
+    );
+
+    scope.$digest();
+
+    openDropdown(el);
+    var choicesEls = $(el).find('.ui-select-choices-row');
+    expect(choicesEls.length).toEqual(10);
+
+    scope.peopleObj['11'] = { name: 'Camila',   email: 'camila@email.com',    age: 1, country: 'Ecuador' };
+    scope.$digest();
+
+    choicesEls = $(el).find('.ui-select-choices-row');
+    expect(choicesEls.length).toEqual(11);
+
+  });
+
+  it('should bind model correctly (with object as source) using the key of collection', function() {
+    var el = compileTemplate(
+      '<ui-select ng-model="selection.selected"> \
+        <ui-select-match placeholder="Pick one...">{{$select.selected.value.name}}</ui-select-match> \
+        <ui-select-choices repeat="person.key as (key,person) in peopleObj | filter: $select.search"> \
+          <div ng-bind-html="person.value.name | highlight: $select.search"></div> \
+          <div ng-bind-html="person.value.email | highlight: $select.search"></div> \
+        </ui-select-choices> \
+      </ui-select>'
+    );
+    // scope.selection.selected = 'Samantha';
+
+    clickItem(el, 'Samantha');
+    scope.$digest();
+    expect(getMatchLabel(el)).toEqual('Samantha');
+    expect(scope.selection.selected).toBe('6');
+
+  });
+
   describe('disabled options', function() {
     function createUiSelect(attrs) {
       var attrsDisabled = '';