  !> MUSCL scheme for the euler equation. This kernel handles only cubic
  !! elements.
  subroutine muscl_euler_cube_solver( mesh, equation, kerneldata, statedata, level, &
                                    & elementalTimestep, timestep )
    !--------------------------------------------------------------------------
    !--------------------------------------------------------------------------
    type(cube_elem_type)     :: mesh
    type(euler_type)         :: equation
    type(kerneldata_type)    :: kerneldata
    type(statedata_type)     :: statedata
    integer, intent(in)      :: level
    procedure(elemental_timestep),pointer,intent(in) :: elementalTimestep
    type(timestep_type) :: timestep
    !--------------------------------------------------------------------------!
    integer             :: xside, yside, zside
    integer             :: left_neighbor, right_neighbor
    real(kind=rk)       :: flux_conv(5), flux_rotated(5)
    integer             :: iElem
    !--------------------------------------------------------------------------!

 !calculate fluxes elementwise and update conservative variables
 
do iElem = 1, mesh%descriptor%fluid%nVals

!x-direction
!right side
call calc_hlle_flux( left = kerneldata%state_der(iElem,1,q__E,:), & 
                   & right = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__E, iElem),1,q__W,:), & 
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> no rotation for x-direction
flux_rotated = (flux_conv) / (mesh%length)
!> update conservative variables
call elementalTimestep(timestep, statedata%state, iElem, 1,(-1.0_rk)*flux_rotated)

!left side
call calc_hlle_flux( left = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__W, iElem),1,q__E,:), &  
                   & right = kerneldata%state_der(iElem,1,q__W,:), &
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> no rotation for x-direction
flux_rotated = (flux_conv) / (mesh%length)
!> update conservative variables
call elementalTimestep(timestep, statedata%state, iElem, 1, flux_rotated)

!y-direction
!right side
call calc_hlle_flux( left = kerneldata%state_der(iElem,1,q__N,[1,3,4,2,5]), & 
                   & right = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__N, iElem),1,q__S,[1,3,4,2,5]), & 
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> rotate back the fluxes
      flux_rotated(1) = flux_conv(1)
      flux_rotated(2) = flux_conv(4)
      flux_rotated(3) = flux_conv(2)
      flux_rotated(4) = flux_conv(3)
      flux_rotated(5) = flux_conv(5)
      flux_rotated = flux_rotated / (mesh%length)
!> update conservative variables
call elementalTimestep(timestep, statedata%state, iElem, 1,(-1.0_rk)*flux_rotated)

!left side
call calc_hlle_flux( left = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__S, iElem),1,q__N,[1,3,4,2,5]), &  
                   & right = kerneldata%state_der(iElem,1,q__S,[1,3,4,2,5]), &
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> rotate back the fluxes
      flux_rotated(1) = flux_conv(1)
      flux_rotated(2) = flux_conv(4)
      flux_rotated(3) = flux_conv(2)
      flux_rotated(4) = flux_conv(3)
      flux_rotated(5) = flux_conv(5)
      flux_rotated = flux_rotated / (mesh%length)
!> update conservative variables
call elementalTimestep(timestep, statedata%state, iElem, 1, flux_rotated)

!z-direction
!right side
call calc_hlle_flux( left = kerneldata%state_der(iElem,1,q__T,[1,4,2,3,5]), & 
                   & right = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__T, iElem),1,q__B,[1,4,2,3,5]), & 
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> rotate back the fluxes
      flux_rotated(1) = flux_conv(1)
      flux_rotated(2) = flux_conv(3)
      flux_rotated(3) = flux_conv(4)
      flux_rotated(4) = flux_conv(2)
      flux_rotated(5) = flux_conv(5)
      flux_rotated = flux_rotated / (mesh%length)
!> update conservative variables
call elementalTimestep(timestep, statedata%state, iElem, 1,(-1.0_rk)*flux_rotated)

!left side
call calc_hlle_flux( left = kerneldata%state_der(mesh%descriptor%neigh(1)%nghElems(q__B, iElem),1,q__T,[1,4,2,3,5]), &  
                   & right = kerneldata%state_der(iElem,1,q__B,[1,4,2,3,5]), &
                   & isen_coef = equation%isen_coef,  &  
                   & flux = flux_conv                       ) 
!> rotate back the fluxes
      flux_rotated(1) = flux_conv(1)
      flux_rotated(2) = flux_conv(3)
      flux_rotated(3) = flux_conv(4)
      flux_rotated(4) = flux_conv(2)
      flux_rotated(5) = flux_conv(5)
      flux_rotated = flux_rotated / (mesh%length)
call elementalTimestep(timestep, statedata%state, iElem, 1, flux_rotated)

end do


