diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 3e2ddb4e4082845cb418e9f92603963037c9bc04..061606cc4f29c2b44c430f7d2bf74c0e4819ad0e 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -44,11 +44,13 @@ testsuite_SOURCES = \
 	namespaces.c \
 	mail-raw.c \
 	testsuite-common.c \
+	testsuite-objects.c \
 	$(cmds) \
 	ext-testsuite.c \
 	testsuite.c
 
 noinst_HEADERS = \
 	testsuite-common.h \
+	testsuite-objects.h \
 	namespaces.h \
 	mail-raw.h
diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c
index 925592c00918ac662b8fae4b74705a331674a614..8dc5a952993337b2f9de2e1714f321c81a79e78c 100644
--- a/src/testsuite/cmd-test-set.c
+++ b/src/testsuite/cmd-test-set.c
@@ -15,6 +15,7 @@
 #include "sieve-result.h"
 
 #include "testsuite-common.h"
+#include "testsuite-objects.h"
 
 #include <stdio.h>
 
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index bc253964f62bbbe3a7a994b2ee177f66a9c6cfdc..ff3e2317aabfb883d585edce6e03e4f7554c3dd2 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -14,38 +14,9 @@
 #include "sieve-generator.h"
 #include "sieve-dump.h"
 
+#include "testsuite-objects.h"
 #include "testsuite-common.h"
 
-/* 
- * Types
- */
- 
-struct testsuite_object_registration {
-	int ext_id;
-	const struct testsuite_object *object;
-};
- 
-struct testsuite_validator_context {
-	struct hash_table *object_registrations;
-};
-
-/* 
- * Testsuite core objects
- */
- 
-enum testsuite_object_code {
-	TESTSUITE_OBJECT_MESSAGE,
-	TESTSUITE_OBJECT_ENVELOPE
-};
-
-const struct testsuite_object *testsuite_core_objects[] = {
-	&message_testsuite_object, &envelope_testsuite_object
-};
-
-const unsigned int testsuite_core_objects_count =
-	N_ELEMENTS(testsuite_core_objects);
-
-
 /*
  * Global data
  */
@@ -54,14 +25,6 @@ const unsigned int testsuite_core_objects_count =
 
 struct sieve_message_data testsuite_msgdata;
 
-/* 
- * Forward declarations
- */
- 
-static void _testsuite_object_register
-	(pool_t pool, struct testsuite_validator_context *ctx, 
-		const struct testsuite_object *obj, int ext_id);
-
 /* 
  * Testsuite message environment 
  */
@@ -143,16 +106,8 @@ void testsuite_message_deinit(void)
  * Validator context 
  */
 
-static inline struct testsuite_validator_context *
-	get_validator_context(struct sieve_validator *valdtr)
-{
-	return (struct testsuite_validator_context *) 
-		sieve_validator_extension_get_context(valdtr, ext_testsuite_my_id);
-}
-
 bool testsuite_validator_context_initialize(struct sieve_validator *valdtr)
 {
-	unsigned int i;
 	pool_t pool = sieve_validator_pool(valdtr);
 	struct testsuite_validator_context *ctx = 
 		p_new(pool, struct testsuite_validator_context, 1);
@@ -161,202 +116,9 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr)
 	ctx->object_registrations = hash_create
 		(pool, pool, 0, str_hash, (hash_cmp_callback_t *) strcmp);
 
