diff -ur spamass-milt.Rcpt/spamass-milter.cpp spamass-milt.Rcpt.Aflag/spamass-milter.cpp
--- spamass-milt.Rcpt/spamass-milter.cpp	2004-09-24 14:33:06.000000000 -0400
+++ spamass-milt.Rcpt.Aflag/spamass-milter.cpp	2004-09-24 14:47:46.000000000 -0400
@@ -166,6 +168,8 @@
 char **spamc_argv;
 bool flag_bucket = false;
 bool flag_bucket_only = false;
+bool flag_bucket_and_reject = false;
+int bucket_and_reject_score = 0;
 char *spambucket;
 bool flag_full_email = false;		/* pass full email address to spamc */
 bool flag_expand = false;	/* alias/virtusertable expansion */
@@ -184,7 +184,7 @@
 main(int argc, char* argv[])
 {
    int c, err = 0;
-   const char *args = "fd:mMp:P:r:R:u:D:i:b:B:e:x";
+   const char *args = "a:fd:mMp:P:r:R:u:D:i:b:B:e:x";
    char *sock = NULL;
    bool dofork = false;
    char *pidfilename = NULL;
@@ -264,6 +264,12 @@
 				// XXX we should probably verify that optarg is vaguely sane
 				spambucket = strdup( optarg );
 				break;
+			case 'a':
+				flag_bucket_and_reject = true;
+				bucket_and_reject_score = atoi(optarg);
+				if(!bucket_and_reject_score)
+					flag_bucket_and_reject = false;
+				break;
 			case 'x':
 				flag_expand = true;
 				break;
@@ -286,12 +292,15 @@
    if (!sock || err) {
       cout << PACKAGE_NAME << " - Version " << PACKAGE_VERSION << endl;
       cout << "SpamAssassin Sendmail Milter Plugin" << endl;
-      cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d xx[,yy...]] [-D host]" << endl;
+      cout << "Usage: spamass-milter -p socket [-a -1|n|0] [-b|-B bucket] [-d xx[,yy...]]" <<endl; 
+      cout << "                      [-D host]" << endl;
       cout << "                      [-e defaultdomain] [-f] [-i networks] [-m] [-M]" << endl;
       cout << "                      [-P pidfile] [-r nn] [-u defaultuser] [-x]" << endl;
       cout << "                      [-R recipient_filter_prog]" << endl;
       cout << "                      [-- spamc args ]" << endl;
       cout << "   -p socket: path to create socket" << endl;
+      cout << "   -a -1|num|0: bucket all spam, bucket spam scoring higher than num" << endl;
+      cout << "                or bucket all spam that does not get rejected." << endl;
       cout << "   -b bucket: redirect spam to this mail address.  The orignal" << endl;
       cout << "          recipient(s) will not receive anything." << endl;
       cout << "   -B bucket: add this mail address as a BCC recipient of spam." << endl;
@@ -419,6 +428,10 @@
 assassinate(SMFICTX* ctx, SpamAssassin* assassin)
 {
   struct context *sctx = (struct context*)smfi_getpriv(ctx);
+  char * queue_id = smfi_getsymval(ctx, "i");
+  int do_bucket = false;
+  int score = 0;
+		
   // find end of header (eol in last line of header)
   // and beginning of body
   string::size_type eoh1 = assassin->d().find("\n\n");
@@ -441,7 +454,7 @@
 		do_reject = true;
 	if (reject_score != -1)
 	{
-		int score, rv;
+		int rv;
 		const char *spam_status = assassin->spam_status().c_str();
 		/* SA 3.0 uses the keyword "score" */
 		rv = sscanf(spam_status,"%*s score=%d", &score);
@@ -468,8 +481,28 @@
 		debug(D_MISC, "Rejecting");
 		smfi_setreply(ctx, "550", "5.7.1", "Blocked by SpamAssassin");
 
+		/* Send spam to the bucket if -b or -B AND
+		   if -a was specified (without a param of 0) AND
+		   if the -a parameter is higher than score
+		   OR reject_score = -1 OR -a parameter is -1 */ 
+		 
+
+		if (flag_bucket) {
+			if (flag_bucket_and_reject) { 
+				// a param to -a of 0 makes above flag false
+				if (bucket_and_reject_score <= score)
+					do_bucket = true;
+				if (reject_score == -1)
+					do_bucket = true;
+				if (bucket_and_reject_score == -1)
+					do_bucket = true;
+			} else {
+				do_bucket = false;
+			}
+		} else
+			do_bucket = false;
 
-		if (flag_bucket)
+		if (do_bucket)
 		{
 			/* If we also want a copy of the spam, shell out to sendmail and
 			   send another copy.  The milter API will not let you send the
@@ -484,6 +517,8 @@
 #endif
 			char *fmt="%s \"%s\"";
 			FILE *p;
+			
+			debug(D_COPY,"%s: spambucket copying....", queue_id);
 
 #if defined(HAVE_ASPRINTF)
 			asprintf(&buf, fmt, SENDMAIL, spambucket);
@@ -526,22 +561,59 @@
 #if defined(HAVE_ASPRINTF)
 			free(buf);
 #endif 
-		}
+		} else if (flag_bucket)
+			debug(D_COPY,"%s: spambucket copying thwarted by -a. -a param: %d, score %d", 
+					queue_id,
+					bucket_and_reject_score,
+					score
+					);
 		return SMFIS_REJECT;
 	}
   }
 
-  /* Drop the message into the spam bucket if it's spam */
-  if ( flag_bucket ) {
-        if (!assassin->spam_flag().empty()) {
-          // first, add the spambucket address
-          if ( smfi_addrcpt( ctx, spambucket ) != MI_SUCCESS ) {
-                throw string( "Failed to add spambucket to recipients" );
-          }
-          if (flag_bucket_only) {
-                // Move recipients to a non-active header, one at a
-                // time. Note, this may generate multiple X-Spam-Orig-To
-                // headers, but that's okay.
+  /* Drop the message into the spam bucket if it's spam
+     AND either of:
+                 -a is not set or -a param is 0
+                 score is larger than -a param
+                 -a parameter is -1, signifying bucket everything */
+  if (flag_bucket) {
+	if (!assassin->spam_flag().empty()) {
+		if (!flag_bucket_and_reject) {
+			do_bucket = true;
+		} else if (bucket_and_reject_score <= score) {
+			do_bucket = true;
+		} else if (bucket_and_reject_score == -1) {
+			do_bucket = true;
+		} else {
+			do_bucket = false;
+		}
+		if(!do_bucket) {
+			debug(D_COPY,
+			"%s: spambucket copying thwarted by -a. -a param: %d, score %d", 
+				queue_id,
+				bucket_and_reject_score,
+				score
+			);
+		}
+	} else
+		debug(D_COPY,
+		"%s: spambucket - Not spam, not bucketing. score %d",
+			queue_id,
+			score
+		);
+  }
+
+  if (do_bucket)
+  {
+	debug(D_COPY,"%s: spambucket copying....", queue_id);
+	// first, add the spambucket address
+	if ( smfi_addrcpt( ctx, spambucket ) != MI_SUCCESS ) {
+		throw string( "Failed to add spambucket to recipients" );
+	}
+	if (flag_bucket_only) {
+		// Move recipients to a non-active header, one at a
+		// time. Note, this may generate multiple X-Spam-Orig-To
+		// headers, but that's okay.
                 while( !assassin->recipients.empty()) {
                   if ( smfi_addheader( ctx, "X-Spam-Orig-To", (char *)assassin->recipients.front().c_str()) != MI_SUCCESS ) {
                         throw string( "Failed to save recipient" );
@@ -554,8 +626,7 @@
                   }
                   assassin->recipients.pop_front();
                 }
-          }
-        }
+	}
   }
 
   update_or_insert(assassin, ctx, assassin->spam_report(), &SpamAssassin::set_spam_report, "X-Spam-Report");
