PsiFile (@NotNull DocumentWindowImpl newDocumentWindow, @NotNull PsiFile newInjectedPsi, @NotNull Place shreds, @NotNull PsiFile hostPsiFile, @NotNull PsiDocumentManager documentManager) { List<DocumentWindow> injected = InjectedLanguageUtilBase.getCachedInjectedDocuments(hostPsiFile); for (int i = injected.size()-1; i>=0; i--) { DocumentWindowImpl oldDocument = (DocumentWindowImpl)injected.get(i); PsiFileImpl oldFile = (PsiFileImpl)documentManager.getCachedPsiFile(oldDocument); FileViewProvider viewProvider; if (oldFile == null || !oldFile.isValid() || !((viewProvider = oldFile.getViewProvider()) instanceof InjectedFileViewProvider) || ((InjectedFileViewProvider)viewProvider).isDisposed() ) { injected.remove(i); Disposer.dispose(oldDocument); continue; } ASTNode newInjectedNode = newInjectedPsi.getNode(); ASTNode oldFileNode = oldFile.getNode(); assert newInjectedNode != null : "New node is null"; if (oldDocument.areRangesEqual(newDocumentWindow)) { if (oldFile.getFileType() != newInjectedPsi.getFileType() || oldFile.getLanguage() != newInjectedPsi.getLanguage()) { injected.remove(i); Disposer.dispose(oldDocument); continue; } oldFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, newInjectedPsi.getUserData(FileContextUtil.INJECTED_IN_ELEMENT)); assert shreds.isValid(); mergePsi(oldFile, oldFileNode, newInjectedPsi, newInjectedNode); assert shreds.isValid(); return oldFile; } else if (intersect(oldDocument, newDocumentWindow)) { injected.remove(i); // injected fragments should not overlap. In the End, there can be only one. } } injected.add(newDocumentWindow); return newInjectedPsi; }