-	/* Register core testsuite objects */
-	for ( i = 0; i < testsuite_core_objects_count; i++ ) {
-		const struct testsuite_object *object = testsuite_core_objects[i];
-		
-		_testsuite_object_register(pool, ctx, object, ext_testsuite_my_id);
-	}
-
-	sieve_validator_extension_set_context(valdtr, ext_testsuite_my_id, ctx);
-
-	return TRUE;
-}
-
-/* 
- * Testsuite object registry
- */
- 
-static void _testsuite_object_register
-(pool_t pool, struct testsuite_validator_context *ctx, 
-	const struct testsuite_object *obj, int ext_id) 
-{	
-	struct testsuite_object_registration *reg;
-	
-	reg = p_new(pool, struct testsuite_object_registration, 1);
-	reg->object = obj;
-	reg->ext_id = ext_id;
-
-	hash_insert(ctx->object_registrations, (void *) obj->identifier, (void *) reg);
-}
- 
-void testsuite_object_register
-(struct sieve_validator *valdtr, const struct testsuite_object *obj, int ext_id) 
-{
-	pool_t pool = sieve_validator_pool(valdtr);
-	struct testsuite_validator_context *ctx = get_validator_context(valdtr);
-
-	_testsuite_object_register(pool, ctx, obj, ext_id);
-}
-
-const struct testsuite_object *testsuite_object_find
-(struct sieve_validator *valdtr, const char *identifier, int *ext_id) 
-{
-	struct testsuite_validator_context *ctx = get_validator_context(valdtr);		
-	struct testsuite_object_registration *reg =
-		(struct testsuite_object_registration *) 
-			hash_lookup(ctx->object_registrations, identifier);
-			
-	if ( reg == NULL ) return NULL;
-
-	if ( ext_id != NULL ) *ext_id = reg->ext_id;
-
-  return reg->object;
-}
- 
-/* 
- * Testsuite object code
- */ 
- 
-const struct sieve_operand_class testsuite_object_oprclass = 
-	{ "testsuite-object" };
-
-const struct testsuite_object_operand_interface testsuite_object_oprint = {
-	SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects)
-};
-
-const struct sieve_operand testsuite_object_operand = { 
-	"testsuite-object",
-	&testsuite_extension, 
-	TESTSUITE_OPERAND_OBJECT, 
-	&testsuite_object_oprclass,
-	&testsuite_object_oprint
-};
-
-static void testsuite_object_emit
-	(struct sieve_binary *sbin, const struct testsuite_object *obj, int ext_id)
-{ 
-	(void) sieve_operand_emit_code(sbin, obj->operand, ext_id);	
-	(void) sieve_binary_emit_byte(sbin, obj->code);
-}
-
-const struct testsuite_object *testsuite_object_read
-(struct sieve_binary *sbin, sieve_size_t *address)
-{
-	const struct sieve_operand *operand;
-	const struct testsuite_object_operand_interface *intf;	
-	unsigned int obj_code; 
-
-	operand = sieve_operand_read(sbin, address);
-	if ( operand == NULL || operand->class != &testsuite_object_oprclass ) 
-		return NULL;
-	
-	intf = operand->interface;
-	if ( intf == NULL ) 
-		return NULL;
-			
-	if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) 
-		return NULL;
-
-	return sieve_extension_get_object
-		(struct testsuite_object, intf->testsuite_objects, obj_code);
-}
-
-bool testsuite_object_dump
-(const struct sieve_dumptime_env *denv, sieve_size_t *address)
-{
-	const struct testsuite_object *object;
-
-	sieve_code_mark(denv);
-		
-	if ( (object = testsuite_object_read(denv->sbin, address)) == NULL )
-		return FALSE;
-	
-	sieve_code_dumpf(denv, "TESTSUITE_OBJECT: %s", object->identifier);
-		
-	return TRUE;
-}
-
-/* 
- * Testsuite object argument
- */
- 
-static bool arg_testsuite_object_generate
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg, 
-		struct sieve_command_context *cmd);
-
-const struct sieve_argument testsuite_object_argument = 
-	{ "testsuite-object", NULL, NULL, NULL, arg_testsuite_object_generate };
- 
-struct testsuite_object_argctx {
-	const struct testsuite_object *object;
-	int ext_id;
-};
-
-bool testsuite_object_argument_activate
-(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
-	struct sieve_command_context *cmd) 
-{
-	const char *objname = sieve_ast_argument_strc(arg);
-	const struct testsuite_object *object;
-	int ext_id;
-	struct testsuite_object_argctx *ctx;
-	
-	object = testsuite_object_find(valdtr, objname, &ext_id);
-	if ( object == NULL ) {
-		sieve_command_validate_error(valdtr, cmd, 
-			"unknown testsuite object '%s'", objname);
-		return FALSE;
-	}
+	testsuite_register_core_objects(pool, ctx);
 	
-	ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1);
-	ctx->object = object;
-	ctx->ext_id = ext_id;
-	
-	arg->argument = &testsuite_object_argument;
-	arg->context = (void *) ctx;
-	
-	return TRUE;
-}
-
-static bool arg_testsuite_object_generate
-	(struct sieve_generator *generator, struct sieve_ast_argument *arg, 
-	struct sieve_command_context *cmd ATTR_UNUSED)
-{
-	struct sieve_binary *sbin = sieve_generator_get_binary(generator);
-	struct testsuite_object_argctx *ctx = 
-		(struct testsuite_object_argctx *) arg->context;
-	
-	testsuite_object_emit(sbin, ctx->object, ctx->ext_id);
-		
-	return TRUE;
-}
-
-/* 
- * Testsuite core object implementation
- */
- 
-static bool tsto_message_set_member(int id, string_t *value);
-
-const struct testsuite_object message_testsuite_object = { 
-	"message",
-	TESTSUITE_OBJECT_MESSAGE,
-	&testsuite_object_operand,
-	NULL, tsto_message_set_member, NULL
-};
-
-const struct testsuite_object envelope_testsuite_object = { 
-	"envelope",
-	TESTSUITE_OBJECT_ENVELOPE,
-	&testsuite_object_operand,
-	NULL, NULL, NULL
-};
+	sieve_validator_extension_set_context(valdtr, ext_testsuite_my_id, ctx);
 
