diff --git a/images/bullet_move.png b/images/bullet_move.png
new file mode 100644
index 0000000000000000000000000000000000000000..45f869428fd24f50acd6a16be70bf04a9f014e08
Binary files /dev/null and b/images/bullet_move.png differ
diff --git a/term_reference_tree.css b/term_reference_tree.css
index 40ba2cfbe530fa873c2fd7809636b9201eeb2623..5b72ebbfe96c05ff9ea680bf4105ec880c3d7370 100644
--- a/term_reference_tree.css
+++ b/term_reference_tree.css
@@ -94,6 +94,37 @@
   background-position: middle left;
 }
 
+.term-reference-tree-track-list.order-list li.track-item {
+	padding-left:0;
+}
+
+.term-reference-tree-track-list.order-list li.track-item:hover {
+	color:#000;
+	background-image: none;
+}
+
+.term-reference-tree-track-list.order-list .term-reference-tree-button-move, .term-reference-tree-track-list.order-list .term-reference-tree-button-delete{
+	display:inline-block; vertical-align:middle; zoom:1;
+	width:16px; height:16px;
+	background-repeat: no-repeat;
+	background-position: bottom center;
+	margin:0 5px;
+}
+
+
+.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-move{
+	background-image: url("images/bullet_move.png");
+}
+.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-move:hover{
+	cursor:move;
+}
+.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-delete{
+	background-image: url("images/bullet_delete.png"); float:right;
+}
+.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-:hover{
+	cursor:pointer;
+}
+
 .term-reference-tree-track-list li.term_ref_tree_nothing_message {
   list-style-type: none;
   list-style-image: none;
diff --git a/term_reference_tree.js b/term_reference_tree.js
index 319312f2dd0626ef4545bc66e3310f0467a8fb9e..23e742b3ed68653a749ebbabd0b7e7bbb71af887 100644
--- a/term_reference_tree.js
+++ b/term_reference_tree.js
@@ -28,7 +28,26 @@
         //currently selected items to it.
         if($(this).hasClass('term-reference-tree-track-list-shown')) {
           var track_list_container = $(this).find('.term-reference-tree-track-list');
-          
+          var tracklist_is_orderable = track_list_container.is('.order-list');
+					if(tracklist_is_orderable){
+						track_list_container.sortable({
+							update: function(event, ui) {
+								console.log('sort update : event', event);
+								console.log('sort update : ui', ui);
+
+								$.each(event.target.children, function(index, val) {
+									var $item = $(val),
+								// event.target = ul.list
+								// ui.item = li.track-item
+											control_id = $item.data('control_id'),
+											$hiddenInput = $('#'+control_id).parent('.form-item').next('input[type=hidden]');
+											// $hiddenInput.attr('value', $item.index());
+											$hiddenInput.val($item.index());
+								});
+							},
+						});
+					}
+					
           //Var to track whether using checkboxes or radio buttons.
           var input_type =
             ( $(this).has('input[type=checkbox]').size() > 0 ) ? 'checkbox' : 'radio';
@@ -40,14 +59,22 @@
           var labels = checked_controls.next();
           var label_element;
           
+					//get delta
+					if(tracklist_is_orderable){
+						var weights = checked_controls.parent('.form-item').next('input[type=hidden]');
+					}
+
           //For each label of the checked boxes, add item to the track list.
           labels.each(function(index) {
             label_element = $(labels[index]);
+						delta = tracklist_is_orderable ? $(weights[index]).val() : -1;
+						
             addItemToTrackList(
               track_list_container,         //Where to add new item.
               label_element.html(),         //Text of new item.
               $(label_element).attr('for'), //Id of control new item is for.
-              input_type                    //checkbox or radio
+              input_type,                   //checkbox or radio
+							delta													//delta
             );
           }); //End labels.each
           
@@ -62,10 +89,14 @@
             //Remove the "nothing selected" message if showing - add it later if needed.
             //removeNothingSelectedMessage(track_list_container);
             var event_target = $(event.target);
-            var control_id = event_target.data('control_id');
-
-            if(control_id) {
-              event_target.remove();
+						var event_parent_list = event_target.parent('li');
+            var control_id = event_parent_list.data('control_id');
+						// console.log('event', event);
+						// console.log('event_target.parent("li")', event_target.parent('li'));
+						// console.log('control_id', control_id);
+						// console.log('event_target.is(term-reference-tree-delete)', event_target.is('term-reference-tree-delete'));
+            if(event_target.is('.term-reference-tree-button-delete') && control_id) {
+              event_parent_list.remove();
 
               var checkbox = $('#' + control_id);
               checkbox.removeAttr('checked');
@@ -89,7 +120,8 @@
                 track_list_container,         //Where to add new item.
                 label_element.html(),         //Text of new item.
                 $(label_element).attr('for'), //Id of control new item is for.
-                input_type                    //checkbox or radio
+                input_type,                   //checkbox or radio
+								-1													// delta
               );
             }
             else {
@@ -144,8 +176,9 @@
    * 
    * @param control_type Control type - 'checkbox' or 'radio'.
    */
-  function addItemToTrackList(track_list_container, item_text, control_id, control_type) {
-    var new_item = $('<li class="track-item">' + item_text + '</li>');
+  function addItemToTrackList(track_list_container, item_text, control_id, control_type, delta) {
+		console.log('addItemToTrackList');
+    var new_item = $('<li class="track-item" delta="'+ delta +'"><div class="term-reference-tree-button-move"></div>' + item_text + '<div class="term-reference-tree-button-delete"></div></li>');
     new_item.data('control_id', control_id);
     
     //Add an id for easy finding of the item.
@@ -173,35 +206,66 @@
       }
       return;
     }
-    
-    //Using checkboxes, so there can be more than one selected item.
-    //Find the right place to put the new item, to match the order of the
-    //checkboxes.
+
+		//Using checkboxes, so there can be more than one selected item.
+    //Find the right place to put the new item, 
+		// to match the order of the checkboxes.
+		// OR order of delta
     var list_items = track_list_container.find('li');
     var item_comparing_to;
-    
+  
     //Flag to tell whether the item was inserted.
     var inserted_flag = false;
-    list_items.each(function(index){
-      item_comparing_to = $(list_items[index]);
+
+		if(!track_list_container.is('.order-list')){
+	    
+	    list_items.each(function(index){
+	      item_comparing_to = $(list_items[index]);
       
-      //If item is already on the track list, do nothing.
-      if ( control_id == item_comparing_to.data('control_id') ) {
-        inserted_flag = true;
-        return false; //Returning false stops the loop.
-      }
-      else if ( control_id < item_comparing_to.data('control_id') ) {
-        //Add it here.
-        item_comparing_to.before(new_item);
-        inserted_flag = true;
-        return false; //Returning false stops the loop.
-      }
-    });
+	      //If item is already on the track list, do nothing.
+	      if ( control_id == item_comparing_to.data('control_id') ) {
+	        inserted_flag = true;
+	        return false; //Returning false stops the loop.
+	      }
+	      else if ( control_id < item_comparing_to.data('control_id') ) {
+	        //Add it here.
+	        item_comparing_to.before(new_item);
+	        inserted_flag = true;
+	        return false; //Returning false stops the loop.
+	      }
+	    });
     
-    //If not inserted yet, add new item at the end of the track list.
-    if ( ! inserted_flag ) {
-      track_list_container.append(new_item);
-    }
+	    //If not inserted yet, add new item at the end of the track list.
+	    if ( ! inserted_flag ) {
+      	track_list_container.append(new_item);
+	    }
+		
+		}else{
+			if( ! track_list_container.find('#'+new_item.attr('id')).size() ){
+				
+				if(delta == -1){
+					track_list_container.append(new_item);				
+					inserted_flag = true;
+				}else{
+					list_items.each(function(index){
+			      item_comparing_to = $(this);
+						if ( delta < item_comparing_to.attr('delta') ) {
+			        //Add it here.
+			        item_comparing_to.before(new_item);
+			        inserted_flag = true;
+			        return false; //Returning false stops the loop.
+			      }
+			    });
+			    //If not inserted yet, add new item at the end of the track list.
+			    if ( ! inserted_flag )
+		      	track_list_container.append(new_item);
+		    
+				}
+
+				track_list_container.sortable('refresh');
+			}
+		}
+		
   }
   
   /**
@@ -246,7 +310,7 @@
 
   // This helper function checks if the maximum number of choices is already selected.
   // If so, it disables all the other options.  If not, it enables them.
-  function checkMaxChoices(item, checkbox) {
+  function checkMaxChoices(item, checkbox, order_list) {
     var maxChoices = -1;
     try {
       maxChoices = parseInt(Drupal.settings.term_reference_tree.trees[item.attr('id')]['max_choices']);
diff --git a/term_reference_tree.module b/term_reference_tree.module
index 1aea8b531d81c88ea58f3a1bcd05443483ab19a2..4346ed47a589bd32c68d2982bcd3ff80f82160c6 100644
--- a/term_reference_tree.module
+++ b/term_reference_tree.module
@@ -33,7 +33,7 @@ function term_reference_tree_element_info() {
       '#input' => false,
       '#theme' => array('checkbox_tree_track_list'),
       '#pre_render' => array('form_pre_render_conditional_form_element'),
-    ),
+    )
   );
   
   return $types;
@@ -183,6 +183,7 @@ function _term_reference_tree_flatten($element, &$form_state) {
   $children = element_children($element);
   foreach($children as $c) {
     $child = $element[$c];
+		// dsm($child, '$child');
     if (array_key_exists('#type', $child) && ($child['#type'] == 'radio' || $child['#type'] == 'checkbox')) {
       $output[] = $child;
     }
diff --git a/term_reference_tree.widget.inc b/term_reference_tree.widget.inc
index 8bae7a1fb46632d924d2625b9897235506b7da0f..1d4f6b758387564850b55ed9f9d56a185fdacf1c 100644
--- a/term_reference_tree.widget.inc
+++ b/term_reference_tree.widget.inc
@@ -19,6 +19,7 @@ function term_reference_tree_field_widget_info() {
         'select_parents' => 0,
         'cascading_selection' => 0,
         'track_list' => 0,
+        'track_list_order' => 0,
         'token_display' => '',
         'parent_term_id' => '',
         'max_depth' => '',
@@ -171,7 +172,18 @@ function term_reference_tree_field_widget_settings_form($field, $instance) {
       '#default_value' => $settings['track_list'],
       '#return_value' => 1,
     );
+
+    $form['track_list_order'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Track list drag and drop order'),
+      '#description' => t(
+          'Allow drag and drop selected terms ordering on tracklist.'),
+      '#default_value' => $settings['track_list_order'],
+      '#return_value' => 1,
+      '#element_validate' => array('_term_reference_tree_track_list_order_validate'),
+    );
     
+
     $form['max_depth'] = array(
       '#type' => 'textfield',
       '#title' => t('Maximum Depth'),
@@ -251,6 +263,18 @@ function _term_reference_tree_cascading_selection_validate($element, &$form_stat
   }
 }
 
+function _term_reference_tree_track_list_order_validate($element, &$form_state){
+  if ($form_state['values']['instance']['widget']['settings']['track_list'] == 0 && $form_state['values']['instance']['widget']['settings']['track_list_order'] == 1) {
+    // This is pretty wonky syntax for the field name in form_set_error, but it's
+    // correct.
+    form_set_error('field][track_list_order', t('You must enable Track List if Track List Order is enabled.'));
+  }
+	/*
+		TODO check if number of values is diffrent from 1
+	*/
+}
+
+
 /**
  * Process the checkbox_tree widget.
  * 
@@ -310,6 +334,7 @@ function term_reference_tree_process_checkbox_tree($element, $form_state) {
       $element[] = array(
         '#type' => 'checkbox_tree_track_list',
         '#max_choices' => $max_choices,
+				'#track_list_order' => $element['#track_list_order'],
       );
     }
   } 
@@ -443,7 +468,8 @@ function theme_checkbox_tree_label($variables) {
 function theme_checkbox_tree_track_list($variables) {
   //Should the label be singular or plural? Depends on cardinality of term field.
   static $nothingselected;
-  
+  // dsm($variables, 'theme_checkbox_tree_track_list : $variables');
+
   if(!$nothingselected) {
     $nothingselected = t('[Nothing selected]');
     //Add the "Nothing selected" text. To style it, replace it with whatever you want.
@@ -459,17 +485,17 @@ function theme_checkbox_tree_track_list($variables) {
       'Selected item (click the item to uncheck it)',
       'Selected items (click an item to uncheck it)'
   );
+	$order = $variables['element']['#track_list_order'] ? 'order-list' : '';
   $output = 
     '<div class="term-reference-track-list-container">
        <div class="term-reference-track-list-label">' . $label . '</div>
-       <ul class="term-reference-tree-track-list"><li class="term_ref_tree_nothing_message">'.$nothingselected.'</li></ul>
+       <ul class="term-reference-tree-track-list '.$order.'"><li class="term_ref_tree_nothing_message">'.$nothingselected.'</li></ul>
      </div>';
      
 
   return $output;
 }
 
-
 /**
  * Implements hook_widget_field_form().
  */
@@ -512,6 +538,7 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
       $element['#select_parents'] = $settings['select_parents'];
       $element['#cascading_selection'] = $settings['cascading_selection'];
       $element['#track_list'] = $settings['track_list'];
+      $element['#track_list_order'] = $settings['track_list_order'];
       $element['#parent_tid'] = $settings['parent_term_id'] || $field['settings']['allowed_values'][0]['parent'];
       $element['#vocabulary'] = $voc->vid;
       $element['#token_display'] = module_exists('token') ? $settings['token_display'] : '';
@@ -523,7 +550,11 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
     '#element_validate' => array('_term_reference_tree_widget_validate'),
     '#properties' => $properties,
   );
