Index: uspace/app/bithenge/test.c
===================================================================
--- uspace/app/bithenge/test.c	(revision 43788b27b09a2c46c1076f96736c5d958a7268e3)
+++ uspace/app/bithenge/test.c	(revision 5a7c0e69a8cde81b5273b8c4db8c48fa734f8665)
@@ -69,9 +69,9 @@
 		bithenge_node_dec_ref(node);
 	} else {
-		bithenge_transform_context_t context;
+		bithenge_scope_t scope;
 		bithenge_transform_t *transform = NULL;
 		bithenge_node_t *node = NULL, *node2 = NULL;
 
-		bithenge_transform_context_init(&context);
+		bithenge_scope_init(&scope);
 
 		rc = bithenge_parse_script(argv[1], &transform);
@@ -87,5 +87,5 @@
 		}
 
-		rc = bithenge_transform_apply(transform, &context, node, &node2);
+		rc = bithenge_transform_apply(transform, &scope, node, &node2);
 		if (rc != EOK) {
 			printf("Error applying transform: %s\n", str_error(rc));
@@ -113,5 +113,5 @@
 		bithenge_node_dec_ref(node2);
 		bithenge_transform_dec_ref(transform);
-		bithenge_transform_context_destroy(&context);
+		bithenge_scope_destroy(&scope);
 		return 1;
 	}
Index: uspace/app/bithenge/transform.c
===================================================================
--- uspace/app/bithenge/transform.c	(revision 43788b27b09a2c46c1076f96736c5d958a7268e3)
+++ uspace/app/bithenge/transform.c	(revision 5a7c0e69a8cde81b5273b8c4db8c48fa734f8665)
@@ -61,7 +61,6 @@
 }
 
-static int ascii_apply(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_node_t *in,
-    bithenge_node_t **out)
+static int ascii_apply(bithenge_transform_t *self, bithenge_scope_t *scope,
+    bithenge_node_t *in, bithenge_node_t **out)
 {
 	int rc;
@@ -103,7 +102,6 @@
 };
 
