/**
  * invalidates the item
  *
  * @param id
  * @param recursive
  */
 public void invalidateItem(ItemId id, boolean recursive) {
   VirtualNodeState state = id.equals(rootNodeId) ? root : (VirtualNodeState) nodes.get(id);
   if (state != null) {
     if (recursive) {
       VirtualPropertyState[] props = state.getProperties();
       for (int i = 0; i < props.length; i++) {
         props[i].notifyStateUpdated();
       }
       for (ChildNodeEntry pe : state.getChildNodeEntries()) {
         invalidateItem(pe.getId(), true);
       }
     }
     state.notifyStateUpdated();
   }
 }
 /**
  * Recursively discards all the properties and nodes in the subtree rooted at the given node
  * state.
  *
  * @param state root of the subtree to be discarded
  */
 private void discardTree(NodeState state) {
   for (Name name : state.getPropertyNames()) {
     try {
       getItemState(new PropertyId(state.getNodeId(), name)).discard();
     } catch (ItemStateException e) {
       log.warn("Unable to discard virtual property " + name, e);
     }
   }
   for (ChildNodeEntry entry : state.getChildNodeEntries()) {
     try {
       discardTree((NodeState) getItemState(entry.getId()));
     } catch (ItemStateException e) {
       log.warn("Unable to discard virtual node " + entry.getId(), e);
     }
   }
   state.discard();
 }