subroutine uv_subtract_comm(line,comm,error)
  use image_def
  use gbl_format
  use gkernel_interfaces
  use imager_interfaces, only : sub_uv_subtract, map_message 
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Support for command  
  !     UV_SUBTRACT Integration [Factor] /FILE LineUVTable ContUVTable    
  !       [/RANGE Cmin Cmax [TYPE]]  ! Not yet implemented
  !
  !       Subtract a continuum from a line table
  !
  !   LineUVTable     The line UV table  
  !   ContUVTable     The Continuum UV Table  
  !   Integration     The smoothing time constant 
  !   Factor          Scale factor  
  !
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line !! Command line
  character(len=*), intent(in) :: comm !! Command name
  logical, intent(inout) :: error      !! Logical error flag
  ! Constants
  character(len=*), parameter :: rname='UV_SUBTRACT'
  integer, parameter :: o_file =1  ! /FILE (mandatory...) option
  ! Local
  character(len=filename_length) :: all_table
  character(len=filename_length) :: cont_table
  character(len=filename_length) :: line_table
  real(8) :: dtime
  integer :: wcol(2)
  real :: factor
  integer :: n
  !
  ! Code 
  call sic_ch(line,o_file,1,all_table,n,.true.,error)
  if ((n.eq.0).or.error) then
    call map_message(seve%e,rname,'Missing Input Line UV table name')
    error = .true.
    return
  endif
  call sic_ch(line,o_file,2,cont_table,n,.true.,error)
  if ((n.eq.0).or.error) then
    call map_message(seve%e,rname,'Missing Continuum UV table name')
    error = .true.
    return
  endif
  !
  if (sic_narg(o_file).ge.3) then
    call sic_ch(line,o_file,3,line_table,n,.true.,error)
    if ((n.eq.0).or.error) then
      call map_message(seve%e,rname,'Missing Output Line UV table name')
      error = .true.
      return
    endif
  else
    call map_message(seve%w,rname,'Overwriting Input UV Table '//trim(all_table))
    line_table = ' '
    n = 1
  endif  
  !
  dtime = 2.0  ! Seconds
  call sic_r8(line,0,1,dtime,.false.,error)
  if (error) return
  dtime = 0.5d0*dtime
  factor = 1.0
  call sic_r4(line,0,2,factor,.false.,error)
  if (error) return
  !
  ! Need to implement the /RANGE option - Header needed for that...
  wcol = 0 ! Default to full range
  call sub_uv_subtract(all_table,cont_table,line_table(1:n),dtime,wcol,factor,error)
end subroutine uv_subtract_comm
!
subroutine sub_uv_subtract(uv_input,uv_cont,uv_output,dtime,wicol,factor,error)
  use image_def
  use gbl_format
  use gkernel_interfaces
  use imager_interfaces, except_this => sub_uv_subtract
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Support for command UV_SUBTRACT  
  !       Subtract a continuum from a line table
  !
  ! From  original UV_SUBTRACT task created by S.Guilloteau 19-Jun-1991
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: uv_input    !! Input  UV table name
  character(len=*), intent(in) :: uv_cont     !! Continuum UV table
  character(len=*), intent(in) :: uv_output   !! Output UV table
  real(8), intent(in)  :: dtime               !! Smoothing Time
  integer, intent(in)  :: wicol(2)            !! Channel range
  real, intent(in)  :: factor                 !! Scale factor
  logical, intent(out) :: error               !! Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='UV_SUBTRACT'
  real(8), parameter :: pi=3.14159265358979323846d0
  real(8), parameter :: f_to_k = 1.d0/299792458.d-6
  ! Local
  type(gildas) :: x,y,z ! Input, Continuum, Output
  character(len=filename_length) :: name
  character(len=80) :: mess
  character(len=3) :: cwrite
  real(8) :: time,stime
  integer :: wcol(2)
  logical :: err, lexist, do_over
  !
  complex(4) :: resul, self
  integer :: i,nvs,nvi,nsc,nc,n,j, k, nblock, ier
  real :: rbase(2),reel,imgi,uv(2)
  real :: kilow,weight
  real(8), allocatable :: ipw(:)
  integer, allocatable :: ipi(:)
  real(8) :: freq
  integer :: igood, ibad, sever
  !
  error = .false.
  self = cmplx(1.0,0.0)
  weight = 1.0
  wcol = wicol
  !
  call gildas_null(z, type = 'UVT')
  do_over = (len_trim(uv_output).eq.0)
  !
  ! Open continuum table
  n = len_trim(uv_cont)
  call gildas_null (y, type = 'UVT')
  name = uv_cont(1:n)
  call gdf_read_gildas (y, name, '.uvt', error)
  if (error) then
    call map_message(seve%e,rname,'Cannot read continuum UV table')
    return
  endif
  !
  ! Open Input line table
  call gildas_null (x, type = 'UVT')
  name = uv_input
  call sic_parse_file (name,' ','.uvt',x%file)
  inquire(file=trim(x%file),exist=lexist)  !! ,readwrite=cwrite)
  if (.not.lexist) then
    call map_message(seve%e,rname,'No such file '//trim(x%file))
    error = .true.
    return
  endif
  !
  if (do_over) then
    ! Rewrite to Input file 
    cwrite = 'NO  '
    inquire(file=trim(x%file),WRITE=cwrite)   ! It seems that READWRITE does not produce the expected result
    if (cwrite.eq.'YES') then
      x%loca%read = .false.
    else
      call map_message(seve%e,rname,'Input/output UV table is not Writable')
      error = .true.
      return
    endif
  else
    ! Open input file for Read only
    x%loca%read = .true.
  endif
  call gdf_read_gildas (x, name, '.uvt', error, data=.false.)
  if (error) then
    call map_message(seve%e,rname,'Cannot read input/output UV table')
    error = .true.
    return
  endif
  !
  call gdf_copy_header(x,z,error)  
  if (.not.do_over) then
    name = uv_output
    call sic_parse_file (name,' ','.uvt',z%file)    
    call gdf_create_image(z,error)
    if (error) then
      call map_message(seve%e,rname,'Cannot Create output UV table')
      return
    endif
  endif
  !
  ! All images connected -- do the job
  freq = y%gil%val(1)+y%gil%fres*(y%gil%val(1)/y%gil%freq)*((y%gil%nchan+1)*0.5-y%gil%ref(1))
  kilow = freq*f_to_k
  nsc = min(max(1,wcol(1)),y%gil%nchan)
  wcol(1) = nsc 
  if (wcol(2).eq.0) then
    wcol(2) = nsc
  else
    wcol(2) = max(1,min(wcol(2),nsc))
  endif
  !
  ! Load time variable and sort by time order
  !
  ! Sort self-cal table
  nvs = y%gil%dim(1)
  nvi = y%gil%nvisi
  allocate (ipw(nvi), ipi(nvi), stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'Memory allocation error')
    error = .true.
    return
  endif
  call dotime (nvs, nvi, y%r2d, ipw, ipi, stime)
  !
  call gdf_nitems('SPACE_GILDAS',nblock,x%gil%dim(1))
  nblock = min(nblock,x%gil%dim(2))  ! A decent number of visibilities...
  !
  allocate (x%r2d(x%gil%dim(1),nblock), stat=ier)
  nc = x%gil%nchan
  !
  ! Loop over line table
  x%blc = 0
  x%trc = 0
  igood = 0
  ibad = 0
  do i=1,x%gil%dim(2),nblock
    write(mess,*) i,' / ',x%gil%nvisi,nblock
    call map_message(seve%d,rname,mess)
    x%blc(2) = i
    x%trc(2) = min(x%gil%dim(2),i-1+nblock) 
    call gdf_read_data(x,x%r2d,error)
    if (error) exit
    k = 1
    do j=x%blc(2),x%trc(2)
      !
      ! Get time and baseline
      call getiba (x%r2d(:,k),stime,time,rbase,uv)
      !
      ! Compute the observed reference visibility for that baseline
      call geself (nvs, nvi, wcol,y%r2d,    &
     &        time,dtime,ipw,ipi,   &
     &        rbase,resul,uv)
      !
      ! No data: flag
      if (resul.eq.cmplx(0.,0.)) then
        call doflag (nc,x%r2d(:,k))
        ibad = ibad+1
      else
        ! Compute fraction of source to remove
        reel = factor*real(resul)
        imgi = factor*imag(resul)
        ! Remove source
        call dosubt (nc,x%r2d(:,k),reel,imgi)
        igood = igood+1
      endif
      k = k+1
    enddo
    ! Write through Z output (X == Z if overwriting)
    z%blc = x%blc
    z%trc = x%trc
    call gdf_write_data (z,x%r2d,error)
    if (error) exit
  enddo
  ! end loop
  if (igood.eq.0) then
    mess = 'All visibilities flagged'
    sever = seve%e
    error = .true.
  else 
    write(mess,'(A,I0,A,I0,A)') 'Subtracted ',igood,' Visibilities, flagged ',ibad,' ones'
    if (igood.gt.2*ibad) then 
      sever = seve%i
    else
      sever = seve%w
    endif
  endif
  call map_message(sever,rname,mess)
  if (.not.do_over) then
    err = .false.
    call gdf_close_image(z,err)
    error = err.or.error
  endif
  err = .false.
  call gdf_close_image(y,err)
  error = err.or.error
  call gdf_close_image(x,err)
  error = err.or.error
  !
end subroutine sub_uv_subtract
