/// <summary>
 /// Construtor padrão.
 /// </summary>
 /// <param name="source">Relação da coleção de origem dos dados.</param>
 /// <param name="comparer">Comparador que será utilizado para ordenar os itens.</param>
 public SortableObservableCollection(IObservableCollection <T> source, IComparer <T> comparer)
 {
     source.Require("source").NotNull();
     comparer.Require("comparer").NotNull();
     _source   = source;
     _comparer = comparer;
     _comparerPropertiesContainer = comparer as IPropertiesContainer;
     _source.CollectionChanged   += SourceCollectionChanged;
     _indexes = new BaseObservableCollection <int>();
     for (var i = 0; i < _source.Count; i++)
     {
         _indexes.Add(i);
     }
     foreach (var i in _source)
     {
         RegisterItem(i);
     }
     CalculateIndexes();
 }
 /// <summary>
 /// Método acionado quando a coleção de origem for alterada.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 {
     if (e.Action == NotifyCollectionChangedAction.Add)
     {
         for (var i = 0; i < e.NewItems.Count; i++)
         {
             var item     = (T)e.NewItems[i];
             var inserted = false;
             for (var j = 0; j < _indexes.Count; j++)
             {
                 if (_comparer.Compare(_source[_indexes[j]], item) > 0)
                 {
                     _indexes.Insert(j, e.NewStartingIndex + i);
                     RegisterItem(item);
                     inserted = true;
                     break;
                 }
             }
             if (!inserted)
             {
                 _indexes.Add(e.NewStartingIndex + i);
             }
         }
     }
     else if (e.Action == NotifyCollectionChangedAction.Move)
     {
         for (var i = 0; i < e.NewItems.Count; i++)
         {
             var newIndex = -1;
             var oldIndex = -1;
             for (var j = 0; (newIndex < 0 || oldIndex < 0) && j < _indexes.Count; j++)
             {
                 if (newIndex < 0 && _indexes[j] == e.NewStartingIndex + i)
                 {
                     newIndex = j;
                 }
                 else if (oldIndex < 0 && _indexes[j] == e.OldStartingIndex + i)
                 {
                     oldIndex = j;
                 }
             }
             if (newIndex >= 0 && oldIndex >= 0)
             {
                 var aux = _indexes[newIndex];
                 _indexes[newIndex] = _indexes[oldIndex];
                 _indexes[oldIndex] = aux;
             }
         }
     }
     else if (e.Action == NotifyCollectionChangedAction.Remove)
     {
         for (var i = 0; i < e.OldItems.Count; i++)
         {
             for (var j = 0; j < _indexes.Count; j++)
             {
                 if (_indexes[j] == e.OldStartingIndex + i)
                 {
                     UnregisterItem((T)e.OldItems[i]);
                     _indexes.CollectionChanged -= IndexesCollectionChanged;
                     _indexes.Clear();
                     for (var x = 0; x < _source.Count; x++)
                     {
                         _indexes.Add(x);
                     }
                     try
                     {
                         CalculateIndexesWithoutNotifyChanges();
                     }
                     finally
                     {
                         _indexes.CollectionChanged += IndexesCollectionChanged;
                     }
                     if (CollectionChanged != null)
                     {
                         CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, e.OldItems[i], j));
                     }
                     break;
                 }
             }
         }
     }
     else if (e.Action == NotifyCollectionChangedAction.Replace)
     {
         CalculateIndexes();
     }
     else if (e.Action == NotifyCollectionChangedAction.Reset)
     {
         try
         {
             _indexes.CollectionChanged -= IndexesCollectionChanged;
             foreach (var item in _source)
             {
                 UnregisterItem(item);
             }
             for (var i = 0; i < _source.Count; i++)
             {
                 _indexes.Add(i);
             }
         }
         finally
         {
             _indexes.CollectionChanged += IndexesCollectionChanged;
         }
         CalculateIndexes();
     }
 }