Index: uspace/lib/bithenge/include/bithenge/blob.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/blob.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/blob.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Raw binary blobs.
+ */
+
+#ifndef BITHENGE_BLOB_H_
+#define BITHENGE_BLOB_H_
+
+#include <sys/types.h>
+#include "tree.h"
+
+/** A blob of raw binary data.
+ * @implements bithenge_node_t */
+typedef struct {
+	/** @privatesection */
+	struct bithenge_node_t base;
+} bithenge_blob_t;
+
+/** Operations providing random access to binary data.
+ * @todo Should these be thread-safe? */
+typedef struct bithenge_random_access_blob_ops_t {
+	/** @copydoc bithenge_blob_t::bithenge_blob_size */
+	int (*size)(bithenge_blob_t *self, aoff64_t *size);
+	/** @copydoc bithenge_blob_t::bithenge_blob_read */
+	int (*read)(bithenge_blob_t *self, aoff64_t offset, char *buffer,
+	    aoff64_t *size);
+	/** @copydoc bithenge_blob_t::bithenge_blob_read_bits */
+	int (*read_bits)(bithenge_blob_t *self, aoff64_t offset, char *buffer,
+	    aoff64_t *size, bool little_endian);
+	/** Destroy the blob.
+	 * @param blob The blob. */
+	void (*destroy)(bithenge_blob_t *self);
+} bithenge_random_access_blob_ops_t;
+
+/** A blob built from an object that supports only sequential reading.
+ * @implements bithenge_blob_t */
+typedef struct {
+	/** @privatesection */
+	/** The base random-access blob. */
+	bithenge_blob_t base;
+	/** Operations providing sequential access. */
+	const struct bithenge_sequential_blob_ops_t *ops;
+	/** Buffer containing all data read. */
+	char *buffer;
+	/** Size of buffer. */
+	aoff64_t buffer_size;
+	/** Amount of data actually in buffer. */
+	aoff64_t data_size;
+} bithenge_sequential_blob_t;
+
+/** Operations providing sequential access to binary data.
+ * @memberof bithenge_sequential_blob_t */
+typedef struct bithenge_sequential_blob_ops_t {
+
+	/** Get the total size of the blob. If the total size cannot be
+	 * determined easily, this field may be null or return an error,
+	 * forcing the entire blob to be read to determine its size.
+	 *
+	 * @memberof bithenge_blob_t
+	 * @param self The blob.
+	 * @param[out] size Total size of the blob.
+	 * @return EOK on success or an error code from errno.h.
+	 */
+	int (*size)(bithenge_sequential_blob_t *self, aoff64_t *size);
+
+	/** Read the next part of the blob. If the requested data extends
+	 * beyond the end of the blob, the data up until the end of the blob
+	 * will be read.
+	 *
+	 * @param self The blob.
+	 * @param[out] buffer Buffer to read into. If an error occurs, the contents are
+	 * undefined.
+	 * @param[in,out] size Number of bytes to read; may be 0. If not enough
+	 * data is left in the blob, the actual number of bytes read should be
+	 * stored here. If an error occurs, the contents are undefined.
+	 * @return EOK on success or an error code from errno.h.
+	 */
+	int (*read)(bithenge_sequential_blob_t *self, char *buffer,
+	    aoff64_t *size);
+
+	/** Destroy the blob.
+	 * @param self The blob. */
+	void (*destroy)(bithenge_sequential_blob_t *self);
+} bithenge_sequential_blob_ops_t;
+
+/** Get the total size of the blob.
+ *
+ * @memberof bithenge_blob_t
+ * @param self The blob.
+ * @param[out] size Total size of the blob.
+ * @return EOK on success or an error code from errno.h.
+ */
+static inline int bithenge_blob_size(bithenge_blob_t *self, aoff64_t *size)
+{
+	assert(self);
+	assert(self->base.blob_ops);
+	return self->base.blob_ops->size(self, size);
+}
+
+/** Read part of the blob. If the requested data extends beyond the end of the
+ * blob, the data up until the end of the blob will be read. If the offset is
+ * beyond the end of the blob, even if the size is zero, an error will be
+ * returned.
+ *
+ * @memberof bithenge_blob_t
+ * @param self The blob.
+ * @param offset Byte offset within the blob.
+ * @param[out] buffer Buffer to read into. If an error occurs, the contents are
+ * undefined.
+ * @param[in,out] size Number of bytes to read; may be 0. If the requested
+ * range extends beyond the end of the blob, the actual number of bytes read
+ * should be stored here. If an error occurs, the contents are undefined.
+ * @return EOK on success or an error code from errno.h.
+ */
+static inline int bithenge_blob_read(bithenge_blob_t *self, aoff64_t offset,
+    char *buffer, aoff64_t *size)
+{
+	assert(self);
+	assert(self->base.blob_ops);
+	if (!self->base.blob_ops->read)
+		return EINVAL;
+	return self->base.blob_ops->read(self, offset, buffer, size);
+}
+
+/** Read part of the bit blob. If the requested data extends beyond the end of
+ * the blob, the data up until the end of the blob will be read. If the offset
+ * is beyond the end of the blob, even if the size is zero, an error will be
+ * returned.
+ *
+ * @memberof bithenge_blob_t
+ * @param self The blob.
+ * @param offset Byte offset within the blob.
+ * @param[out] buffer Buffer to read into. If an error occurs, the contents are
+ * undefined.
+ * @param[in,out] size Number of bytes to read; may be 0. If the requested
+ * range extends beyond the end of the blob, the actual number of bytes read
+ * should be stored here. If an error occurs, the contents are undefined.
+ * @param little_endian If true, bytes will be filled starting at the least
+ * significant bit; otherwise, they will be filled starting at the most
+ * significant bit.
+ * @return EOK on success or an error code from errno.h.
+ */
+static inline int bithenge_blob_read_bits(bithenge_blob_t *self,
+    aoff64_t offset, char *buffer, aoff64_t *size, bool little_endian)
+{
+	assert(self);
+	assert(self->base.blob_ops);
+	if (!self->base.blob_ops->read_bits)
+		return EINVAL;
+	return self->base.blob_ops->read_bits(self, offset, buffer, size,
+	    little_endian);
+}
+
+/** Check whether the blob is empty.
+ *
+ * @memberof bithenge_blob_t
+ * @param self The blob.
+ * @param[out] out Holds whether the blob is empty.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_blob_empty(bithenge_blob_t *self, bool *out)
+{
+	assert(self);
+	assert(self->base.blob_ops);
+	aoff64_t size;
+	int rc = bithenge_blob_size(self, &size);
+	*out = size == 0;
+	return rc;
+}
+
+/** 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)
+{
+	return &blob->base;
+}
+
+/** 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;
+}
+
+/** Increment a blob's reference count.
+ * @param blob The blob to reference. */
+static inline void bithenge_blob_inc_ref(bithenge_blob_t *blob)
+{
+	bithenge_node_inc_ref(bithenge_blob_as_node(blob));
+}
+
+/** Decrement a blob's reference count.
+ * @param blob The blob to dereference, or NULL. */
+static inline void bithenge_blob_dec_ref(bithenge_blob_t *blob)
+{
+	if (blob)
+		bithenge_node_dec_ref(bithenge_blob_as_node(blob));
+}
+
+/** @memberof bithenge_blob_t */
+int bithenge_init_random_access_blob(bithenge_blob_t *,
+    const bithenge_random_access_blob_ops_t *);
+/** @memberof bithenge_sequential_blob_t */
+int bithenge_init_sequential_blob(bithenge_sequential_blob_t *,
+    const bithenge_sequential_blob_ops_t *);
+/** @memberof bithenge_blob_t */
+int bithenge_new_blob_from_data(bithenge_node_t **, const void *, size_t);
+/** @memberof bithenge_blob_t */
+int bithenge_new_blob_from_buffer(bithenge_node_t **, const void *, size_t,
+    bool);
+int bithenge_new_offset_blob(bithenge_node_t **, bithenge_blob_t *, aoff64_t);
+int bithenge_new_subblob(bithenge_node_t **, bithenge_blob_t *, aoff64_t,
+    aoff64_t);
+/** @memberof bithenge_blob_t */
+int bithenge_blob_equal(bool *, bithenge_blob_t *, bithenge_blob_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/compound.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/compound.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/compound.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Compound transforms.
+ */
+
+#ifndef BITHENGE_COMPOUND_H_
+#define BITHENGE_COMPOUND_H_
+
+#include "expression.h"
+#include "transform.h"
+
+int bithenge_new_composed_transform(bithenge_transform_t **,
+    bithenge_transform_t **, size_t);
+int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *,
+    bithenge_transform_t *, bithenge_transform_t *);
+int bithenge_partial_transform(bithenge_transform_t **,
+    bithenge_transform_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/expression.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/expression.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/expression.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Expressions.
+ */
+
+#ifndef BITHENGE_EXPRESSION_H_
+#define BITHENGE_EXPRESSION_H_
+
+#include "blob.h"
+#include "transform.h"
+#include "tree.h"
+
+/** An expression that calculates a value given a scope. */
+typedef struct {
+	/** @privatesection */
+	const struct bithenge_expression_ops *ops;
+	unsigned int refs;
+} bithenge_expression_t;
+
+/** Operations provided by an expression. */
+typedef struct bithenge_expression_ops {
+	/** @copydoc bithenge_expression_t::bithenge_expression_evaluate */
+	int (*evaluate)(bithenge_expression_t *self, bithenge_scope_t *scope,
+	    bithenge_node_t **out);
+	/** Destroy the expression.
+	 * @param self The expression. */
+	void (*destroy)(bithenge_expression_t *self);
+} bithenge_expression_ops_t;
+
+/** Increment an expression's reference count.
+ * @param self The expression to reference. */
+static inline void bithenge_expression_inc_ref(bithenge_expression_t *self)
+{
+	assert(self);
+	self->refs++;
+}
+
+/** Decrement an expression's reference count and free it if appropriate.
+ * @param self The expression to dereference, or NULL. */
+static inline void bithenge_expression_dec_ref(bithenge_expression_t *self)
+{
+	if (!self)
+		return;
+	assert(self->ops);
+	assert(self->refs > 0);
+	if (--self->refs == 0)
+		self->ops->destroy(self);
+}
+
+/** Evaluate an expression. Takes ownership of nothing.
+ * @memberof bithenge_expression_t
+ * @param self The expression.
+ * @param scope The scope.
+ * @param[out] out Where the output tree will be stored.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_expression_evaluate(bithenge_expression_t *self,
+    bithenge_scope_t *scope, bithenge_node_t **out)
+{
+	assert(self);
+	assert(self->ops);
+	return self->ops->evaluate(self, scope, out);
+}
+
+/** The binary operators supported by @a bithenge_binary_expression(). */
+typedef enum {
+	BITHENGE_EXPRESSION_INVALID_BINARY_OP,
+
+	BITHENGE_EXPRESSION_ADD,
+	BITHENGE_EXPRESSION_SUBTRACT,
+	BITHENGE_EXPRESSION_MULTIPLY,
+	BITHENGE_EXPRESSION_INTEGER_DIVIDE,
+	BITHENGE_EXPRESSION_MODULO,
+
+	BITHENGE_EXPRESSION_LESS_THAN,
+	BITHENGE_EXPRESSION_GREATER_THAN,
+	BITHENGE_EXPRESSION_LESS_THAN_OR_EQUAL,
+	BITHENGE_EXPRESSION_GREATER_THAN_OR_EQUAL,
+	BITHENGE_EXPRESSION_EQUALS,
+	BITHENGE_EXPRESSION_NOT_EQUALS,
+
+	BITHENGE_EXPRESSION_AND,
+	BITHENGE_EXPRESSION_OR,
+
+	BITHENGE_EXPRESSION_MEMBER,
+	BITHENGE_EXPRESSION_CONCAT,
+} bithenge_binary_op_t;
+
+int bithenge_init_expression(bithenge_expression_t *,
+    const bithenge_expression_ops_t *);
+int bithenge_binary_expression(bithenge_expression_t **, bithenge_binary_op_t,
+    bithenge_expression_t *, bithenge_expression_t *);
+int bithenge_in_node_expression(bithenge_expression_t **);
+int bithenge_current_node_expression(bithenge_expression_t **);
+int bithenge_param_expression(bithenge_expression_t **, int);
+int bithenge_const_expression(bithenge_expression_t **, bithenge_node_t *);
+int bithenge_scope_member_expression(bithenge_expression_t **,
+    bithenge_node_t *);
+int bithenge_subblob_expression(bithenge_expression_t **,
+    bithenge_expression_t *, bithenge_expression_t *, bithenge_expression_t *,
+    bool);
+int bithenge_param_wrapper(bithenge_transform_t **, bithenge_transform_t *,
+    bithenge_expression_t **);
+int bithenge_expression_transform(bithenge_transform_t **,
+    bithenge_expression_t *);
+int bithenge_inputless_transform(bithenge_transform_t **,
+    bithenge_expression_t *);
+
+int bithenge_concat_blob(bithenge_node_t **, bithenge_blob_t *,
+    bithenge_blob_t *);
+int bithenge_concat_blob_lazy(bithenge_node_t **, bithenge_blob_t *,
+    bithenge_expression_t *, bithenge_scope_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/file.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/file.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/file.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Access files as blobs.
+ */
+
+#ifndef BITHENGE_FILE_H_
+#define BITHENGE_FILE_H_
+
+#include <stdio.h>
+#include "blob.h"
+
+int bithenge_new_file_blob(bithenge_node_t **, const char *);
+int bithenge_new_file_blob_from_fd(bithenge_node_t **, int);
+int bithenge_new_file_blob_from_file(bithenge_node_t **, FILE *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/helenos/os.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/helenos/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/helenos/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BITHENGE_HELENOS_OS_H_
+#define BITHENGE_HELENOS_OS_H_
+
+#include <bool.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <macros.h>
+#include <mem.h>
+#include <stdlib.h>
+#include <str.h>
+#include <str_error.h>
+
+typedef int64_t bithenge_int_t;
+#define BITHENGE_PRId PRId64
+
+typedef struct {
+	const char *string;
+	size_t offset;
+	wchar_t ch;
+} string_iterator_t;
+
+static inline string_iterator_t string_iterator(const char *string)
+{
+	string_iterator_t i;
+	i.string = string;
+	i.offset = 0;
+	i.ch = str_decode(i.string, &i.offset, STR_NO_LIMIT);
+	return i;
+}
+
+static inline bool string_iterator_done(const string_iterator_t *i)
+{
+	return i->ch == L'\0';
+}
+
+static inline int string_iterator_next(string_iterator_t *i, wchar_t *out)
+{
+	*out = i->ch;
+	if (*out == U_SPECIAL)
+		return EINVAL;
+	i->ch = str_decode(i->string, &i->offset, STR_NO_LIMIT);
+	return EOK;
+}
+
+static inline void *memchr(const void *s, int c, size_t n)
+{
+	for (size_t i = 0; i < n; i++)
+		if (((char *)s)[i] == c)
+			return (void *)(s + i);
+	return NULL;
+}
+
+static inline int bithenge_parse_int(const char *start, bithenge_int_t *result)
+{
+	const char *real_start = *start == '-' ? start + 1 : start;
+	uint64_t val;
+	int rc = str_uint64_t(real_start, NULL, 10, false, &val);
+	*result = val;
+	if (*start == '-')
+		*result = -*result;
+	return rc;
+}
+
+#endif
Index: uspace/lib/bithenge/include/bithenge/linux/os.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/linux/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/linux/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BITHENGE_LINUX_OS_H_
+#define BITHENGE_LINUX_OS_H_
+
+#include <endian.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <memory.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#define max(aleph, bet) ((aleph) > (bet) ? (aleph) : (bet))
+#define min(aleph, bet) ((aleph) < (bet) ? (aleph) : (bet))
+
+#define EOK 0
+#define ELIMIT EINVAL
+
+typedef intmax_t bithenge_int_t;
+#define BITHENGE_PRId PRIdMAX
+typedef uint64_t aoff64_t;
+typedef const char *string_iterator_t;
+
+static inline string_iterator_t string_iterator(const char *string)
+{
+	return string;
+}
+
+static inline int string_iterator_next(string_iterator_t *i, wchar_t *out)
+{
+	wint_t rc = btowc(*(*i)++); // TODO
+	*out = (wchar_t) rc;
+	return rc == WEOF ? EILSEQ : EOK;
+}
+
+static inline bool string_iterator_done(const string_iterator_t *i)
+{
+	return !**i;
+}
+
+static inline size_t str_length(const char *string)
+{
+	return strlen(string);
+}
+
+static inline const char *str_chr(const char *string, wchar_t ch)
+{
+	return strchr(string, wctob(ch)); // TODO
+}
+
+static inline int str_cmp(const char *s1, const char *s2)
+{
+	return strcmp(s1, s2);
+}
+
+static inline int str_lcmp(const char *s1, const char *s2, size_t max_len)
+{
+	return strncmp(s1, s2, max_len);
+}
+
+static inline char *str_dup(const char *s)
+{
+	return strdup(s);
+}
+
+static inline char *str_ndup(const char *s, size_t max_len)
+{
+	return strndup(s, max_len);
+}
+
+static inline const char *str_error(int e)
+{
+	return strerror(e);
+}
+
+static inline uint16_t uint16_t_le2host(uint16_t val)
+{
+	return le16toh(val);
+}
+
+static inline uint16_t uint16_t_be2host(uint16_t val)
+{
+	return be16toh(val);
+}
+
+static inline uint32_t uint32_t_le2host(uint32_t val)
+{
+	return le32toh(val);
+}
+
+static inline uint32_t uint32_t_be2host(uint32_t val)
+{
+	return be32toh(val);
+}
+
+static inline uint64_t uint64_t_le2host(uint64_t val)
+{
+	return le64toh(val);
+}
+
+static inline uint64_t uint64_t_be2host(uint64_t val)
+{
+	return be64toh(val);
+}
+
+static inline int bithenge_parse_int(const char *start, bithenge_int_t *result)
+{
+	errno = 0;
+	*result = strtoll(start, NULL, 10);
+	return errno;
+}
+
+#endif
Index: uspace/lib/bithenge/include/bithenge/os.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/os.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BITHENGE_OS_H_
+#define BITHENGE_OS_H_
+
+#ifdef __HELENOS__
+#include "helenos/os.h"
+#else
+#include "linux/os.h"
+#endif
+
+#ifdef BITHENGE_FAILURE_ENABLE
+#include "failure.h"
+#else
+static inline int bithenge_should_fail(void)
+{
+	return 0;
+}
+#endif
+
+#endif
Index: uspace/lib/bithenge/include/bithenge/print.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/print.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/print.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Write a tree as JSON or other text formats.
+ */
+
+#ifndef BITHENGE_PRINT_H_
+#define BITHENGE_PRINT_H_
+
+#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;
+
+int bithenge_print_node(bithenge_print_type_t, bithenge_node_t *);
+int bithenge_print_node_to_string(char **, size_t *, bithenge_print_type_t,
+    bithenge_node_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/script.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/script.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/script.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Script parsing.
+ */
+
+#ifndef BITHENGE_SCRIPT_H_
+#define BITHENGE_SCRIPT_H_
+
+#include "transform.h"
+
+int bithenge_parse_script(const char *, bithenge_transform_t **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/sequence.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/sequence.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/sequence.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Sequence transforms.
+ */
+
+#ifndef BITHENGE_SEQUENCE_H_
+#define BITHENGE_SEQUENCE_H_
+
+#include "transform.h"
+
+int bithenge_new_struct(bithenge_transform_t **,
+    bithenge_named_transform_t *);
+int bithenge_repeat_transform(bithenge_transform_t **, bithenge_transform_t *,
+    bithenge_expression_t *);
+int bithenge_do_while_transform(bithenge_transform_t **,
+    bithenge_transform_t *, bithenge_expression_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/source.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/source.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/source.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Provide various external sources of data.
+ */
+
+#ifndef BITHENGE_SOURCE_H_
+#define BITHENGE_SOURCE_H_
+
+#include "tree.h"
+
+int bithenge_node_from_source(bithenge_node_t **, const char *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/transform.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/transform.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/transform.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Transforms.
+ */
+
+#ifndef BITHENGE_TRANSFORM_H_
+#define BITHENGE_TRANSFORM_H_
+
+#include "blob.h"
+#include "tree.h"
+
+/** A transform that creates a new tree from an old tree. */
+typedef struct {
+	/** @privatesection */
+	const struct bithenge_transform_ops *ops;
+	unsigned int refs;
+	int num_params;
+} bithenge_transform_t;
+
+/** Context and parameters used when applying transforms. */
+typedef struct bithenge_scope {
+	/** @privatesection */
+	unsigned int refs;
+	struct bithenge_scope *outer;
+	char *error;
+	bool barrier;
+	int num_params;
+	bithenge_node_t **params;
+	bithenge_node_t *current_node;
+	bithenge_node_t *in_node;
+} bithenge_scope_t;
+
+/** Increment a scope's reference count.
+ * @memberof bithenge_scope_t
+ * @param self The scope to reference. */
+static inline void bithenge_scope_inc_ref(bithenge_scope_t *self)
+{
+	assert(self);
+	self->refs++;
+}
+
+/** Operations that may be provided by a transform. All transforms must provide
+ * apply and/or prefix_apply. To be used in struct transforms and repeat
+ * transforms, transforms must provide prefix_length and/or prefix_apply. */
+typedef struct bithenge_transform_ops {
+	/** @copydoc bithenge_transform_t::bithenge_transform_apply */
+	int (*apply)(bithenge_transform_t *self, bithenge_scope_t *scope,
+	    bithenge_node_t *in, bithenge_node_t **out);
+	/** @copydoc bithenge_transform_t::bithenge_transform_prefix_length */
+	int (*prefix_length)(bithenge_transform_t *self,
+	    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out);
+	/** @copydoc bithenge_transform_t::bithenge_transform_prefix_apply */
+	int (*prefix_apply)(bithenge_transform_t *self,
+	    bithenge_scope_t *scope, bithenge_blob_t *blob,
+	    bithenge_node_t **out_node, aoff64_t *out_size);
+	/** Destroy the transform.
+	 * @param self The transform. */
+	void (*destroy)(bithenge_transform_t *self);
+} bithenge_transform_ops_t;
+
+/** Get the number of parameters required by a transform. This number is used
+ * by the parser and param-wrapper. Takes ownership of nothing.
+ * @param self The transform.
+ * @return The number of parameters required. */
+static inline int bithenge_transform_num_params(bithenge_transform_t *self)
+{
+	assert(self);
+	return self->num_params;
+}
+
+/** Increment a transform's reference count.
+ * @param self The transform to reference. */
+static inline void bithenge_transform_inc_ref(bithenge_transform_t *self)
+{
+	assert(self);
+	self->refs++;
+}
+
+/** Decrement a transform's reference count and free it if appropriate.
+ * @param self The transform to dereference, or NULL. */
+static inline void bithenge_transform_dec_ref(bithenge_transform_t *self)
+{
+	if (!self)
+		return;
+	assert(self->ops);
+	assert(self->refs > 0);
+	if (--self->refs == 0)
+		self->ops->destroy(self);
+}
+
+/** A transform with a name. */
+typedef struct {
+	/** The transform's name. */
+	const char *name;
+	/** The transform. */
+	bithenge_transform_t *transform;
+} bithenge_named_transform_t;
+
+/** Transform that decodes an 8-bit unsigned integer */
+extern bithenge_transform_t bithenge_uint8_transform;
+/** Transform that decodes a 16-bit little-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint16le_transform;
+/** Transform that decodes a 16-bit big-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint16be_transform;
+/** Transform that decodes a 32-bit little-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint32le_transform;
+/** Transform that decodes a 32-bit big-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint32be_transform;
+/** Transform that decodes a 64-bit little-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint64le_transform;
+/** Transform that decodes a 64-bit big-endian unsigned integer */
+extern bithenge_transform_t bithenge_uint64be_transform;
+
+/** @cond */
+extern bithenge_transform_t bithenge_ascii_transform;
+extern bithenge_transform_t bithenge_bit_transform;
+extern bithenge_transform_t bithenge_bits_be_transform;
+extern bithenge_transform_t bithenge_bits_le_transform;
+extern bithenge_transform_t bithenge_invalid_transform;
+extern bithenge_transform_t bithenge_known_length_transform;
+extern bithenge_transform_t bithenge_nonzero_boolean_transform;
+extern bithenge_transform_t bithenge_uint_le_transform;
+extern bithenge_transform_t bithenge_uint_be_transform;
+extern bithenge_transform_t bithenge_zero_terminated_transform;
+extern bithenge_named_transform_t *bithenge_primitive_transforms;
+/** @endcond */
+
+/** @memberof bithenge_transform_t */
+int bithenge_init_transform(bithenge_transform_t *,
+    const bithenge_transform_ops_t *, int);
+/** @memberof bithenge_transform_t */
+int bithenge_transform_apply(bithenge_transform_t *, bithenge_scope_t *,
+    bithenge_node_t *, bithenge_node_t **);
+/** @memberof bithenge_transform_t */
+int bithenge_transform_prefix_length(bithenge_transform_t *,
+    bithenge_scope_t *, bithenge_blob_t *, aoff64_t *);
+/** @memberof bithenge_transform_t */
+int bithenge_transform_prefix_apply(bithenge_transform_t *, bithenge_scope_t *,
+    bithenge_blob_t *, bithenge_node_t **, aoff64_t *);
+int bithenge_new_barrier_transform(bithenge_transform_t **, int);
+int bithenge_barrier_transform_set_subtransform(bithenge_transform_t *,
+    bithenge_transform_t *);
+
+/** @memberof bithenge_scope_t */
+int bithenge_scope_new(bithenge_scope_t **, bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+void bithenge_scope_dec_ref(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+const char *bithenge_scope_get_error(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+int bithenge_scope_error(bithenge_scope_t *, const char *, ...);
+/** @memberof bithenge_scope_t */
+bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
+/** @memberof bithenge_scope_t */
+bithenge_node_t *bithenge_scope_in_node(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+void bithenge_scope_set_in_node(bithenge_scope_t *, bithenge_node_t *);
+/** @memberof bithenge_scope_t */
+void bithenge_scope_set_barrier(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+bool bithenge_scope_is_barrier(bithenge_scope_t *);
+/** @memberof bithenge_scope_t */
+int bithenge_scope_alloc_params(bithenge_scope_t *, int);
+/** @memberof bithenge_scope_t */
+int bithenge_scope_set_param(bithenge_scope_t *, int, bithenge_node_t *);
+/** @memberof bithenge_scope_t */
+int bithenge_scope_get_param(bithenge_scope_t *, int, bithenge_node_t **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/bithenge/include/bithenge/tree.h
===================================================================
--- uspace/lib/bithenge/include/bithenge/tree.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
+++ uspace/lib/bithenge/include/bithenge/tree.h	(revision 8fc0f47c1df8d2de3f0806c0f4fae3fc186c5a63)
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012 Sean Bartell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bithenge
+ * @{
+ */
+/**
+ * @file
+ * Trees and nodes.
+ */
+
+#ifndef BITHENGE_TREE_H_
+#define BITHENGE_TREE_H_
+
+#include <assert.h>
+#include <sys/types.h>
+#include "os.h"
+
+/** Indicates the type of a tree node. */
+typedef enum {
+	/** 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;
+
+/** A tree node. It can have any of the types in @a bithenge_node_type_t. */
+typedef struct bithenge_node_t {
+	/** @privatesection */
+	bithenge_node_type_t type;
+	unsigned int refs;
+	union {
+		/** @privatesection */
+		const struct bithenge_internal_node_ops_t *internal_ops;
+		bool boolean_value;
+		bithenge_int_t integer_value;
+		struct {
+			/** @privatesection */
+			const char *ptr;
+			bool needs_free;
+		} string_value;
+		const struct bithenge_random_access_blob_ops_t *blob_ops;
+	};
+} bithenge_node_t;
+
+/** A callback function used to iterate over a node's children. It takes
+ * ownership of a reference to both the key and the value.
+ * @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 *self, bithenge_for_each_func_t func, void *data);
+	/** @copydoc bithenge_node_t::bithenge_node_get */
+	int (*get)(bithenge_node_t *self, bithenge_node_t *key,
+	    bithenge_node_t **out);
+	/** Destroys the internal node.
+	 * @param self The node to destroy. */
+	void (*destroy)(bithenge_node_t *self);
+} 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)
+{
+	return node->type;
+}
+
+/** Increment a node's reference count.
+ * @memberof bithenge_node_t
+ * @param node The node to reference. */
+static inline void bithenge_node_inc_ref(bithenge_node_t *node)
+{
+	assert(node);
+	node->refs++;
+}
+
+/** @memberof bithenge_node_t */
+void bithenge_node_dec_ref(bithenge_node_t *node);
+
+/** Iterate over a node's children.
+ * @memberof bithenge_node_t
+ * @param self 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 *self,
+    bithenge_for_each_func_t func, void *data)
+{
+	assert(self->type == BITHENGE_NODE_INTERNAL);
+	return self->internal_ops->for_each(self, func, data);
+}
+
+/** @memberof bithenge_node_t */
+int bithenge_node_get(bithenge_node_t *, bithenge_node_t *,
+    bithenge_node_t **);
+
+/** Get the value of a boolean node.
+ * @memberof bithenge_node_t
+ * @param self The boolean node.
+ * @return The node's value. */
+static inline bool bithenge_boolean_node_value(bithenge_node_t *self)
+{
+	assert(self->type == BITHENGE_NODE_BOOLEAN);
+	return self->boolean_value;
+}
+
+/** Get the value of an integer node.
+ * @memberof bithenge_node_t
+ * @param self The integer node.
+ * @return The node's value. */
+static inline bithenge_int_t bithenge_integer_node_value(bithenge_node_t *self)
+{
+	assert(self->type == BITHENGE_NODE_INTEGER);
+	return self->integer_value;
+}
+
+/** Get the value of an string node.
+ * @memberof bithenge_node_t
+ * @param self The string node.
+ * @return The node's value. */
+static inline const char *bithenge_string_node_value(bithenge_node_t *self)
+{
+	assert(self->type == BITHENGE_NODE_STRING);
+	return self->string_value.ptr;
+}
+
+/** @memberof bithenge_node_t */
+int bithenge_init_internal_node(bithenge_node_t *,
+    const bithenge_internal_node_ops_t *);
+/** @memberof bithenge_node_t */
+int bithenge_new_empty_internal_node(bithenge_node_t **);
+/** @memberof bithenge_node_t */
+int bithenge_new_simple_internal_node(bithenge_node_t **, bithenge_node_t **,
+    bithenge_int_t, bool needs_free);
+/** @memberof bithenge_node_t */
+int bithenge_new_boolean_node(bithenge_node_t **, bool);
+/** @memberof bithenge_node_t */
+int bithenge_new_integer_node(bithenge_node_t **, bithenge_int_t);
+/** @memberof bithenge_node_t */
+int bithenge_new_string_node(bithenge_node_t **, const char *, bool);
+/** @memberof bithenge_node_t */
+int bithenge_node_equal(bool *, bithenge_node_t *, bithenge_node_t *);
+
+#endif
+
+/** @}
+ */
