subroutine compare_bundle(State1,State2,tol,rc)
type(ESMF_FieldBundle), intent(inout) :: State1
type(ESMF_FieldBundle), intent(inout) :: State2
real, intent(in) :: tol
integer, optional, intent(out) :: rc
integer :: status
integer :: ii,i,j,k
real, pointer :: ptr3_1(:,:,:) => null()
real, pointer :: ptr3_2(:,:,:) => null()
real, pointer :: ptr2_1(:,:) => null()
real, pointer :: ptr2_2(:,:) => null()
integer :: itemcount,rank1,rank2,lb(3),ub(3)
character(len=ESMF_MAXSTR), allocatable :: NameList(:)
logical, allocatable :: foundDiff(:)
type(ESMF_Field) :: Field1,Field2
call ESMF_FieldBundleGet(State1,fieldcount=itemCount,_RC)
allocate(NameList(itemCount),_STAT)
allocate(foundDiff(itemCount),_STAT)
call ESMF_FieldBundleGet(State1,fieldNameList=NameList,_RC)
do ii=1,itemCount
call ESMF_FieldBundleGet(State1,trim(nameList(ii)),field=field1,_RC)
call ESMF_FieldBundleGet(State2,trim(nameList(ii)),field=field2,_RC)
call ESMF_FieldGet(field1,rank=rank1,_RC)
call ESMF_FieldGet(field1,rank=rank2,_RC)
_ASSERT(rank1==rank2,'needs informative message')
foundDiff(ii)=.false.
if (rank1==2) then
call ESMF_FieldGet(field1,farrayPtr=ptr2_1,_RC)
call ESMF_FieldGet(field2,farrayPtr=ptr2_2,_RC)
do i=1,size(ptr2_1,1)
do j=1,size(ptr2_1,2)
if (abs(ptr2_1(i,j)-ptr2_2(i,j)) .gt. tol) then
foundDiff(ii)=.true.
exit
end if
enddo
enddo
else if (rank1==3) then
call ESMF_FieldGet(field1,farrayPtr=ptr3_1,_RC)
call ESMF_FieldGet(field2,farrayPtr=ptr3_2,_RC)
lb=lbound(ptr3_1)
ub=ubound(ptr3_1)
do i=1,size(ptr3_1,1)
do j=1,size(ptr3_1,2)
do k=lb(3),ub(3)
if (abs(ptr3_1(i,j,k)-ptr3_2(i,j,k)) .gt. tol) then
foundDiff(ii)=.true.
exit
end if
enddo
enddo
enddo
end if
if (foundDiff(ii)) then
_FAIL('found difference when compare state')
end if
enddo
_RETURN(ESMF_SUCCESS)
end subroutine compare_bundle