subroutine mx_clean (map,huv,uvdata,uvp,uvv,   &
     &    method,hdirty,hbeam,hclean,hresid,hprim,   &
     &    w_grid,w_mapu,w_mapv,p_cct, dcct, smask, slist,   &
     &    sblock, cpu0, uvmax)
  use clean_def
  use image_def
  use gbl_message
  use imager_interfaces, except_this => mx_clean
  !----------------------------------------------------------------------
  ! @ private
  ! GILDAS: CLEAN Internal routine
  ! Implementation of MX CLEAN deconvolution algorithm.
  !----------------------------------------------------------------------
  type (clean_par), intent(inout) :: method
  type (uvmap_par), intent(inout) :: map
  type (gildas), intent(inout) :: huv
  type (gildas), intent(inout) :: hdirty
  type (gildas), intent(inout) :: hbeam
  type (gildas), intent(inout) :: hclean
  type (gildas), intent(inout) :: hresid
  type (gildas), intent(inout) :: hprim
  real, intent(inout) :: dcct(3,hclean%gil%dim(3),*)
  logical, intent(inout) :: smask(:,:)
  integer, intent(in) :: slist(*)
  integer, intent(in) :: sblock
  real, intent(inout) :: uvdata(huv%gil%dim(1),huv%gil%dim(2))
  real, intent(in) :: uvp(*)
  real, intent(in) :: uvv(*)
  real, intent(inout) :: w_grid(*)
  real, intent(inout) :: w_mapu(*)
  real, intent(inout) :: w_mapv(*)
  real, intent(in) :: cpu0
  real, intent(inout) :: uvmax
  type (cct_par), intent(out) :: p_cct(method%m_iter)
  !
  logical :: error
  integer nx,ny,nz,nf, mc,nclean, i, nu,nv
  real fhat
  real, allocatable :: mapx(:), mapy(:)
  real, pointer :: p_resid(:,:)
  real, pointer :: p_clean(:,:)
  real, pointer :: p_beam(:,:,:)
  real, pointer :: p_prim(:,:,:)   ! Primary beam
  real, pointer :: p_atten(:,:,:) ! Mosaic weight
  type(cct_par), allocatable :: p_comp(:)      ! Clean values
  complex, allocatable :: p_work(:,:)
  real, allocatable :: p_tfbeam(:,:,:)
  integer, allocatable :: p_niter(:)
  real, allocatable :: w_fft(:)
  real, dimension(1,1,1), target ::dummy3d
  integer ier,iplane
  character(len=message_length) :: chain
  character(len=*), parameter :: rname = 'MX'
  !
  nx = hdirty%gil%dim(1)
  ny = hdirty%gil%dim(2)
  mc = method%m_iter
  !
  ! Get some memory
  allocate (p_work(nx,ny),p_tfbeam(nx,ny,1),stat=ier)
  nclean = nx*ny
  allocate (p_comp(nclean),stat=ier)
  allocate (mapx(nx),mapy(ny),stat=ier)
  allocate (w_fft(max(nx,ny)),stat=ier)
  !
  call loadxy (method,huv,hdirty,mapx,nx,mapy,ny)
  !
  ! Prepare beam parameters
  method%ibeam = 1             ! Test
  method%iplane = 1            ! Test
  error = .false.
  call get_clean (method,hbeam,hbeam%r3d,error)
  if (error) return
  call get_beam (method,hbeam,hresid,hprim,  &
     &    p_tfbeam,p_work,w_fft,fhat,error)
  if (error) return
  !
  ! Find components in all planes...
  nz = max(hdirty%gil%dim(3),1)
  allocate (p_niter(nz),stat=ier)
  nf = max(1,hprim%gil%dim(1))
  p_beam  => hbeam%r3d(:,:,1:1)
  if (method%mosaic) then
    p_prim => hprim%r3d
    p_atten=> method%atten
  else
    p_prim => dummy3d
    p_atten=> dummy3d
  endif
  !
  ! Loop here if needed
  nu = huv%gil%dim(1)
  nv = huv%gil%nvisi  ! not %dim(2)
  do iplane = method%first, method%last
    !
    method%iplane = iplane
    call beam_plane(method,hbeam,hdirty)
    write(chain,'(A,I6,I6)') 'Image & Beam planes ',   &
        &      method%iplane,method%ibeam
    !omp!$ chain = trim(chain)//cthread
    call map_message(seve%d,rname,chain)
    !
    method%iplane = iplane
    p_resid => hresid%r3d(:,:,iplane)
    p_clean => hclean%r3d(:,:,iplane)
    p_beam  => hbeam%r3d(:,:,method%ibeam:method%ibeam)
    !
    call get_clean (method, hbeam, p_beam, error)
    !
    call mx_major_cycle90 (map,uvdata,   &
     &      nu,nv,uvp,uvv,   &
     &      method,hdirty,   &
     &      p_clean,p_beam,p_resid,   &
     &      nx,ny,1,         &
     &      p_comp,nclean,   &
     &      p_cct, p_niter(iplane),   &
     &      slist, method%nlist,   &
     &      nf, p_prim, p_atten,   &
     &      w_grid, w_mapu, w_mapv, mapx, mapy,   &
     &      p_tfbeam, cpu0, uvmax)
    !
    ! Add clean components to clean map
    write(chain,1001) 'Restoring plane ',iplane
    call map_message(seve%d,rname,chain)
    ! Could be replaced by CLEAN_MAKE90... to be checked...
    if (p_niter(iplane).ne.0) then
      !! Print *,'adding residual '
      call clean_make90(method,hclean,p_clean,p_cct)
      p_clean = p_clean+p_resid
    else
      p_clean = p_resid
    endif
