diff --git a/sieve/tests/reject.sieve b/sieve/tests/reject.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..9e07c84c838f7a164291b55556e52639849e9fc8
--- /dev/null
+++ b/sieve/tests/reject.sieve
@@ -0,0 +1,8 @@
+require "reject";
+
+if address :contains "to" "vestingbar" {
+	reject "Don't send unrequested messages.";
+	stop;
+}
+
+keep;
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index e2e57618136db62cbd0ab03207137b2627a771cb..03035877dcecfc46576028c4ec914449bc2ac011 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -1,3 +1,13 @@
+/* Extension reject 
+ * ----------------
+ *
+ * Authors: Stephan Bosch
+ * Specification: RFC3028, draft-ietf-sieve-refuse-reject-04
+ * Implementation: validation, generation and interpretation, no actual 
+ *   execution. 
+ * Status: experimental, largely untested
+ *
+ */
 
 #include <stdio.h>
 
@@ -10,26 +20,31 @@
 
 static bool ext_reject_load(int ext_id);
 static bool ext_reject_validator_load(struct sieve_validator *validator);
-static bool ext_reject_generator_load(struct sieve_generator *generator);
 
-static bool cmd_reject_validate(struct sieve_validator *validator, struct sieve_command_context *cmd);
-static bool cmd_reject_generate(struct sieve_generator *generator,	struct sieve_command_context *ctx); 
+static bool cmd_reject_validate
+	(struct sieve_validator *validator, struct sieve_command_context *cmd);
+static bool cmd_reject_generate
+	(struct sieve_generator *generator,	struct sieve_command_context *ctx); 
 
 static bool ext_reject_opcode_dump
-	(struct sieve_interpreter *interp, struct sieve_binary *sbin, sieve_size_t *address);
+	(struct sieve_interpreter *interp, struct sieve_binary *sbin, 
+		sieve_size_t *address);
+static bool ext_reject_opcode_execute
+	(struct sieve_interpreter *interp, struct sieve_binary *sbin, 
+		sieve_size_t *address);
 
 /* Extension definitions */
 
 static int ext_my_id;
 
 struct sieve_opcode reject_opcode = 
-	{ ext_reject_opcode_dump, NULL };
+	{ ext_reject_opcode_dump, ext_reject_opcode_execute };
 	
 struct sieve_extension reject_extension = { 
 	"reject", 
 	ext_reject_load,
 	ext_reject_validator_load, 
-	ext_reject_generator_load, 
+	NULL, 
 	NULL, 
 	&reject_opcode, 
 	NULL 
@@ -98,20 +113,13 @@ static bool cmd_reject_generate
 	return TRUE;
 }
 
-/* Load extension into generator */
-static bool ext_reject_generator_load(struct sieve_generator *generator ATTR_UNUSED)
-{
-	return TRUE;
-}
-
-
 /* 
  * Code dump
  */
  
 static bool ext_reject_opcode_dump
-	(struct sieve_interpreter *interp ATTR_UNUSED, 
-	struct sieve_binary *sbin, sieve_size_t *address)
+	(struct sieve_interpreter *interp ATTR_UNUSED, struct sieve_binary *sbin, 
+		sieve_size_t *address)
 {
 	printf("REJECT\n");
 	
@@ -119,3 +127,26 @@ static bool ext_reject_opcode_dump
 		sieve_opr_string_dump(sbin, address);
 }
 
+/*
+ * Execution
+ */
+
+static bool ext_reject_opcode_execute
+	(struct sieve_interpreter *interp ATTR_UNUSED, struct sieve_binary *sbin, 
+		sieve_size_t *address)
+{
+	string_t *reason;
+
+	t_push();
+
+	if ( !sieve_opr_string_read(sbin, address, &reason) ) {
+		t_pop();
+		return FALSE;
+	}
+
+	printf(">> REJECT \"%s\"\n", str_c(reason));
+
+	t_pop();
+	return TRUE;
+}
+