diff --git a/tsk3/fs/hfs.c b/tsk3/fs/hfs.c
index 227e7d1b6e868554b62041e0220d5cf5a52bca34..e487848bb0b9afc63bf24c9a8187c9fddea5dde8 100644
--- a/tsk3/fs/hfs.c
+++ b/tsk3/fs/hfs.c
@@ -8,6 +8,8 @@
 ** 14900 Conference Center Drive
 ** Chantilly, VA 20151
 **
+** Copyright (c) 2009 Brian Carrier.  All rights reserved.
+**
 ** Judson Powers [jpowers@atc-nycorp.com]
 ** Copyright (c) 2008 ATC-NY.  All rights reserved.
 ** This file contains data developed with support from the National
@@ -136,7 +138,8 @@ cnid_to_array(uint32_t cnid, uint8_t array[4])
  * fork = 0 and start_block = 0.)
  */
 static int
-hfs_ext_compare_keys(HFS_INFO * hfs, uint32_t cnid, hfs_ext_key * key)
+hfs_ext_compare_keys(HFS_INFO * hfs, uint32_t cnid,
+    hfs_btree_key_ext * key)
 {
     TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
     uint32_t key_cnid;
@@ -164,8 +167,9 @@ hfs_ext_compare_keys(HFS_INFO * hfs, uint32_t cnid, hfs_ext_key * key)
     return 1;
 }
 
+
 /** \internal
- * Returns the length of an HFS+ B-tree key based on the tree header
+ * Returns the length of an HFS+ B-tree INDEX key based on the tree header
  * structure and the length claimed in the record.  With some trees,
  * the length given in the record is not used. 
  * Note that this neither detects nor correctly handles 8-bit keys
@@ -175,20 +179,20 @@ hfs_ext_compare_keys(HFS_INFO * hfs, uint32_t cnid, hfs_ext_key * key)
  * @param header Tree header
  * @returns Length of key
  */
-static uint16_t
-hfs_get_keylen(HFS_INFO * hfs, uint16_t keylen,
-    hfs_btree_header_record * header)
+uint16_t
+hfs_get_idxkeylen(HFS_INFO * hfs, uint16_t keylen,
+    const hfs_btree_header_record * header)
 {
     TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
 
     // if the flag is set, use the length given in the record
-    if (tsk_getu32(fs->endian, header->attr) & HFS_BT_VARKEYS)
+    if (tsk_getu32(fs->endian, header->attr) & HFS_BT_HEAD_ATTR_VARIDXKEYS)
         return keylen;
     else
-        return tsk_getu16(fs->endian, header->max_len);
+        return tsk_getu16(fs->endian, header->maxKeyLen);
 }
 
