Index: uspace/app/bithenge/Makefile
===================================================================
--- uspace/app/bithenge/Makefile	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/Makefile	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -35,4 +35,5 @@
 	helenos/block.c \
 	blob.c \
+	compound.c \
 	expression.c \
 	file.c \
Index: uspace/app/bithenge/Makefile.linux
===================================================================
--- uspace/app/bithenge/Makefile.linux	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/Makefile.linux	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -36,4 +36,5 @@
 SOURCES = \
 	blob.c \
+	compound.c \
 	expression.c \
 	file.c \
Index: uspace/app/bithenge/compound.c
===================================================================
--- uspace/app/bithenge/compound.c	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
+++ uspace/app/bithenge/compound.c	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "compound.h"
+#include "expression.h"
+#include "transform.h"
+#include "tree.h"
+
+
+
+/***************** compose_transform                         *****************/
+
+typedef struct {
+	bithenge_transform_t base;
+	bithenge_transform_t **xforms;
+	size_t num;
+} compose_transform_t;
+
+static bithenge_transform_t *compose_as_transform(compose_transform_t *xform)
+{
+	return &xform->base;
+}
+
+static compose_transform_t *transform_as_compose(bithenge_transform_t *xform)
+{
+	return (compose_transform_t *)xform;
+}
+
+static int compose_apply(bithenge_transform_t *base, bithenge_scope_t *scope,
+    bithenge_node_t *in, bithenge_node_t **out)
+{
+	int rc;
+	compose_transform_t *self = transform_as_compose(base);
+	bithenge_node_inc_ref(in);
+
+	/* i ranges from (self->num - 1) to 0 inside the loop. */
+	for (size_t i = self->num; i--; ) {
+		bithenge_node_t *tmp;
+		rc = bithenge_transform_apply(self->xforms[i], scope, in,
+		    &tmp);
+		bithenge_node_dec_ref(in);
+		if (rc != EOK)
+			return rc;
+		in = tmp;
+	}
+
+	*out = in;
+	return rc;
+}
+
+static int compose_prefix_length(bithenge_transform_t *base,
+    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
+{
+	compose_transform_t *self = transform_as_compose(base);
+	return bithenge_transform_prefix_length(self->xforms[self->num - 1],
+	    scope, blob, out);
+}
+
+static void compose_destroy(bithenge_transform_t *base)
+{
+	compose_transform_t *self = transform_as_compose(base);
+	for (size_t i = 0; i < self->num; i++)
+		bithenge_transform_dec_ref(self->xforms[i]);
+	free(self->xforms);
+	free(self);
+}
+
+static const bithenge_transform_ops_t compose_transform_ops = {
+	.apply = compose_apply,
+	.prefix_length = compose_prefix_length,
+	.destroy = compose_destroy,
+};
+
+/** Create a composition of multiple transforms. When the result is applied to a
+ * node, each transform is applied in turn, with the last transform applied
+ * first. @a xforms may contain any number of transforms or no transforms at
+ * all. This function takes ownership of @a xforms and the references therein.
+ * @param[out] out Holds the result.
+ * @param[in] xforms The transforms to apply.
+ * @param num The number of transforms.
+ * @return EOK on success or an error code from errno.h. */
+int bithenge_new_composed_transform(bithenge_transform_t **out,
+    bithenge_transform_t **xforms, size_t num)
+{
+	if (num == 0) {
+		/* TODO: optimize */
+	} else if (num == 1) {
+		*out = xforms[0];
+		free(xforms);
+		return EOK;
+	}
+
+	int rc;
+	compose_transform_t *self = malloc(sizeof(*self));
+	if (!self) {
+		rc = ENOMEM;
+		goto error;
+	}
+	rc = bithenge_init_transform(compose_as_transform(self),
+	    &compose_transform_ops, 0);
+	if (rc != EOK)
+		goto error;
+	self->xforms = xforms;
+	self->num = num;
+	*out = compose_as_transform(self);
+	return EOK;
+error:
+	for (size_t i = 0; i < num; i++)
+		bithenge_transform_dec_ref(xforms[i]);
+	free(xforms);
+	free(self);
+	return rc;
+}
+
+
+
+/***************** if_transform                              *****************/
+
+typedef struct {
+	bithenge_transform_t base;
+	bithenge_expression_t *expr;
+	bithenge_transform_t *true_xform, *false_xform;
+} if_transform_t;
+
+static inline bithenge_transform_t *if_as_transform(if_transform_t *self)
+{
+	return &self->base;
+}
+
+static inline if_transform_t *transform_as_if(bithenge_transform_t *base)
+{
+	return (if_transform_t *)base;
+}
+
+static int if_transform_choose(if_transform_t *self, bithenge_scope_t *scope,
+    bool *out)
+{
+	bithenge_node_t *cond_node;
+	int rc = bithenge_expression_evaluate(self->expr, scope, &cond_node);
+	if (rc != EOK)
+		return rc;
+	if (bithenge_node_type(cond_node) != BITHENGE_NODE_BOOLEAN) {
+		bithenge_node_dec_ref(cond_node);
+		return EINVAL;
+	}
+	*out = bithenge_boolean_node_value(cond_node);
+	bithenge_node_dec_ref(cond_node);
+	return EOK;
+}
+
+static int if_transform_apply(bithenge_transform_t *base,
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
+{
+	if_transform_t *self = transform_as_if(base);
+	bool cond;
+	int rc = if_transform_choose(self, scope, &cond);
+	if (rc != EOK)
+		return rc;
+	return bithenge_transform_apply(
+	    cond ? self->true_xform : self->false_xform, scope, in, out);
+}
+
+static int if_transform_prefix_length(bithenge_transform_t *base,
+    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
+{
+	if_transform_t *self = transform_as_if(base);
+	bool cond;
+	int rc = if_transform_choose(self, scope, &cond);
+	if (rc != EOK)
+		return rc;
+	return bithenge_transform_prefix_length(
+	    cond ? self->true_xform : self->false_xform, scope, in, out);
+}
+
+static void if_transform_destroy(bithenge_transform_t *base)
+{
+	if_transform_t *self = transform_as_if(base);
+	bithenge_expression_dec_ref(self->expr);
+	bithenge_transform_dec_ref(self->true_xform);
+	bithenge_transform_dec_ref(self->false_xform);
+	free(self);
+}
+
+static const bithenge_transform_ops_t if_transform_ops = {
+	.apply = if_transform_apply,
+	.prefix_length = if_transform_prefix_length,
+	.destroy = if_transform_destroy,
+};
+
+/** Create a transform that applies either of two transforms depending on a
+ * boolean expression. Takes references to @a expr, @a true_xform, and
+ * @a false_xform.
+ * @param[out] out Holds the new transform.
+ * @param expr The boolean expression to evaluate.
+ * @param true_xform The transform to apply if the expression is true.
+ * @param false_xform The transform to apply if the expression is false.
+ * @return EOK on success or an error code from errno.h. */
+int bithenge_if_transform(bithenge_transform_t **out,
+    bithenge_expression_t *expr, bithenge_transform_t *true_xform,
+    bithenge_transform_t *false_xform)
+{
+	int rc;
+	if_transform_t *self = malloc(sizeof(*self));
+	if (!self) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = bithenge_init_transform(if_as_transform(self), &if_transform_ops,
+	    0);
+	if (rc != EOK)
+		goto error;
+
+	self->expr = expr;
+	self->true_xform = true_xform;
+	self->false_xform = false_xform;
+	*out = if_as_transform(self);
+	return EOK;
+
+error:
+	free(self);
+	bithenge_expression_dec_ref(expr);
+	bithenge_transform_dec_ref(true_xform);
+	bithenge_transform_dec_ref(false_xform);
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/app/bithenge/compound.h
===================================================================
--- uspace/app/bithenge/compound.h	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
+++ uspace/app/bithenge/compound.h	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -0,0 +1,51 @@
+/*
+ * 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 *);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/bithenge/expression.c
===================================================================
--- uspace/app/bithenge/expression.c	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/expression.c	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -100,5 +100,5 @@
 
 	/* Check types and get values. */
-	bithenge_int_t a_int, b_int;
+	bithenge_int_t a_int = 0, b_int = 0;
 	switch (self->op) {
 	case BITHENGE_EXPRESSION_ADD: /* fallthrough */
@@ -961,117 +961,4 @@
 }
 
-
-
-/***************** if_transform                              *****************/
-
-typedef struct {
-	bithenge_transform_t base;
-	bithenge_expression_t *expr;
-	bithenge_transform_t *true_xform, *false_xform;
-} if_transform_t;
-
-static inline bithenge_transform_t *if_as_transform(if_transform_t *self)
-{
-	return &self->base;
-}
-
-static inline if_transform_t *transform_as_if(bithenge_transform_t *base)
-{
-	return (if_transform_t *)base;
-}
-
-static int if_transform_choose(if_transform_t *self, bithenge_scope_t *scope,
-    bool *out)
-{
-	bithenge_node_t *cond_node;
-	int rc = bithenge_expression_evaluate(self->expr, scope, &cond_node);
-	if (rc != EOK)
-		return rc;
-	if (bithenge_node_type(cond_node) != BITHENGE_NODE_BOOLEAN) {
-		bithenge_node_dec_ref(cond_node);
-		return EINVAL;
-	}
-	*out = bithenge_boolean_node_value(cond_node);
-	bithenge_node_dec_ref(cond_node);
-	return EOK;
-}
-
-static int if_transform_apply(bithenge_transform_t *base,
-    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
-{
-	if_transform_t *self = transform_as_if(base);
-	bool cond;
-	int rc = if_transform_choose(self, scope, &cond);
-	if (rc != EOK)
-		return rc;
-	return bithenge_transform_apply(
-	    cond ? self->true_xform : self->false_xform, scope, in, out);
-}
-
-static int if_transform_prefix_length(bithenge_transform_t *base,
-    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
-{
-	if_transform_t *self = transform_as_if(base);
-	bool cond;
-	int rc = if_transform_choose(self, scope, &cond);
-	if (rc != EOK)
-		return rc;
-	return bithenge_transform_prefix_length(
-	    cond ? self->true_xform : self->false_xform, scope, in, out);
-}
-
-static void if_transform_destroy(bithenge_transform_t *base)
-{
-	if_transform_t *self = transform_as_if(base);
-	bithenge_expression_dec_ref(self->expr);
-	bithenge_transform_dec_ref(self->true_xform);
-	bithenge_transform_dec_ref(self->false_xform);
-	free(self);
-}
-
-static const bithenge_transform_ops_t if_transform_ops = {
-	.apply = if_transform_apply,
-	.prefix_length = if_transform_prefix_length,
-	.destroy = if_transform_destroy,
-};
-
-/** Create a transform that applies either of two transforms depending on a
- * boolean expression. Takes references to @a expr, @a true_xform, and
- * @a false_xform.
- * @param[out] out Holds the new transform.
- * @param expr The boolean expression to evaluate.
- * @param true_xform The transform to apply if the expression is true.
- * @param false_xform The transform to apply if the expression is false.
- * @return EOK on success or an error code from errno.h. */
-int bithenge_if_transform(bithenge_transform_t **out,
-    bithenge_expression_t *expr, bithenge_transform_t *true_xform,
-    bithenge_transform_t *false_xform)
-{
-	int rc;
-	if_transform_t *self = malloc(sizeof(*self));
-	if (!self) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = bithenge_init_transform(if_as_transform(self), &if_transform_ops,
-	    0);
-	if (rc != EOK)
-		goto error;
-
-	self->expr = expr;
-	self->true_xform = true_xform;
-	self->false_xform = false_xform;
-	*out = if_as_transform(self);
-	return EOK;
-
-error:
-	free(self);
-	bithenge_expression_dec_ref(expr);
-	bithenge_transform_dec_ref(true_xform);
-	bithenge_transform_dec_ref(false_xform);
-	return rc;
-}
-
 /** @}
  */
Index: uspace/app/bithenge/expression.h
===================================================================
--- uspace/app/bithenge/expression.h	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/expression.h	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -120,6 +120,4 @@
 int bithenge_inputless_transform(bithenge_transform_t **,
     bithenge_expression_t *);
-int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *,
-    bithenge_transform_t *, bithenge_transform_t *);
 
 #endif
Index: uspace/app/bithenge/script.c
===================================================================
--- uspace/app/bithenge/script.c	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/script.c	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -38,4 +38,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include "compound.h"
 #include "expression.h"
 #include "os.h"
@@ -537,5 +538,5 @@
 			next_token(state);
 			bithenge_expression_t *start = parse_expression(state);
-			bool absolute_limit;
+			bool absolute_limit = false;
 			if (state->token == ',') {
 				absolute_limit = false;
Index: uspace/app/bithenge/transform.c
===================================================================
--- uspace/app/bithenge/transform.c	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/transform.c	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -948,106 +948,4 @@
 bithenge_named_transform_t *bithenge_primitive_transforms = primitive_transforms;
 
-typedef struct {
-	bithenge_transform_t base;
-	bithenge_transform_t **xforms;
-	size_t num;
-} compose_transform_t;
-
-static bithenge_transform_t *compose_as_transform(compose_transform_t *xform)
-{
-	return &xform->base;
-}
-
-static compose_transform_t *transform_as_compose(bithenge_transform_t *xform)
-{
-	return (compose_transform_t *)xform;
-}
-
-static int compose_apply(bithenge_transform_t *base, bithenge_scope_t *scope,
-    bithenge_node_t *in, bithenge_node_t **out)
-{
-	int rc;
-	compose_transform_t *self = transform_as_compose(base);
-	bithenge_node_inc_ref(in);
-
-	/* i ranges from (self->num - 1) to 0 inside the loop. */
-	for (size_t i = self->num; i--; ) {
-		bithenge_node_t *tmp;
-		rc = bithenge_transform_apply(self->xforms[i], scope, in,
-		    &tmp);
-		bithenge_node_dec_ref(in);
-		if (rc != EOK)
-			return rc;
-		in = tmp;
-	}
-
-	*out = in;
-	return rc;
-}
-
-static int compose_prefix_length(bithenge_transform_t *base,
-    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
-{
-	compose_transform_t *self = transform_as_compose(base);
-	return bithenge_transform_prefix_length(self->xforms[self->num - 1],
-	    scope, blob, out);
-}
-
-static void compose_destroy(bithenge_transform_t *base)
-{
-	compose_transform_t *self = transform_as_compose(base);
-	for (size_t i = 0; i < self->num; i++)
-		bithenge_transform_dec_ref(self->xforms[i]);
-	free(self->xforms);
-	free(self);
-}
-
-static const bithenge_transform_ops_t compose_transform_ops = {
-	.apply = compose_apply,
-	.prefix_length = compose_prefix_length,
-	.destroy = compose_destroy,
-};
-
-/** Create a composition of multiple transforms. When the result is applied to a
- * node, each transform is applied in turn, with the last transform applied
- * first. @a xforms may contain any number of transforms or no transforms at
- * all. This function takes ownership of @a xforms and the references therein.
- * @param[out] out Holds the result.
- * @param[in] xforms The transforms to apply.
- * @param num The number of transforms.
- * @return EOK on success or an error code from errno.h. */
-int bithenge_new_composed_transform(bithenge_transform_t **out,
-    bithenge_transform_t **xforms, size_t num)
-{
-	if (num == 0) {
-		/* TODO: optimize */
-	} else if (num == 1) {
-		*out = xforms[0];
-		free(xforms);
-		return EOK;
-	}
-
-	int rc;
-	compose_transform_t *self = malloc(sizeof(*self));
-	if (!self) {
-		rc = ENOMEM;
-		goto error;
-	}
-	rc = bithenge_init_transform(compose_as_transform(self),
-	    &compose_transform_ops, 0);
-	if (rc != EOK)
-		goto error;
-	self->xforms = xforms;
-	self->num = num;
-	*out = compose_as_transform(self);
-	return EOK;
-error:
-	for (size_t i = 0; i < num; i++)
-		bithenge_transform_dec_ref(xforms[i]);
-	free(xforms);
-	free(self);
-	return rc;
-}
-
 /** @}
  */
Index: uspace/app/bithenge/transform.h
===================================================================
--- uspace/app/bithenge/transform.h	(revision 0b60d2d47221c07abcdbaee1d5cc498326a6864f)
+++ uspace/app/bithenge/transform.h	(revision 3c703767f6ec69e1d894e99c18f5144778023d4c)
@@ -148,6 +148,4 @@
 int bithenge_new_barrier_transform(bithenge_transform_t **,
     bithenge_transform_t *, int);
-int bithenge_new_composed_transform(bithenge_transform_t **,
-    bithenge_transform_t **, size_t);
 
 int bithenge_scope_new(bithenge_scope_t **, bithenge_scope_t *);
