subroutine bind_f90_box_iterator_copy_constructor( &
    out_self, &
    other)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), pointer :: out_self
  type(box_iterator), intent(in) :: other

  nullify(out_self)
  allocate(out_self)
  out_self = other
end subroutine bind_f90_box_iterator_copy_constructor

subroutine bind_f90_box_iterator_type_new( &
    out_self, &
    i, &
    j, &
    k, &
    i23, &
    i3e, &
    i3s, &
    ind, &
    inext, &
    mesh, &
    nbox, &
    oxyz, &
    rxyz, &
    rxyz_nbox, &
    subbox, &
    tmp, &
    whole)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box, only: box_iterator, cell
  implicit none
  type(box_iterator), pointer :: out_self
  integer, intent(in) :: i
  integer, intent(in) :: j
  integer, intent(in) :: k
  integer, optional, intent(in) :: i23
  integer, optional, intent(in) :: i3e
  integer, optional, intent(in) :: i3s
  integer, optional, intent(in) :: ind
  type(cell), pointer, optional :: mesh
  logical, optional, intent(in) :: whole
  integer, dimension(3), optional, intent(in) :: inext
  real(kind = gp), dimension(3), optional, intent(in) :: oxyz
  real(kind = gp), dimension(3), optional, intent(in) :: rxyz
  real(kind = gp), dimension(3), optional, intent(in) :: rxyz_nbox
  real(kind = gp), dimension(3), optional, intent(in) :: tmp
  integer, dimension(2, &
 3), optional, intent(in) :: nbox
  integer, dimension(2, &
 3), optional, intent(in) :: subbox

  nullify(out_self)
  allocate(out_self)
  out_self%i = i
  out_self%j = j
  out_self%k = k
  if (present(i23)) out_self%i23 = i23
  if (present(i3e)) out_self%i3e = i3e
  if (present(i3s)) out_self%i3s = i3s
  if (present(ind)) out_self%ind = ind
  if (present(inext)) out_self%inext = inext
  if (present(mesh)) out_self%mesh => mesh
  if (present(nbox)) out_self%nbox = nbox
  if (present(oxyz)) out_self%oxyz = oxyz
  if (present(rxyz)) out_self%rxyz = rxyz
  if (present(rxyz_nbox)) out_self%rxyz_nbox = rxyz_nbox
  if (present(subbox)) out_self%subbox = subbox
  if (present(tmp)) out_self%tmp = tmp
  if (present(whole)) out_self%whole = whole
end subroutine bind_f90_box_iterator_type_new

subroutine bind_f90_box_iterator_free( &
    self)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), pointer :: self

  deallocate(self)
  nullify(self)
end subroutine bind_f90_box_iterator_free

subroutine bind_f90_box_iterator_empty( &
    out_self)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
end subroutine bind_f90_box_iterator_empty

subroutine bind_f90_cell_copy_constructor( &
    out_self, &
    other)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(cell), pointer :: out_self
  type(cell), intent(in) :: other

  nullify(out_self)
  allocate(out_self)
  out_self = other
end subroutine bind_f90_cell_copy_constructor

subroutine bind_f90_cell_type_new( &
    out_self, &
    dom, &
    habc, &
    hgrids, &
    ndim, &
    ndims, &
    volume_element)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(cell), pointer :: out_self
  type(domain), intent(in) :: dom
  integer(kind = f_long), intent(in) :: ndim
  real(kind = gp), intent(in) :: volume_element
  real(kind = gp), dimension(3), intent(in) :: hgrids
  integer, dimension(3), intent(in) :: ndims
  real(kind = gp), dimension(3, &
 3), intent(in) :: habc

  nullify(out_self)
  allocate(out_self)
  out_self%dom = dom
  out_self%habc = habc
  out_self%hgrids = hgrids
  out_self%ndim = ndim
  out_self%ndims = ndims
  out_self%volume_element = volume_element
end subroutine bind_f90_cell_type_new

subroutine bind_f90_cell_free( &
    self)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(cell), pointer :: self

  deallocate(self)
  nullify(self)
end subroutine bind_f90_cell_free

subroutine bind_cell_null( &
    out_me)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(cell), pointer :: out_me

  nullify(out_me)
  allocate(out_me)
  out_me = cell_null( &
)
end subroutine bind_cell_null

subroutine bind_box_iter( &
    out_boxit, &
    mesh, &
    nbox, &
    origin, &
    i3s, &
    n3p, &
    centered, &
    cutoff)
  use numerics, only: onehalf, &
    pi
  use f_utils, only: f_zero
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), pointer :: out_boxit
  type(cell), target, intent(in) :: mesh
  integer, optional, intent(in) :: i3s
  integer, optional, intent(in) :: n3p
  logical, optional, intent(in) :: centered
  real(kind = gp), optional, intent(in) :: cutoff
  real(kind = gp), dimension(3), optional, intent(in) :: origin
  integer, dimension(2, &
 3), optional, intent(in) :: nbox

  nullify(out_boxit)
  allocate(out_boxit)
  out_boxit = box_iter( &
    mesh, &
    nbox, &
    origin, &
    i3s, &
    n3p, &
    centered, &
    cutoff)
end subroutine bind_box_iter