-static bool tsto_message_set_member(int id, string_t *value) 
-{
-	if ( id != -1 ) return FALSE;
-	
-	testsuite_message_set(value);
-	
 	return TRUE;
 }
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 2d878b3152ee61920e233452d5db089a7249ee4a..0cac40c8b6d5b034b5a7a8d6e632360228790d93 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -1,5 +1,5 @@
-#ifndef __EXT_TESTSUITE_COMMON_H
-#define __EXT_TESTSUITE_COMMON_H
+#ifndef __TESTSUITE_COMMON_H
+#define __TESTSUITE_COMMON_H
 
 extern const struct sieve_extension testsuite_extension;
 
@@ -16,51 +16,18 @@ void testsuite_message_set(string_t *message);
 
 /* Testsuite validator context */
 
+struct testsuite_validator_context {
+	struct hash_table *object_registrations;
+};
+
 bool testsuite_validator_context_initialize(struct sieve_validator *valdtr);
 
 /* Testsuite operands */
 
-struct testsuite_object_operand_interface {
-	struct sieve_extension_obj_registry testsuite_objects;
-};
-
-extern const struct sieve_operand_class testsuite_object_oprclass;
 extern const struct sieve_operand testsuite_object_operand;
 
 enum testsuite_operand_code {
 	TESTSUITE_OPERAND_OBJECT
 };
 
