HashMap<Integer, PSTDescriptorItem> getPSTDescriptorItems(PSTNodeInputStream in)
      throws PSTException, IOException {
    // make sure the signature is correct
    in.seek(0);
    int sig = in.read();
    if (sig != 0x2) {
      throw new PSTException("Unable to process descriptor node, bad signature: " + sig);
    }

    HashMap<Integer, PSTDescriptorItem> output = new HashMap<Integer, PSTDescriptorItem>();
    int numberOfItems = (int) in.seekAndReadLong(2, 2);
    int offset;
    if (this.getPSTFileType() == PSTFile.PST_TYPE_ANSI) {
      offset = 4;
    } else {
      offset = 8;
    }

    byte[] data = new byte[(int) in.length()];
    in.seek(0);
    in.read(data);

    for (int x = 0; x < numberOfItems; x++) {
      PSTDescriptorItem item = new PSTDescriptorItem(data, offset, this);
      output.put(item.descriptorIdentifier, item);
      if (this.getPSTFileType() == PSTFile.PST_TYPE_ANSI) {
        offset += 12;
      } else {
        offset += 24;
      }
    }

    return output;
  }
  /**
   * read the name-to-id map from the file and load it in
   *
   * @param in
   * @throws IOException
   * @throws PSTException
   */
  private void processNameToIdMap(RandomAccessFile in) throws IOException, PSTException {
    // Create our guid map
    for (int i = 0; i < guidStrings.length; ++i) {
      UUID uuid = UUID.fromString(guidStrings[i]);
      guidMap.put(uuid, i);
      /*
      			System.out.printf("guidMap[{%s}] = %d\n", uuid.toString(), i);
      /**/
    }

    // process the name to id map
    DescriptorIndexNode nameToIdMapDescriptorNode = (getDescriptorIndexNode(97));
    // nameToIdMapDescriptorNode.readData(this);

    // get the descriptors if we have them
    HashMap<Integer, PSTDescriptorItem> localDescriptorItems = null;
    if (nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier != 0) {
      // PSTDescriptor descriptor = new PSTDescriptor(this,
      // nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier);
      // localDescriptorItems = descriptor.getChildren();
      localDescriptorItems =
          this.getPSTDescriptorItems(
              nameToIdMapDescriptorNode.localDescriptorsOffsetIndexIdentifier);
    }

    // process the map
    // PSTTableBC bcTable = new PSTTableBC(nameToIdMapDescriptorNode.dataBlock.data,
    // nameToIdMapDescriptorNode.dataBlock.blockOffsets);
    OffsetIndexItem off =
        this.getOffsetIndexNode(nameToIdMapDescriptorNode.dataOffsetIndexIdentifier);
    PSTNodeInputStream nodein = new PSTNodeInputStream(this, off);
    byte[] tmp = new byte[1024];
    nodein.read(tmp);
    PSTTableBC bcTable = new PSTTableBC(nodein);

    HashMap<Integer, PSTTableBCItem> tableItems = (bcTable.getItems());
    // Get the guids
    PSTTableBCItem guidEntry = tableItems.get(2); // PidTagNameidStreamGuid
    guids = getData(guidEntry, localDescriptorItems);
    int nGuids = guids.length / 16;
    UUID[] uuidArray = new UUID[nGuids];
    int[] uuidIndexes = new int[nGuids];
    int offset = 0;
    for (int i = 0; i < nGuids; ++i) {
      long mostSigBits =
          (PSTObject.convertLittleEndianBytesToLong(guids, offset, offset + 4) << 32)
              | (PSTObject.convertLittleEndianBytesToLong(guids, offset + 4, offset + 6) << 16)
              | PSTObject.convertLittleEndianBytesToLong(guids, offset + 6, offset + 8);
      long leastSigBits = PSTObject.convertBigEndianBytesToLong(guids, offset + 8, offset + 16);
      uuidArray[i] = new UUID(mostSigBits, leastSigBits);
      if (guidMap.containsKey(uuidArray[i])) {
        uuidIndexes[i] = guidMap.get(uuidArray[i]);
      } else {
        uuidIndexes[i] = -1; // We don't know this guid
      }
      /*
      			System.out.printf("uuidArray[%d] = {%s},%d\n", i, uuidArray[i].toString(), uuidIndexes[i]);
      /**/
      offset += 16;
    }

    // if we have a reference to an internal descriptor
    PSTTableBCItem mapEntries = tableItems.get(3); //
    byte[] nameToIdByte = getData(mapEntries, localDescriptorItems);

    // process the entries
    for (int x = 0; x + 8 < nameToIdByte.length; x += 8) {
      int dwPropertyId = (int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x, x + 4);
      int wGuid = (int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x + 4, x + 6);
      int wPropIdx = ((int) PSTObject.convertLittleEndianBytesToLong(nameToIdByte, x + 6, x + 8));
      if ((wGuid & 0x0001) == 0) {
        wPropIdx += 0x8000;
        wGuid >>= 1;
        int guidIndex;
        if (wGuid == 1) {
          guidIndex = PS_MAPI;
        } else if (wGuid == 2) {
          guidIndex = PS_PUBLIC_STRINGS;
        } else {
          guidIndex = uuidIndexes[wGuid - 3];
        }
        nameToId.put((long) dwPropertyId | ((long) guidIndex << 32), wPropIdx);
        idToName.put(wPropIdx, (long) dwPropertyId);
        /*
        				System.out.printf("0x%08X:%04X, 0x%08X\n", dwPropertyId, guidIndex, wPropIdx);
        /**/
      }
      // else the identifier is a string
    }
  }