-
+#if 0
 /** \internal
  * Process a B-Tree node record and return the record contents and the 
  * offset of the data content in the record. 
@@ -225,9 +229,9 @@ hfs_read_key(HFS_INFO * hfs, hfs_btree_header_record * header,
     keylen = tsk_getu16(fs->endian, dest);
     // use the header to figure out if we should be ignoring this length or not
     if (header)
-        keylen = hfs_get_keylen(hfs, keylen, header);
+        keylen = hfs_get_idxkeylen(hfs, keylen, header);
 
-    if ((header && (keylen > tsk_getu16(fs->endian, header->max_len)))
+    if ((header && (keylen > tsk_getu16(fs->endian, header->maxKeyLen)))
         || (!header && (keylen > 516))) {       /* sanity check key length */
         tsk_errno = TSK_ERR_FS_GENFS;
         snprintf(tsk_errstr, TSK_ERRSTR_L,
@@ -249,7 +253,7 @@ hfs_read_key(HFS_INFO * hfs, hfs_btree_header_record * header,
 
     return rec_off + 2 + keylen;        /* return record data address */
 }
-
+#endif
 
 
 /**
@@ -375,7 +379,7 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
     }
 
     /* start at root node */
-    cur_node = tsk_getu32(fs->endian, hfs->extents_header.root);
+    cur_node = tsk_getu32(fs->endian, hfs->extents_header.rootNode);
 
     /* if the root node is zero, then the extents btree is empty */
     /* if no files have overflow extents, the Extents B-tree still
@@ -439,14 +443,14 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
 
         /* With an index node, find the record with the largest key that is smaller
          * to or equal to cnid */
-        if (node_desc->kind == HFS_BTREE_INDEX_NODE) {
+        if (node_desc->type == HFS_BT_NODE_TYPE_IDX) {
             uint32_t next_node = 0;
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 int cmp;
                 size_t rec_off;
-                hfs_ext_key *key;
+                hfs_btree_key_ext *key;
 
                 // get the record offset in the node 
                 rec_off =
@@ -460,7 +464,7 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                     free(node);
                     return 1;
                 }
-                key = (hfs_ext_key *) & node[rec_off];
+                key = (hfs_btree_key_ext *) & node[rec_off];
 
                 cmp = hfs_ext_compare_keys(hfs, cnid, key);
 
@@ -476,19 +480,20 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
 
                 /* save the info from this record unless it is bigger than cnid */
                 if ((cmp <= 0) || (next_node == 0)) {
-                    int keylen = tsk_getu16(fs->endian, key->key_len);
-                    if (rec_off + 2 + keylen > nodesize) {
+                    int keylen =
+                        hfs_get_idxkeylen(hfs, tsk_getu16(fs->endian,
+                            key->key_len) + 2, &(hfs->extents_header));
+                    if (rec_off + keylen > nodesize) {
                         tsk_errno = TSK_ERR_FS_GENFS;
                         snprintf(tsk_errstr, TSK_ERRSTR_L,
                             "hfs_ext_find_extent_record_attr: offset and keylenth of record %d in index node %d too large (%zu vs %"
                             PRIu16 ")", rec, cur_node,
-                            rec_off + 2 + keylen, nodesize);
+                            rec_off + keylen, nodesize);
                         free(node);
                         return 1;
                     }
                     next_node =
-                        tsk_getu32(fs->endian,
-                        &node[rec_off + 2 + keylen]);
+                        tsk_getu32(fs->endian, &node[rec_off + keylen]);
                 }
                 else {
                     // we are bigger than cnid, so move on to the next node
@@ -509,12 +514,12 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
         }
 
         /* with a leaf, we process until we are past cnid.  We move right too if we can */
-        else if (node_desc->kind == HFS_BTREE_LEAF_NODE) {
+        else if (node_desc->type == HFS_BT_NODE_TYPE_LEAF) {
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 size_t rec_off;
-                hfs_ext_key *key;
+                hfs_btree_key_ext *key;
                 uint32_t rec_cnid;
                 hfs_extents *extents;
                 TSK_OFF_T ext_off = 0;
@@ -533,7 +538,7 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                     free(node);
                     return 1;
                 }
-                key = (hfs_ext_key *) & node[rec_off];
+                key = (hfs_btree_key_ext *) & node[rec_off];
 
                 if (tsk_verbose)
                     tsk_fprintf(stderr,
@@ -602,7 +607,7 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                 "hfs_ext_find_extent_record: btree node %" PRIu32
                 " (%" PRIuOFF ") is neither index nor leaf (%" PRIu8 ")",
-                cur_node, cur_off, node_desc->kind);
+                cur_node, cur_off, node_desc->type);
             free(node);
             return 1;
         }
@@ -620,8 +625,8 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
  * @returns -1 if key1 is smaller, 0 if equal, and 1 if key1 is larger
  */
 int
-hfs_cat_compare_keys(HFS_INFO * hfs, hfs_cat_key * key1,
-    hfs_cat_key * key2)
+hfs_cat_compare_keys(HFS_INFO * hfs, hfs_btree_key_cat * key1,
+    hfs_btree_key_cat * key2)
 {
     TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
     uint32_t cnid1, cnid2;
@@ -649,7 +654,7 @@ hfs_cat_compare_keys(HFS_INFO * hfs, hfs_cat_key * key1,
 * record was not found. Check tsk_errno to determine if error occured.
 */
 static TSK_OFF_T
-hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
+hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_btree_key_cat * needle)
 {
     TSK_FS_INFO *fs = &(hfs->fs_info);
     uint32_t cur_node;          /* node id of the current node */
@@ -665,7 +670,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
         return 0;
 
     /* start at root node */
-    cur_node = tsk_getu32(fs->endian, hfs->catalog_header.root);
+    cur_node = tsk_getu32(fs->endian, hfs->catalog_header.rootNode);
 
     /* if the root node is zero, then the extents btree is empty */
     /* if no files have overflow extents, the Extents B-tree still
@@ -728,13 +733,13 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
 
         /* With an index node, find the record with the largest key that is smaller
          * to or equal to cnid */
-        if (node_desc->kind == HFS_BTREE_INDEX_NODE) {
+        if (node_desc->type == HFS_BT_NODE_TYPE_IDX) {
             uint32_t next_node = 0;
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 size_t rec_off;
-                hfs_cat_key *key;
+                hfs_btree_key_cat *key;
 
                 // get the record offset in the node
                 rec_off =
@@ -748,7 +753,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     free(node);
                     return 1;
                 }
-                key = (hfs_cat_key *) & node[rec_off];
+                key = (hfs_btree_key_cat *) & node[rec_off];
 
                 /*
                    if (tsk_verbose)
@@ -762,7 +767,9 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                 /* save the info from this record unless it is bigger than cnid */
                 if ((hfs_cat_compare_keys(hfs, key, needle) <= 0)
                     || (next_node == 0)) {
-                    int keylen = tsk_getu16(fs->endian, key->key_len) + 2;
+                    int keylen =
+                        hfs_get_idxkeylen(hfs, tsk_getu16(fs->endian,
+                            key->key_len) + 2, &(hfs->catalog_header));
                     if (rec_off + keylen > nodesize) {
                         tsk_errno = TSK_ERR_FS_GENFS;
                         snprintf(tsk_errstr, TSK_ERRSTR_L,
@@ -793,12 +800,12 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
         }
 
         /* With a leaf, we look for the specific record. */
-        else if (node_desc->kind == HFS_BTREE_LEAF_NODE) {
+        else if (node_desc->type == HFS_BT_NODE_TYPE_LEAF) {
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 size_t rec_off;
-                hfs_cat_key *key;
+                hfs_btree_key_cat *key;
                 size_t rec_off2;
                 int diff;
 
@@ -814,7 +821,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     free(node);
                     return 0;
                 }
-                key = (hfs_cat_key *) & node[rec_off];
+                key = (hfs_btree_key_cat *) & node[rec_off];
 
                 /*
                    if (tsk_verbose)
@@ -856,7 +863,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                 "hfs_cat_get_record_offset: btree node %" PRIu32
                 " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")",
-                cur_node, cur_off, node_desc->kind);
+                cur_node, cur_off, node_desc->type);
             free(node);
             return 0;
         }
@@ -1019,7 +1026,7 @@ static uint8_t
 hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
 {
     TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
-    hfs_cat_key key;            /* current catalog key */
+    hfs_btree_key_cat key;      /* current catalog key */
     hfs_thread thread;          /* thread record */
     hfs_file_folder record;     /* file/folder record */
     TSK_OFF_T off;
@@ -1046,7 +1053,7 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
     /* first look up the thread record for the item we're searching for */
 
     /* set up the thread record key */
-    memset((char *) &key, 0, sizeof(hfs_cat_key));
+    memset((char *) &key, 0, sizeof(hfs_btree_key_cat));
     cnid_to_array((uint32_t) inum, key.parent_cnid);
 
     /* look up the thread record */
@@ -1067,7 +1074,7 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
     /* now look up the actual file/folder record */
 
     /* build key */
-    memset((char *) &key, 0, sizeof(hfs_cat_key));
+    memset((char *) &key, 0, sizeof(hfs_btree_key_cat));
     memcpy((char *) key.parent_cnid, (char *) thread.parent_cnid,
         sizeof(key.parent_cnid));
     memcpy((char *) &key.name, (char *) &thread.name, sizeof(key.name));
@@ -1128,15 +1135,14 @@ hfs_find_highest_inum(HFS_INFO * hfs)
 {
     // @@@ get actual number from Catalog file (go to far right)
     /* I haven't gotten looking at the end of the Catalog B-Tree to work
-       properly. A fast method: if HFS_BIT_VOLUME_CNIDS_REUSED is set, then
+       properly. A fast method: if HFS_VH_ATTR_CNIDS_REUSED is set, then
        the maximum CNID is 2^32-1; if it's not set, then nextCatalogId is
        supposed to be larger than all CNIDs on disk.
      */
 
     TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
 
-    if (tsk_getu32(fs->endian,
-            hfs->fs->attr) & HFS_BIT_VOLUME_CNIDS_REUSED)
+    if (tsk_getu32(fs->endian, hfs->fs->attr) & HFS_VH_ATTR_CNIDS_REUSED)
         return (TSK_INUM_T) 0xffffffff;
     else
         return (TSK_INUM_T) tsk_getu32(fs->endian,
@@ -2291,9 +2297,9 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
     tsk_fprintf(hFile, "--------------------------------------------\n");
 
     tsk_fprintf(hFile, "File System Signature: ");
-    if (tsk_getu16(fs->endian, hfs->fs->signature) == HFSPLUS_MAGIC)
+    if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_VH_SIG_HFSPLUS)
         tsk_fprintf(hFile, "HFS+\n");
-    else if (tsk_getu16(fs->endian, hfs->fs->signature) == HFSX_MAGIC)
+    else if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_VH_SIG_HFSX)
         tsk_fprintf(hFile, "HFSX\n");
     else
         tsk_fprintf(hFile, "Unknown\n");
@@ -2326,33 +2332,30 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
     tsk_fprintf(hFile, "\n");
 
     tsk_fprintf(hFile, "Volume Identifier: %08" PRIx32 "%08" PRIx32 "\n",
-        tsk_getu32(fs->endian, &(sb->finder_info[24])),
-        tsk_getu32(fs->endian, &(sb->finder_info[28])));
+        tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_ID1]),
+        tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_ID2]));
 
 
     // print last mounted info
     tsk_fprintf(hFile, "\nLast Mounted By: ");
-    if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFSPLUS_MOUNT_VERSION)
+    if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFS_VH_MVER_HFSPLUS)
         tsk_fprintf(hFile, "Mac OS X\n");
