subroutine individual_energy(x_rung,x_DFA,c_rung,c_DFA,LDA_centered,nEns,wEns,nCC,aCC,nGrid,weight,nBas,AO,dAO, &
                                          T,V,ERI,ENuc,eKS,Pw,rhow,drhow,J,Fx,FxHF,Fc,P,rho,drho,occnum,Cx_choice,doNcentered,Ew)

! Compute unrestricted individual energies as well as excitation energies

  implicit none
  include 'parameters.h'

! Input variables

  integer,intent(in)            :: x_rung,c_rung
  integer,intent(in)            :: x_DFA,c_DFA
  logical,intent(in)            :: LDA_centered
  integer,intent(in)            :: nEns
  double precision,intent(in)   :: wEns(nEns)
  integer,intent(in)            :: nCC
  double precision,intent(in)   :: aCC(nCC,nEns-1)
  integer,intent(in)            :: nGrid
  double precision,intent(in)   :: weight(nGrid)
  integer,intent(in)            :: nBas
  double precision,intent(in)   :: AO(nBas,nGrid)
  double precision,intent(in)   :: dAO(ncart,nBas,nGrid)

  double precision,intent(in)   :: T(nBas,nBas)
  double precision,intent(in)   :: V(nBas,nBas)
  double precision,intent(in)   :: ERI(nBas,nBas,nBas,nBas)
  double precision,intent(in)   :: ENuc

  double precision,intent(in)   :: eKS(nBas,nspin)     
  double precision,intent(in)   :: Pw(nBas,nBas,nspin) 
  double precision,intent(in)   :: rhow(nGrid,nspin)
  double precision,intent(in)   :: drhow(ncart,nGrid,nspin)

  double precision,intent(in)   :: P(nBas,nBas,nspin,nEns)
  double precision,intent(in)   :: rho(nGrid,nspin,nEns)
  double precision,intent(in)   :: drho(ncart,nGrid,nspin,nEns)

  double precision,intent(inout):: J(nBas,nBas,nspin)
  double precision,intent(inout):: Fx(nBas,nBas,nspin)
  double precision,intent(inout):: FxHF(nBas,nBas,nspin)
  double precision,intent(inout):: Fc(nBas,nBas,nspin)
  double precision,intent(in)   :: Ew
  double precision,intent(in)   :: occnum(nBas,nspin,nEns)
  integer,intent(in)            :: Cx_choice
  logical,intent(in)            :: doNcentered


! Local variables

  double precision              :: ET(nspin,nEns)
  double precision              :: EV(nspin,nEns)
  double precision              :: EH(nsp,nEns)
  double precision              :: Ex(nspin,nEns)
  double precision              :: Ec(nsp,nEns)
  double precision              :: LZH(nsp)
  double precision              :: LZx(nspin)
  double precision              :: LZc(nsp)
  double precision              :: Eaux(nspin,nEns) 

  double precision              :: ExDD(nspin,nEns) 
  double precision              :: EcDD(nsp,nEns) 

  double precision              :: OmH(nEns)
  double precision              :: Omx(nEns)
  double precision              :: Omc(nEns)
  double precision              :: Omaux(nEns)                   
  double precision              :: OmxDD(nEns)
  double precision              :: OmcDD(nEns)

  double precision,external     :: trace_matrix

  integer                       :: ispin,iEns,iBas
  double precision,allocatable  :: nEl(:)
  double precision,allocatable  :: kappa(:)

  double precision              :: E(nEns)
  double precision              :: Om(nEns)

  double precision,external     :: electron_number

! Compute scaling factor for N-centered ensembles

  allocate(nEl(nEns),kappa(nEns))

  nEl(:) = 0d0
  do iEns=1,nEns
    do iBas=1,nBas
      do ispin=1,nspin
        nEl(iEns) = nEl(iEns) + occnum(iBas,ispin,iEns) 
      end do
    end do
    kappa(iEns) = nEl(iEns)/nEl(1)
  end do

!------------------------------------------------------------------------
! Kinetic energy
!------------------------------------------------------------------------

  do ispin=1,nspin
    do iEns=1,nEns
        ET(ispin,iEns) = trace_matrix(nBas,matmul(P(:,:,ispin,iEns),T(:,:))) 
    end do
  end do

!------------------------------------------------------------------------
! Potential energy
!------------------------------------------------------------------------

  do iEns=1,nEns
    do ispin=1,nspin
        EV(ispin,iEns) = trace_matrix(nBas,matmul(P(:,:,ispin,iEns),V(:,:)))
    end do
  end do

!------------------------------------------------------------------------
! Individual Hartree energy
!------------------------------------------------------------------------

  LZH(:) = 0d0
  EH(:,:) = 0d0
  call hartree_individual_energy(nBas,nEns,Pw,P,ERI,LZH,EH)

