subroutine mrtindex_file_old_byname(indexfile,directory,rw,fileid,error)
  use gbl_message
  use gkernel_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_file_old_byname
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private-generic mrtindex_file_old
  !  Open an 'old' (already existing) index file in the Input indeX
  ! Open or reuse a pre-opened file, and return its identifier in the
  ! list of opened files
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: indexfile  !
  character(len=*), intent(in)    :: directory  !
  logical,          intent(in)    :: rw         ! Open in RW mode?
  integer(kind=4),  intent(out)   :: fileid     !
  logical,          intent(inout) :: error      !
  ! Local
  character(len=*), parameter :: rname='FILE>OLD'
  integer(kind=4) :: lun,ifile,ier
  logical :: fopened
  !
  inquire(file=indexfile,opened=fopened,number=lun,iostat=ier)
  if (ier.ne.0) then
    call putios('E-FILE>OLD,  ',ier)
    error = .true.
    return
  endif
  !
  if (fopened) then
    ! File is Fortran-opened: find it in the index file list
    ! Do not rely on the file name, which is not perfect (case
    ! insensitive filesystems, sym- or hard-links, etc). Use its
    ! logical unit instead (Fortran guarantees it is unique)
    if (ix_opened.eq.0 .or. ix_files(ix_opened)%lun.ne.lun) then
      call mrtindex_message(seve%e,rname,  &
        'Lost my mind: file '//trim(indexfile)//' is Fortran-opened but not in IX')
      error = .true.
      return
    endif
    !
    fileid = ix_opened
    call mrtindex_file_old_byid(fileid,rw,error)
    return  ! Always
    !
  else
    ! File is not Fortran-opened. No better solution than looping on the
    ! file list and comparing their names.
    ! ZZZ Can we improve this file search? e.g. a dichotomic search?
    do ifile=1,ix_ndir
      if (indexfile.eq.ix_files(ifile)%spec) then
        ! We already know this one in our list, just open it
        fileid = ifile
        call mrtindex_file_old_byid(fileid,rw,error)
        return  ! Always
      endif
    enddo
  endif
  !
  ! Else, have to allocate a new one. Make room for referencing (at least)
  ! 1 more file
  call reallocate_ix_dirs(ix_ndir+1,error)
  if (error)  return
  !
  ix_ndir = ix_ndir+1
  fileid = ix_ndir
  ix_dirs(fileid) = directory
  ix_files(fileid)%spec = indexfile
  ix_files(fileid)%nspec = len_trim(indexfile)
  !
  call mrtindex_file_classic_old(fileid,rw,error)
  if (error)  return
  !
end subroutine mrtindex_file_old_byname
!
subroutine mrtindex_file_old_byid(fileid,rw,error)
  use gbl_message
  use mrtindex_interfaces, except_this=>mrtindex_file_old_byid
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private-generic mrtindex_file_old
  !  Open an 'old' (already existing) index file in the Input indeX
  ! Reuse a pre-opened file given its identifier
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in)    :: fileid   !
  logical,          intent(in)    :: rw       ! Open in RW mode?
  logical,          intent(inout) :: error    !
  ! Local
  character(len=*), parameter :: rname='FILE>OLD'
  !
  ! Sanity check
  if (fileid.le.0 .or. fileid.gt.ix_ndir) then
    call mrtindex_message(seve%e,rname,'Internal error: no such file')
    error = .true.
    return
  endif
  !
  if (fileid.eq.ix_opened) then
    ! This file is the one currently Fortran-opened
    if (ix_files(fileid)%readwrite .or. .not.rw) then
      ! File is opened in correct mode, nothing to do
      return
    else
      ! Current mode is not enough: must close and reopen it
      continue
    endif
  endif
  !
  ! ZZZ Should we do a full Classic open or just a Fortran open (classic_file_fopen)?
  call mrtindex_file_classic_old(fileid,rw,error)
  if (error)  return
  !
