Index: uspace/app/bithenge/expression.c
===================================================================
--- uspace/app/bithenge/expression.c	(revision 0ce01037640ac4718581ca6f60b0f6de5061aa93)
+++ uspace/app/bithenge/expression.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
@@ -424,15 +424,17 @@
 {
 	param_wrapper_t *self = transform_as_param_wrapper(base);
-	bithenge_scope_t inner;
-	bithenge_scope_init(&inner);
-	int rc = param_wrapper_fill_scope(self, &inner, outer);
-	if (rc != EOK)
-		goto error;
-
-	rc = bithenge_transform_apply(self->transform, &inner, in, out);
+	bithenge_scope_t *inner;
+	int rc = bithenge_scope_new(&inner);
+	if (rc != EOK)
+		return rc;
+	rc = param_wrapper_fill_scope(self, inner, outer);
+	if (rc != EOK)
+		goto error;
+
+	rc = bithenge_transform_apply(self->transform, inner, in, out);
 	in = NULL;
 
 error:
-	bithenge_scope_destroy(&inner);
+	bithenge_scope_dec_ref(inner);
 	return rc;
 }
@@ -442,16 +444,17 @@
 {
 	param_wrapper_t *self = transform_as_param_wrapper(base);
-	bithenge_scope_t inner;
-	bithenge_scope_init(&inner);
-	int rc = param_wrapper_fill_scope(self, &inner, outer);
-	if (rc != EOK)
-		goto error;
-
-	rc = bithenge_transform_prefix_length(self->transform, &inner, in,
-	    out);
+	bithenge_scope_t *inner;
+	int rc = bithenge_scope_new(&inner);
+	if (rc != EOK)
+		return rc;
+	rc = param_wrapper_fill_scope(self, inner, outer);
+	if (rc != EOK)
+		goto error;
+
+	rc = bithenge_transform_prefix_length(self->transform, inner, in, out);
 	in = NULL;
 
 error:
-	bithenge_scope_destroy(&inner);
+	bithenge_scope_dec_ref(inner);
 	return rc;
 }
Index: uspace/app/bithenge/sequence.c
===================================================================
--- uspace/app/bithenge/sequence.c	(revision 0ce01037640ac4718581ca6f60b0f6de5061aa93)
+++ uspace/app/bithenge/sequence.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
@@ -50,5 +50,5 @@
 	const struct seq_node_ops *ops;
 	bithenge_blob_t *blob;
-	bithenge_scope_t scope;
+	bithenge_scope_t *scope;
 	aoff64_t *ends;
 	size_t num_ends;
@@ -114,5 +114,5 @@
 		bithenge_blob_t *subblob = bithenge_node_as_blob(subblob_node);
 		aoff64_t field_size;
-		rc = bithenge_transform_prefix_length(subxform, &self->scope,
+		rc = bithenge_transform_prefix_length(subxform, self->scope,
 		    subblob, &field_size);
 		bithenge_node_dec_ref(subblob_node);
@@ -177,5 +177,5 @@
 
 		aoff64_t size;
-		rc = bithenge_transform_prefix_apply(subxform, &self->scope,
+		rc = bithenge_transform_prefix_apply(subxform, self->scope,
 		    bithenge_node_as_blob(blob_node), out, &size);
 		bithenge_node_dec_ref(blob_node);
@@ -209,6 +209,6 @@
 		}
 
-		rc = bithenge_transform_apply(subxform, &self->scope,
-		    blob_node, out);
+		rc = bithenge_transform_apply(subxform, self->scope, blob_node,
+		    out);
 		bithenge_node_dec_ref(blob_node);
 		bithenge_transform_dec_ref(subxform);
@@ -235,5 +235,5 @@
 static void seq_node_destroy(seq_node_t *self)
 {
-	bithenge_scope_destroy(&self->scope);
+	bithenge_scope_dec_ref(self->scope);
 	bithenge_blob_dec_ref(self->blob);
 	free(self->ends);
@@ -248,5 +248,5 @@
 static bithenge_scope_t *seq_node_scope(seq_node_t *self)
 {
-	return &self->scope;
+	return self->scope;
 }
 
@@ -267,8 +267,13 @@
 	self->num_ends = 0;
 	self->end_on_empty = end_on_empty;
-	bithenge_scope_init(&self->scope);
-	int rc = bithenge_scope_copy(&self->scope, scope);
+	int rc = bithenge_scope_new(&self->scope);
 	if (rc != EOK) {
-		bithenge_scope_destroy(&self->scope);
+		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;
 	}
@@ -936,17 +941,21 @@
 		}
 
-		bithenge_scope_t scope;
-		bithenge_scope_init(&scope);
-		rc = bithenge_scope_copy(&scope,
+		bithenge_scope_t *scope;
+		rc = bithenge_scope_new(&scope);
+		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);
+		bithenge_scope_set_current_node(scope, subxform_result);
 		if (rc != EOK) {
-			bithenge_scope_destroy(&scope);
+			bithenge_scope_dec_ref(scope);
 			return rc;
 		}
 		bithenge_node_t *expr_result;
-		rc = bithenge_expression_evaluate(self->expr, &scope,
+		rc = bithenge_expression_evaluate(self->expr, scope,
 		    &expr_result);
-		bithenge_scope_destroy(&scope);
+		bithenge_scope_dec_ref(scope);
 		if (rc != EOK)
 			return rc;
Index: uspace/app/bithenge/test.c
===================================================================
--- uspace/app/bithenge/test.c	(revision 0ce01037640ac4718581ca6f60b0f6de5061aa93)
+++ uspace/app/bithenge/test.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
@@ -69,25 +69,33 @@
 		bithenge_node_dec_ref(node);
 	} else {
-		bithenge_scope_t scope;
+		bithenge_scope_t *scope = NULL;
 		bithenge_transform_t *transform = NULL;
 		bithenge_node_t *node = NULL, *node2 = NULL;
 
-		bithenge_scope_init(&scope);
+		rc = bithenge_scope_new(&scope);
+		if (rc != EOK) {
+			printf("Error creating scope: %s\n", str_error(rc));
+			scope = NULL;
+			goto error;
+		}
 
 		rc = bithenge_parse_script(argv[1], &transform);
 		if (rc != EOK) {
 			printf("Error parsing script: %s\n", str_error(rc));
+			transform = NULL;
 			goto error;
 		}
 
-		int rc = bithenge_node_from_source(&node, argv[2]);
+		rc = bithenge_node_from_source(&node, argv[2]);
 		if (rc != EOK) {
 			printf("Error creating node from source: %s\n", str_error(rc));
+			node = NULL;
 			goto error;
 		}
 
-		rc = bithenge_transform_apply(transform, &scope, node, &node2);
+		rc = bithenge_transform_apply(transform, scope, node, &node2);
 		if (rc != EOK) {
 			printf("Error applying transform: %s\n", str_error(rc));
+			node2 = NULL;
 			goto error;
 		}
@@ -105,4 +113,6 @@
 		bithenge_node_dec_ref(node2);
 		node2 = NULL;
+		bithenge_scope_dec_ref(scope);
+		scope = NULL;
 		printf("\n");
 
@@ -113,5 +123,5 @@
 		bithenge_node_dec_ref(node2);
 		bithenge_transform_dec_ref(transform);
-		bithenge_scope_destroy(&scope);
+		bithenge_scope_dec_ref(scope);
 		return 1;
 	}
Index: uspace/app/bithenge/transform.c
===================================================================
--- uspace/app/bithenge/transform.c	(revision 0ce01037640ac4718581ca6f60b0f6de5061aa93)
+++ uspace/app/bithenge/transform.c	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
@@ -165,23 +165,32 @@
 }
 
