Index: uspace/app/bithenge/blob.c
===================================================================
--- uspace/app/bithenge/blob.c	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/blob.c	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -226,11 +226,11 @@
 };
 
-/** Create a blob from data. Unlike with @a
+/** Create a blob node from data. Unlike with @a
  * bithenge_blob_t::bithenge_new_blob_from_buffer, the data is copied into a
  * new buffer and the original data can be changed after this call. The blob
- * must be freed with @a bithenge_blob_t::bithenge_blob_destroy after it is
+ * must be freed with @a bithenge_node_t::bithenge_node_destroy after it is
  * used.
  * @memberof bithenge_blob_t
- * @param[out] out Stores the created blob.
+ * @param[out] out Stores the created blob node.
  * @param[in] data The data.
  * @param len The length of the data.
@@ -264,9 +264,9 @@
 }
 
-/** Create a blob from a buffer. The buffer must exist as long as the blob
- * does. The blob must be freed with @a bithenge_blob_t::bithenge_blob_destroy
+/** Create a blob node from a buffer. The buffer must exist as long as the blob
+ * does. The blob must be freed with @a bithenge_node_t::bithenge_node_destroy
  * after it is used.
  * @memberof bithenge_blob_t
- * @param[out] out Stores the created blob.
+ * @param[out] out Stores the created blob node.
  * @param[in] buffer The buffer, which must not be changed until the blob is
  * destroyed.
Index: uspace/app/bithenge/blob.h
===================================================================
--- uspace/app/bithenge/blob.h	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/blob.h	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -41,5 +41,6 @@
 #include "tree.h"
 
-/** A blob of raw binary data. */
+/** A blob of raw binary data.
+ * @implements bithenge_node_t */
 typedef struct {
 	/** @privatesection */
@@ -55,5 +56,7 @@
 	int (*read)(bithenge_blob_t *blob, aoff64_t offset, char *buffer,
 	    aoff64_t *size);
-	/** @copydoc bithenge_blob_t::bithenge_blob_destroy */
+	/** Destroy the blob.
+	 * @param blob The blob.
+	 * @return EOK on success or an error code from errno.h. */
 	int (*destroy)(bithenge_blob_t *blob);
 } bithenge_random_access_blob_ops_t;
@@ -148,4 +151,8 @@
 }
 
+/** Cast a blob node to a generic node.
+ * @memberof bithenge_blob_t
+ * @param blob The blob to cast.
+ * @return The blob node as a generic node. */
 static inline bithenge_node_t *bithenge_blob_as_node(bithenge_blob_t *blob)
 {
@@ -153,6 +160,11 @@
 }
 
+/** Cast a generic node to a blob node.
+ * @memberof bithenge_blob_t
+ * @param node The node to cast, which must be a blob node.
+ * @return The generic node as a blob node. */
 static inline bithenge_blob_t *bithenge_node_as_blob(bithenge_node_t *node)
 {
+	assert(node->type == BITHENGE_NODE_BLOB);
 	return (bithenge_blob_t *)node;
 }
Index: uspace/app/bithenge/block.c
===================================================================
--- uspace/app/bithenge/block.c	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/block.c	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -93,5 +93,5 @@
 
 /** Create a blob for a block device. The blob must be freed with
- * @a bithenge_blob_t::bithenge_blob_destroy after it is used.
+ * @a bithenge_node_t::bithenge_node_destroy after it is used.
  * @param[out] out Stores the created blob.
  * @param service_id The service ID of the block device.
Index: uspace/app/bithenge/file.c
===================================================================
--- uspace/app/bithenge/file.c	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/file.c	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -133,5 +133,5 @@
 
 /** Create a blob for a file. The blob must be freed with @a
- * bithenge_blob_t::bithenge_blob_destroy after it is used.
+ * bithenge_node_t::bithenge_node_destroy after it is used.
  * @param[out] out Stores the created blob.
  * @param filename The name of the file.
@@ -149,5 +149,5 @@
 
 /** Create a blob for a file descriptor. The blob must be freed with @a
- * bithenge_blob_t::bithenge_blob_destroy after it is used.
+ * bithenge_node_t::bithenge_node_destroy after it is used.
  * @param[out] out Stores the created blob.
  * @param fd The file descriptor.
@@ -159,5 +159,5 @@
 
 /** Create a blob for a file pointer. The blob must be freed with @a
- * bithenge_blob_t::bithenge_blob_destroy after it is used.
+ * bithenge_node_t::bithenge_node_destroy after it is used.
  * @param[out] out Stores the created blob.
  * @param file The file pointer.
Index: uspace/app/bithenge/print.c
===================================================================
--- uspace/app/bithenge/print.c	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/print.c	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -141,9 +141,11 @@
 }
 
+/** Print a tree as text.
+ * @param type The format to use.
+ * @param tree The root node of the tree to print.
+ * @return EOK on success or an error code from errno.h. */
 int bithenge_print_node(bithenge_print_type_t type, bithenge_node_t *tree)
 {
 	switch (bithenge_node_type(tree)) {
-	case BITHENGE_NODE_NONE:
-		return EINVAL;
 	case BITHENGE_NODE_INTERNAL:
 		return print_internal(type, tree);
@@ -159,2 +161,5 @@
 	return ENOTSUP;
 }
+
+/** @}
+ */
Index: uspace/app/bithenge/print.h
===================================================================
--- uspace/app/bithenge/print.h	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/print.h	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -40,6 +40,11 @@
 #include "tree.h"
 
+/** Specifies the format to be used when printing. */
 typedef enum {
+	/** Print a Python value. Note that internal nodes will be represented
+	 * as unordered dictionaries. */
 	BITHENGE_PRINT_PYTHON,
+	/** Print JSON. Due to the limitations of JSON, type information may be
+	 * lost. */
 	BITHENGE_PRINT_JSON,
 } bithenge_print_type_t;
Index: uspace/app/bithenge/tree.c
===================================================================
--- uspace/app/bithenge/tree.c	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/tree.c	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -47,4 +47,8 @@
 }
 
