Index: uspace/app/bithenge/expression.c
===================================================================
--- uspace/app/bithenge/expression.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
+++ uspace/app/bithenge/expression.c	(revision 0191bd3efb1fc5fd218c8631ca40bac06aa0f3a8)
@@ -425,5 +425,5 @@
 	param_wrapper_t *self = transform_as_param_wrapper(base);
 	bithenge_scope_t *inner;
-	int rc = bithenge_scope_new(&inner);
+	int rc = bithenge_scope_new(&inner, outer);
 	if (rc != EOK)
 		return rc;
@@ -445,5 +445,5 @@
 	param_wrapper_t *self = transform_as_param_wrapper(base);
 	bithenge_scope_t *inner;
-	int rc = bithenge_scope_new(&inner);
+	int rc = bithenge_scope_new(&inner, outer);
 	if (rc != EOK)
 		return rc;
@@ -454,4 +454,25 @@
 	rc = bithenge_transform_prefix_length(self->transform, inner, in, out);
 	in = NULL;
+
+error:
+	bithenge_scope_dec_ref(inner);
+	return rc;
+}
+
+static int param_wrapper_prefix_apply(bithenge_transform_t *base,
+    bithenge_scope_t *outer, bithenge_blob_t *in, bithenge_node_t **out_node,
+    aoff64_t *out_length)
+{
+	param_wrapper_t *self = transform_as_param_wrapper(base);
+	bithenge_scope_t *inner;
+	int rc = bithenge_scope_new(&inner, outer);
+	if (rc != EOK)
+		return rc;
+	rc = param_wrapper_fill_scope(self, inner, outer);
+	if (rc != EOK)
+		goto error;
+
+	rc = bithenge_transform_prefix_apply(self->transform, inner, in,
+	    out_node, out_length);
 
 error:
@@ -474,4 +495,5 @@
 	.apply = param_wrapper_apply,
 	.prefix_length = param_wrapper_prefix_length,
+	.prefix_apply = param_wrapper_prefix_apply,
 	.destroy = param_wrapper_destroy,
 };
Index: uspace/app/bithenge/sequence.c
===================================================================
--- uspace/app/bithenge/sequence.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
+++ uspace/app/bithenge/sequence.c	(revision 0191bd3efb1fc5fd218c8631ca40bac06aa0f3a8)
@@ -267,15 +267,7 @@
 	self->num_ends = 0;
 	self->end_on_empty = end_on_empty;
-	int rc = bithenge_scope_new(&self->scope);
-	if (rc != EOK) {
-		free(self->ends);
-		return rc;
-	}
-	rc = bithenge_scope_copy(self->scope, scope);
-	if (rc != EOK) {
-		bithenge_scope_dec_ref(self->scope);
-		free(self->ends);
-		return rc;
-	}
+	self->scope = scope;
+	if (self->scope)
+		bithenge_scope_inc_ref(self->scope);
 	return EOK;
 }
@@ -468,7 +460,19 @@
 		return rc;
 	}
-
-	rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, scope,
+	bithenge_scope_t *inner;
+	rc = bithenge_scope_new(&inner, scope);
+	if (rc != EOK) {
+		free(node);
+		return rc;
+	}
+	/* We should inc_ref(node) here, but that would make a cycle. Instead,
+	 * we leave it 1 too low, so that when the only remaining use of node
+	 * is the scope, node will be destroyed. Also see the comment in
+	 * struct_node_destroy. */
+	bithenge_scope_set_current_node(inner, struct_as_node(node));
+
+	rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, inner,
 	    blob, self->num_subtransforms, false);
