subroutine mosaic_restore(line,error)
  use clean_arrays
  use clean_types
  use gbl_message
  use gkernel_interfaces
  use mapping_interfaces, except_this => mosaic_restore
  !---------------------------------------------------------------------
  ! @ private
  !
  ! Restore (like in UV_RESTORE) a mosaic image
  !
  ! Required input
  !   the CCT table
  !   the RESIDUAL image (obtained by imaging the UV table
  !     obtained by UV_RESIDUAL)
  !   the PRIMARY beams
  ! Output 
  !   the restored CLEAN image
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: line
  logical, intent(inout) :: error
  !
  character(len=*), parameter :: task='MOSAIC_RESTORE'
  type(gildas) :: huv_save
  real, pointer :: prima(:,:,:)
  real, pointer :: resid(:,:)
  real, pointer :: clean(:,:)
  real, pointer :: duv_previous(:,:), duv_next(:,:)
  real, allocatable :: response(:,:)
  integer :: nx,ny,np,nc,ic,ip,i,j,ier
  real :: wr, wr2, ws2, wmin
  logical :: zero, err
  !
  ! Code
  error = .false.
  ! Compute the primary beams if not done
  if (hprim%loca%size.eq.0) then
    call map_message(seve%e,task,'Primary beams undefined')
    error = .true.
    return
  endif
  !
  call gildas_null(huv_save,type='UVT')
  call gdf_copy_header(huv, huv_save, error)
  !
  ! Compute the UV Residual and the pure CLEAN part
  nullify (duv_previous, duv_next)
  call sub_uv_residual(task,line,duv_previous,duv_next,.true.,error)
  if (error) return
  !
  ! Associate DUV and HUV to the UV Residual
  duv => duv_next
  ! Resize UV data  
  huv%gil%nvisi = ubound(duv,2)
  huv%gil%dim(2) = huv%gil%nvisi
  !
  ! Perform the Imaging
  call mosaic_uvmap(task,line,error)
  !
  ! At this stage : DIRTY is the RESIDUAL...
  call gdf_copy_header(hdirty,hresid,error)
  hresid%r3d => dresid 
  !
  prima => dprim(:,:,:,1)
  np = hprim%gil%dim(1)
  nc = hresid%gil%dim(3)
  ny = hresid%gil%dim(2)
  nx = hresid%gil%dim(1)
  !
  ! Compute the "weight" function 1/N
  wmin = 0.01    ! Hum ?
  ws2 =  0.0     ! Search weight
  wr2 =  0.04    ! Restore weight 20 % level of primary beam
  allocate(response(nx,ny),stat=ier)
  !
  response = 0
  do ip=1,np
    response(:,:) = response(:,:)+prima(ip,:,:)**2
  enddo
  where (response.gt.wr2) 
    response = 1.0/response
  else where
    response = 0.0
  end where
  !
  ! For test, can reset DCLEAN or RESID
  zero = .false.
  call sic_get_logi('ZERO_CLEAN',zero,err)
  if (zero) dclean = 0.0
  zero = .false.
  call sic_get_logi('ZERO_RESID',zero,err)
  if (zero) dresid = 0.0
  !
  ! Loop on channels
  do ic=1,nc
    resid => hresid%r3d(:,:,ic)
    clean => hclean%r3d(:,:,ic)
    ! Mosaic case
    clean = clean + resid*response
    where (response.eq.0) clean = hclean%gil%bval ! Undefined pixel there
  enddo
  !
  call sic_delvariable ('CLEAN',.false.,error)
  ! Redefine CLEAN data set 
  call sic_mapgildas('CLEAN',hclean,error,dclean)! Clean buffers
  hclean%loca%size = hdirty%loca%size
  !
  ! Must clean in some way the intermediate UV_BUFFERS and
  ! re-associate the HUV header - Use a new UV_DISCARD_BUFFER tool
  ! to factorize that.
  !
  zero = .false. 
  call sic_get_logi('ZERO_KEEPUV',zero,err)
  !
  if (.not.zero) then
    !call uv_dump_buffers(task//' before')
    !Print *,'Discarding UV buffers '
    call uv_discard_buffers(duv_previous, duv_next, error)
    !call uv_dump_buffers(task//' after')
    call gdf_copy_header(huv_save,huv,error)
    !
  else
    call map_message(seve%w,task,'Keeping UV residuals')
    call uv_clean_buffers (duv_previous, duv_next,error)
    if (error) return
    !
    if (allocated(duvt)) deallocate (duvt)            ! UV data not plotted
    uv_plotted = .false.
    !
    ! Indicate optimization and save status
    optimize(code_save_uv)%change = optimize(code_save_uv)%change + 1
    save_data(code_save_uv) = .true.
    !
    ! Not needed here: weights are unchanged
    ! do_weig = .true.  ! Recompute weight 
    !
    ! Resize UV data and redefine SIC variables 
    huv%gil%nvisi = ubound(duv,2)
    huv%gil%dim(2) = huv%gil%nvisi
    !
    call sic_delvariable ('UV',.false.,error)
    call sic_mapgildas ('UV',huv,error,duv) 
  endif
end subroutine mosaic_restore
