public Object retrieveView(
      ResourceStore store, ResourceStoreRequest request, StorageItem item, Request req)
      throws IOException {
    RepositoryItemUid itemUid = null;

    if (item == null) {
      if (store instanceof RepositoryRouter) {
        RepositoryRouter repositoryRouter = (RepositoryRouter) store;
        // item is either not present or is not here yet (remote index)
        // the we can "simulate" what route would be used to get it, and just get info from the
        // route
        RequestRoute route;

        try {
          route = repositoryRouter.getRequestRouteForRequest(request);
        } catch (ItemNotFoundException e) {
          // this is thrown while getting routes for any path "outside" of legal ones is given
          // like /content/foo/bar, since 2nd pathelem may be "repositories", "groups", "shadows",
          // etc
          // (depends on
          // type of registered reposes)
          return null;
        }

        // request would be processed by targeted repository
        Repository itemRepository = route.getTargetedRepository();

        // create an UID against that repository
        itemUid = itemRepository.createUid(route.getRepositoryPath());
      } else if (store instanceof Repository) {
        itemUid = ((Repository) store).createUid(request.getRequestPath());
      } else {
        // this is highly unbelievable, unless Core gets extended by 3rd party
        return null;
      }
    } else {
      itemUid = item.getRepositoryItemUid();

      if ((item instanceof StorageLinkItem) && dereferenceLinks()) {
        // TODO: we may have "deeper" links too! Implement this properly!
        try {
          item =
              repositoryRouter.dereferenceLink(
                  (StorageLinkItem) item,
                  request.isRequestLocalOnly(),
                  request.isRequestRemoteOnly());
        } catch (Exception e) {
          getLogger()
              .warn("Failed to dereference the storagelink " + item.getRepositoryItemUid(), e);

          // leave item unchanged
        }
      }
    }

    // so, we ended with:
    // itemUid is always populated, hence we have Repository and repository path
    // so, item may be null or non-null, if non-null, it may be link

    // check for item not found finally. Those may be allowed in proxy repositories only.
    if (item == null && !processNotFoundItems(itemUid.getRepository())) {
      // return not-applicable. This is not a proxy repository, and the item is not found. Since it
      // is not
      // proxy repo, it will be never cached from remote too, simply, it is not here.
      return null;
    }

    return retrieveView(request, itemUid, item, req);
  }