-
+	
+	if ($settings['track_list_order']) {
+		drupal_add_library('system', 'ui.sortable');
+	}
+	
   return $element;
 }
 
@@ -544,25 +575,58 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
  *   The validated element.
  */
 function _term_reference_tree_widget_validate(&$element, &$form_state) {
+	dsm($element, '_term_reference_tree_widget_validate | $element');
   $items = _term_reference_tree_flatten($element, $form_state);
+	dsm($items, '$items');
   $value = array();
 
   if ($element['#max_choices'] != 1) {
-    foreach($items as $child) {
-      if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
-        array_push($value, array($element['#value_key'] => $child['#value']));
-
-        // If the element is leaves only and select parents is on, then automatically
-        // add all the parents of each selected value.
-        if ($element['#select_parents'] && $element['#leaves_only']) {
-          foreach($child['#parent_values'] as $parent_tid) {
-            if (!in_array(array($element['#value_key'] => $parent_tid), $value)) {
-              array_push($value, array($element['#value_key'] => $parent_tid));
-            }
-          }
-        }
-      } 
-    }
+		if(!$element['#track_list_order']){
+	    foreach($items as $child) {
+	      if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
+	        array_push($value, array( $element['#value_key'] => $child['#value']));
+
+	        // If the element is leaves only and select parents is on, then automatically
+	        // add all the parents of each selected value.
+	        if ($element['#select_parents'] && $element['#leaves_only']) {
+	          foreach($child['#parent_values'] as $parent_tid) {
+	            if (!in_array(array($element['#value_key'] => $parent_tid), $value)) {
+	              array_push($value, array($element['#value_key'] => $parent_tid));
+	            }
+	          }
+	        }
+
+	      } 
+	    }
+			
+		}else{
+			$selected_terms = array();			
+			foreach($items as $child) {
+	      if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
+					$delta = $form_state['input'][$child['#value'].'-weight'];
+	        $selected_terms[$delta] = array($element['#value_key'] => $child['#value']);
+				
+	        // If the element is leaves only and select parents is on, then automatically
+	        // add all the parents of each selected value.
+	        if ($element['#select_parents'] && $element['#leaves_only']) {
+	          foreach($child['#parent_values'] as $parent_tid) {
+	            if (!in_array(array($element['#value_key'] => $parent_tid), $selected_terms)) {
+								$delta = $form_state['input'][$parent_tid.'-weight'];
+				        $selected_terms[$delta] = array($element['#value_key'] => $parent_tid);
+	            }
+	          }
+	        }
+
+	      } 
+	    }
+			// reorder items
+			ksort($selected_terms);
+			// record in value
+			foreach ($selected_terms as $delta => $term) {
+				$value[] = $term;
+			}
+
+		}
   }
   else {
     // If it's a tree of radio buttons, they all have the same value, so we can just
@@ -575,6 +639,8 @@ function _term_reference_tree_widget_validate(&$element, &$form_state) {
     }
   }
   