-    else if (tsk_getu32(fs->endian,
-            sb->last_mnt_ver) == HFSJ_MOUNT_VERSION)
+    else if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFS_VH_MVER_HFSJ)
         tsk_fprintf(hFile, "Mac OS X, Journaled\n");
-    else if (tsk_getu32(fs->endian, sb->last_mnt_ver) == FSK_MOUNT_VERSION)
+    else if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFS_VH_MVER_FSK)
         tsk_fprintf(hFile, "failed journal replay\n");
-    else if (tsk_getu32(fs->endian,
-            sb->last_mnt_ver) == FSCK_MOUNT_VERSION)
+    else if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFS_VH_MVER_FSCK)
         tsk_fprintf(hFile, "fsck_hfs\n");
-    else if (tsk_getu32(fs->endian,
-            sb->last_mnt_ver) == OS89_MOUNT_VERSION)
+    else if (tsk_getu32(fs->endian, sb->last_mnt_ver) == HFS_VH_MVER_OS89)
         tsk_fprintf(hFile, "Mac OS 8.1 - 9.2.2\n");
     else
         tsk_fprintf(hFile, "Unknown (%" PRIx32 "\n",
             tsk_getu32(fs->endian, sb->last_mnt_ver));
 
     /* State of the file system */
-    if ((tsk_getu32(fs->endian, hfs->fs->attr) & HFS_BIT_VOLUME_UNMOUNTED)
+    if ((tsk_getu32(fs->endian, hfs->fs->attr) & HFS_VH_ATTR_UNMOUNTED)
         && (!(tsk_getu32(fs->endian,
-                    hfs->fs->attr) & HFS_BIT_VOLUME_INCONSISTENT)))
+                    hfs->fs->attr) & HFS_VH_ATTR_INCONSISTENT)))
         tsk_fprintf(hFile, "Volume Unmounted Properly\n");
     else
         tsk_fprintf(hFile, "Volume Unmounted Improperly\n");
@@ -2362,7 +2365,7 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
 
 
     // Dates
-    mac_time = hfs2unixtime(tsk_getu32(fs->endian, hfs->fs->c_date));
+    mac_time = hfs2unixtime(tsk_getu32(fs->endian, hfs->fs->cr_date));
     tsk_fprintf(hFile, "\nCreation Date: \t%s", ctime(&mac_time));
 
     mac_time = hfs2unixtime(tsk_getu32(fs->endian, hfs->fs->m_date));
@@ -2375,12 +2378,11 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
     tsk_fprintf(hFile, "Last Checked Date: \t%s", ctime(&mac_time));
 
 
-    if (tsk_getu32(fs->endian,
-            hfs->fs->attr) & HFS_BIT_VOLUME_SOFTWARE_LOCK)
+    if (tsk_getu32(fs->endian, hfs->fs->attr) & HFS_VH_ATTR_SOFTWARE_LOCK)
         tsk_fprintf(hFile, "Software write protect enabled\n");
 
     /* Print journal information */
