diff --git a/src/select2.js b/src/select2.js
index c3b99ae..6233dbc 100644
--- a/src/select2.js
+++ b/src/select2.js
@@ -6,233 +6,273 @@
  * @params [options] {object} The configuration options passed to $.fn.select2(). Refer to the documentation
  */
 angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelect2', ['uiSelect2Config', '$timeout', function (uiSelect2Config, $timeout) {
-  var options = {};
-  if (uiSelect2Config) {
-    angular.extend(options, uiSelect2Config);
-  }
-  return {
-    require: 'ngModel',
-    priority: 1,
-    compile: function (tElm, tAttrs) {
-      var watch,
-        repeatOption,
-        repeatAttr,
-        isSelect = tElm.is('select'),
-        isMultiple = angular.isDefined(tAttrs.multiple);
-
-      // Enable watching of the options dataset if in use
-      if (tElm.is('select')) {
-        repeatOption = tElm.find( 'optgroup[ng-repeat], optgroup[data-ng-repeat], option[ng-repeat], option[data-ng-repeat]');
-
-        if (repeatOption.length) {
-          repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat');
-          watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop();
-        }
-      }
-
-      return function (scope, elm, attrs, controller) {
-        // instance-specific options
-        var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2));
-
-        /*
-        Convert from Select2 view-model to Angular view-model.
-        */
-        var convertToAngularModel = function(select2_data) {
-          var model;
-          if (opts.simple_tags) {
-            model = [];
-            angular.forEach(select2_data, function(value, index) {
-              model.push(value.id);
-            });
-          } else {
-            model = select2_data;
-          }
-          return model;
-        };
-
-        /*
-        Convert from Angular view-model to Select2 view-model.
-        */
-        var convertToSelect2Model = function(angular_data) {
-          var model = [];
-          if (!angular_data) {
-            return model;
-          }
-
-          if (opts.simple_tags) {
-            model = [];
-            angular.forEach(
-              angular_data,
-              function(value, index) {
-                model.push({'id': value, 'text': value});
-              });
-          } else {
-            model = angular_data;
-          }
-          return model;
-        };
-
-        if (isSelect) {
-          // Use <select multiple> instead
-          delete opts.multiple;
-          delete opts.initSelection;
-        } else if (isMultiple) {
-          opts.multiple = true;
-        }
+    var options = {};
+    if (uiSelect2Config) {
+        angular.extend(options, uiSelect2Config);
+    }
+    return {
+        require: 'ngModel',
+        priority: 1,
+        scope: {
+            uiData: '=',
+            uiSelect2: '='
+        },
+        compile: function (tElm, tAttrs) {
+            var watch,
+              repeatOption,
+              repeatAttr,
+              isSelect = tElm.is('select'),
+              isMultiple = angular.isDefined(tAttrs.multiple);
 
-        if (controller) {
-          // Watch the model for programmatic changes
-           scope.$watch(tAttrs.ngModel, function(current, old) {
-            if (!current) {
-              return;
-            }
-            if (current === old) {
-              return;
+            // Enable watching of the options dataset if in use
+            if (tElm.is('select')) {
+                repeatOption = tElm.find('optgroup[ng-repeat], optgroup[data-ng-repeat], option[ng-repeat], option[data-ng-repeat]');
+
+                if (repeatOption.length) {
+                    repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat');
+                    watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop();
+                }
             }
-            controller.$render();
-          }, true);
-          controller.$render = function () {
-            if (isSelect) {
-              elm.select2('val', controller.$viewValue);
-            } else {
-              if (opts.multiple) {
-                controller.$isEmpty = function (value) {
-                  return !value || value.length === 0;
-                };
-                var viewValue = controller.$viewValue;
-                if (angular.isString(viewValue)) {
-                  viewValue = viewValue.split(',');
+
+            return function (scope, elm, attrs, controller) {
+                // instance-specific options
+                //var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2));
+                var opts = scope.uiSelect2;
+
+
+
+                if (opts === undefined) {
+                    opts = {};
                 }
-                elm.select2(
-                  'data', convertToSelect2Model(viewValue));
-                if (opts.sortable) {
-                  elm.select2("container").find("ul.select2-choices").sortable({
-                    containment: 'parent',
-                    start: function () {
-                      elm.select2("onSortStart");
-                    },
-                    update: function () {
-                      elm.select2("onSortEnd");
-                      elm.trigger('change');
+
+
+                /*
+                Convert from Select2 view-model to Angular view-model.
+                */
+                var convertToAngularModel = function (select2_data) {
+                    var model;
+                    if (opts.simple_tags) {
+                        model = [];
+                        angular.forEach(select2_data, function (value, index) {
+                            model.push(value.id);
+                        });
+                    } else {
+                        model = select2_data;
+                    }
+                    return model;
+                };
+
+                /*
+                Convert from Angular view-model to Select2 view-model.
+                */
+                var convertToSelect2Model = function (angular_data) {
+                    var model = [];
+                    if (!angular_data) {
+                        return model;
+                    }
+
+                    if (opts.simple_tags) {
+                        model = [];
+                        angular.forEach(
+                          angular_data,
+                          function (value, index) {
+                              model.push({ 'id': value, 'text': value });
+                          });
+                    } else {
+                        model = angular_data;
                     }
-                  });
-                }                  
-              } else {
-                if (angular.isObject(controller.$viewValue)) {
-                  elm.select2('data', controller.$viewValue);
-                } else if (!controller.$viewValue) {
-                  elm.select2('data', null);
-                } else {
-                  elm.select2('val', controller.$viewValue);
+                    return model;
+                };
+
+                if (isSelect) {
+                    // Use <select multiple> instead
+
+                    delete opts.multiple;
+                    delete opts.initSelection;
+                } else if (isMultiple) {
+                    opts.multiple = true;
                 }
-              }
-            }
-          };
-
-          // Watch the options dataset for changes
-          if (watch) {
-            scope.$watch(watch, function (newVal, oldVal, scope) {
-              if (angular.equals(newVal, oldVal)) {
-                return;
-              }
-              // Delayed so that the options have time to be rendered
-              $timeout(function () {
-                elm.select2('val', controller.$viewValue);
-                // Refresh angular to remove the superfluous option
-                controller.$render();
-                if(newVal && !oldVal && controller.$setPristine) {
-                  controller.$setPristine(true);
+
+                if (controller) {
+                    // Watch the model for programmatic changes
+                    scope.$watch(tAttrs.ngModel, function (current, old) {
+                        if (!current) {
+                            return;
+                        }
+                        if (current === old) {
+                            return;
+                        }
+                        controller.$render();
+                    }, true);
+                    controller.$render = function () {
+                        if (isSelect) {
+                            elm.select2('val', controller.$viewValue);
+                        } else {
+                            if (opts.multiple) {
+                                controller.$isEmpty = function (value) {
+                                    return !value || value.length === 0;
+                                };
+                                var viewValue = controller.$viewValue;
+                                if (angular.isString(viewValue)) {
+                                    viewValue = viewValue.split(',');
+                                }
+                                elm.select2(
+                                  'data', convertToSelect2Model(viewValue));
+                                if (opts.sortable) {
+                                    elm.select2("container").find("ul.select2-choices").sortable({
+                                        containment: 'parent',
+                                        start: function () {
+                                            elm.select2("onSortStart");
+                                        },
+                                        update: function () {
+                                            elm.select2("onSortEnd");
+                                            elm.trigger('change');
+                                        }
+                                    });
+                                }
+                            } else {
+
+                                if (angular.isObject(controller.$viewValue)) {
+                                    elm.select2('data', controller.$viewValue);
+                                } else if (!controller.$viewValue) {
+                                    elm.select2('data', null);
+                                } else {
+                                    elm.select2('val', controller.$viewValue);
+                                }
+
+                            }
+                        }
+                    };
+
+                    // Watch the options dataset for changes
+                    if (watch) {
+                        scope.$watch(watch, function (newVal, oldVal, scope) {
+                            if (angular.equals(newVal, oldVal)) {
+                                return;
+                            }
+                            // Delayed so that the options have time to be rendered
+                            $timeout(function () {
+
+                                elm.select2('val', controller.$viewValue);
+                                // Refresh angular to remove the superfluous option
+                                controller.$render();
+                                if (newVal && !oldVal && controller.$setPristine) {
+                                    controller.$setPristine(true);
+                                }
+
+                            });
+                        });
+                    }
+
+                    // Update valid and dirty statuses
+                    controller.$parsers.push(function (value) {
+                        var div = elm.prev();
+                        div
+                          .toggleClass('ng-invalid', !controller.$valid)
+                          .toggleClass('ng-valid', controller.$valid)
+                          .toggleClass('ng-invalid-required', !controller.$valid)
+                          .toggleClass('ng-valid-required', controller.$valid)
+                          .toggleClass('ng-dirty', controller.$dirty)
+                          .toggleClass('ng-pristine', controller.$pristine);
+                        return value;
+                    });
+
+                    if (!isSelect) {
+                        // Set the view and model value and update the angular template manually for the ajax/multiple select2.
+                        elm.bind("change", function (e) {
+                            e.stopImmediatePropagation();
+
+                            if (scope.$$phase || scope.$root.$$phase) {
+                                return;
+                            }
+                            scope.$apply(function () {
+                                console.log(elm.select2('val'));
+                                controller.$setViewValue(elm.select2('val'));
+
+                                if (scope.uiData !== undefined) {
+                                    scope.uiData = convertToAngularModel(elm.select2('data'));
+                                }
+                            });
+                        });
+
+                        if (opts.initSelection) {
+                            var initSelection = opts.initSelection;
+                            opts.initSelection = function (element, callback) {
+                                initSelection(element, function (value) {
+                                    var isPristine = controller.$pristine;
+
+                                    controller.$setViewValue(value.id);
+
+                                    if (scope.uiData !== undefined) {
+                                        scope.uiData = convertToAngularModel(value);
+                                    }
+
+
+                                    callback(value);
+                                    if (isPristine) {
+                                        controller.$setPristine();
+                                    }
+                                    elm.prev().toggleClass('ng-pristine', controller.$pristine);
+                                });
+                            };
+                        }
+                    }
                 }
-              });
-            });
-          }
-
-          // Update valid and dirty statuses
-          controller.$parsers.push(function (value) {
-            var div = elm.prev();
-            div
-              .toggleClass('ng-invalid', !controller.$valid)
-              .toggleClass('ng-valid', controller.$valid)
-              .toggleClass('ng-invalid-required', !controller.$valid)
-              .toggleClass('ng-valid-required', controller.$valid)
-              .toggleClass('ng-dirty', controller.$dirty)
-              .toggleClass('ng-pristine', controller.$pristine);
-            return value;
-          });
-
-          if (!isSelect) {
-            // Set the view and model value and update the angular template manually for the ajax/multiple select2.
-            elm.bind("change", function (e) {
-              e.stopImmediatePropagation();
-              
-              if (scope.$$phase || scope.$root.$$phase) {
-                return;
-              }
-              scope.$apply(function () {
-                controller.$setViewValue(
-                  convertToAngularModel(elm.select2('data')));
-              });
-            });
-
-            if (opts.initSelection) {
-              var initSelection = opts.initSelection;
-              opts.initSelection = function (element, callback) {
-                initSelection(element, function (value) {
-                  var isPristine = controller.$pristine;
-                  controller.$setViewValue(convertToAngularModel(value));
-                  callback(value);
-                  if (isPristine) {
-                    controller.$setPristine();
-                  }
-                  elm.prev().toggleClass('ng-pristine', controller.$pristine);
+
+                elm.bind("$destroy", function () {
+                    elm.select2("destroy");
+                });
+
+                attrs.$observe('disabled', function (value) {
+                    elm.select2('enable', !value);
+                });
+
+                attrs.$observe('readonly', function (value) {
+                    elm.select2('readonly', !!value);
                 });
-              };
-            }
-          }
-        }
 
-        elm.bind("$destroy", function() {
-          elm.select2("destroy");
-        });
+                if (attrs.ngMultiple) {
+                    scope.$watch(attrs.ngMultiple, function (newVal) {
+                        attrs.$set('multiple', !!newVal);
+                        elm.select2(opts);
+                    });
+                }
 
-        attrs.$observe('disabled', function (value) {
-          elm.select2('enable', !value);
-        });
+                // Initialize the plugin late so that the injected DOM does not disrupt the template compiler
+                $timeout(function () {
 
-        attrs.$observe('readonly', function (value) {
-          elm.select2('readonly', !!value);
-        });
+                    elm.select2(opts);
 
-        if (attrs.ngMultiple) {
-          scope.$watch(attrs.ngMultiple, function(newVal) {
-            attrs.$set('multiple', !!newVal);
-            elm.select2(opts);
-          });
-        }
 
-        // Initialize the plugin late so that the injected DOM does not disrupt the template compiler
-        $timeout(function () {
-          elm.select2(opts);
-
-          // Set initial value - I'm not sure about this but it seems to need to be there
-          elm.select2('data', controller.$modelValue);
-          // important!
-          controller.$render();
-
-          // Not sure if I should just check for !isSelect OR if I should check for 'tags' key
-          if (!opts.initSelection && !isSelect) {
-              var isPristine = controller.$pristine;
-              controller.$pristine = false;
-              controller.$setViewValue(
-                  convertToAngularModel(elm.select2('data'))
-              );
-              if (isPristine) {
-                  controller.$setPristine();
-              }
-            elm.prev().toggleClass('ng-pristine', controller.$pristine);
-          }
-        });
-      };
-    }
-  };
+                    // Set initial value - I'm not sure about this but it seems to need to be there
+
+                    elm.select2('val', controller.$modelValue);
+
+                    // important!
+                    controller.$render();
+
+                    // Not sure if I should just check for !isSelect OR if I should check for 'tags' key
+                    if (!opts.initSelection && !isSelect) {
+                        var isPristine = controller.$pristine;
+                        controller.$pristine = false;
+
+                        controller.$setViewValue(
+                            elm.select2('val')
+                        );
+
+                        if (scope.uiData !== undefined) {
+                            scope.uiData = convertToAngularModel(elm.select2('data'));
+                        }
+
+
+
+                        if (isPristine) {
+                            controller.$setPristine();
+                        }
+                        elm.prev().toggleClass('ng-pristine', controller.$pristine);
+                    }
+                });
+            };
+        }
+    };
 }]);