I seriously don't know how this ever could have worked correctly...
We'll start by seeing that all tags that are associated with a language can not be reached, because they are stored in $lookup[$language][$view], but lookup later is only done on $lookup[$view]. So we are correcting this in a way that all tags are first of all associated with a language and then with a view. (See $lookup[$lang][$view])
Then we see that whatever we do, we override the caching of the lookup in line 151 anyway, so we can shorten that code tremendously.
Further we see that in line 159 the $language of the needles is overwritten with the $language from one random menu entry. This is done exactly once and not used thereafter, except that further cache lookups are stored as that $language. Since all this has no use anyway, we can simply remove this. (For reference, that parameter should somehow filter by language, but that is not the task of this class. That filtering has to be done earlier in the model.)
Last but not least, we are doing the lookup by both the view and the language.
This whole PR does not adress the fact that it does not support menu items with more than one tag, that there is only one view that it is checked against, that there is no fallback to the tags view, that _findItem() is only used in one method and thus completely unnecessary and could simply be merged into getTagRoute() and that it is doing A LOT of additional work that simply is not necessary. But at least this way it is a lot more correct and its behavior is more deterministically than before.
No testing instructions from me so far, since I found this during a code review. Asking a maintainer to review this.
We have some SEO issues with tags (like before).
I have also changed the title of the tag for signle tag view from H2 to H1.
Regarding 1): That is the same behavior as before.
The thing is, that this fixes a bunch of simple programming mistakes... This still needs a code review.