-    if (tsk_getu32(fs->endian, sb->attr) & HFS_BIT_VOLUME_JOURNALED) {
+    if (tsk_getu32(fs->endian, sb->attr) & HFS_VH_ATTR_JOURNALED) {
         tsk_fprintf(hFile, "\nJournal Info Block: %" PRIu32 "\n",
             tsk_getu32(fs->endian, sb->jinfo_blk));
     }
@@ -2391,32 +2393,32 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
     tsk_fprintf(hFile, "Range: %" PRIuINUM " - %" PRIuINUM "\n",
         fs->first_inum, fs->last_inum);
 
-    inode = tsk_getu32(fs->endian, &(sb->finder_info[0]));
+    inode = tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_BOOT]);
     tsk_fprintf(hFile, "Bootable Folder ID: %" PRIuINUM, inode);
     if (inode > 0)
         print_inode_file(hFile, fs, inode);
     tsk_fprintf(hFile, "\n");
 
-    inode = tsk_getu32(fs->endian, &(sb->finder_info[4]));
+    inode = tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_START]);
     tsk_fprintf(hFile, "Startup App ID: %" PRIuINUM, inode);
     if (inode > 0)
         print_inode_file(hFile, fs, inode);
     tsk_fprintf(hFile, "\n");
 
-    inode = tsk_getu32(fs->endian, &(sb->finder_info[8]));
+    inode = tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_OPEN]);
     tsk_fprintf(hFile, "Startup Open Folder ID: %" PRIuINUM, inode);
     if (inode > 0)
         print_inode_file(hFile, fs, inode);
     tsk_fprintf(hFile, "\n");
 
-    inode = tsk_getu32(fs->endian, &(sb->finder_info[12]));
+    inode = tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_BOOT9]);
     tsk_fprintf(hFile, "Mac OS 8/9 Blessed System Folder ID: %" PRIuINUM,
         inode);
     if (inode > 0)
         print_inode_file(hFile, fs, inode);
     tsk_fprintf(hFile, "\n");
 
-    inode = tsk_getu32(fs->endian, &(sb->finder_info[20]));
+    inode = tsk_getu32(fs->endian, sb->finder_info[HFS_VH_FI_BOOTX]);
     tsk_fprintf(hFile, "Mac OS X Blessed System Folder ID: %" PRIuINUM,
         inode);
     if (inode > 0)
@@ -2445,7 +2447,7 @@ hfs_fsstat(TSK_FS_INFO * fs, FILE * hFile)
     tsk_fprintf(hFile, "Number of Free Blocks: %" PRIu32 "\n",
         tsk_getu32(fs->endian, sb->free_blks));
 
-    if (tsk_getu32(fs->endian, hfs->fs->attr) & HFS_BIT_VOLUME_BADBLOCKS)
+    if (tsk_getu32(fs->endian, hfs->fs->attr) & HFS_VH_ATTR_BADBLOCKS)
         tsk_fprintf(hFile, "Volume has bad blocks\n");
 
     return 0;
@@ -2531,6 +2533,8 @@ hfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum,
     if (hfs_cat_file_lookup(hfs, inum, &entry) == 0) {
         tsk_fprintf(hFile, "\n");
 
+        /* The cat.perm union contains file-type specific values.
+         * Print them if they are relevant. */
         if ((fs_file->meta->type == TSK_FS_META_TYPE_CHR) ||
             (fs_file->meta->type == TSK_FS_META_TYPE_BLK)) {
             tsk_fprintf(hFile, "Device ID:\t%" PRIu32 "\n",
@@ -2572,6 +2576,7 @@ hfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum,
                 entry.cat.u_info.flags) & HFS_FINDER_FLAG_IS_ALIAS)
             tsk_fprintf(hFile, "Is alias\n");
 
+        // @@@ The tech note has a table that converts nums to encoding names. 
         tsk_fprintf(hFile, "Text encoding:\t%" PRIx32 "\n",
             tsk_getu32(fs->endian, entry.cat.text_enc));
 
@@ -2711,7 +2716,7 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     }
 
     if (hfs_checked_read_random(fs, (char *) hfs->fs, len,
-            (TSK_OFF_T) HFS_SBOFF)) {
+            (TSK_OFF_T) HFS_VH_OFF)) {
         snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_open: superblock");
         fs->tag = 0;
         free(hfs->fs);
@@ -2722,9 +2727,9 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     /*
      * Verify we are looking at an HFS+ image
      */
-    if (tsk_fs_guessu16(fs, hfs->fs->signature, HFSPLUS_MAGIC) &&
-        tsk_fs_guessu16(fs, hfs->fs->signature, HFSX_MAGIC) &&
-        tsk_fs_guessu16(fs, hfs->fs->signature, HFS_MAGIC)) {
+    if (tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFSPLUS) &&
+        tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFSX) &&
+        tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFS)) {
 
         fs->tag = 0;
         free(hfs->fs);
@@ -2738,14 +2743,14 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     /*
      * Handle an HFS-wrapped HFS+ image
      */
-    if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_MAGIC) {
+    if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_VH_SIG_HFS) {
 
         hfs_wrapper_sb *wrapper_sb = (hfs_wrapper_sb *) hfs->fs;
 
         if ((tsk_getu16(fs->endian,
-                    wrapper_sb->drEmbedSigWord) == HFSPLUS_MAGIC)
+                    wrapper_sb->drEmbedSigWord) == HFS_VH_SIG_HFSPLUS)
             || (tsk_getu16(fs->endian,
-                    wrapper_sb->drEmbedSigWord) == HFSX_MAGIC)) {
+                    wrapper_sb->drEmbedSigWord) == HFS_VH_SIG_HFSX)) {
 
             TSK_FS_INFO *fs_info2;
             uint16_t drAlBlSt =
@@ -2872,17 +2877,17 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
         return NULL;
     }
 