+	bithenge_scope_dec_ref(inner);
 	if (rc != EOK) {
 		free(node);
@@ -480,11 +484,4 @@
 	node->prefix = prefix;
 	*out = struct_as_node(node);
-
-	/* We should inc_ref(*out) here, but that would make a cycle. Instead,
-	 * we leave it 1 too low, so that when the only remaining use of *out
-	 * is the scope, *out will be destroyed. Also see the comment in
-	 * struct_node_destroy. */
-	bithenge_scope_set_current_node(seq_node_scope(struct_as_seq(node)),
-	    *out);
 
 	return EOK;
@@ -942,16 +939,11 @@
 
 		bithenge_scope_t *scope;
-		rc = bithenge_scope_new(&scope);
+		rc = bithenge_scope_new(&scope,
+		    seq_node_scope(do_while_as_seq(self)));
 		if (rc != EOK) {
 			bithenge_node_dec_ref(subxform_result);
 			return rc;
 		}
-		rc = bithenge_scope_copy(scope,
-		    seq_node_scope(do_while_as_seq(self)));
 		bithenge_scope_set_current_node(scope, subxform_result);
-		if (rc != EOK) {
-			bithenge_scope_dec_ref(scope);
-			return rc;
-		}
 		bithenge_node_t *expr_result;
 		rc = bithenge_expression_evaluate(self->expr, scope,
Index: uspace/app/bithenge/test.c
===================================================================
--- uspace/app/bithenge/test.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
+++ uspace/app/bithenge/test.c	(revision 0191bd3efb1fc5fd218c8631ca40bac06aa0f3a8)
@@ -73,5 +73,5 @@
 		bithenge_node_t *node = NULL, *node2 = NULL;
 
-		rc = bithenge_scope_new(&scope);
+		rc = bithenge_scope_new(&scope, NULL);
 		if (rc != EOK) {
 			printf("Error creating scope: %s\n", str_error(rc));
Index: uspace/app/bithenge/transform.c
===================================================================
--- uspace/app/bithenge/transform.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
+++ uspace/app/bithenge/transform.c	(revision 0191bd3efb1fc5fd218c8631ca40bac06aa0f3a8)
@@ -166,8 +166,9 @@
 
 /** Create a transform scope. It must be dereferenced with @a
- * bithenge_scope_dec_ref after it is used.
+ * bithenge_scope_dec_ref after it is used. Takes ownership of nothing.
  * @param[out] out Holds the new scope.
+ * @param outer The outer scope, or NULL.
  * @return EOK on success or an error code from errno.h. */
-int bithenge_scope_new(bithenge_scope_t **out)
+int bithenge_scope_new(bithenge_scope_t **out, bithenge_scope_t *outer)
 {
 	bithenge_scope_t *self = malloc(sizeof(*self));
@@ -175,4 +176,7 @@
 		return ENOMEM;
 	self->refs = 1;
+	if (outer)
+		bithenge_scope_inc_ref(outer);
+	self->outer = outer;
 	self->num_params = 0;
 	self->params = NULL;
@@ -186,11 +190,14 @@
 void bithenge_scope_dec_ref(bithenge_scope_t *self)
 {
-	if (!--self->refs) {
-		bithenge_node_dec_ref(self->current_node);
-		for (int i = 0; i < self->num_params; i++)
-			bithenge_node_dec_ref(self->params[i]);
-		free(self->params);
-		free(self);
-	}
+	if (!self)
+		return;
+	if (--self->refs)
+		return;
+	bithenge_node_dec_ref(self->current_node);
+	for (int i = 0; i < self->num_params; i++)
+		bithenge_node_dec_ref(self->params[i]);
+	bithenge_scope_dec_ref(self->outer);
+	free(self->params);
+	free(self);
 }
 
@@ -279,8 +286,12 @@
 {
 	assert(scope);
-	assert(i >= 0 && i < scope->num_params);
-	*out = scope->params[i];
-	bithenge_node_inc_ref(*out);
-	return EOK;
+	if (scope->num_params) {
+		assert(i >= 0 && i < scope->num_params);
+		*out = scope->params[i];
+		bithenge_node_inc_ref(*out);
+		return EOK;
+	} else {
+		return bithenge_scope_get_param(scope->outer, i, out);
+	}
 }
 
@@ -307,13 +318,8 @@
 	scope_transform_t *self = transform_as_param(base);
 	bithenge_scope_t *inner_scope;
-	int rc = bithenge_scope_new(&inner_scope);
-	if (rc != EOK)
-		return rc;
-	rc = bithenge_scope_copy(inner_scope, scope);
-	if (rc != EOK)
-		goto error;
-	bithenge_scope_set_current_node(inner_scope, NULL);
+	int rc = bithenge_scope_new(&inner_scope, scope);
+	if (rc != EOK)
+		return rc;
 	rc = bithenge_transform_apply(self->transform, scope, in, out);
-error:
 	bithenge_scope_dec_ref(inner_scope);
 	return rc;
Index: uspace/app/bithenge/transform.h
===================================================================
--- uspace/app/bithenge/transform.h	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
+++ uspace/app/bithenge/transform.h	(revision 0191bd3efb1fc5fd218c8631ca40bac06aa0f3a8)
@@ -50,7 +50,8 @@
 
 /** Context and parameters used when applying transforms. */
-typedef struct {
+typedef struct bithenge_scope {
 	/** @privatesection */
 	unsigned int refs;
+	struct bithenge_scope *outer;
 	int num_params;
 	bithenge_node_t **params;
@@ -148,5 +149,5 @@
     bithenge_transform_t **, size_t);
 
-int bithenge_scope_new(bithenge_scope_t **);
+int bithenge_scope_new(bithenge_scope_t **, bithenge_scope_t *);
 void bithenge_scope_dec_ref(bithenge_scope_t *);
 int bithenge_scope_copy(bithenge_scope_t *, bithenge_scope_t *);
