!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
function eclass_inte_eq(a,b)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two integers
  !---------------------------------------------------------------------
  logical :: eclass_inte_eq
  integer(kind=4), intent(in) :: a
  integer(kind=4), intent(in) :: b
  !
  eclass_inte_eq = a.eq.b
  !
end function eclass_inte_eq
!
function eclass_2inte_eq(i1,i2,j1,j2)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two pairs of integers
  !---------------------------------------------------------------------
  logical :: eclass_2inte_eq
  integer(kind=4), intent(in) :: i1,i2
  integer(kind=4), intent(in) :: j1,j2
  !
  eclass_2inte_eq = i1.eq.i2 .and. j1.eq.j2
  !
end function eclass_2inte_eq
!
function eclass_2inte1char_eq(i1,i2,j1,j2,k1,k2)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two pairs of integers + 1 pair of chars
  !---------------------------------------------------------------------
  logical :: eclass_2inte1char_eq
  integer(kind=4),  intent(in) :: i1,i2
  integer(kind=4),  intent(in) :: j1,j2
  character(len=*), intent(in) :: k1,k2
  !
  eclass_2inte1char_eq = i1.eq.i2 .and. j1.eq.j2 .and. k1.eq.k2
  !
end function eclass_2inte1char_eq
!
function eclass_2inte2char_eq(i1,i2,j1,j2,k1,k2,l1,l2)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two pairs of integers + 2 pairs of chars
  !---------------------------------------------------------------------
  logical :: eclass_2inte2char_eq
  integer(kind=4),  intent(in) :: i1,i2
  integer(kind=4),  intent(in) :: j1,j2
  character(len=*), intent(in) :: k1,k2
  character(len=*), intent(in) :: l1,l2
  !
  eclass_2inte2char_eq = i1.eq.i2 .and. j1.eq.j2 .and.   &
                         k1.eq.k2 .and. l1.eq.l2
  !
end function eclass_2inte2char_eq
!
function eclass_dble_eq(a,b)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two real*8
  ! WARNING: there is no tolerance here, because we assume we compare
  ! values which we know must be equal
  !---------------------------------------------------------------------
  logical :: eclass_dble_eq
  real(kind=8), intent(in) :: a
  real(kind=8), intent(in) :: b
  !
  eclass_dble_eq = a.eq.b
  !
end function eclass_dble_eq
!
function eclass_2dble_eq(x1,x2,y1,y2)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two pairs of real*8 (e.g. coordinates)
  ! WARNING: there is no tolerance here, because we assume we compare
  ! values which we know must be equal
  !---------------------------------------------------------------------
  logical :: eclass_2dble_eq
  real(kind=8), intent(in) :: x1,x2
  real(kind=8), intent(in) :: y1,y2
  !
  eclass_2dble_eq = x1.eq.x2 .and. y1.eq.y2
  !
end function eclass_2dble_eq
!
function eclass_2dble3inte_eq(x1,x2,y1,y2,i1,i2,j1,j2,k1,k2)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two pairs of real*8 and two triplets of
  ! integer*4
  !---------------------------------------------------------------------
  logical :: eclass_2dble3inte_eq
  real(kind=8),    intent(in) :: x1,x2
  real(kind=8),    intent(in) :: y1,y2
  integer(kind=4), intent(in) :: i1,i2
  integer(kind=4), intent(in) :: j1,j2
  integer(kind=4), intent(in) :: k1,k2
  !
  eclass_2dble3inte_eq = x1.eq.x2 .and. y1.eq.y2 .and.  &
                         i1.eq.i2 .and. j1.eq.j2 .and. k1.eq.k2
  !
end function eclass_2dble3inte_eq
!
function eclass_char_eq(a,b)
  !---------------------------------------------------------------------
  ! @ public
  ! Equality routine between two characters
  !---------------------------------------------------------------------
  logical :: eclass_char_eq
  character(len=*), intent(in) :: a
  character(len=*), intent(in) :: b
  !
  eclass_char_eq = a.eq.b
  !
