! Demonstrates a bug with the XE integration with Visual Studio 2005
! most likely related to the OMP preprocessor

    SUBROUTINE ArrayBug()

    USE OMP_lib !**PARALLEL

    IMPLICIT NONE

    INTEGER, PARAMETER :: nRadii=4000
    INTEGER :: iRadius

    REAL(8), DIMENSION(0:10001,28) :: CmTentative
    REAL(8), DIMENSION(:,:), ALLOCATABLE, TARGET :: GShared
    REAL(8), DIMENSION(:), ALLOCATABLE, TARGET :: ZShared,YShared,XtShared,CpShared
    REAL(8), DIMENSION(:,:), POINTER :: G
    REAL(8), DIMENSION(:), POINTER :: Z,Y,Xt,Cp
    INTEGER :: allocationStatus

    INTEGER :: iSpecies

    LOGICAL :: inParallel
    INTEGER :: iParallel,debugThrInfo,iThread,maxThreads


! Allocate the arrays needed for solving the tri-diagonal system
    maxThreads=OMP_GET_MAX_THREADS()
    ALLOCATE( GShared(nRadii,3*maxThreads),STAT=allocationStatus)
    ALLOCATE(XtShared(nRadii*maxThreads),  STAT=allocationStatus)
    ALLOCATE( YShared(nRadii*maxThreads),  STAT=allocationStatus)
    ALLOCATE( ZShared(nRadii*maxThreads),  STAT=allocationStatus)
    ALLOCATE(CpShared(nRadii*maxThreads),  STAT=allocationStatus)

!Testing for debug
    DO iThread=1,maxThreads
        DO iRadius=1,nRadii
            XtShared((iThread-1)*nRadii+iRadius)=(100+iThread)*1d5+iRadius
            YShared( (iThread-1)*nRadii+iRadius)=(200+iThread)*1d5+iRadius
            ZShared( (iThread-1)*nRadii+iRadius)=(300+iThread)*1d5+iRadius
            CpShared((iThread-1)*nRadii+iRadius)=(400+iThread)*1d5+iRadius
            GShared(iRadius,(iThread-1)*3+1)=(5100+iThread)*1d5+iRadius
            GShared(iRadius,(iThread-1)*3+2)=(5200+iThread)*1d5+iRadius
            GShared(iRadius,(iThread-1)*3+3)=(5300+iThread)*1d5+iRadius
        END DO
    END DO

    ! CpShared correct in debugger windows
    CpShared=-2
    CpShared(1)=7.89 ! use these to get correct addresses

    ! CmTentative wrong in debugger windows
    CmTentative=-1
    CmTentative(0,1)=1.23
    CmTentative(2,3)=4.56
!** Set breakpoint here, and examine CmTentative using datatips, watch, or quickwatch.
!** Try typing "CmTentative" into memory window.
!** To get actual address of CmTentative, step thru disassembled code

    DO iSpecies=1,3
        CmTentative(1:nRadii,iSpecies)=iSpecies
    END DO
    DO iSpecies=1,3
        iThread=MOD((iSpecies-1),2)
        Cp => CpShared(iThread*nRadii+1:(iThread+1)*nRadii)
        CmTentative(1:nRadii,iSpecies)=Cp(1:nRadii)
    END DO
!End testing

!** If the following OMP parallel region is removed, there is no problem.
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO PRIVATE(iSpecies,iRadius,iThread,inParallel,iParallel,debugThrInfo,Xt,Y,Z,Cp,G)

L_Spec3:        DO iSpecies=1,3
                    iThread=OMP_GET_THREAD_NUM() ! these are numbered 0,1,...,maxThreads-1
                    
                    ! Point to the correct parts of the shared arrays
                    G  => GShared (1:nRadii,iThread*3+1:(iThread+1)*3)
                    Xt => XtShared(iThread*nRadii+1:(iThread+1)*nRadii)
                    Y  => YShared (iThread*nRadii+1:(iThread+1)*nRadii)
                    Z  => ZShared (iThread*nRadii+1:(iThread+1)*nRadii)
                    Cp => CpShared(iThread*nRadii+1:(iThread+1)*nRadii)


                END DO L_Spec3
!$OMP END DO
!$OMP END PARALLEL

    ! Return the allocated memory
    IF(ALLOCATED(GShared)) THEN
        DEALLOCATE(GShared)
    END IF
    IF(ALLOCATED(XtShared)) THEN
        DEALLOCATE(XtShared)
    END IF
    IF(ALLOCATED(YShared)) THEN
        DEALLOCATE(YShared)
    END IF
    IF(ALLOCATED(ZShared)) THEN
        DEALLOCATE(ZShared)
    END IF
    IF(ALLOCATED(CpShared)) THEN
        DEALLOCATE(CpShared)
    END IF

    RETURN
    END