-/** Initialize a transform scope. It must be destroyed with @a
- * bithenge_scope_destroy after it is used.
- * @param[out] scope The scope to initialize. */
-void bithenge_scope_init(bithenge_scope_t *scope)
-{
-	scope->num_params = 0;
-	scope->params = NULL;
-	scope->current_node = NULL;
-}
-
-/** Destroy a transform scope.
- * @param scope The scope to destroy.
+/** Create a transform scope. It must be dereferenced with @a
+ * bithenge_scope_dec_ref after it is used.
+ * @param[out] out Holds the new scope.
  * @return EOK on success or an error code from errno.h. */
-void bithenge_scope_destroy(bithenge_scope_t *scope)
-{
-	bithenge_node_dec_ref(scope->current_node);
-	for (int i = 0; i < scope->num_params; i++)
-		bithenge_node_dec_ref(scope->params[i]);
-	free(scope->params);
+int bithenge_scope_new(bithenge_scope_t **out)
+{
+	bithenge_scope_t *self = malloc(sizeof(*self));
+	if (!self)
+		return ENOMEM;
+	self->refs = 1;
+	self->num_params = 0;
+	self->params = NULL;
+	self->current_node = NULL;
+	*out = self;
+	return EOK;
+}
+
+/** Dereference a transform scope.
+ * @param self The scope to dereference. */
+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);
+	}
 }
 
@@ -297,13 +306,15 @@
 {
 	scope_transform_t *self = transform_as_param(base);
-	bithenge_scope_t inner_scope;
-	bithenge_scope_init(&inner_scope);
-	int rc = bithenge_scope_copy(&inner_scope, scope);
+	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);
+	bithenge_scope_set_current_node(inner_scope, NULL);
 	rc = bithenge_transform_apply(self->transform, scope, in, out);
 error:
-	bithenge_scope_destroy(&inner_scope);
+	bithenge_scope_dec_ref(inner_scope);
 	return rc;
 }
Index: uspace/app/bithenge/transform.h
===================================================================
--- uspace/app/bithenge/transform.h	(revision 0ce01037640ac4718581ca6f60b0f6de5061aa93)
+++ uspace/app/bithenge/transform.h	(revision f9c314a53c0d9c61fa71982d7b33573332b7f4cd)
@@ -52,8 +52,13 @@
 typedef struct {
 	/** @privatesection */
+	unsigned int refs;
 	int num_params;
 	bithenge_node_t **params;
 	bithenge_node_t *current_node;
 } bithenge_scope_t;
+
+static inline void bithenge_scope_inc_ref(bithenge_scope_t *self) {
+	self->refs++;
+}
 
 /** Operations that may be provided by a transform. All transforms must provide
@@ -143,6 +148,6 @@
     bithenge_transform_t **, size_t);
 
-void bithenge_scope_init(bithenge_scope_t *);
-void bithenge_scope_destroy(bithenge_scope_t *);
+int bithenge_scope_new(bithenge_scope_t **);
+void bithenge_scope_dec_ref(bithenge_scope_t *);
 int bithenge_scope_copy(bithenge_scope_t *, bithenge_scope_t *);
 void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