end subroutine mrtindex_file_old_byid
!
subroutine mrtindex_file_update(indexfile,directory,pattern,overwrite,  &
  present,error)
  use gildas_def
  use gbl_message
  use classic_api
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_file_update
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private
  ! Build/Update (according to overwrite flag) the index file
  !---------------------------------------------------------------------
  character(len=*),     intent(in)    :: indexfile  !
  character(len=*),     intent(in)    :: directory  !
  type(user_pattern_t), intent(in)    :: pattern    ! Pattern(s) for file(s) to be indexed
  logical,              intent(in)    :: overwrite  !
  logical,              intent(in)    :: present    ! Is it expected to find FITS files?
  logical,              intent(inout) :: error      !
  ! Local
  character(len=*), parameter :: rname='FILE>UPDATE'
  integer(kind=4) :: mfile,nfile,nfile2,ier,fileid,j,gagdate
  character(len=fitsname_length), allocatable :: filelist(:),filelist2(:)
  character(len=imbfits_pattern_length) :: string
  !
  ! Build a single file list
  if (pattern%bylist) then  ! By list of dates
    ! A bit complicated as we have to iterate several file patterns
    !
    ! Need to guess an upper limit for the max number of files in the final
    ! list:
    call gag_directory_num(directory,mfile,error)
    if (error)  return
    allocate(filelist(mfile),stat=ier)
    if (failed_allocate(rname,'file list',ier,error)) return
    !
    nfile = 0
    do j=1,pattern%datelist%nlist
      do gagdate=pattern%datelist%i1(j),pattern%datelist%i2(j),pattern%datelist%i3(j)
        call gag_toyyyymmdd(gagdate,string,error)
        if (error)  return
        call gag_directory(directory,imbfits_name(string),filelist2,nfile2,error)
        if (error)  return
        if (nfile2.gt.0) then
          filelist(nfile+1:nfile+nfile2) = filelist2(1:nfile2)
          nfile = nfile+nfile2
        endif
      enddo
    enddo
  else
    ! Single file pattern
    call gag_directory(directory,pattern%custom,filelist,nfile,error)
    if (error)  return
  endif
  !
  ! And now build the index
  if (nfile.le.0 .and. .not.present) then
    ! Do not create the index file. We want to create it if this directory
    ! is explicitely searched in, but not e.g. in a recursive search.
    return
  endif
  !
  call mrtindex_file_new(indexfile,overwrite,directory,fileid,error)
  if (error)  return
  !
  call mrtindex_index_write(ix_files(fileid),directory,filelist,nfile,error)
  if (error)  continue
  !
  ! Do not keep opened this file, we may be building|updating a large
  ! number
  call mrtindex_file_close(ix_files(fileid),error)
  if (error)  continue
  !
end subroutine mrtindex_file_update
!
subroutine mrtindex_file_new(indexfile,overwrite,directory,fileid,error)
  use gkernel_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_file_new
  !---------------------------------------------------------------------
  ! @ private
  !  Open the index file. Create new one if requested or if it does
  ! not exists. Also return its memory identifier.
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: indexfile  !
  logical,          intent(in)    :: overwrite  !
  character(len=*), intent(in)    :: directory  ! The directory indexed by the index file
  integer(kind=4),  intent(out)   :: fileid     !
  logical,          intent(inout) :: error      !
  ! Local
  logical :: new
  integer(kind=4) :: nspec
  !
  ! Define the output file
  new = .true.
  nspec = len_trim(indexfile)
  !
  if (gag_inquire(indexfile,nspec).eq.0) then
    ! File exists
    if (overwrite) then
      ! Create a new one from scratch
      call gag_filrm(indexfile)
    else
      new = .false.
    endif
  endif
  !
  if (new) then
    ! File does not exist
    call mrtindex_file_classic_new(indexfile,error)
    if (error)  return
  endif
  !
  ! Update the existing file
  call mrtindex_file_old(indexfile,directory,.true.,fileid,error)
  if (error)  return
  !