end function eclass_char_eq
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine eclass_inte(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,             external      :: equiv   ! l = equiv(i1,i2)
  type(eclass_inte_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val(eclass%nequ) = eclass%val(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val(ival),eclass%val(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val(eclass%nequ) = eclass%val(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_inte
!
subroutine eclass_2inte(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,              external      :: equiv   !
  type(eclass_2inte_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2inte
!
subroutine eclass_2inte1char(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2inte1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,                   external      :: equiv   !
  type(eclass_2inte1char_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%val3(eclass%nequ) = eclass%val3(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ),  &
                eclass%val3(ival),eclass%val3(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%val3(eclass%nequ) = eclass%val3(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2inte1char
!
subroutine eclass_2inte2char(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2inte2char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,                   external      :: equiv   !
  type(eclass_2inte2char_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%val3(eclass%nequ) = eclass%val3(1)
  ! eclass%val4(eclass%nequ) = eclass%val4(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ),  &
                eclass%val3(ival),eclass%val3(iequ),  &
                eclass%val4(ival),eclass%val4(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%val3(eclass%nequ) = eclass%val3(ival)
      eclass%val4(eclass%nequ) = eclass%val4(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2inte2char
!
subroutine eclass_dble(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,             external      :: equiv   !
  type(eclass_dble_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val(eclass%nequ) = eclass%val(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val(ival),eclass%val(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val(eclass%nequ) = eclass%val(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_dble
!
subroutine eclass_2dble(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,              external      :: equiv   !
  type(eclass_2dble_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2dble
!
subroutine eclass_2dble1char(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2dble1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,                   external      :: equiv   !
  type(eclass_2dble1char_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%val3(eclass%nequ) = eclass%val3(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ),  &
                eclass%val3(ival),eclass%val3(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%val3(eclass%nequ) = eclass%val3(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2dble1char
!
subroutine eclass_2dble3inte(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_2dble3inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,                   external      :: equiv   !
  type(eclass_2dble3inte_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val1(eclass%nequ) = eclass%val1(1)
  ! eclass%val2(eclass%nequ) = eclass%val2(1)
  ! eclass%val3(eclass%nequ) = eclass%val3(1)
  ! eclass%val4(eclass%nequ) = eclass%val4(1)
  ! eclass%val5(eclass%nequ) = eclass%val5(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val1(ival),eclass%val1(iequ),  &
                eclass%val2(ival),eclass%val2(iequ),  &
                eclass%val3(ival),eclass%val3(iequ),  &
                eclass%val4(ival),eclass%val4(iequ),  &
                eclass%val5(ival),eclass%val5(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val1(eclass%nequ) = eclass%val1(ival)
      eclass%val2(eclass%nequ) = eclass%val2(ival)
      eclass%val3(eclass%nequ) = eclass%val3(ival)
      eclass%val4(eclass%nequ) = eclass%val4(ival)
      eclass%val5(eclass%nequ) = eclass%val5(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_2dble3inte
!
subroutine eclass_char(equiv,eclass)
  use gmath_interfaces, except_this=>eclass_char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  logical,             external      :: equiv   ! l = equiv(c1,c2)
  type(eclass_char_t), intent(inout) :: eclass  !
  ! Local
  integer(kind=4) :: ival,iequ
  logical :: listed
  !
  if (eclass%nval.le.0) then
    eclass%nequ = 0
    return
  endif
  !
  ! First element is also the first equivalence class
  eclass%nequ = 1
  ! eclass%val(eclass%nequ) = eclass%val(1)
  ! eclass%cnt(eclass%nequ) = eclass%cnt(1)
  eclass%bak(1) = eclass%nequ
  !
  ! Loop over first element of all pairs
  do ival=2,eclass%nval
    listed = .false.
    do iequ=1,eclass%nequ
      if (equiv(eclass%val(ival),eclass%val(iequ))) then
        listed = .true.
        eclass%cnt(iequ) = eclass%cnt(iequ)+eclass%cnt(ival)
        eclass%bak(ival) = iequ
        exit
      endif
    enddo
    if (.not.listed) then
      eclass%nequ = eclass%nequ+1
      eclass%val(eclass%nequ) = eclass%val(ival)
      eclass%cnt(eclass%nequ) = eclass%cnt(ival)
      eclass%bak(ival) = eclass%nequ
    endif
  enddo
  !
end subroutine eclass_char
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine reallocate_eclass_inte(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_inte_t), intent(inout) :: eclass
  integer(kind=4),     intent(in)    :: nval
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>INTE'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_inte(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val(nval),eclass%cnt(nval),eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_inte(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_inte
!
subroutine reallocate_eclass_2inte(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte_t), intent(inout) :: eclass
  integer(kind=4),      intent(in)    :: nval
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2INTE'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2inte(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),eclass%cnt(nval),eclass%bak(nval),  &
       stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2inte(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2inte
!
subroutine reallocate_eclass_2inte1char(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2inte1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte1char_t), intent(inout) :: eclass
  integer(kind=4),           intent(in)    :: nval
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2INTE1CHAR'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2inte1char(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),eclass%val3(nval),  &
              eclass%cnt(nval),eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2inte1char(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2inte1char
!
subroutine reallocate_eclass_2inte2char(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2inte2char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte2char_t), intent(inout) :: eclass
  integer(kind=4),           intent(in)    :: nval
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2INTE2CHAR'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2inte2char(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),  &
              eclass%val3(nval),eclass%val4(nval),  &
              eclass%cnt(nval),eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2inte2char(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2inte2char
!
subroutine reallocate_eclass_dble(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_dble_t), intent(inout) :: eclass
  integer(kind=4),     intent(in)    :: nval
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>DBLE'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_dble(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val(nval),eclass%cnt(nval),eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_dble(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_dble
!
subroutine reallocate_eclass_2dble(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble_t), intent(inout) :: eclass
  integer(kind=4),      intent(in)    :: nval
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2DBLE'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2dble(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),eclass%cnt(nval),eclass%bak(nval),  &
       stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2dble(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2dble
!
subroutine reallocate_eclass_2dble1char(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2dble1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble1char_t), intent(inout) :: eclass
  integer(kind=4),           intent(in)    :: nval
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2DBLE1CHAR'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2dble1char(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),eclass%val3(nval),  &
              eclass%cnt(nval),eclass%bak(nval),  &
              stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2dble1char(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2dble1char
!
subroutine reallocate_eclass_2dble3inte(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_2dble3inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble3inte_t), intent(inout) :: eclass
  integer(kind=4),           intent(in)    :: nval
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>2DBLE3INTE'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val1)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_2dble3inte(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val1(nval),eclass%val2(nval),eclass%val3(nval),  &
              eclass%val4(nval),eclass%val5(nval),eclass%cnt(nval),   &
              eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_2dble3inte(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_2dble3inte
!
subroutine reallocate_eclass_char(eclass,nval,error)
  use gbl_message
  use gmath_interfaces, except_this=>reallocate_eclass_char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_char_t), intent(inout) :: eclass
  integer(kind=4),     intent(in)    :: nval
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>ECLASS>CHAR'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  alloc = .true.
  if (associated(eclass%val)) then
     if (eclass%nval.eq.nval) then
        write(mess,'(a,i0)')  &
          'Eclass already associated at the right size: ',nval
        call gmath_message(seve%d,rname,mess)
        alloc = .false.
     else
        write(mess,'(a)') 'Pointer eclass already associated but with a different size => Freeing it first'
        call gmath_message(seve%d,rname,mess)
        call free_eclass_char(eclass,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(eclass%val(nval),eclass%cnt(nval),eclass%bak(nval),stat=ier)
     if (ier.ne.0) then
        call gmath_message(seve%e,rname,'Could not allocate memory for eclass')
        call free_eclass_char(eclass,error)
        return
     endif
     write(mess,'(a,i0)') 'Allocated ECLASS of size: ',nval
     call gmath_message(seve%d,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  eclass%nval = nval
  !
end subroutine reallocate_eclass_char
!
subroutine free_eclass_inte(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_inte_t), intent(inout) :: eclass
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>INTE'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val))  return
  !
  eclass%nval = 0
  if (associated(eclass%val))  deallocate(eclass%val)
  if (associated(eclass%cnt))  deallocate(eclass%cnt)
  if (associated(eclass%bak))  deallocate(eclass%bak)
  !
end subroutine free_eclass_inte
!
subroutine free_eclass_2inte(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte_t), intent(inout) :: eclass
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2INTE'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2inte
!
subroutine free_eclass_2inte1char(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2inte1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte1char_t), intent(inout) :: eclass
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2INTE1CHAR'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%val3))  deallocate(eclass%val3)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2inte1char
!
subroutine free_eclass_2inte2char(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2inte2char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2inte2char_t), intent(inout) :: eclass
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2INTE2CHAR'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%val3))  deallocate(eclass%val3)
  if (associated(eclass%val4))  deallocate(eclass%val4)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2inte2char
!
subroutine free_eclass_dble(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_dble_t), intent(inout) :: eclass
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>DBLE'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val))  return
  !
  eclass%nval = 0
  if (associated(eclass%val))  deallocate(eclass%val)
  if (associated(eclass%cnt))  deallocate(eclass%cnt)
  if (associated(eclass%bak))  deallocate(eclass%bak)
  !
end subroutine free_eclass_dble
!
subroutine free_eclass_2dble(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2dble
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble_t), intent(inout) :: eclass
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2DBLE'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2dble
!
subroutine free_eclass_2dble1char(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2dble1char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble1char_t), intent(inout) :: eclass
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2DBLE1CHAR'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%val3))  deallocate(eclass%val3)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2dble1char
!
subroutine free_eclass_2dble3inte(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_2dble3inte
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_2dble3inte_t), intent(inout) :: eclass
  logical,                   intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>2DBLE3INTE'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val1))  return
  !
  eclass%nval = 0
  if (associated(eclass%val1))  deallocate(eclass%val1)
  if (associated(eclass%val2))  deallocate(eclass%val2)
  if (associated(eclass%val3))  deallocate(eclass%val3)
  if (associated(eclass%val4))  deallocate(eclass%val4)
  if (associated(eclass%val5))  deallocate(eclass%val5)
  if (associated(eclass%cnt))   deallocate(eclass%cnt)
  if (associated(eclass%bak))   deallocate(eclass%bak)
  !
end subroutine free_eclass_2dble3inte
!
subroutine free_eclass_char(eclass,error)
  use gbl_message
  use gmath_interfaces, except_this=>free_eclass_char
  use eclass_types
  !---------------------------------------------------------------------
  ! @ public
  !---------------------------------------------------------------------
  type(eclass_char_t), intent(inout) :: eclass
  logical,             intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='FREE>ECLASS>CHAR'
  !
  call gmath_message(seve%t,rname,'Welcome')
  !
  if (.not.associated(eclass%val))  return
  !
  eclass%nval = 0
  if (associated(eclass%val))  deallocate(eclass%val)
  if (associated(eclass%cnt))  deallocate(eclass%cnt)
  if (associated(eclass%bak))  deallocate(eclass%bak)
  !
end subroutine free_eclass_char
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine eclass_getnext(eclass,iclass,ielem,found,error)
  use gbl_message
  use eclass_types
  use gmath_interfaces, except_this=>eclass_getnext
  !---------------------------------------------------------------------
  ! @ public
  !  Utility routine: get the index of the next element which is in the
  ! iclass-th class.
  !---------------------------------------------------------------------
  class(eclass_common_t), intent(in)    :: eclass  ! The equivalence classes
  integer(kind=4),        intent(in)    :: iclass  ! The ith equivalence class we search into
  integer(kind=4),        intent(inout) :: ielem   ! Starting point (can be 0) and next (output) value found
  logical,                intent(out)   :: found   ! Found a new element?
  logical,                intent(inout) :: error   ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='ECLASS>GET>NEXT'
  integer(kind=4) :: ival
  !
  if (iclass.le.0 .or. iclass.gt.eclass%nequ) then
    call gmath_message(seve%e,rname,'Invalid class number')
    error = .true.
    return
  endif
  !
  found = .false.
  do ival=ielem+1,eclass%nval
    if (eclass%bak(ival).eq.iclass) then
      ielem = ival
      found = .true.
      return
    endif
  enddo
  !
end subroutine eclass_getnext
!
subroutine eclass_getprev(eclass,iclass,ielem,found,error)
  use gbl_message
  use eclass_types
  use gmath_interfaces, except_this=>eclass_getprev
  !---------------------------------------------------------------------
  ! @ public
  !  Utility routine: get the index of the previous element which is in
  ! the iclass-th class.
  !---------------------------------------------------------------------
  class(eclass_common_t), intent(in)    :: eclass  ! The equivalence classes
  integer(kind=4),        intent(in)    :: iclass  ! The ith equivalence class we search into
  integer(kind=4),        intent(inout) :: ielem   ! Starting point (can be N+1) and previous (output) value found
  logical,                intent(out)   :: found   ! Found a new element?
  logical,                intent(inout) :: error   ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='ECLASS>GET>PREV'
  integer(kind=4) :: ival
  !
  if (iclass.le.0 .or. iclass.gt.eclass%nequ) then
    call gmath_message(seve%e,rname,'Invalid class number')
    error = .true.
    return
  endif
  !
  found = .false.
  do ival=ielem-1,1,-1
    if (eclass%bak(ival).eq.iclass) then
      ielem = ival
      found = .true.
      return
    endif
  enddo
  !
end subroutine eclass_getprev
