@Nullable
 protected <E extends PsiElement> E getStubOrPsiParentOfType(final Class<E> parentClass) {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return (E) stub.getParentStubOfType(parentClass);
   }
   return PsiTreeUtil.getParentOfType(this, parentClass);
 }
 @Nullable
 protected PsiElement getStubOrPsiParent() {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return stub.getParentStub().getPsi();
   }
   return getParent();
 }
 @Override
 public PsiElement getContext() {
   T stub = myStub;
   if (stub != null) {
     if (!(stub instanceof PsiFileStub)) {
       return stub.getParentStub().getPsi();
     }
   }
   return super.getContext();
 }
 public <Psi extends PsiElement> Psi[] getStubOrPsiChildren(TokenSet filter, ArrayFactory<Psi> f) {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return (Psi[]) stub.getChildrenByType(filter, f);
   } else {
     final ASTNode[] nodes = getNode().getChildren(filter);
     Psi[] psiElements = f.create(nodes.length);
     for (int i = 0; i < nodes.length; i++) {
       psiElements[i] = (Psi) nodes[i].getPsi();
     }
     return psiElements;
   }
 }
 public <Psi extends PsiElement> Psi[] getStubOrPsiChildren(TokenSet filter, Psi[] array) {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return (Psi[]) stub.getChildrenByType(filter, array);
   } else {
     final ASTNode[] nodes = getNode().getChildren(filter);
     Psi[] psiElements =
         (Psi[]) Array.newInstance(array.getClass().getComponentType(), nodes.length);
     for (int i = 0; i < nodes.length; i++) {
       psiElements[i] = (Psi) nodes[i].getPsi();
     }
     return psiElements;
   }
 }
 public <Stub extends StubElement, Psi extends PsiElement> Psi[] getStubOrPsiChildren(
     final IStubElementType<Stub, Psi> elementType, ArrayFactory<Psi> f) {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return (Psi[]) stub.getChildrenByType(elementType, f);
   } else {
     final ASTNode[] nodes = SharedImplUtil.getChildrenOfType(getNode(), elementType);
     Psi[] psiElements = f.create(nodes.length);
     for (int i = 0; i < nodes.length; i++) {
       psiElements[i] = (Psi) nodes[i].getPsi();
     }
     return psiElements;
   }
 }
  @Override
  public boolean isValid() {
    T stub = myStub;
    if (stub != null) {
      StubElement parent = stub.getParentStub();
      if (parent == null) {
        LOG.error("No parent for stub " + stub + " of class " + stub.getClass());
        return false;
      }
      PsiElement psi = parent.getPsi();
      return psi != null && psi.isValid();
    }

    return super.isValid();
  }
 public <Stub extends StubElement, Psi extends PsiElement> Psi[] getStubOrPsiChildren(
     final IStubElementType<Stub, Psi> elementType, Psi[] array) {
   T stub = myStub;
   if (stub != null) {
     //noinspection unchecked
     return (Psi[]) stub.getChildrenByType(elementType, array);
   } else {
     final ASTNode[] nodes = SharedImplUtil.getChildrenOfType(getNode(), elementType);
     Psi[] psiElements =
         (Psi[]) Array.newInstance(array.getClass().getComponentType(), nodes.length);
     for (int i = 0; i < nodes.length; i++) {
       psiElements[i] = (Psi) nodes[i].getPsi();
     }
     return psiElements;
   }
 }
 @Nullable
 public <Psi extends PsiElement> Psi getStubOrPsiChild(
     final IStubElementType<? extends StubElement, Psi> elementType) {
   T stub = myStub;
   if (stub != null) {
     final StubElement<Psi> element = stub.findChildStubByType(elementType);
     if (element != null) {
       return element.getPsi();
     }
   } else {
     final ASTNode childNode = getNode().findChildByType(elementType);
     if (childNode != null) {
       return (Psi) childNode.getPsi();
     }
   }
   return null;
 }