public Map<String, VProperty> getPropertiesMap(boolean includePrimaryType) {
    Map<String, VProperty> propertiesMap = new HashMap<String, VProperty>();
    for (Map.Entry<String, VPropertyDefinitionI> entry : properties.entrySet()) {
      // TODO: Replace with VProperty Factory
      VProperty newProp =
          new XMLProperty(name, entry.getValue().getDefaultValue(), AbstractProperty.STRING_PREFIX);
      propertiesMap.put(entry.getKey(), newProp);
    }
    if (includePrimaryType) {
      propertiesMap.put(
          AbstractProperty.JCR_PRIMARYTYPE,
          new XMLProperty(AbstractProperty.JCR_PRIMARYTYPE, name, AbstractProperty.STRING_PREFIX));
    }

    // also get supertype properties
    for (String supertype : supertypes) {
      VNodeDefinition vNodeDefinition = VNodeDefinition.getDefinition(supertype);
      if (vNodeDefinition != null) propertiesMap.putAll(vNodeDefinition.getPropertiesMap(false));
      else {
        log.error("Could not get definition for " + supertype);
      }
    }

    return propertiesMap;
  }
  public JCRItemWrapper getItem(String path, final boolean checkVersion)
      throws PathNotFoundException, RepositoryException {
    if (sessionCacheByPath.containsKey(path)) {
      return sessionCacheByPath.get(path);
    }
    if (path.contains(DEREF_SEPARATOR)) {
      JCRNodeWrapper parent =
          (JCRNodeWrapper)
              getItem(StringUtils.substringBeforeLast(path, DEREF_SEPARATOR), checkVersion);
      return dereference(parent, StringUtils.substringAfterLast(path, DEREF_SEPARATOR));
    }
    Map<String, JCRStoreProvider> dynamicMountPoints = sessionFactory.getDynamicMountPoints();
    for (Map.Entry<String, JCRStoreProvider> mp : dynamicMountPoints.entrySet()) {
      if (path.startsWith(mp.getKey() + "/")) {
        String localPath = path.substring(mp.getKey().length());
        JCRStoreProvider provider = mp.getValue();
        Item item = getProviderSession(provider).getItem(provider.getRelativeRoot() + localPath);
        if (item.isNode()) {
          return provider.getNodeWrapper((Node) item, localPath, null, this);
        } else {
          return provider.getPropertyWrapper((Property) item, this);
        }
      }
    }
    Map<String, JCRStoreProvider> mountPoints = sessionFactory.getMountPoints();
    for (Map.Entry<String, JCRStoreProvider> mp : mountPoints.entrySet()) {
      String key = mp.getKey();
      if (key.equals("/") || path.equals(key) || path.startsWith(key + "/")) {
        String localPath = path;
        if (!key.equals("/")) {
          localPath = localPath.substring(key.length());
        }
        JCRStoreProvider provider = mp.getValue();
        if (localPath.equals("")) {
          localPath = "/";
        }
        //                Item item = getProviderSession(provider).getItem(localPath);
        Session session = getProviderSession(provider);
        if (session instanceof JahiaSessionImpl
            && getUser() != null
            && sessionFactory.getCurrentAliasedUser() != null
            && sessionFactory.getCurrentAliasedUser().equals(getUser())) {
          ((JahiaSessionImpl) session).toggleThisSessionAsAliased();
        }
        Item item = session.getItem(provider.getRelativeRoot() + localPath);
        if (item.isNode()) {
          final Node node = (Node) item;
          JCRNodeWrapper wrapper = provider.getNodeWrapper(node, localPath, null, this);
          if (getUser() != null
              && sessionFactory.getCurrentAliasedUser() != null
              && !sessionFactory.getCurrentAliasedUser().equals(getUser())) {
            final JCRNodeWrapper finalWrapper = wrapper;
            JCRTemplate.getInstance()
                .doExecuteWithUserSession(
                    sessionFactory.getCurrentAliasedUser().getUsername(),
                    getWorkspace().getName(),
                    getLocale(),
                    new JCRCallback<Object>() {
                      public Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
                        return session.getNodeByUUID(finalWrapper.getIdentifier(), checkVersion);
                      }
                    });
          }
          if (checkVersion
              && (versionDate != null || versionLabel != null)
              && node.isNodeType("mix:versionable")) {
            wrapper = getFrozenVersionAsRegular(node, provider);
          }
          sessionCacheByPath.put(path, wrapper);
          sessionCacheByIdentifier.put(wrapper.getIdentifier(), wrapper);

          return wrapper;
        } else {
          return provider.getPropertyWrapper((Property) item, this);
        }
      }
    }
    throw new PathNotFoundException(path);
  }