subroutine sicsort(line,error)
  use gildas_def
  use gbl_format
  use gbl_message
  use sic_dependencies_interfaces, no_interface1=>gr4_trie_i4,  &
                                   no_interface2=>gr8_trie_i4,  &
                                   no_interface3=>gi4_trie_i4,  &
                                   no_interface4=>gi8_trie_i4,  &
                                   no_interface5=>gch_trie_i4,  &
                                   no_interface6=>gi4_sort,  &
                                   no_interface7=>gi8_sort,  &
                                   no_interface8=>gch_sort
  use sic_interfaces, except_this=>sicsort
  use sic_types
  !---------------------------------------------------------------------
  ! @ private
  ! SIC Support routine for command
  !  SORT KeyVar Var1 Var2 ... VarN
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line   ! Command line
  logical,          intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='SORT'
  character(len=varname_length) :: var
  integer(kind=address_length) :: ipkey,ipvar
  type(sic_descriptor_t) :: desc
  integer :: vtype
  integer(kind=4), allocatable :: iwork(:)
  real(kind=4), allocatable :: swork(:)
  real(kind=8), allocatable :: dwork(:)
  integer(kind=1), allocatable :: cwork(:)  ! Support for character arrays
  !
  integer :: nc,ier,i,nsort
  integer(kind=index_length) :: nxy,nplane,j
  integer(kind=4) :: memory(1)
  integer(kind=1) :: membyt(1)
  logical :: found
  !
  call sic_ke(line,0,1,var,nc,.true.,error)
  if (error) return
  call sic_descriptor (var,desc,found)  ! no transposition
  !
  ! Check it is a 1-D array
  if (desc%ndim.ne.1) then
     call sic_message(seve%e,rname,'Only 1-D array allowed')
     error = .true.
     return
  else
     nxy = desc%dims(1)
  endif
  !
  vtype = desc%type
  allocate(iwork(nxy),stat=ier)
  if (ier.ne.0) then
     call sic_message(seve%e,rname,'Insufficient memory for work space')
     error = .true.
     return
  endif
  ipkey = gag_pointer(desc%addr,memory)
  if (vtype.eq.fmt_r4) then
     call gr4_trie_i4(memory(ipkey),iwork,nxy,error)
  else if (vtype.eq.fmt_r8) then
     call gr8_trie_i4(memory(ipkey),iwork,nxy,error)
  else if (vtype.eq.fmt_i4) then
     call gi4_trie_i4(memory(ipkey),iwork,nxy,error)
  else if (vtype.eq.fmt_i8) then
     call gi8_trie_i4(memory(ipkey),iwork,nxy,error)
  else if (vtype.gt.0) then
     call gch_trie_i4(memory(ipkey),iwork,nxy,vtype,error)
  else
     call sic_message(seve%e,rname,'Kind of data not supported for sorting key')
     error = .true.
  endif
  if (error) then
     deallocate(iwork)
     return
  endif
  !
  ! Now sort all the others by G*_SORT
  nsort = sic_narg(0)
  do i=2,nsort
     call sic_ke(line,0,i,var,nc,.true.,error)
     if (error) exit
     call sic_descriptor (var,desc,found)  ! no transposition
     if (.not.found) cycle
     !
     vtype = desc%type
     !
     if (desc%ndim.le.2 .and. desc%dims(1).eq.nxy) then
        nplane = max(1,desc%dims(2))
        if (vtype.eq.fmt_r4 .or. vtype.eq.fmt_i4 .or. vtype.eq.fmt_l) then
           ipvar = gag_pointer(desc%addr,memory)
           if (.not.allocated(swork))  allocate(swork(nxy),stat=ier)
           do j=1,nplane
              ! Sort with gi4_sort which preserves bits (R*4 to R*4 may not
              ! preserve bits)
              if (ipvar.ne.ipkey)  call gi4_sort(memory(ipvar),swork,iwork,nxy)
              ipvar = ipvar+nxy
           enddo
           !
        else if (vtype.eq.fmt_r8 .or. vtype.eq.fmt_i8) then
           ipvar = gag_pointer(desc%addr,memory)
           if (.not.allocated(dwork))  allocate(dwork(nxy),stat=ier)
           do j=1,nplane
              ! Sort with gi8_sort which preserves bits (R*8 to R*8 may not
              ! preserve bits)
              if (ipvar.ne.ipkey)  call gi8_sort(memory(ipvar),dwork,iwork,nxy)
              ipvar = ipvar+2*nxy
           enddo
           !
        else if (vtype.gt.0) then  ! Character array
           ipvar = bytpnt(desc%addr,membyt)
           allocate(cwork(vtype*nxy),stat=ier)
           do j=1,nplane
              if (ipvar.ne.ipkey)  call gch_sort(membyt(ipvar),cwork,iwork,vtype,nxy)
              ipvar = ipvar+vtype*nxy
           enddo
           deallocate(cwork)  ! Always, size can differ from one variable to another
           !
        else
           call sic_message(seve%e,rname,  &
             'Type of array '//trim(var)//' is not supported for sorting')
           error = .true.
           exit
        endif
     else
        call sic_message(seve%e,rname,'Size mismatch for '//var)
        error = .true.
        exit
     endif
  enddo
  !
  if (allocated(swork)) deallocate(swork)
  if (allocated(dwork)) deallocate(dwork)
  if (allocated(iwork)) deallocate(iwork)
end subroutine sicsort
!
subroutine gr8_locate (x,np,xlim,nlim,mlim)
  use gildas_def
  use sic_interfaces
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  ! DISPLAY	Internal routine
  !	Find NLIM and MLIM such as
  !	 	X(NLIM) < XLIM < X(MLIM)
  ! or vice versa
  !	 	X(NLIM) > XLIM > X(MLIM)
  !	for input data ordered.
  !	Use a dichotomic search for that
  !---------------------------------------------------------------------
  integer(kind=size_length), intent(in)  :: np     !
  real(kind=8),              intent(in)  :: x(np)  !
  real(kind=8),              intent(in)  :: xlim   !
  integer(kind=size_length), intent(out) :: nlim   !
  integer(kind=size_length), intent(out) :: mlim   !
  ! Local
  integer(kind=size_length) :: ninf,nsup,nmid
  !
  if (x(1).lt.x(np)) then
     if (x(1).gt.xlim) then
        nlim = 1
        mlim = 1
        return
     elseif (x(np).lt.xlim) then
        nlim = np
        mlim = np
        return
     endif
     ninf = 1
     nsup = np
     !
     do while(nsup.gt.ninf+1)
        nmid = (nsup + ninf)/2
        if (x(nmid).lt.xlim) then
           ninf = nmid
        else
           nsup = nmid
        endif
     enddo
     nlim = ninf
     mlim = nsup
  else
     if (x(1).lt.xlim) then
        nlim = 1
        mlim = 1
        return
     elseif (x(np).gt.xlim) then
        nlim = np
        mlim = np
        return
     endif
     ninf = 1
     nsup = np
     !
     do while(nsup.gt.ninf+1)
        nmid = (nsup + ninf)/2
        if (x(nmid).gt.xlim) then
           ninf = nmid
        else
           nsup = nmid
        endif
     enddo
     nlim = ninf
     mlim = nsup
  endif
end subroutine gr8_locate
!
subroutine gr4_locate (x,np,xlim,nlim,mlim)
  use gildas_def
  use sic_interfaces
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  ! DISPLAY	Internal routine
  !	Find NLIM and MLIM such as
  !	 	X(NLIM) < XLIM < X(MLIM)
  ! or vice versa
  !	 	X(NLIM) > XLIM > X(MLIM)
  !	for input data ordered.
  !	Use a dichotomic search for that
  !---------------------------------------------------------------------
  integer(kind=size_length), intent(in)  :: np     !
  real(kind=4),              intent(in)  :: x(np)  !
  real(kind=4),              intent(in)  :: xlim   !
  integer(kind=size_length), intent(out) :: nlim   !
  integer(kind=size_length), intent(out) :: mlim   !
  ! Local
  integer(kind=size_length) :: ninf,nsup,nmid
  !
  if (x(1).lt.x(np)) then
     if (x(1).gt.xlim) then
        nlim = 1
        mlim = 1
        return
     elseif (x(np).lt.xlim) then
        nlim = np
        mlim = np
        return
     endif
     ninf = 1
     nsup = np
     !
     do while(nsup.gt.ninf+1)
        nmid = (nsup + ninf)/2
        if (x(nmid).lt.xlim) then
           ninf = nmid
        else
           nsup = nmid
        endif
     enddo
     nlim = ninf
     mlim = nsup
  else
     if (x(1).lt.xlim) then
        nlim = 1
        mlim = 1
        return
     elseif (x(np).gt.xlim) then
        nlim = np
        mlim = np
        return
     endif
     ninf = 1
     nsup = np
     !
     do while(nsup.gt.ninf+1)
        nmid = (nsup + ninf)/2
        if (x(nmid).gt.xlim) then
           ninf = nmid
        else
           nsup = nmid
        endif
     enddo
     nlim = ninf
     mlim = nsup
  endif
end subroutine gr4_locate