!------------------------------------------------------------------------
! Individual exchange energy
!------------------------------------------------------------------------

  LZx(:) = 0d0
  Ex(:,:) = 0d0
  call exchange_individual_energy(x_rung,x_DFA,LDA_centered,nEns,wEns,nCC,aCC,nGrid,weight,nBas,ERI,  &
                                               Pw,rhow,drhow,P,rho,drho,Cx_choice,doNcentered,LZx,Ex)

!------------------------------------------------------------------------
! Individual correlation energy
!------------------------------------------------------------------------

  LZc(:) = 0d0
  Ec(:,:) = 0d0
  call correlation_individual_energy(c_rung,c_DFA,LDA_centered,nEns,wEns,nGrid,weight, & 
                                                  rhow,drhow,rho,drho,LZc,Ec)

!------------------------------------------------------------------------
! Compute auxiliary energies
!------------------------------------------------------------------------
 
  call auxiliary_energy(nBas,nEns,eKS,occnum,Eaux)

!------------------------------------------------------------------------
! Compute derivative discontinuities
!------------------------------------------------------------------------

  do ispin=1,nspin 
    call exchange_derivative_discontinuity(x_rung,x_DFA,nEns,wEns,nCC,aCC,nGrid,weight, &
                                           rhow(:,ispin),drhow(:,:,ispin),Cx_choice,&
                                           doNcentered,kappa,ExDD(ispin,:))
  end do

  call correlation_derivative_discontinuity(c_rung,c_DFA,nEns,wEns,nGrid,weight,rhow,drhow,EcDD)

! Scaling derivative discontinuity for N-centered ensembles

!  if(doNcentered) then

!     do iEns=1,nEns
!       ExDD(:,iEns) = (1d0 - kappa(iEns))*ExDD(:,iEns)
!       EcDD(:,iEns) = (1d0 - kappa(iEns))*EcDD(:,iEns)
!     end do

!  end if

!------------------------------------------------------------------------
! Total energy
!------------------------------------------------------------------------

  if(doNcentered) then

    do iEns=1,nEns
      E(iEns) = sum(Eaux(:,iEns))                                     & 
              + kappa(iEns)*(sum(LZH(:)) + sum(LZx(:)) + sum(LZc(:))) &
              + sum(ExDD(:,iEns)) + sum(EcDD(:,iEns))
    end do

  else 

    do iEns=1,nEns
      E(iEns) = sum(Eaux(:,iEns))                       & 
              + sum(LZH(:)) + sum(LZx(:)) + sum(LZc(:)) &
              + sum(ExDD(:,iEns)) + sum(EcDD(:,iEns))
    end do

  end if

print*,'LZshift=',sum(LZH(:)) + sum(LZx(:)) + sum(LZc(:))
  
! do iEns=1,nEns
!   E(iEns)   = sum(ET(:,iEns)) + sum(EV(:,iEns))                     & 
!             + sum(EH(:,iEns)) + sum(Ex(:,iEns)) + sum(Ec(:,iEns))   & 
!             + sum(LZH(:)) + sum(LZx(:)) + sum(LZc(:)) &
!             + sum(ExDD(:,iEns)) + sum(EcDD(:,iEns))
! end do

!------------------------------------------------------------------------
! Excitation energies
!------------------------------------------------------------------------

  do iEns=1,nEns

    Om(iEns) = E(iEns) - E(1)

    OmH(iEns)   = sum(EH(:,iEns)) - sum(EH(:,1)) 
    Omx(iEns)   = sum(Ex(:,iEns)) - sum(Ex(:,1))
    Omc(iEns)   = sum(Ec(:,iEns)) - sum(Ec(:,1))

    Omaux(iEns) = sum(Eaux(:,iEns)) - sum(Eaux(:,1))

    OmxDD(iEns) = sum(ExDD(:,iEns)) - sum(ExDD(:,1))
    OmcDD(iEns) = sum(EcDD(:,iEns)) - sum(EcDD(:,1))

  end do

  if(doNcentered) then

    do iEns=1,nEns
      OmH(iEns)   = OmH(iEns) + (kappa(iEns) - kappa(1))*sum(LZH(:))
      Omx(iEns)   = Omx(iEns) + (kappa(iEns) - kappa(1))*sum(LZx(:))
      Omc(iEns)   = Omc(iEns) + (kappa(iEns) - kappa(1))*sum(LZc(:))

      Omaux(iEns) = Omaux(iEns) &
                  + (kappa(iEns) - kappa(1))*(sum(LZH(:)) + sum(LZx(:)) + sum(LZc(:))) 

    end do

  end if

!------------------------------------------------------------------------
! Dump results
!------------------------------------------------------------------------

  call print_individual_energy(nEns,ENuc,Ew,ET,EV,EH,Ex,Ec,Eaux,LZH,LZx,LZc,ExDD,EcDD,E, & 
                                            Om,OmH,Omx,Omc,Omaux,OmxDD,OmcDD)

end subroutine individual_energy