-    if (tsk_getu16(fs->endian, hfs->fs->version) == 4)
+    if (tsk_getu16(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSPLUS)
         hfs->is_case_sensitive = 0;
-    else if (tsk_getu16(fs->endian, hfs->fs->version) == 5) {
-        if (hfs->catalog_header.k_type == 0xcf)
+    else if (tsk_getu16(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSX) {
+        if (hfs->catalog_header.compType == HFS_BT_HEAD_COMP_SENS)
             hfs->is_case_sensitive = 0;
-        else if (hfs->catalog_header.k_type == 0xbc)
+        else if (hfs->catalog_header.compType == HFS_BT_HEAD_COMP_INSENS)
             hfs->is_case_sensitive = 1;
         else {
             tsk_fprintf(stderr,
                 "hfs_open: invalid value (0x%02" PRIx8
-                ") for key compare type\n", hfs->catalog_header.k_type);
+                ") for key compare type\n", hfs->catalog_header.compType);
             hfs->is_case_sensitive = 0;
         }
     }
@@ -2898,8 +2903,8 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->inum_count = fs->last_inum + 1;
 
     snprintf((char *) fs->fs_id, 17, "%08" PRIx32 "%08" PRIx32,
-        tsk_getu32(fs->endian, &(hfs->fs->finder_info[24])),
-        tsk_getu32(fs->endian, &(hfs->fs->finder_info[28])));
+        tsk_getu32(fs->endian, hfs->fs->finder_info[HFS_VH_FI_ID1]),
+        tsk_getu32(fs->endian, hfs->fs->finder_info[HFS_VH_FI_ID2]));
     fs->fs_id_used = 16;
 
     /* journal */
diff --git a/tsk3/fs/hfs_dent.c b/tsk3/fs/hfs_dent.c
index d9aaa666c137d511bc8cdcbbb76248c2764367ad..76302c540639c2f3570cbbe21f8b41efa89d5b10 100644
--- a/tsk3/fs/hfs_dent.c
+++ b/tsk3/fs/hfs_dent.c
@@ -8,6 +8,8 @@
 ** 14900 Conference Center Drive
 ** Chantilly, VA 20151
 **
+** Copyright (c) 2009 Brian Carrier.  All rights reserved.
+**
 ** Judson Powers [jpowers@atc-nycorp.com]
 ** Copyright (c) 2008 ATC-NY.  All rights reserved.
 ** This file contains data developed with support from the National
@@ -298,7 +300,7 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
     }
 
     /* start at root node */
-    cur_node = tsk_getu32(fs->endian, hfs->catalog_header.root);
+    cur_node = tsk_getu32(fs->endian, hfs->catalog_header.rootNode);
 
     /* if the root node is zero, then the extents btree is empty */
     /* if no files have overflow extents, the Extents B-tree still
@@ -364,13 +366,13 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
 
         /* With an index node, find the record with the largest key that is smaller
          * to or equal to cnid */