-static int prefix_length_1(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+static int prefix_length_1(bithenge_transform_t *self, bithenge_scope_t *scope,
+    bithenge_blob_t *blob, aoff64_t *out)
 {
 	*out = 1;
@@ -111,7 +109,6 @@
 }
 
-static int prefix_length_2(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+static int prefix_length_2(bithenge_transform_t *self, bithenge_scope_t *scope,
+    bithenge_blob_t *blob, aoff64_t *out)
 {
 	*out = 2;
@@ -119,7 +116,6 @@
 }
 
-static int prefix_length_4(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+static int prefix_length_4(bithenge_transform_t *self, bithenge_scope_t *scope,
+    bithenge_blob_t *blob, aoff64_t *out)
 {
 	*out = 4;
@@ -127,7 +123,6 @@
 }
 
-static int prefix_length_8(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+static int prefix_length_8(bithenge_transform_t *self, bithenge_scope_t *scope,
+    bithenge_blob_t *blob, aoff64_t *out)
 {
 	*out = 8;
@@ -137,5 +132,5 @@
 #define MAKE_UINT_TRANSFORM(NAME, TYPE, ENDIAN, PREFIX_LENGTH_FUNC)            \
 	static int NAME##_apply(bithenge_transform_t *self,                    \
-	    bithenge_transform_context_t *context, bithenge_node_t *in,        \
+	    bithenge_scope_t *scope, bithenge_node_t *in,                      \
 	    bithenge_node_t **out)                                             \
 	{                                                                      \
@@ -176,6 +171,5 @@
 
 static int zero_terminated_apply(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_node_t *in,
-    bithenge_node_t **out)
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
 {
 	int rc;
@@ -201,6 +195,5 @@
 
 static int zero_terminated_prefix_length(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
 {
 	int rc;
@@ -251,5 +244,5 @@
 	bithenge_node_t base;
 	struct struct_transform *transform;
-	bithenge_transform_context_t *context;
+	bithenge_scope_t *scope;
 	bithenge_blob_t *blob;
 } struct_node_t;
@@ -281,5 +274,5 @@
 
 static int struct_node_for_one(const char *name,
-    bithenge_transform_t *subxform, bithenge_transform_context_t *context,
+    bithenge_transform_t *subxform, bithenge_scope_t *scope,
     bithenge_blob_t **blob, bithenge_for_each_func_t func, void *data)
 {
@@ -288,5 +281,5 @@
 
 	aoff64_t sub_size;
-	rc = bithenge_transform_prefix_length(subxform, context, *blob,
+	rc = bithenge_transform_prefix_length(subxform, scope, *blob,
 	    &sub_size);
 	if (rc != EOK)
@@ -299,5 +292,5 @@
 		goto error;
 
-	rc = bithenge_transform_apply(subxform, context, subblob_node,
+	rc = bithenge_transform_apply(subxform, scope, subblob_node,
 	    &subxform_result);
 	bithenge_node_dec_ref(subblob_node);
@@ -357,5 +350,5 @@
 	for (size_t i = 0; subxforms[i].transform; i++) {
 		rc = struct_node_for_one(subxforms[i].name,
-		    subxforms[i].transform, struct_node->context, &blob, func,
+		    subxforms[i].transform, struct_node->scope, &blob, func,
 		    data);
 		if (rc != EOK)
@@ -391,6 +384,5 @@
 
 static int struct_transform_apply(bithenge_transform_t *base,
-    bithenge_transform_context_t *context, bithenge_node_t *in,
-    bithenge_node_t **out)
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
 {
 	struct_transform_t *self = transform_as_struct(base);
@@ -409,5 +401,5 @@
 	node->transform = self;
 	bithenge_node_inc_ref(in);
-	node->context = context;
+	node->scope = scope;
 	node->blob = bithenge_node_as_blob(in);
 	*out = struct_as_node(node);
@@ -416,6 +408,5 @@
 
 static int struct_transform_prefix_length(bithenge_transform_t *base,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
 {
 	struct_transform_t *self = transform_as_struct(base);
@@ -433,5 +424,5 @@
 		    self->subtransforms[i].transform;
 		aoff64_t sub_size;
-		rc = bithenge_transform_prefix_length(subxform, context, blob,
+		rc = bithenge_transform_prefix_length(subxform, scope, blob,
 		    &sub_size);
 		if (rc != EOK)
@@ -517,7 +508,6 @@
 }
 
-static int compose_apply(bithenge_transform_t *base,
-    bithenge_transform_context_t *context, bithenge_node_t *in,
-    bithenge_node_t **out)
+static int compose_apply(bithenge_transform_t *base, bithenge_scope_t *scope,
+    bithenge_node_t *in, bithenge_node_t **out)
 {
 	int rc;
@@ -528,5 +518,5 @@
 	for (size_t i = self->num; i--; ) {
 		bithenge_node_t *tmp;
-		rc = bithenge_transform_apply(self->xforms[i], context, in,
+		rc = bithenge_transform_apply(self->xforms[i], scope, in,
 		    &tmp);
 		bithenge_node_dec_ref(in);
@@ -541,10 +531,9 @@
 
 static int compose_prefix_length(bithenge_transform_t *base,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+    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],
-	    context, blob, out);
+	    scope, blob, out);
 }
 
Index: uspace/app/bithenge/transform.h
===================================================================
--- uspace/app/bithenge/transform.h	(revision 43788b27b09a2c46c1076f96736c5d958a7268e3)
+++ uspace/app/bithenge/transform.h	(revision 5a7c0e69a8cde81b5273b8c4db8c48fa734f8665)
@@ -51,35 +51,96 @@
 typedef struct {
 	/** @privatesection */
-} bithenge_transform_context_t;
+	bithenge_node_t **params;
+	int num_params;
+} bithenge_scope_t;
 
 /** Operations that may be provided by a transform. */
 typedef struct bithenge_transform_ops {
 	/** @copydoc bithenge_transform_t::bithenge_transform_apply */
-	int (*apply)(bithenge_transform_t *self,
-	    bithenge_transform_context_t *context, bithenge_node_t *in,
-	    bithenge_node_t **out);
+	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_transform_context_t *context, bithenge_blob_t *blob,
-	    aoff64_t *out);
+	    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out);
 	/** Destroy the transform.
 	 * @param self The transform. */
 	void (*destroy)(bithenge_transform_t *self);
+	/** The number of parameters required. */
+	int num_params;
 } bithenge_transform_ops_t;
 
-/** Initialize a transform context. It must be destroyed with @a
- * bithenge_transform_context_destroy after it is used.
- * @param[out] context The context to initialize. */
-static inline void bithenge_transform_context_init(
-    bithenge_transform_context_t *context)
-{
-}
-
-/** Destroy a transform context.
- * @param context The context to destroy.
- * @return EOK on success or an error code from errno.h. */
-static inline void bithenge_transform_context_destroy(
-    bithenge_transform_context_t *context)
-{
+/** Initialize a transform scope. It must be destroyed with @a
+ * bithenge_scope_destroy after it is used.
+ * @param[out] scope The scope to initialize. */
+static inline void bithenge_scope_init(bithenge_scope_t *scope)
+{
+	scope->params = NULL;
+	scope->num_params = 0;
+}
+
+/** Destroy a transform scope.
+ * @param scope The scope to destroy.
+ * @return EOK on success or an error code from errno.h. */
+static inline void bithenge_scope_destroy(bithenge_scope_t *scope)
+{
+	for (int i = 0; i < scope->num_params; i++)
+		bithenge_node_dec_ref(scope->params[i]);
+	free(scope->params);
+}
+
+/** Allocate parameters. The parameters must then be set with @a
+ * bithenge_scope_set_param.
+ * @param scope The scope in which to allocate parameters.
+ * @param num_params The number of parameters to allocate.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_scope_alloc_params(bithenge_scope_t *scope,
+    int num_params)
+{
+	scope->params = malloc(sizeof(*scope->params) * num_params);
+	if (!scope->params)
+		return ENOMEM;
+	scope->num_params = num_params;
+	return EOK;
+}
+
+/** Set a parameter. Takes a reference to @a value. Note that range checking is
+ * not done in release builds.
+ * @param scope The scope in which to allocate parameters.
+ * @param i The index of the parameter to set.
+ * @param value The value to store in the parameter.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_scope_set_param( bithenge_scope_t *scope, int i,
+    bithenge_node_t *node)
+{
+	assert(scope);
+	assert(i >= 0 && i < scope->num_params);
+	scope->params[i] = node;
+	return EOK;
+}
+
+/** Get a parameter. Note that range checking is not done in release builds.
+ * @param scope The scope to get the parameter from.
+ * @param i The index of the parameter to set.
+ * @param[out] out Stores a new reference to the parameter.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_scope_get_param(bithenge_scope_t *scope, int i,
+    bithenge_node_t **out)
+{
+	assert(scope);
+	assert(i >= 0 && i < scope->num_params);
+	*out = scope->params[i];
+	bithenge_node_inc_ref(*out);
+	return EOK;
+}
+
+/** Get the number of parameters required by a transform. 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);
+	assert(self->ops);
+	return self->ops->num_params;
 }
 
@@ -87,15 +148,14 @@
  * @memberof bithenge_transform_t
  * @param self The transform.
- * @param context The context.
+ * @param scope The scope.
  * @param in The input tree.
  * @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_transform_apply(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_node_t *in,
-    bithenge_node_t **out)
-{
-	assert(self);
-	assert(self->ops);
-	return self->ops->apply(self, context, in, out);
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
+{
+	assert(self);
+	assert(self->ops);
+	return self->ops->apply(self, scope, in, out);
 }
 
@@ -106,5 +166,5 @@
  * @memberof bithenge_transform_t
  * @param self The transform.
- * @param context The context.
+ * @param scope The scope.
  * @param blob The blob.
  * @param[out] out Where the prefix length will be stored.
@@ -112,6 +172,5 @@
  * errno.h. */
 static inline int bithenge_transform_prefix_length(bithenge_transform_t *self,
-    bithenge_transform_context_t *context, bithenge_blob_t *blob,
-    aoff64_t *out)
+    bithenge_scope_t *scope, bithenge_blob_t *blob, aoff64_t *out)
 {
 	assert(self);
@@ -119,5 +178,5 @@
 	if (!self->ops->prefix_length)
 		return ENOTSUP;
-	return self->ops->prefix_length(self, context, blob, out);
+	return self->ops->prefix_length(self, scope, blob, out);
 }
 