subroutine bind_box_nbox_from_cutoff( &
    mesh, &
    out_nbox, &
    oxyz, &
    cutoff, &
    inner)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(cell), intent(in) :: mesh
  real(kind = gp), intent(in) :: cutoff
  logical, optional, intent(in) :: inner
  real(kind = gp), dimension(3), intent(in) :: oxyz
  integer, dimension(2, &
 3), intent(out) :: out_nbox

  out_nbox = box_nbox_from_cutoff( &
    mesh, &
    oxyz, &
    cutoff, &
    inner)
end subroutine bind_box_nbox_from_cutoff

subroutine bind_box_next_z( &
    out_ok, &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  logical :: out_ok
  type(box_iterator), intent(inout) :: bit

  out_ok = box_next_z( &
    bit)
end subroutine bind_box_next_z

subroutine bind_box_next_y( &
    out_ok, &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  logical :: out_ok
  type(box_iterator), intent(inout) :: bit

  out_ok = box_next_y( &
    bit)
end subroutine bind_box_next_y

subroutine bind_box_next_x( &
    out_ok, &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  logical :: out_ok
  type(box_iterator), intent(inout) :: bit

  out_ok = box_next_x( &
    bit)
end subroutine bind_box_next_x

subroutine bind_box_next_point( &
    out_box_next_point, &
    boxit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  logical :: out_box_next_point
  type(box_iterator), intent(inout) :: boxit

  out_box_next_point = box_next_point( &
    boxit)
end subroutine bind_box_next_point

subroutine bind_cell_new( &
    out_mesh, &
    dom, &
    ndims, &
    hgrids)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use f_utils, only: f_assert
  use wrapper_linalg, only: det_3x3
  use dictionaries, only: f_err_throw
  use at_domain
  use box
  implicit none
  type(cell), pointer :: out_mesh
  type(domain), intent(in) :: dom
  integer, dimension(3), intent(in) :: ndims
  real(kind = gp), dimension(3), intent(in) :: hgrids

  nullify(out_mesh)
  allocate(out_mesh)
  out_mesh = cell_new( &
    dom, &
    ndims, &
    hgrids)
end subroutine bind_cell_new

subroutine bind_cell_r( &
    out_t, &
    mesh, &
    i, &
    dim)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  real(kind = gp) :: out_t
  type(cell), intent(in) :: mesh
  integer, intent(in) :: i
  integer, intent(in) :: dim

  out_t = cell_r( &
    mesh, &
    i, &
    dim)
end subroutine bind_cell_r

subroutine bind_box_iter_square_gd( &
    out_box_iter_square_gd, &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  real(kind = gp) :: out_box_iter_square_gd
  type(box_iterator), intent(in) :: bit

  out_box_iter_square_gd = box_iter_square_gd( &
    bit)
end subroutine bind_box_iter_square_gd

subroutine bind_box_iter_closest_r( &
    bit, &
    out_r, &
    rxyz, &
    orthorhombic)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(in) :: bit
  logical, optional, intent(in) :: orthorhombic
  real(kind = gp), dimension(3), intent(out) :: out_r
  real(kind = gp), dimension(3), intent(in) :: rxyz

  out_r = box_iter_closest_r( &
    bit, &
    rxyz, &
    orthorhombic)
end subroutine bind_box_iter_closest_r

subroutine bind_box_iter_distance( &
    out_box_iter_distance, &
    bit, &
    rxyz0)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  real(kind = gp) :: out_box_iter_distance
  type(box_iterator), intent(in) :: bit
  real(kind = gp), dimension(3), intent(in) :: rxyz0

  out_box_iter_distance = box_iter_distance( &
    bit, &
    rxyz0)
end subroutine bind_box_iter_distance

subroutine bind_nullify_box_iterator( &
    boxit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(out) :: boxit

  call nullify_box_iterator( &
    boxit)
end subroutine bind_nullify_box_iterator

subroutine bind_box_iter_set_nbox( &
    bit, &
    nbox, &
    oxyz, &
    cutoff)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(inout) :: bit
  real(kind = gp), optional, intent(in) :: cutoff
  real(kind = gp), dimension(3), optional, intent(in) :: oxyz
  integer, dimension(2, &
 3), optional, intent(in) :: nbox

  call box_iter_set_nbox( &
    bit, &
    nbox, &
    oxyz, &
    cutoff)
end subroutine bind_box_iter_set_nbox

subroutine bind_box_iter_expand_nbox( &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(inout) :: bit

  call box_iter_expand_nbox( &
    bit)
end subroutine bind_box_iter_expand_nbox

subroutine bind_box_iter_rewind( &
    bit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(inout) :: bit

  call box_iter_rewind( &
    bit)
end subroutine bind_box_iter_rewind

subroutine bind_box_iter_split( &
    boxit, &
    ntasks, &
    itask)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(inout) :: boxit
  integer, intent(in) :: ntasks
  integer, intent(in) :: itask

  call box_iter_split( &
    boxit, &
    ntasks, &
    itask)
end subroutine bind_box_iter_split

subroutine bind_box_iter_merge( &
    boxit)
  use numerics, only: onehalf, &
    pi
  use f_precisions, gp=>f_double
  use at_domain
  use box
  implicit none
  type(box_iterator), intent(inout) :: boxit

  call box_iter_merge( &
    boxit)
end subroutine bind_box_iter_merge