!    !> calculate fluxes over sides and update conservative variables
!    do xside = 1, mesh%side%xdir%nsides
!      !
!      left_neighbor  = mesh%side%xdir%left_elemid(xside)
!      right_neighbor = mesh%side%xdir%right_elemid(xside)
!
!      !> calculate the convective flux
!      call calc_hlle_flux( left  = kerneldata%state_der(left_neighbor,1,q__E,:),  &  ! in
!                      right = kerneldata%state_der(right_neighbor,1,q__W,:), &  ! in
!                      isen_coef = equation%isen_coef,  &  ! in
!                      flux = flux_conv                       )  ! out
!
!      !> no rotation for x-direction
!      flux_rotated = (flux_conv) / (mesh%length)
!      !flux_rotated = (flux_conv) * scheme%time%dt / (mesh%length)
!      !
!      !> update conservative variables
!      call elementalTimestep(timestep, statedata%state, left_neighbor, 1,(-1.0_rk)*flux_rotated)
!      call elementalTimestep(timestep, statedata%state, right_neighbor, 1, flux_rotated)
!      !statedata%state(left_neighbor,1,:) = &
!      !statedata%state(left_neighbor,1,:) - flux_rotated
!      !statedata%state(right_neighbor,1,:) = &
!      !statedata%state(right_neighbor,1,:) + flux_rotated
!      !
!    enddo !xside
!
!    do yside = 1, mesh%side%ydir%nsides
!      !
!      left_neighbor  = mesh%side%ydir%left_elemid(yside)
!      right_neighbor = mesh%side%ydir%right_elemid(yside)
!
!      !> calculate the convective flux
!!> \todo use rotation of variables here!
!      call calc_hlle_flux(left  = kerneldata%state_der(left_neighbor, 1, q__N,[1,3,4,2,5]),  & ! in
!                     right = kerneldata%state_der(right_neighbor,1, q__S ,[1,3,4,2,5]), & ! in
!                     isen_coef = equation%isen_coef,            & ! in
!                     flux = flux_conv                                 ) ! out
!      !> rotate back the fluxes
!      flux_rotated(1) = flux_conv(1)
!      flux_rotated(2) = flux_conv(4)
!      flux_rotated(3) = flux_conv(2)
!      flux_rotated(4) = flux_conv(3)
!      flux_rotated(5) = flux_conv(5)
!      !
!      flux_rotated = flux_rotated / (mesh%length)
!      !flux_rotated = flux_rotated * scheme%time%dt / (mesh%length)
!      !
!
!      !> update conservative variables
!      call elementalTimestep(timestep, statedata%state, left_neighbor, 1,(-1.0_rk)*flux_rotated)
!      call elementalTimestep(timestep, statedata%state, right_neighbor, 1, flux_rotated)
!      !statedata%state(left_neighbor,1,:) = &
!      !statedata%state(left_neighbor,1,:) - flux_rotated
!      !statedata%state(right_neighbor,1,:) = &
!      !statedata%state(right_neighbor,1,:) + flux_rotated
!      !
!    enddo !yside
!
!    do zside = 1, mesh%side%zdir%nsides
!      !
!      left_neighbor  = mesh%side%zdir%left_elemid(zside)
!      right_neighbor = mesh%side%zdir%right_elemid(zside)
!
!      !> calculate the convective flux
!!> \todo use rotation of variables here!
!      call calc_hlle_flux(left  = kerneldata%state_der(left_neighbor,1,q__T,[1,4,2,3,5]),  & ! in
!                     right = kerneldata%state_der(right_neighbor,1,q__B,[1,4,2,3,5]), & ! in
!                     isen_coef = equation%isen_coef,            & ! in
!                     flux = flux_conv                                 ) ! out
!
!      !> rotate back the fluxes
!      flux_rotated(1) = flux_conv(1)
!      flux_rotated(2) = flux_conv(3)
!      flux_rotated(3) = flux_conv(4)
!      flux_rotated(4) = flux_conv(2)
!      flux_rotated(5) = flux_conv(5)
!
!      !
!      flux_rotated = flux_rotated / (mesh%length)
!      !flux_rotated = flux_rotated * scheme%time%dt / (mesh%length)
!      !
!
!      !> update conservative variables
!      call elementalTimestep(timestep, statedata%state, left_neighbor, 1,(-1.0_rk)*flux_rotated)
!      call elementalTimestep(timestep, statedata%state, right_neighbor, 1, flux_rotated)
!      !statedata%state(left_neighbor,1,:) = &
!      !statedata%state(left_neighbor,1,:) - flux_rotated
!      !statedata%state(right_neighbor,1,:) = &
!      !statedata%state(right_neighbor,1,:) + flux_rotated
!      !
!    enddo !zside
!    !
  end subroutine muscl_euler_cube_solver