+	dsm($value, '$value');
+
   if ($element['#required'] && empty($value)) {
     // The title is already check_plained so it's appropriate to use !.
     form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
@@ -701,7 +767,23 @@ function _term_reference_tree_build_item(&$element, &$term, &$form_state, &$valu
       $parents_for_id = array_merge($element['#parents'], array($term->tid));
       $e['#id'] = drupal_html_id('edit-' . implode('-', $parents_for_id));
       $e['#parents'] = $element['#parents'];
-    }
+    }else if($element['#track_list_order']){
+			$delta = 0;
+			$i = -1;
+			if(isset($value[$term->tid])){
+				foreach ($value as $tid) {
+					$i++;
+					if($term->tid == $tid)
+						break;
+				}
+			}
+			
+			$e_weight = array(
+			  '#type' => 'hidden',
+			  '#value' => $i,
+				'#name' => $term->tid.'-weight',
+			);
+		}
   }
   else {
     $e = array(
@@ -710,9 +792,12 @@ function _term_reference_tree_build_item(&$element, &$term, &$form_state, &$valu
     );
   }
 
-
   $container[$term->tid] = $e;  
 
+	if(isset($e_weight)){
+		$container[$term->tid.'-weight'] = $e_weight;
+	}
+
   if (($depth + 1 <= $element['#max_depth'] || !$element['#max_depth']) && property_exists($term, 'children') && count($term->children) > 0) {
     $parents = $parent_tids;
     $parents[] = $term->tid;