-        if (node_desc->kind == HFS_BTREE_INDEX_NODE) {
+        if (node_desc->type == HFS_BT_NODE_TYPE_IDX) {
             uint32_t next_node = 0;
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 size_t rec_off;
-                hfs_cat_key *key;
+                hfs_btree_key_cat *key;
 
                 // get the record offset in the node
                 rec_off =
@@ -385,7 +387,7 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     free(node);
                     return TSK_COR;
                 }
-                key = (hfs_cat_key *) & node[rec_off];
+                key = (hfs_btree_key_cat *) & node[rec_off];
 
                 if (tsk_verbose)
                     tsk_fprintf(stderr,
@@ -397,7 +399,9 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                 /* save the info from this record unless it is bigger than cnid */
                 if ((tsk_getu32(fs->endian, key->parent_cnid) <= cnid)
                     || (next_node == 0)) {
-                    int keylen = tsk_getu16(fs->endian, key->key_len) + 2;
+                    int keylen =
+                        hfs_get_idxkeylen(hfs, tsk_getu16(fs->endian,
+                            key->key_len) + 2, &(hfs->catalog_header));
                     if (rec_off + keylen > nodesize) {
                         tsk_errno = TSK_ERR_FS_GENFS;
                         snprintf(tsk_errstr, TSK_ERRSTR_L,
@@ -431,12 +435,12 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
         }
 
         /* with a leaf, we process until we are past cnid.  We move right too if we can */
-        else if (node_desc->kind == HFS_BTREE_LEAF_NODE) {
+        else if (node_desc->type == HFS_BT_NODE_TYPE_LEAF) {
             int rec;
 
             for (rec = 0; rec < num_rec; rec++) {
                 size_t rec_off;
-                hfs_cat_key *key;
+                hfs_btree_key_cat *key;
                 uint16_t rec_type;
                 size_t rec_off2;
 
@@ -453,7 +457,7 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     free(node);
                     return TSK_COR;
                 }
-                key = (hfs_cat_key *) & node[rec_off];
+                key = (hfs_btree_key_cat *) & node[rec_off];
 
                 if (tsk_verbose)
                     tsk_fprintf(stderr,
@@ -570,7 +574,7 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                 "hfs_dir_open_meta: btree node %" PRIu32
                 " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")",
-                cur_node, cur_off, node_desc->kind);
+                cur_node, cur_off, node_desc->type);
 
             tsk_fs_name_free(fs_name);
             free(node);
diff --git a/tsk3/fs/tsk_hfs.h b/tsk3/fs/tsk_hfs.h
index f2d2861c8e8d0ecda7797c77132f68f56f3734e3..355e0931a1c582ad382004c2da5f6faf855c22b7 100644
--- a/tsk3/fs/tsk_hfs.h
+++ b/tsk3/fs/tsk_hfs.h
@@ -8,6 +8,8 @@
 ** 14900 Conference Center Drive
 ** Chantilly, VA 20151
 **
+** Copyright (c) 2009 Brian Carrier.  All rights reserved.
+** 
 ** Judson Powers [jpowers@atc-nycorp.com]
 ** Copyright (c) 2008 ATC-NY.  All rights reserved.
 ** This file contains data developed with support from the National
@@ -80,27 +82,8 @@
  * Constants
  */
 
-#define HFS_MAGIC	    0x4244      /* BD in big endian */
-#define HFSPLUS_MAGIC	0x482b  /* H+ in big endian */
-#define HFSX_MAGIC      0x4858  /* HX in big endian */
-
-#define HFSPLUS_VERSION 0x0004  /* all HFS+ volumes are version 4 */
-#define HFSX_VERSION    0x0005  /* HFSX volumes start with version 5 */
-
-#define HFSPLUS_MOUNT_VERSION 0x31302e30        /* '10.0' for Mac OS X */
-#define HFSJ_MOUNT_VERSION    0x4846534a        /* 'HFSJ' for journaled HFS+ on Mac OS X */
-#define FSK_MOUNT_VERSION     0x46534b21        /* 'FSK!' for failed journal replay */
-#define FSCK_MOUNT_VERSION    0x6673636b        /* 'fsck' for fsck_hfs */
-#define OS89_MOUNT_VERSION    0x382e3130        /* '8.10' for Mac OS 8.1-9.2.2 */
-
-#define HFS_SBOFF	1024
 #define HFS_FILE_CONTENT_LEN 160        // size of two hfs_fork data structures
 
-/* b-tree kind types */
-#define HFS_BTREE_LEAF_NODE	-1
-#define HFS_BTREE_INDEX_NODE	 0
-#define HFS_BTREE_HEADER_NODE	 1
-#define HFS_BTREE_MAP_NODE	 2
 
 #define HFS_MAXNAMLEN		765     /* maximum HFS+ name length in bytes, when encoded in UTF8, not including terminating null */
 
@@ -118,19 +101,7 @@
  */
 #define NSEC_BTWN_1904_1970	(uint32_t) 2082844800U
 
-#define HFS_BIT_VOLUME_UNMOUNTED	(uint32_t)(1 << 8)      /* set if the volume was unmounted properly; as per TN 1150, modern Macintosh OSes always leave this bit set for the boot volume */
-#define HFS_BIT_VOLUME_BADBLOCKS        (uint32_t)(1 << 9)      /* set if there are any bad blocks for this volume (in the Extents B-tree) */
-#define HFS_BIT_VOLUME_INCONSISTENT	(uint32_t)(1 << 11)     /* cleared if the volume was unmounted properly */
-#define HFS_BIT_VOLUME_CNIDS_REUSED     (uint32_t)(1 << 12)     /* set if CNIDs have wrapped around past the maximum value and are being reused; in this case, there are CNIDs on the disk larger than the nextCatalogId field */
-#define HFS_BIT_VOLUME_JOURNALED	(uint32_t)(1 << 13)
-#define HFS_BIT_VOLUME_SOFTWARE_LOCK	(uint32_t)(1 << 14)     /* set if volume should be write-protected in software */
 
-/* constants for BTree header record attributes */
-#define HFS_BT_BIGKEYS 0x00000002       /* kBTBigKeysMask : key length field is 16 bits */
-// NOTE: HFS_BT_BIGKEYS must be set for all HFS+ BTrees
-#define HFS_BT_VARKEYS 0x00000004       /* kBTVariableIndexKeysMask : keys in index nodes are variable length */
-// NOTE: this bit is required to be set for the Catalog B-tree and cleared
-// for the Extents B-tree
 
 /* predefined files */
 #define HFS_ROOT_PARENT_ID         1
@@ -182,9 +153,9 @@ typedef struct {
     uint8_t o_flags;            /* owner flags */
     uint8_t mode[2];            /* file mode */
     union {
-        uint8_t inum[4];        /* inode number */
-        uint8_t nlink[4];       /* link count */
-        uint8_t raw[4];         /* raw device */
+        uint8_t inum[4];        /* inode number (for hard link files) */
+        uint8_t nlink[4];       /* link count (for direct node files) */
+        uint8_t raw[4];         /* device id (for block and char device files) */
     } special;
 } hfs_access_perm;
 
@@ -223,15 +194,62 @@ typedef struct {
     hfs_ext_desc extents[8];
 } hfs_extents;
 
-/* fork data structure */
+/* Fork data structure.  This is used in both the volume header and catalog tree. */
 typedef struct {
     uint8_t logic_sz[8];        /* The size (in bytes) of the fork */
-    uint8_t clmp_sz[4];         /* For forks in volume header, clump size.  For
+    uint8_t clmp_sz[4];         /* For "special files" in volume header, clump size.  For
                                  * catalog files, this is number of blocks read or not used. */
     uint8_t total_blk[4];       /* total blocks in all extents of the fork */
     hfs_ext_desc extents[8];
 } hfs_fork;
 
+
+
+/****************************************************
+ * Super block / volume header
+ */
+#define HFS_VH_OFF	1024    // byte offset in volume to volume header
+
+// signature values
+#define HFS_VH_SIG_HFS	    0x4244      /* BD in big endian */
+#define HFS_VH_SIG_HFSPLUS	0x482b  /* H+ in big endian */
+#define HFS_VH_SIG_HFSX      0x4858     /* HX in big endian */
+
+// version values
+#define HFS_VH_VER_HFSPLUS 0x0004       /* all HFS+ volumes are version 4 */
+#define HFS_VH_VER_HFSX    0x0005       /* HFSX volumes start with version 5 */
+
+// attr values (
+// bits 0 to 7 are reserved
+#define HFS_VH_ATTR_UNMOUNTED       (uint32_t)(1<<8)    /* set if the volume was unmounted properly; as per TN 1150, modern Macintosh OSes always leave this bit set for the boot volume */
+#define HFS_VH_ATTR_BADBLOCKS       (uint32_t)(1<<9)    /* set if there are any bad blocks for this volume (in the Extents B-tree) */
+#define HFS_VH_ATTR_NOCACHE         (uint32_t)(1<<10)   /* set if volume should not be cached */
+#define HFS_VH_ATTR_INCONSISTENT	(uint32_t)(1<<11)       /* cleared if the volume was unmounted properly */
+#define HFS_VH_ATTR_CNIDS_REUSED    (uint32_t)(1<<12)   /* set if CNIDs have wrapped around past the maximum value and are being reused; in this case, there are CNIDs on the disk larger than the nextCatalogId field */
+#define HFS_VH_ATTR_JOURNALED       (uint32_t)(1<<13)
+// 14 is reserved
+#define HFS_VH_ATTR_SOFTWARE_LOCK	(uint32_t)(1 << 15)     /* set if volume should be write-protected in software */
+// 16 to 31 are reserved
+
+
+// last_mnt_ver values
+#define HFS_VH_MVER_HFSPLUS 0x31302e30  /* '10.0' for Mac OS X */
+#define HFS_VH_MVER_HFSJ    0x4846534a  /* 'HFSJ' for journaled HFS+ on Mac OS X */
+#define HFS_VH_MVER_FSK     0x46534b21  /* 'FSK!' for failed journal replay */
+#define HFS_VH_MVER_FSCK    0x6673636b  /* 'fsck' for fsck_hfs */
+#define HFS_VH_MVER_OS89    0x382e3130  /* '8.10' for Mac OS 8.1-9.2.2 */
+
+/* Index values for finder_info array */
+#define HFS_VH_FI_BOOT  0       /*Directory ID of bootable directory */
+#define HFS_VH_FI_START 1       /* Parent dir ID of startup app */
+#define HFS_VH_FI_OPEN  2       /* Directory to open when volume is mounted */
+#define HFS_VH_FI_BOOT9 3       /* Directory ID of OS 8 or 9 bootable sys folder */
+#define HFS_VH_FI_RESV1 4
+#define HFS_VH_FI_BOOTX 5       /* Directory ID of OS X bootable system (CoreServices dir) */
+#define HFS_VH_FI_ID1   6       /* OS X Volume ID part 1 */
+#define HFS_VH_FI_ID2   7       /* OS X Volume ID part 2 */
+
+
 /*
 ** HFS+/HFSX Super Block
 */
@@ -241,23 +259,30 @@ typedef struct {
     uint8_t attr[4];            /* volume attributes */
     uint8_t last_mnt_ver[4];    /* last mounted version */
     uint8_t jinfo_blk[4];       /* journal info block */
-    uint8_t c_date[4];          /* volume creation date */
-    uint8_t m_date[4];          /* volume last modified date */
-    uint8_t bkup_date[4];       /* volume last backup date */
-    uint8_t chk_date[4];        /* date of last consistency check */
-    uint8_t file_cnt[4];        /* number of files on volume */
-    uint8_t fldr_cnt[4];        /* number of folders on volume */
-    uint8_t blk_sz[4];          /* allocation block size */
+
+    uint8_t cr_date[4];         /* volume creation date (NOT in GMT) */
+    uint8_t m_date[4];          /* volume last modified date (GMT) */
+    uint8_t bkup_date[4];       /* volume last backup date (GMT) */
+    uint8_t chk_date[4];        /* date of last consistency check (GMT) */
+
+    uint8_t file_cnt[4];        /* number of files on volume (not incl. special files) */
+    uint8_t fldr_cnt[4];        /* number of folders on volume (not incl. root dir) */
+
+    uint8_t blk_sz[4];          /* allocation block size (in bytes) */
     uint8_t blk_cnt[4];         /* number of blocks on disk */
     uint8_t free_blks[4];       /* unused block count */
-    uint8_t next_alloc[4];      /* start of next allocation search */
-    uint8_t rsrc_clmp_sz[4];    /* default clump size for resource forks */
-    uint8_t data_clmp_sz[4];    /* default clump size for data forks */
-    uint8_t next_cat_id[4];     /* next catalog id */
-    uint8_t write_cnt[4];       /* write count */
-    uint8_t enc_bmp[8];         /* encoding bitmap */
-    uint8_t finder_info[32];
-    hfs_fork alloc_file;        /* location and size of allocation file */
+
+    uint8_t next_alloc[4];      /* block addr to start allocation search from */
+    uint8_t rsrc_clmp_sz[4];    /* default clump size for resource forks (in bytes) */
+    uint8_t data_clmp_sz[4];    /* default clump size for data forks (in bytes) */
+    uint8_t next_cat_id[4];     /* next catalog id for allocation */
+
+    uint8_t write_cnt[4];       /* write count: incremented each time it is mounted and modified */
+    uint8_t enc_bmp[8];         /* encoding bitmap (identifies which encodings were used in FS) */
+
+    uint8_t finder_info[8][4];  /* Special finder details */
+
+    hfs_fork alloc_file;        /* location and size of allocation bitmap file */
     hfs_fork ext_file;          /* location and size of extents file */
     hfs_fork cat_file;          /* location and size of catalog file */
     hfs_fork attr_file;         /* location and size of attributes file */
@@ -300,19 +325,82 @@ typedef struct {
     uint8_t drCTExtRec[12];     /* extent record with size and location of catalog file */
 } hfs_wrapper_sb;
 
+
+
+/********* B-Tree data structures **********/
+
+/* Node descriptor that starts each node in a B-tree */
+// type values
+#define HFS_BT_NODE_TYPE_LEAF	-1
+#define HFS_BT_NODE_TYPE_IDX	 0
+#define HFS_BT_NODE_TYPE_HEAD	 1
+#define HFS_BT_NODE_TYPE_MAP	 2
+
+// header that starts every B-tree node
+typedef struct {
+    uint8_t flink[4];           /* node num of next node of same type */
+    uint8_t blink[4];           /* node num of prev node of same type */
+    int8_t type;                /* type of this node */
+    uint8_t height;             /* level in B-tree (0 for root, 1 for leaf) */
+    uint8_t num_rec[2];         /* number of records this node */
+    uint8_t res[2];             /* reserved */
+} hfs_btree_node;
+
+/*****************/
+// structure for the 1st record in the B-Tree header node
+
+// type values
+#define HFS_BT_HEAD_TYPE_CNTL   0       // control file (catalog, extents, attributes)
+#define HFS_BT_HEAD_TYPE_USER   128     // hot file
+#define HFS_BT_HEAD_TYPE_RSV    255
+
+// compType values
+#define HFS_BT_HEAD_COMP_SENS    0xCF   // case sensitive
+#define HFS_BT_HEAD_COMP_INSENS    0xBC // case insensitive
+
+// attr values
+#define HFS_BT_HEAD_ATTR_BIGKEYS 0x00000002     /* key length field is 16 bits (req'd for HFS+) */
+#define HFS_BT_HEAD_ATTR_VARIDXKEYS 0x00000004  /* Keys in INDEX nodes are variable length */
+// NOTE: VARIDXKEYS is required for the Catalog B-tree and cleared for the Extents B-tree
+
 typedef struct {
-    uint8_t key_len[2];
+    uint8_t depth[2];           /* current depth of btree */
+    uint8_t rootNode[4];        /* node number of root node */
+    uint8_t leafRecords[4];     /* number of records in leaf nodes */
+    uint8_t firstLeafNode[4];   /* number of first leaf node (0 if no leafs) */
+    uint8_t lastLeafNode[4];    /* number of last leaf node (0 if no leafs) */
+    uint8_t nodesize[2];        /* byte size of each node (512..32768) */
+    uint8_t maxKeyLen[2];       /* max key length in an index or leaf node */
+    uint8_t totalNodes[4];      /* number of nodes in btree (free or in use) */
+    uint8_t freeNodes[4];       /* unused nodes in btree */
+    uint8_t res[2];             /* reserved */
+    uint8_t clumpSize[4];       /* clump size */
+    uint8_t type;               /* btree type (control or user) */
+    uint8_t compType;           /* HFSX Only: identifies of key comparisons are case sensitive */
+    uint8_t attr[4];            /* attributes */
+    uint8_t res2[64];           /* reserved */
+} hfs_btree_header_record;
+
+/* key for category records */
+typedef struct {
+    uint8_t key_len[2];         // length of key minus 2
     uint8_t parent_cnid[4];
     hfs_uni_str name;
-} hfs_cat_key;
+} hfs_btree_key_cat;
 
+/* Key for extents records */
 typedef struct {
-    uint8_t key_len[2];
+    uint8_t key_len[2];         // length of key minus 2
     uint8_t fork_type[1];
     uint8_t pad[1];
     uint8_t file_id[4];
     uint8_t start_block[4];
-} hfs_ext_key;
+} hfs_btree_key_ext;
+
+/* Record contents for index record after key */
+typedef struct {
+    uint8_t childNode[4];
+} hfs_btree_index_record;
 
 typedef struct {
     uint32_t inum;              /* inode number */
@@ -321,32 +409,8 @@ typedef struct {
     TSK_DADDR_T offs;           /* offset of beginning of inode */
 } htsk_fs_inode_mode_struct;
 
-typedef struct {
-    uint8_t flink[4];           /* next node number */
-    uint8_t blink[4];           /* previous node number */
-    int8_t kind;                /* type of node */
-    uint8_t height;             /* level in B-tree */
-    uint8_t num_rec[2];         /* number of records this node */
-    uint8_t res[2];             /* reserved */
-} hfs_btree_node;
 
-typedef struct {
-    uint8_t depth[2];           /* current depth of btree */
-    uint8_t root[4];            /* node number of root node */
-    uint8_t leaf[4];            /* number of records in leaf nodes */
-    uint8_t firstleaf[4];       /* number of first leaf node */
-    uint8_t lastleaf[4];        /* number of last leaf node */
-    uint8_t nodesize[2];        /* byte size of leaf node (512..32768) */
-    uint8_t max_len[2];         /* max key length in an index or leaf node */
-    uint8_t total[4];           /* number of nodes in btree (free or in use) */
-    uint8_t free[4];            /* unused nodes in btree */
-    uint8_t res[2];             /* reserved */
-    uint8_t clmp_sz[4];         /* clump size */
-    uint8_t bt_type;            /* btree type */
-    uint8_t k_type;             /* key compare type */
-    uint8_t attr[4];            /* attributes */
-    uint8_t res2[64];           /* reserved */
-} hfs_btree_header_record;
+
 
 typedef struct {
     int8_t v[2];
@@ -474,6 +538,9 @@ extern uint8_t hfs_checked_read_random(TSK_FS_INFO *, char *, size_t,
     TSK_OFF_T);
 extern uint8_t hfs_uni2ascii(TSK_FS_INFO *, uint8_t *, int, char *, int);
 extern int hfs_unicode_compare(HFS_INFO *, hfs_uni_str *, hfs_uni_str *);
+extern uint16_t hfs_get_idxkeylen(HFS_INFO * hfs, uint16_t keylen,
+    const hfs_btree_header_record * header);
+
 
 extern TSK_RETVAL_ENUM
 hfs_dir_open_meta(TSK_FS_INFO *, TSK_FS_DIR **, TSK_INUM_T);