-/* Testsuite object access */
-
-struct testsuite_object {
-	const char *identifier;
-	unsigned int code;
-	const struct sieve_operand *operand;
-	
-	int (*get_member_id)(const char *identifier);
-	bool (*set_member)(int id, string_t *value);
-	string_t *(*get_member)(int id);
-};
-
-const struct testsuite_object *testsuite_object_find
-	(struct sieve_validator *valdtr, const char *identifier, int *ext_id);
-void testsuite_object_register
-	(struct sieve_validator *valdtr, const struct testsuite_object *obj, 
-		int ext_id);
-		
-const struct testsuite_object *testsuite_object_read
-  (struct sieve_binary *sbin, sieve_size_t *address);
-bool testsuite_object_dump
-	(const struct sieve_dumptime_env *denv, sieve_size_t *address);
-	
-bool testsuite_object_argument_activate
-	(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
-		struct sieve_command_context *cmd);
-
-/* Testsuite core objects */
-
-extern const struct testsuite_object message_testsuite_object;
-extern const struct testsuite_object envelope_testsuite_object;
-
-#endif
+#endif /* __TESTSUITE_COMMON_H */
diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ddf0fda4b11848629c55bdd9efd1726524bca22
--- /dev/null
+++ b/src/testsuite/testsuite-objects.c
@@ -0,0 +1,259 @@
+#include "lib.h"
+#include "string.h"
+#include "ostream.h"
+#include "hash.h"
+#include "mail-storage.h"
+
+#include "mail-raw.h"
+#include "namespaces.h"
+#include "sieve.h"
+#include "sieve-code.h"
+#include "sieve-commands.h"
+#include "sieve-extensions-private.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-dump.h"
+
+#include "testsuite-common.h"
+#include "testsuite-objects.h"
+
+/* 
+ * Types
+ */
+ 
+struct testsuite_object_registration {
+	int ext_id;
+	const struct testsuite_object *object;
+};
+ 
+/* 
+ * Testsuite core objects
+ */
+ 
+enum testsuite_object_code {
+	TESTSUITE_OBJECT_MESSAGE,
+	TESTSUITE_OBJECT_ENVELOPE
+};
+
+const struct testsuite_object *testsuite_core_objects[] = {
+	&message_testsuite_object, &envelope_testsuite_object
+};
+
+const unsigned int testsuite_core_objects_count =
+	N_ELEMENTS(testsuite_core_objects);
+
+/* 
+ * Forward declarations
+ */
+ 
+static void _testsuite_object_register
+	(pool_t pool, struct testsuite_validator_context *ctx, 
+		const struct testsuite_object *obj, int ext_id);
+
+/* 
+ * Testsuite object registry
+ */
+ 
+static inline struct testsuite_validator_context *
+	_get_validator_context(struct sieve_validator *valdtr)
+{
+	return (struct testsuite_validator_context *) 
+		sieve_validator_extension_get_context(valdtr, ext_testsuite_my_id);
+}
+ 
+static void _testsuite_object_register
+(pool_t pool, struct testsuite_validator_context *ctx, 
+	const struct testsuite_object *obj, int ext_id) 
+{	
+	struct testsuite_object_registration *reg;
+	
+	reg = p_new(pool, struct testsuite_object_registration, 1);
+	reg->object = obj;
+	reg->ext_id = ext_id;
+
+	hash_insert(ctx->object_registrations, (void *) obj->identifier, (void *) reg);
+}
+ 
+void testsuite_object_register
+(struct sieve_validator *valdtr, const struct testsuite_object *obj, int ext_id) 
+{
+	pool_t pool = sieve_validator_pool(valdtr);
+	struct testsuite_validator_context *ctx = _get_validator_context(valdtr);
+
+	_testsuite_object_register(pool, ctx, obj, ext_id);
+}
+
+const struct testsuite_object *testsuite_object_find
+(struct sieve_validator *valdtr, const char *identifier, int *ext_id) 
+{
+	struct testsuite_validator_context *ctx = _get_validator_context(valdtr);		
+	struct testsuite_object_registration *reg =
+		(struct testsuite_object_registration *) 
+			hash_lookup(ctx->object_registrations, identifier);
+			
+	if ( reg == NULL ) return NULL;
+
+	if ( ext_id != NULL ) *ext_id = reg->ext_id;
+
+  return reg->object;
+}
+
+void testsuite_register_core_objects
+	(pool_t pool, struct testsuite_validator_context *ctx)
+{
+	unsigned int i;
+	
+	/* Register core testsuite objects */
+	for ( i = 0; i < testsuite_core_objects_count; i++ ) {
+		const struct testsuite_object *object = testsuite_core_objects[i];
+		
+		_testsuite_object_register(pool, ctx, object, ext_testsuite_my_id);
+	}
+}
+ 
+/* 
+ * Testsuite object code
+ */ 
+ 
+const struct sieve_operand_class testsuite_object_oprclass = 
+	{ "testsuite-object" };
+
+const struct testsuite_object_operand_interface testsuite_object_oprint = {
+	SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects)
+};
+
+const struct sieve_operand testsuite_object_operand = { 
+	"testsuite-object",
+	&testsuite_extension, 
+	TESTSUITE_OPERAND_OBJECT, 
+	&testsuite_object_oprclass,
+	&testsuite_object_oprint
+};
+
+static void testsuite_object_emit
+	(struct sieve_binary *sbin, const struct testsuite_object *obj, int ext_id)
+{ 
+	(void) sieve_operand_emit_code(sbin, obj->operand, ext_id);	
+	(void) sieve_binary_emit_byte(sbin, obj->code);
+}
+
+const struct testsuite_object *testsuite_object_read
+(struct sieve_binary *sbin, sieve_size_t *address)
+{
+	const struct sieve_operand *operand;
+	const struct testsuite_object_operand_interface *intf;	
+	unsigned int obj_code; 
+
+	operand = sieve_operand_read(sbin, address);
+	if ( operand == NULL || operand->class != &testsuite_object_oprclass ) 
+		return NULL;
+	
+	intf = operand->interface;
+	if ( intf == NULL ) 
+		return NULL;
+			
+	if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) 
+		return NULL;
+
+	return sieve_extension_get_object
+		(struct testsuite_object, intf->testsuite_objects, obj_code);
+}
+
+bool testsuite_object_dump
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
+{
+	const struct testsuite_object *object;
+
+	sieve_code_mark(denv);
+		
+	if ( (object = testsuite_object_read(denv->sbin, address)) == NULL )
+		return FALSE;
+	
+	sieve_code_dumpf(denv, "TESTSUITE_OBJECT: %s", object->identifier);
+		
+	return TRUE;
+}
+
+/* 
+ * Testsuite object argument
+ */
+ 
+static bool arg_testsuite_object_generate
+	(struct sieve_generator *generator, struct sieve_ast_argument *arg, 
+		struct sieve_command_context *cmd);
+
+const struct sieve_argument testsuite_object_argument = 
+	{ "testsuite-object", NULL, NULL, NULL, arg_testsuite_object_generate };
+ 
+struct testsuite_object_argctx {
+	const struct testsuite_object *object;
+	int ext_id;
+};
+
+bool testsuite_object_argument_activate
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
+	struct sieve_command_context *cmd) 
+{
+	const char *objname = sieve_ast_argument_strc(arg);
+	const struct testsuite_object *object;
+	int ext_id;
+	struct testsuite_object_argctx *ctx;
+	
+	object = testsuite_object_find(valdtr, objname, &ext_id);
+	if ( object == NULL ) {
+		sieve_command_validate_error(valdtr, cmd, 
+			"unknown testsuite object '%s'", objname);
+		return FALSE;
+	}
+	
+	ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1);
+	ctx->object = object;
+	ctx->ext_id = ext_id;
+	
+	arg->argument = &testsuite_object_argument;
+	arg->context = (void *) ctx;
+	
+	return TRUE;
+}
+
+static bool arg_testsuite_object_generate
+	(struct sieve_generator *generator, struct sieve_ast_argument *arg, 
+	struct sieve_command_context *cmd ATTR_UNUSED)
+{
+	struct sieve_binary *sbin = sieve_generator_get_binary(generator);
+	struct testsuite_object_argctx *ctx = 
+		(struct testsuite_object_argctx *) arg->context;
+	
+	testsuite_object_emit(sbin, ctx->object, ctx->ext_id);
+		
+	return TRUE;
+}
+
+/* 
+ * Testsuite core object implementation
+ */
+ 
+static bool tsto_message_set_member(int id, string_t *value);
+
+const struct testsuite_object message_testsuite_object = { 
+	"message",
+	TESTSUITE_OBJECT_MESSAGE,
+	&testsuite_object_operand,
+	NULL, tsto_message_set_member, NULL
+};
+
+const struct testsuite_object envelope_testsuite_object = { 
+	"envelope",
+	TESTSUITE_OBJECT_ENVELOPE,
+	&testsuite_object_operand,
+	NULL, NULL, NULL
+};
+
+static bool tsto_message_set_member(int id, string_t *value) 
+{
+	if ( id != -1 ) return FALSE;
+	
+	testsuite_message_set(value);
+	
+	return TRUE;
+}
diff --git a/src/testsuite/testsuite-objects.h b/src/testsuite/testsuite-objects.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8e2b97d1af8e281aaa6adc1d64915949976cef3
--- /dev/null
+++ b/src/testsuite/testsuite-objects.h
@@ -0,0 +1,54 @@
+#ifndef __TESTSUITE_OBJECTS_H
+#define __TESTSUITE_OBJECTS_H
+
+#include "testsuite-common.h"
+
+/* Testsuite object operand */
+
+struct testsuite_object_operand_interface {
+	struct sieve_extension_obj_registry testsuite_objects;
+};
+
+extern const struct sieve_operand_class testsuite_object_oprclass;
+
+/* Testsuite object access */
+
+struct testsuite_object {
+	const char *identifier;
+	unsigned int code;
+	const struct sieve_operand *operand;
+	
+	int (*get_member_id)(const char *identifier);
+	bool (*set_member)(int id, string_t *value);
+	string_t *(*get_member)(int id);
+};
+
+/* Testsuite object registration */
+
+const struct testsuite_object *testsuite_object_find
+	(struct sieve_validator *valdtr, const char *identifier, int *ext_id);
+void testsuite_object_register
+	(struct sieve_validator *valdtr, const struct testsuite_object *obj, 
+		int ext_id);		
+void testsuite_register_core_objects
+	(pool_t pool, struct testsuite_validator_context *ctx);
+		
+/* Testsuite object argument */		
+	
+bool testsuite_object_argument_activate
+	(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
+		struct sieve_command_context *cmd);		
+		
+/* Testsuite object code */
+
+const struct testsuite_object *testsuite_object_read
+  (struct sieve_binary *sbin, sieve_size_t *address);
+bool testsuite_object_dump
+	(const struct sieve_dumptime_env *denv, sieve_size_t *address);
+
+/* Testsuite core objects */
+
+extern const struct testsuite_object message_testsuite_object;
+extern const struct testsuite_object envelope_testsuite_object;
+
+#endif /* __TESTSUITE_OBJECTS_H */