end subroutine mrtindex_file_new
!
subroutine mrtindex_file_classic_new(filename,error)
  use gbl_message
  use gkernel_interfaces
  use classic_api
  use mrtindex_interfaces, except_this=>mrtindex_file_classic_new
  use mrtindex_types
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private
  !  Create (from a Classic point of view) a new index file
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: filename  !
  logical,          intent(inout) :: error     ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='FILE>NEW'
  type(classic_file_t) :: fileout
  integer(kind=entry_length) :: lsize
  logical :: lover,lsingle
  !
  fileout%lun = ox_lun
  fileout%spec = filename
  fileout%nspec = len_trim(filename)
  !
  ! Remove it if requested by user
  lover = .true.
  if (lover .and. gag_inquire(fileout%spec,fileout%nspec).eq.0)  &
    call gag_filrm(fileout%spec(1:fileout%nspec))
  !
  call classic_file_init(fileout,2,8*mrtindex_indx_length,error)
  if (error)  return
  !
  lsingle = .true.
  lsize = 1  ! Ignored if version 2
  call classic_filedesc_init(fileout,classic_kind_mrtcal,lsingle,lsize,  &
    mrtcal_indx_version,mrtindex_indx_length,2.0,error)
  if (error)  return
  !
  call mrtindex_file_close(fileout,error)
  if (error)  return
  !
end subroutine mrtindex_file_classic_new
!
subroutine mrtindex_file_classic_old(fileid,readwrite,error)
  use mrtindex_dependencies_interfaces
  use mrtindex_interfaces, except_this=>mrtindex_file_classic_old
  use mrtindex_messaging
  use mrtindex_types
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  integer(kind=4),  intent(in)    :: fileid     !
  logical,          intent(in)    :: readwrite  !
  logical,          intent(inout) :: error      !
  ! Local
  character(len=*), parameter :: rname='FILE>OLD'
  !
  if (fileid.le.0 .or. fileid.gt.ix_ndir) then
    call mrtindex_message(seve%e,rname,'Internal error: no such file')
    error = .true.
    return
  endif
  !
  ! Close the one which is opened (we ensure there is only one, by design)
  if (ix_opened.ne.0) then
    ! NB: ix_opened and fileid may be equal. In this case, this means we
    ! close and reopen the same file, but maybe with a different access
    ! (e.g. read -> readwrite) mode.
    call mrtindex_file_close(ix_files(ix_opened),error)
    if (error)  return
  endif
  !
  ix_files(fileid)%lun = ix_lun
  call classic_file_open(ix_files(fileid),readwrite,error)
  if (error)  return
  !
  ix_opened = fileid
  !
  call classic_filedesc_open(ix_files(fileid),error)
  if (error)  return
  !
  ! As of today there is only one version supported
  if (ix_files(fileid)%desc%vind.gt.mrtcal_indx_version) then
    call mrtindex_message(seve%e,rname,'This version of index.mrt is too recent')
    call mrtindex_message(seve%e,rname,'Please update your version of Mrtcal')
    error = .true.
    return
  endif
  !
  ! Resize input buffers for this Classic file records
  ! ZZZ One set of buffers per file?
  call reallocate_index_ibuf(ix_files(fileid),error)
  if (error)  return
  if (readwrite) then
    ! Also for output buffers in this case
    call reallocate_index_obuf(ix_files(fileid),error)
    if (error)  return
  endif
  !
  call mrtindex_message(iseve%others,rname,  &
    trim(ix_files(fileid)%spec)//' successfully opened')
  !
end subroutine mrtindex_file_classic_old
!
subroutine mrtindex_file_close(file,error)
  use gkernel_interfaces
  use classic_api
  use mrtindex_vars
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  type(classic_file_t), intent(inout) :: file
  logical,              intent(inout) :: error
  !
  call classic_file_close(file,error)
  if (error)  continue
  !
  if (ix_opened.ne.0) then
    if (ix_files(ix_opened)%lun.eq.file%lun)  ix_opened = 0
  endif
  !
  file%lun = 0
  !
end subroutine mrtindex_file_close
