I am working on generalizing DMRG, for which only the 2-site version is currently supported, to a generalized n-site DMRG. I opened a pull request for it here (https://github.com/ITensor/ITensors.jl/pull/434), and it passes all of the provided tests. But I later realized that it still throws an error if one tries to call DMRG with an MPS vector as an input (i.e. if one is trying to compute excited states, as opposed to just the ground state). After examining the error messages and scouring the repository for a while, I am now fairly certain that the issue is that I have yet to adapt the following function, which appears in ITensors.jl/src/mps/projmps.jl:

```
function product(P::ProjMPS,
v::ITensor)::ITensor
if nsite(P) != 2
error("Only two-site ProjMPS currently supported")
end
Lpm = dag(prime(P.M[P.lpos+1],"Link"))
!isnothing(lproj(P)) && (Lpm *= lproj(P))
Rpm = dag(prime(P.M[P.rpos-1],"Link"))
!isnothing(rproj(P)) && (Rpm *= rproj(P))
pm = Lpm*Rpm
pv = scalar(pm*v)
Mv = pv*dag(pm)
return noprime(Mv)
end
```

I understand that this function multiplies a ProjMPS object and an ITensor object, and that there is a similar function "product(P::ProjMPS, v::ITensor)::ITensor" in ITensors.jl/src/mps/projmpo_mps.jl that calls this first one repeatedly. I also understand that this ultimately works in service of adding a penalizing term w|psi><psi| to the Hamiltonian for some weight w and MPS |psi>. However, I am generally finding this method itself very hard to parse. Would it be possible to get a simple explanation of what this method is really doing, as well as an explanation of what would need to be changed to adapt this to n-site DMRG (and how hard you expect this to be)?