!
    do i=1,method%n_iter
       dcct(1,iplane,i) = (dble(p_cct(i)%ix) -   &
         &          hclean%gil%convert(1,1)) * hclean%gil%convert(3,1) + &
         &          hclean%gil%convert(2,1)
       dcct(2,iplane,i) = (dble(p_cct(i)%iy) -   &
         &          hclean%gil%convert(1,2)) * hclean%gil%convert(3,2) + &
         &          hclean%gil%convert(2,2)
       dcct(3,iplane,i) = p_cct(i)%value
    enddo
  enddo
  !
  ! Clean-up
  if (allocated(p_work)) deallocate(p_work)
  if (allocated(p_tfbeam)) deallocate(p_tfbeam)
  if (allocated(p_comp)) deallocate(p_comp)
  if (allocated(mapx)) deallocate(mapx)
  if (allocated(mapy)) deallocate(mapy)
  if (allocated(w_fft)) deallocate(w_fft)
  if (allocated(p_niter)) deallocate(p_niter)
  return
  !
  1001  format(a,i5,i5)
end subroutine mx_clean
!
subroutine loadxy (method,huv,head,mapx,nx,mapy,ny)
  use clean_def
  use image_def
  !--------------------------------------------------
  ! @ private
  !
  ! MAPPING
  !   Load x,y coordinates
  !--------------------------------------------------
  type (clean_par), intent(in) :: method
  type (gildas), intent(in) :: huv,head
  integer, intent(in) :: nx
  integer, intent(in) :: ny
  real, intent(out) :: mapx(nx)
  real, intent(out) :: mapy(ny)
  !
  real(8), parameter :: pi=3.14159265358979323846d0
  real(8), parameter :: f_to_k = 2.d0*pi/299792458.d-6
  !
  integer i
  real pidsur                  ! 2*pi*D/Lambda
  real(8) :: freq
  !
  freq = huv%gil%convert(2,1)+huv%gil%fres*   &
     &    ((method%first+method%last)*0.5-huv%gil%convert(1,1))
  pidsur = f_to_k * freq
  !
  do i=1,nx
    mapx(i) = pidsur*((i-head%gil%convert(1,1))*head%gil%convert(3,1)   &
     &      +head%gil%convert(2,1))
  enddo
  do i=1,ny
    mapy(i) = pidsur*((i-head%gil%convert(1,2))*head%gil%convert(3,2)   &
     &      +head%gil%convert(2,2))
  enddo
end subroutine loadxy
