function test_sort()
  {
    $raw_tree_array = array(
      array('id' => 1, 'parent_id' => 0, 'sort1' => 'bill', 'sort2' => 0),
        array('id' => 2, 'parent_id' => 1, 'sort1' => 'body', 'sort2' => 1),
          array('id' => 3, 'parent_id' => 2, 'sort1' => 'merfy', 'sort2' => 0),
          array('id' => 4, 'parent_id' => 2, 'sort1' => 'eddy', 'sort2' => 1),
        array('id' => 5, 'parent_id' => 1, 'sort1' => 'body', 'sort2' => 0),
      array('id' => 6, 'parent_id' => 0, 'sort1' => 'alfred', 'sort2' => 1),
        array('id' => 7, 'parent_id' => 6, 'sort1' => 'tom', 'sort2' => 0),
      array('id' => 8, 'parent_id' => 0, 'sort1' => 'cunny', 'sort2' => 4),
    );

    $expected_tree_array = array(
      array('id' => 8, 'parent_id' => 0, 'sort1' => 'cunny', 'sort2' => 4),
      array('id' => 1, 'parent_id' => 0, 'sort1' => 'bill', 'sort2' => 0),
        array('id' => 5, 'parent_id' => 1, 'sort1' => 'body', 'sort2' => 0),
        array('id' => 2, 'parent_id' => 1, 'sort1' => 'body', 'sort2' => 1),
          array('id' => 3, 'parent_id' => 2, 'sort1' => 'merfy', 'sort2' => 0),
          array('id' => 4, 'parent_id' => 2, 'sort1' => 'eddy', 'sort2' => 1),
      array('id' => 6, 'parent_id' => 0, 'sort1' => 'alfred', 'sort2' => 1),
        array('id' => 7, 'parent_id' => 6, 'sort1' => 'tom', 'sort2' => 0),
    );

    $sorted = tree_sorter :: sort($raw_tree_array, array('sort1' => 'DESC', 'sort2' => 'ASC'));

    $this->assertEqual(
      $sorted,
      $expected_tree_array
    );
  }
 function &_fetch(&$counter, $params)
 {
     $tree =& tree::instance();
     if (isset($params['order'])) {
         $order = $params['order'];
         unset($params['order']);
     } else {
         $order = array('priority' => 'ASC');
     }
     $tree_array =& parent::_fetch($counter, $params);
     $tree_array =& tree_sorter::sort($tree_array, $order, 'node_id', 'parent_node_id');
     $path_node = $tree->get_node_by_path($params['path']);
     if (isset($params['include_parent']) && (bool) $params['include_parent']) {
         $path_node_level = $path_node['level'] - 1;
     } else {
         $path_node_level = $path_node['level'];
     }
     $levels_status_array = array();
     $size = count($tree_array);
     $current_pos = 0;
     $parent_data = array();
     foreach ($tree_array as $id => $tree_item) {
         $parent_node_id = $tree_item['parent_node_id'];
         if (!isset($parent_data[$parent_node_id])) {
             if ($parent_node_id == 0) {
                 $parent_data[$parent_node_id]['children_amount'] = 1;
             } else {
                 $parent_data[$parent_node_id]['children_amount'] = $tree->count_accessible_children($parent_node_id);
             }
             $parent_data[$parent_node_id]['counter'] = 0;
         }
         $parent_data[$parent_node_id]['counter']++;
         if ($parent_data[$parent_node_id]['counter'] == 1) {
             $is_first_child = true;
         } else {
             $is_first_child = false;
         }
         if ($parent_data[$parent_node_id]['counter'] == $parent_data[$parent_node_id]['children_amount']) {
             $is_last_child = true;
         } else {
             $is_last_child = false;
         }
         $tree_array[$id]['level'] = $tree_array[$id]['level'] - $path_node_level;
         $levels_status_array[$tree_item['level'] - $path_node_level] = $is_last_child;
         $tree_array[$id]['level_' . $tree_array[$id]['level']] = 1;
         $tree_array[$id]['is_expanded'] = $tree->is_node_expanded($tree_item['node_id']);
         $tree_array[$id]['is_last_child'] = $is_last_child;
         $tree_array[$id]['is_first_child'] = $is_first_child;
         $tree_array[$id]['levels_status'] = $levels_status_array;
         if ($tree_array[$id]['class_name'] == 'image_object' || $tree_array[$id]['class_name'] == 'file_object') {
             $tree_array[$id]['icon'] = '/root?node_id=' . $tree_item['node_id'] . '&icon';
         } elseif (isset($tree_item['icon']) && $tree_item['icon']) {
             $tree_array[$id]['icon'] = $tree_item['icon'];
         } else {
             $tree_array[$id]['icon'] = '/shared/images/generic.gif';
         }
     }
     return $tree_array;
 }
  function _do_sort(& $tree_array, & $sorted_tree_array, $sort_params, $parent_id, $id_hash, $parent_hash)
  {
 		$children = array();
 		
  	foreach($tree_array as $index => $item)
  	{
  		if($item[$parent_hash] == $parent_id)
  		{
  			$children[] = $item;
  			unset($tree_array[$index]);
  		}
  	}

  	if(!($count = sizeof($children)))
  		return;
		
		$children = complex_array :: sort_array($children, $sort_params);
		
		if(!$sorted_tree_array)
		{
			$sorted_tree_array = $children;
		}
		else
		{
			$ids = complex_array :: get_column_values($id_hash, $sorted_tree_array);
			
			$offset = array_search($parent_id, $ids) + 1;
			
			array_splice($sorted_tree_array, $offset, 0, $children);
		}
		
    for($i=0; $i < $count; $i++)
    {
	   	tree_sorter :: _do_sort($tree_array, $sorted_tree_array, $sort_params, $children[$i][$id_hash], $id_hash, $parent_hash);
    }
  }