+/** Destroy a node.
+ * @memberof bithenge_node_t
+ * @param node The node to destroy.
+ * @return EOK on success or an error code from errno.h. */
 int bithenge_node_destroy(bithenge_node_t *node)
 {
@@ -61,5 +65,4 @@
 		return EOK; // the boolean nodes are allocated statically below
 	case BITHENGE_NODE_INTEGER: /* pass-through */
-	case BITHENGE_NODE_NONE:
 		break;
 	}
@@ -81,5 +84,6 @@
 }
 
-static int simple_internal_node_for_each(bithenge_node_t *base, bithenge_for_each_func_t func, void *data)
+static int simple_internal_node_for_each(bithenge_node_t *base,
+    bithenge_for_each_func_t func, void *data)
 {
 	int rc;
@@ -121,5 +125,17 @@
 }
 
-int bithenge_new_simple_internal_node(bithenge_node_t **out, bithenge_node_t **nodes, bithenge_int_t len, bool needs_free)
+/** Create an internal node from a set of keys and values. The node must be
+ * freed with @a bithenge_node_t::bithenge_node_destroy after it is used, which
+ * will also destroy all the key and value nodes.
+ * @memberof bithenge_node_t
+ * @param[out] out Stores the created internal node.
+ * @param nodes The array of key-value pairs. Keys are stored at even indices
+ * and values are stored at odd indices.
+ * @param len The number of key-value pairs in the node array.
+ * @param needs_free If true, when the internal node is destroyed it will free
+ * the nodes array as well as destroying each node inside it.
+ * @return EOK on success or an error code from errno.h. */
+int bithenge_new_simple_internal_node(bithenge_node_t **out,
+    bithenge_node_t **nodes, bithenge_int_t len, bool needs_free)
 {
 	assert(out);
@@ -139,4 +155,10 @@
 static bithenge_node_t true_node = { BITHENGE_NODE_BOOLEAN, .boolean_value = true };
 
+/** Create a boolean node. The node must be freed with @a
+ * bithenge_node_t::bithenge_node_destroy after it is used.
+ * @memberof bithenge_node_t
+ * @param[out] out Stores the created boolean node.
+ * @param value The value for the node to hold.
+ * @return EOK on success or an error code from errno.h. */
 int bithenge_new_boolean_node(bithenge_node_t **out, bool value)
 {
@@ -146,4 +168,10 @@
 }
 
+/** Create an integer node. The node must be freed with @a
+ * bithenge_node_t::bithenge_node_destroy after it is used.
+ * @memberof bithenge_node_t
+ * @param[out] out Stores the created integer node.
+ * @param value The value for the node to hold.
+ * @return EOK on success or an error code from errno.h. */
 int bithenge_new_integer_node(bithenge_node_t **out, bithenge_int_t value)
 {
@@ -158,4 +186,12 @@
 }
 
+/** Create a string node. The node must be freed with @a
+ * bithenge_node_t::bithenge_node_destroy after it is used.
+ * @memberof bithenge_node_t
+ * @param[out] out Stores the created string node.
+ * @param value The value for the node to hold.
+ * @param needs_free Whether the string should be freed when the node is
+ * destroyed.
+ * @return EOK on success or an error code from errno.h. */
 int bithenge_new_string_node(bithenge_node_t **out, const char *value, bool needs_free)
 {
@@ -170,2 +206,5 @@
 	return EOK;
 }
+
+/** @}
+ */
Index: uspace/app/bithenge/tree.h
===================================================================
--- uspace/app/bithenge/tree.h	(revision 5c925ce5a89fdac54d419c827dda95fc9f85e60e)
+++ uspace/app/bithenge/tree.h	(revision 8375d0ebbd973defd24cf49d77c4c2f6567323e9)
@@ -51,14 +51,20 @@
 #endif
 
+/** Indicates the type of a tree node. */
 typedef enum {
-	BITHENGE_NODE_NONE,
-	BITHENGE_NODE_INTERNAL,
+	/** An internal node with labelled edges to other nodes. */
+	BITHENGE_NODE_INTERNAL = 1,
+	/** A leaf node holding a boolean value. */
 	BITHENGE_NODE_BOOLEAN,
+	/** A leaf node holding an integer. */
 	BITHENGE_NODE_INTEGER,
+	/** A leaf node holding a string. */
 	BITHENGE_NODE_STRING,
+	/** A leaf node holding a binary blob. */
 	BITHENGE_NODE_BLOB,
 } bithenge_node_type_t;
 
 typedef struct bithenge_node_t {
+	/** @privatesection */
 	bithenge_node_type_t type;
 	union {
@@ -74,4 +80,24 @@
 } bithenge_node_t;
 
+/** A callback function used to iterate over a node's children.
+ * @memberof bithenge_node_t
+ * @param key The key.
+ * @param value The value.
+ * @param data Data provided to @a bithenge_node_t::bithenge_node_for_each.
+ * @return EOK on success or an error code from errno.h. */
+typedef int (*bithenge_for_each_func_t)(bithenge_node_t *key, bithenge_node_t *value, void *data);
+
+/** Operations providing access to an internal node. */
+typedef struct bithenge_internal_node_ops_t {
+	/** @copydoc bithenge_node_t::bithenge_node_for_each */
+	int (*for_each)(bithenge_node_t *node, bithenge_for_each_func_t func, void *data);
+	/** @copydoc bithenge_node_t::bithenge_node_destroy */
+	int (*destroy)(bithenge_node_t *node);
+} bithenge_internal_node_ops_t;
+
+/** Find the type of a node.
+ * @memberof bithenge_node_t
+ * @param node The node.
+ * @return The type of the node. */
 static inline bithenge_node_type_t bithenge_node_type(const bithenge_node_t *node)
 {
@@ -79,11 +105,10 @@
 }
 
-typedef int (*bithenge_for_each_func_t)(bithenge_node_t *key, bithenge_node_t *value, void *data);
-
-typedef struct bithenge_internal_node_ops_t {
-	int (*for_each)(bithenge_node_t *node, bithenge_for_each_func_t func, void *data);
-	int (*destroy)(bithenge_node_t *node);
-} bithenge_internal_node_ops_t;
-
+/** Iterate over a node's children.
+ * @memberof bithenge_node_t
+ * @param node The internal node to iterate over.
+ * @param func The callback function.
+ * @param data Data to provide to the callback function.
+ * @return EOK on success or an error code from errno.h. */
 static inline int bithenge_node_for_each(bithenge_node_t *node, bithenge_for_each_func_t func, void *data)
 {
@@ -92,4 +117,8 @@
 }
 
+/** Get the value of a boolean node.
+ * @memberof bithenge_node_t
+ * @param node The boolean node.
+ * @return The node's value. */
 static inline bool bithenge_boolean_node_value(bithenge_node_t *node)
 {
@@ -98,4 +127,8 @@
 }
 
+/** Get the value of an integer node.
+ * @memberof bithenge_node_t
+ * @param node The integer node.
+ * @return The node's value. */
 static inline bithenge_int_t bithenge_integer_node_value(bithenge_node_t *node)
 {
@@ -104,4 +137,8 @@
 }
 
+/** Get the value of an string node.
+ * @memberof bithenge_node_t
+ * @param node The string node.
+ * @return The node's value. */
 static inline const char *bithenge_string_node_value(bithenge_node_t *node)
 {
@@ -110,5 +147,6 @@
 }
 
-int bithenge_new_simple_internal_node(bithenge_node_t **, bithenge_node_t **, bithenge_int_t, bool needs_free);
+int bithenge_new_simple_internal_node(bithenge_node_t **, bithenge_node_t **,
+    bithenge_int_t, bool needs_free);
 int bithenge_new_boolean_node(bithenge_node_t **, bool);
 int bithenge_new_integer_node(bithenge_node_t **, bithenge_int_t);
