diff --git a/NEWS b/NEWS
index 9d8976043ee4abbfdfdc6290ea8fd72ea93c8ed1..c087a88d85dca8e7e63684b2ccba76418f666401 100644
--- a/NEWS
+++ b/NEWS
@@ -85,6 +85,14 @@ documents those changes that are of interest to users and admins.
     --ntasks-per-node option.
  -- In select/bluegene with Groups defined for Images, fix possible memory 
     corruption. Other configurations are not affected. 
+ -- BLUEGENE - Fix bug that prevented user specification of linux-image, 
+    mloader-image, and ramdisk-image on job submission.
+ -- BLUEGENE - filter Groups specified for image not just by submitting 
+    user's current group, but all groups the user has access to.
+ -- BLUEGENE - Add salloc options to specify images to be loaded (--blrts-image, 
+    --linux-image, --mloader-image, and --ramdisk-image).
+ -- sbatch will accept batch script containing "#SLURM" options and advise
+    changed to "#SBATCH".
 
 * Changes in SLURM 1.2.18
 =========================
diff --git a/contribs/torque/mpiexec.pl b/contribs/torque/mpiexec.pl
index f468966e7427a485ab34a8eba4653c5578b8b973..26dbc7d6d6de715937e77e07b0104e3b7c6e5e64 100755
--- a/contribs/torque/mpiexec.pl
+++ b/contribs/torque/mpiexec.pl
@@ -45,7 +45,6 @@ use FindBin;
 use Getopt::Long 2.24 qw(:config no_ignore_case require_order);
 use lib "${FindBin::Bin}/../lib/perl";
 use autouse 'Pod::Usage' => qw(pod2usage);
-use Slurm ':all';
 use Switch;
 
 my $srun = "${FindBin::Bin}/srun";
diff --git a/src/common/hostlist.c b/src/common/hostlist.c
index ff6cc15ca240bd28d3011d8b37aa98d81906949b..825e6e33848a9bd930a218284e54608e27cf5091 100644
--- a/src/common/hostlist.c
+++ b/src/common/hostlist.c
@@ -864,9 +864,6 @@ static char *hostrange_pop(hostrange_t hr)
 {
 	size_t size = 0;
 	char *host = NULL;
-#ifdef HAVE_BG
-	int coord[3];
-#endif
 	assert(hr != NULL);
 
 	if (hr->singlehost) {
@@ -877,15 +874,21 @@ static char *hostrange_pop(hostrange_t hr)
 		if (!(host = (char *) malloc(size * sizeof(char))))
 			out_of_memory("hostrange pop");
 #ifdef HAVE_BG
-		coord[0] = hr->hi / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (hr->hi % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (hr->hi % HOSTLIST_BASE);
+		if (hr->width == 3) {
+			int coord[3];
+			coord[0] = hr->hi / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (hr->hi % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (hr->hi % HOSTLIST_BASE);
 		
-		snprintf(host, size, "%s%c%c%c", hr->prefix, 
-			 alpha_num[coord[0]], alpha_num[coord[1]],
-			 alpha_num[coord[2]]);
-		hr->hi--;
+			snprintf(host, size, "%s%c%c%c", hr->prefix, 
+				 alpha_num[coord[0]], alpha_num[coord[1]],
+				 alpha_num[coord[2]]);
+			hr->hi--;
+		} else {
+			snprintf(host, size, "%s%0*lu", hr->prefix, 
+				 hr->width, hr->hi--);
+		}
 #else
 		snprintf(host, size, "%s%0*lu", hr->prefix, 
 			 hr->width, hr->hi--);
@@ -900,9 +903,6 @@ static char *hostrange_shift(hostrange_t hr)
 {
 	size_t size = 0;
 	char *host = NULL;
-#ifdef HAVE_BG
-	int coord[3];
-#endif
 
 	assert(hr != NULL);
 
@@ -915,14 +915,20 @@ static char *hostrange_shift(hostrange_t hr)
 		if (!(host = (char *) malloc(size * sizeof(char))))
 			out_of_memory("hostrange shift");
 #ifdef HAVE_BG
-		coord[0] = hr->lo / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (hr->lo % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (hr->lo % HOSTLIST_BASE);
-		snprintf(host, size, "%s%c%c%c", hr->prefix, 
-			 alpha_num[coord[0]], alpha_num[coord[1]],
-			 alpha_num[coord[2]]);
-		hr->lo++;
+		if (hr->width == 3) {
+			int coord[3];
+			coord[0] = hr->lo / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (hr->lo % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (hr->lo % HOSTLIST_BASE);
+			snprintf(host, size, "%s%c%c%c", hr->prefix, 
+				 alpha_num[coord[0]], alpha_num[coord[1]],
+				 alpha_num[coord[2]]);
+			hr->lo++;
+		} else {
+			snprintf(host, size, "%s%0*lu", hr->prefix,
+				 hr->width, hr->lo++);
+		}
 #else		
 		snprintf(host, size, "%s%0*lu", hr->prefix,
 			hr->width, hr->lo++);
@@ -1049,14 +1055,19 @@ hostrange_to_string(hostrange_t hr, size_t n, char *buf, char *separator)
 		size_t m = (n - len) <= n ? n - len : 0; /* check for < 0 */
 		int ret = 0;
 #ifdef HAVE_BG
-		int coord[3];
-		coord[0] = i / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (i % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (i % HOSTLIST_BASE);
-		ret = snprintf(buf + len, m, "%s%c%c%c", hr->prefix, 
-				alpha_num[coord[0]], alpha_num[coord[1]],
-				alpha_num[coord[2]]);
+		if (hr->width == 3) {
+			int coord[3];
+			coord[0] = i / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (i % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (i % HOSTLIST_BASE);
+			ret = snprintf(buf + len, m, "%s%c%c%c", hr->prefix, 
+					alpha_num[coord[0]], alpha_num[coord[1]],
+					alpha_num[coord[2]]);
+		} else {
+			ret = snprintf(buf + len, m, "%s%0*lu",
+				       hr->prefix, hr->width, i);
+		}
 #else		
 		ret = snprintf(buf + len, m, "%s%0*lu",
 			       hr->prefix, hr->width, i);
@@ -1086,10 +1097,6 @@ hostrange_to_string(hostrange_t hr, size_t n, char *buf, char *separator)
 static size_t hostrange_numstr(hostrange_t hr, size_t n, char *buf)
 {
 	int len = 0;
-#ifdef HAVE_BG
-	int coord[3];
-#endif
-
 	assert(buf != NULL);
 	assert(hr != NULL);
 
@@ -1097,12 +1104,17 @@ static size_t hostrange_numstr(hostrange_t hr, size_t n, char *buf)
 		return 0;
 
 #ifdef HAVE_BG
-	coord[0] = hr->lo / (HOSTLIST_BASE * HOSTLIST_BASE);
-	coord[1] = (hr->lo % (HOSTLIST_BASE * HOSTLIST_BASE)) / HOSTLIST_BASE;
-	coord[2] = (hr->lo % HOSTLIST_BASE);
-	len = snprintf(buf, n, "%c%c%c",  
-		       alpha_num[coord[0]], alpha_num[coord[1]],
-		       alpha_num[coord[2]]);	
+	if (hr->width == 3) {
+		int coord[3];
+		coord[0] = hr->lo / (HOSTLIST_BASE * HOSTLIST_BASE);
+		coord[1] = (hr->lo % (HOSTLIST_BASE * HOSTLIST_BASE)) / HOSTLIST_BASE;
+		coord[2] = (hr->lo % HOSTLIST_BASE);
+		len = snprintf(buf, n, "%c%c%c",  
+			       alpha_num[coord[0]], alpha_num[coord[1]],
+			       alpha_num[coord[2]]);
+	} else {
+		len = snprintf(buf, n, "%0*lu", hr->width, hr->lo);
+	}
 #else		
 	len = snprintf(buf, n, "%0*lu", hr->width, hr->lo);
 #endif
@@ -1110,13 +1122,19 @@ static size_t hostrange_numstr(hostrange_t hr, size_t n, char *buf)
 	if ((len >= 0) && (len < n) && (hr->lo < hr->hi)) {
 		int len2 = 0;
 #ifdef HAVE_BG
-		coord[0] = hr->hi / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (hr->hi % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (hr->hi % HOSTLIST_BASE);
-		len2 = snprintf(buf+len, n-len, "-%c%c%c",  
-				alpha_num[coord[0]], alpha_num[coord[1]],
-				alpha_num[coord[2]]);	
+		if (hr->width == 3) {
+			int coord[3];
+			coord[0] = hr->hi / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (hr->hi % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (hr->hi % HOSTLIST_BASE);
+			len2 = snprintf(buf+len, n-len, "-%c%c%c",  
+					alpha_num[coord[0]], alpha_num[coord[1]],
+					alpha_num[coord[2]]);
+		} else {
+			len2 = snprintf(buf+len, n-len, "-%0*lu", 
+					hr->width, hr->hi);
+		}
 #else				
 		len2 = snprintf(buf+len, n-len, "-%0*lu", hr->width, hr->hi);
 #endif
@@ -1997,15 +2015,20 @@ _hostrange_string(hostrange_t hr, int depth)
 
 	if (!hr->singlehost) {
 #ifdef HAVE_BG
-		int coord[3];
-		int temp = hr->lo+depth;
-		coord[0] = temp / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (temp % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (temp % HOSTLIST_BASE);
-		snprintf(buf+len, MAXHOSTNAMELEN+15 - len, "%c%c%c",
-			 alpha_num[coord[0]], alpha_num[coord[1]],
-			 alpha_num[coord[2]]);
+		if (hr->width == 3) {
+			int coord[3];
+			int temp = hr->lo+depth;
+			coord[0] = temp / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (temp % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (temp % HOSTLIST_BASE);
+			snprintf(buf+len, MAXHOSTNAMELEN+15 - len, "%c%c%c",
+				 alpha_num[coord[0]], alpha_num[coord[1]],
+				 alpha_num[coord[2]]);
+		} else {
+			snprintf(buf+len, MAXHOSTNAMELEN+15 - len, "%0*lu", 
+				 hr->width, hr->lo + depth);
+		}
 #else
 		snprintf(buf+len, MAXHOSTNAMELEN+15 - len, "%0*lu", 
 			 hr->width, hr->lo + depth);
@@ -2704,15 +2727,20 @@ char *hostlist_next(hostlist_iterator_t i)
 	len = snprintf(buf, MAXHOSTNAMELEN + 15, "%s", i->hr->prefix);
 	if (!i->hr->singlehost) {
 #ifdef HAVE_BG
-		int coord[3];
-		int temp = i->hr->lo + i->depth;
-		coord[0] = temp / (HOSTLIST_BASE * HOSTLIST_BASE);
-		coord[1] = (temp % (HOSTLIST_BASE * HOSTLIST_BASE))
-			/ HOSTLIST_BASE;
-		coord[2] = (temp % HOSTLIST_BASE);
-		snprintf(buf + len, MAXHOSTNAMELEN + 15 - len, "%c%c%c",
-			 alpha_num[coord[0]], alpha_num[coord[1]],
-			 alpha_num[coord[2]]);
+		if (i->hr->width == 3) {
+			int coord[3];
+			int temp = i->hr->lo + i->depth;
+			coord[0] = temp / (HOSTLIST_BASE * HOSTLIST_BASE);
+			coord[1] = (temp % (HOSTLIST_BASE * HOSTLIST_BASE))
+				/ HOSTLIST_BASE;
+			coord[2] = (temp % HOSTLIST_BASE);
+			snprintf(buf + len, MAXHOSTNAMELEN + 15 - len, "%c%c%c",
+				 alpha_num[coord[0]], alpha_num[coord[1]],
+				 alpha_num[coord[2]]);
+		} else {
+			snprintf(buf + len, MAXHOSTNAMELEN + 15 - len, "%0*lu",
+				 i->hr->width, i->hr->lo + i->depth);
+		}
 #else
 		snprintf(buf + len, MAXHOSTNAMELEN + 15 - len, "%0*lu",
 			i->hr->width, i->hr->lo + i->depth);
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index 07bd55df9ec6d53301eccd8226c83bee9393f13e..210b25a840a780a5614ac3d365ca80c361e4b44f 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -2569,15 +2569,15 @@ _pack_job_desc_msg(job_desc_msg_t * job_desc_ptr, Buf buffer)
 		}
 		if (job_desc_ptr->linuximage)
 			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
-					     SELECT_DATA_BLRTS_IMAGE, 
+					     SELECT_DATA_LINUX_IMAGE, 
 					     job_desc_ptr->linuximage);
 		if (job_desc_ptr->mloaderimage)
 			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
-					     SELECT_DATA_BLRTS_IMAGE, 
+					     SELECT_DATA_MLOADER_IMAGE, 
 					     job_desc_ptr->mloaderimage);
 		if (job_desc_ptr->ramdiskimage)
 			select_g_set_jobinfo(job_desc_ptr->select_jobinfo, 
-					     SELECT_DATA_BLRTS_IMAGE, 
+					     SELECT_DATA_RAMDISK_IMAGE, 
 					     job_desc_ptr->ramdiskimage);
 		select_g_pack_jobinfo(job_desc_ptr->select_jobinfo, buffer);
 		select_g_free_jobinfo(&job_desc_ptr->select_jobinfo);
diff --git a/src/plugins/select/bluegene/block_allocator/block_allocator.c b/src/plugins/select/bluegene/block_allocator/block_allocator.c
index ff9b8d60c28904d815fd27827108057a95e43e0b..8b89ba29bf4013734464ecbd4daadf11def1808f 100644
--- a/src/plugins/select/bluegene/block_allocator/block_allocator.c
+++ b/src/plugins/select/bluegene/block_allocator/block_allocator.c
@@ -324,8 +324,13 @@ extern int parse_image(void **dest, slurm_parser_enum_t type,
 			image_group->name = xmalloc(i-j+2);
 			snprintf(image_group->name, (i-j)+1, "%s", tmp+j);
 			image_group->gid = gid_from_string(image_group->name);
-			debug3("adding group %s %d", image_group->name,
-			       image_group->gid);
+			if (image_group->gid == (gid_t) -1) {
+				error("Invalid bluegene.conf parameter Groups=%s", 
+				      image_group->name);
+			} else {
+				debug3("adding group %s %d", image_group->name,
+				       image_group->gid);
+			}
 			list_append(n->groups, image_group);
 		}
 		xfree(tmp);
diff --git a/src/plugins/select/bluegene/plugin/bg_job_place.c b/src/plugins/select/bluegene/plugin/bg_job_place.c
index dcedb7b306fd2f32e4f890dd1665f2d7454e85d8..e043a4e8a38edb4046403b02ce54ab87f6b2cbe7 100644
--- a/src/plugins/select/bluegene/plugin/bg_job_place.c
+++ b/src/plugins/select/bluegene/plugin/bg_job_place.c
@@ -4,7 +4,7 @@
  *
  *  $Id$ 
  *****************************************************************************
- *  Copyright (C) 2004 The Regents of the University of California.
+ *  Copyright (C) 2004-2007 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *  Written by Dan Phung <phung4@llnl.gov> and Morris Jette <jette1@llnl.gov>
  *  
@@ -37,11 +37,15 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 \*****************************************************************************/
 
+#include <grp.h>
+#include <pwd.h>
+
 #include "src/common/node_select.h"
 #include "src/slurmctld/trigger_mgr.h"
 #include "bluegene.h"
 
 #define _DEBUG 0
+#define MAX_GROUPS 128
 
 #define SWAP(a,b,t)	\
 _STMT_START {		\
@@ -55,7 +59,11 @@ static int  _find_best_block_match(struct job_record* job_ptr,
 				   uint32_t max_nodes, uint32_t req_nodes,
 				   int spec, bg_record_t** found_bg_record,
 				   bool test_only);
+static int  _get_user_groups(uint32_t user_id, uint32_t group_id, 
+			     gid_t *groups, int max_groups, int *ngroups);
 static void _rotate_geo(uint16_t *req_geometry, int rot_cnt);
+static int  _test_image_perms(char *image_name, List image_list, 
+			      struct job_record* job_ptr);
 
 /* Rotate a 3-D geometry array through its six permutations */
 static void _rotate_geo(uint16_t *req_geometry, int rot_cnt)
@@ -78,6 +86,101 @@ static void _rotate_geo(uint16_t *req_geometry, int rot_cnt)
 
 pthread_mutex_t create_dynamic_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * Get a list of groups associated with a specific user_id
+ * Return 0 on success, -1 on failure
+ */
+static int _get_user_groups(uint32_t user_id, uint32_t group_id, 
+			    gid_t *groups, int max_groups, int *ngroups)
+{
+	struct passwd pwd, *results;
+	char *buffer;
+	static size_t buf_size = 0;
+	int rc;
+
+	if (!buf_size && ((buf_size = sysconf(_SC_GETPW_R_SIZE_MAX)) < 0)) {
+		error("sysconf(_SC_GETPW_R_SIZE_MAX)");
+		return -1;
+	}
+	buffer = xmalloc(buf_size);
+	rc = getpwuid_r((uid_t) user_id, &pwd, buffer, buf_size, &results);
+	if (rc != 0) {
+		error("getpwuid_r(%u): %m", user_id);
+		xfree(buffer);
+		return -1;
+	}
+	*ngroups = max_groups;
+	rc = getgrouplist(pwd.pw_name, (gid_t) group_id, groups, ngroups);
+	xfree(buffer);
+	if (rc < 0) {
+		error("getgrouplist(%s): %m", pwd.pw_name);
+		return -1;
+	}
+	*ngroups = rc;
+
+	return 0;
+}
+
+/*
+ * Determine if the job has permission to use the identified image
+ */
+static int _test_image_perms(char *image_name, List image_list, 
+			     struct job_record* job_ptr)
+{
+	int allow = 0, i, rc;
+	ListIterator itr;
+	ListIterator itr2;
+	image_t *image = NULL;
+	image_group_t *image_group = NULL;
+
+	/* Cache group information for most recently checked user */
+	static gid_t groups[MAX_GROUPS];
+	static int ngroups = -1;
+	static int32_t cache_user = -1;
+
+	itr = list_iterator_create(image_list);
+	while ((image = list_next(itr))) {
+		if (!strcasecmp(image->name, image_name) ||
+		    !strcasecmp(image->name, "*")) {
+			if (image->def) {
+				allow = 1;
+				break;
+			}
+			if (!image->groups ||
+			    !list_count(image->groups)) {
+				allow = 1;
+				break;
+			}
+			if (job_ptr->user_id != cache_user) {
+				rc = _get_user_groups(job_ptr->user_id, 
+						      job_ptr->group_id,
+						      groups, 
+						      MAX_GROUPS, &ngroups);
+				if (rc)		/* Failed to get groups */
+					break;
+				cache_user = job_ptr->user_id;
+			}
+			itr2 = list_iterator_create(image->groups);
+			while ((allow == 0) &&
+			       (image_group = list_next(itr2))) {
+				for (i=0; i<ngroups; i++) {
+					if (image_group->gid
+					    == groups[i]) {
+						allow = 1;
+						break;
+					}
+				}
+			}
+			list_iterator_destroy(itr2);
+			if (allow)
+				break;	
+		}
+	}
+	list_iterator_destroy(itr);
+
+	return allow;
+}
+
 /*
  * finds the best match for a given job request 
  * 
@@ -100,8 +203,6 @@ static int _find_best_block_match(struct job_record* job_ptr,
 	ListIterator itr2;
 	bg_record_t *record = NULL;
 	bg_record_t *found_record = NULL;
-	image_t *image = NULL;
-	image_group_t *image_group = NULL;
 	uint16_t req_geometry[BA_SYSTEM_DIMENSIONS];
 	uint16_t start[BA_SYSTEM_DIMENSIONS];
 	uint16_t conn_type, rotate, target_size = 0;
@@ -207,113 +308,38 @@ static int _find_best_block_match(struct job_record* job_ptr,
 			     SELECT_DATA_ROTATE, &rotate);
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_MAX_PROCS, &max_procs);
+
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_BLRTS_IMAGE, &blrtsimage);
-	if(blrtsimage) {
-		allow = 0;
-		itr = list_iterator_create(bg_blrtsimage_list);
-		while((image = list_next(itr))) {
-			if(!strcasecmp(blrtsimage, image->name)
-			   || !strcasecmp("*", image->name)) {
-				if(image->def) {
-					allow = 1;
-					break;
-				}
-				if(!image->groups ||
-				   !list_count(image->groups)) {
-					allow = 1;
-					break;
-				}				
-				itr2 = list_iterator_create(image->groups);
-				while((image_group = list_next(itr2))) {
-					if(image_group->gid
-					   == job_ptr->group_id) {
-						allow = 1;
-						break;
-					}
-				}
-				list_iterator_destroy(itr2);
-				if(allow)
-					break;	
-			}
-		}
-		list_iterator_destroy(itr);
-		if(!allow) {
+	if (blrtsimage) {
+		allow = _test_image_perms(blrtsimage, bg_blrtsimage_list, 
+					  job_ptr);
+		if (!allow) {
 			error("User %u:%u is not allowed to use BlrtsImage %s",
 			      job_ptr->user_id, job_ptr->group_id, blrtsimage);
 			rc = SLURM_ERROR;
 			goto end_it;
 		}
 	}
+
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_LINUX_IMAGE, &linuximage);
-	if(linuximage) {
-		allow = 0;
-		itr = list_iterator_create(bg_linuximage_list);
-		while((image = list_next(itr))) {
-			if(!strcasecmp(linuximage, image->name)
-			   || !strcasecmp("*", image->name)) {
-				if(image->def) {
-					allow = 1;
-					break;
-				}
-				if(!image->groups
-				   || !list_count(image->groups)) {
-					allow = 1;
-					break;
-				}				
-				itr2 = list_iterator_create(image->groups);
-				while((image_group = list_next(itr2))) {
-					if(image_group->gid
-					   == job_ptr->group_id) {
-						allow = 1;
-						break;
-					}
-				}
-				list_iterator_destroy(itr2);
-				if(allow)
-					break;	
-			}
-		}
-		list_iterator_destroy(itr);
-		if(!allow) {
+	if (linuximage) {
+		allow = _test_image_perms(linuximage, bg_linuximage_list, 
+					  job_ptr);
+		if (!allow) {
 			error("User %u:%u is not allowed to use LinuxImage %s",
 			      job_ptr->user_id, job_ptr->group_id, linuximage);
 			rc = SLURM_ERROR;
 			goto end_it;
 		}
 	}
+
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_MLOADER_IMAGE, &mloaderimage);
-	if(mloaderimage) {
-		allow = 0;
-		itr = list_iterator_create(bg_mloaderimage_list);
-		while((image = list_next(itr))) {
-			if(!strcasecmp(mloaderimage, image->name)
-			   || !strcasecmp("*", image->name)) {
-				if(image->def) {
-					allow = 1;
-					break;
-				}
-				if(!image->groups
-				   || !list_count(image->groups)) {
-					allow = 1;
-					break;
-				}				
-				itr2 = list_iterator_create(image->groups);
-				while((image_group = list_next(itr2))) {
-					if(image_group->gid
-					   == job_ptr->group_id) {
-						allow = 1;
-						break;
-					}
-				}
-				list_iterator_destroy(itr2);
-				if(allow)
-					break;	
-			}
-		}
-		list_iterator_destroy(itr);
+	if (mloaderimage) {
+		allow = _test_image_perms(mloaderimage, bg_mloaderimage_list, 
+					  job_ptr);
 		if(!allow) {
 			error("User %u:%u is not allowed "
 			      "to use MloaderImage %s",
@@ -323,37 +349,12 @@ static int _find_best_block_match(struct job_record* job_ptr,
 			goto end_it;
 		}
 	}
+
 	select_g_get_jobinfo(job_ptr->select_jobinfo,
 			     SELECT_DATA_RAMDISK_IMAGE, &ramdiskimage);
-	if(ramdiskimage) {
-		allow = 0;
-		itr = list_iterator_create(bg_ramdiskimage_list);
-		while((image = list_next(itr))) {
-			if(!strcasecmp(ramdiskimage, image->name)
-			   || !strcasecmp("*", image->name)) {
-				if(image->def) {
-					allow = 1;
-					break;
-				}
-				if(!image->groups
-				   || !list_count(image->groups)) {
-					allow = 1;
-					break;
-				}				
-				itr2 = list_iterator_create(image->groups);
-				while((image_group = list_next(itr2))) {
-					if(image_group->gid
-					   == job_ptr->group_id) {
-						allow = 1;
-						break;
-					}
-				}
-				list_iterator_destroy(itr2);
-				if(allow)
-					break;	
-			}
-		}
-		list_iterator_destroy(itr);
+	if (ramdiskimage) {
+		allow = _test_image_perms(ramdiskimage, bg_ramdiskimage_list, 
+					  job_ptr);
 		if(!allow) {
 			error("User %u:%u is not allowed "
 			      "to use RamDiskImage %s",
diff --git a/src/salloc/opt.c b/src/salloc/opt.c
index c19b41d6871e5a50d635d4a7f29c2c31377b6768..24b7ca9ebf233e6379e909452fac585e7f653d73 100644
--- a/src/salloc/opt.c
+++ b/src/salloc/opt.c
@@ -110,6 +110,10 @@
 #define LONG_OPT_NO_BELL     0x117
 #define LONG_OPT_COMMENT     0x118
 #define LONG_OPT_REBOOT      0x119
+#define LONG_OPT_BLRTS_IMAGE     0x120
+#define LONG_OPT_LINUX_IMAGE     0x121
+#define LONG_OPT_MLOADER_IMAGE   0x122
+#define LONG_OPT_RAMDISK_IMAGE   0x123
 #define LONG_OPT_SOCKETSPERNODE  0x130
 #define LONG_OPT_CORESPERSOCKET  0x131
 #define LONG_OPT_THREADSPERCORE  0x132
@@ -513,6 +517,10 @@ void set_options(const int argc, char **argv)
 		{"jobid",         required_argument, 0, LONG_OPT_JOBID},
 		{"comment",       required_argument, 0, LONG_OPT_COMMENT},
 		{"reboot",	  no_argument,       0, LONG_OPT_REBOOT},
+		{"blrts-image",   required_argument, 0, LONG_OPT_BLRTS_IMAGE},
+		{"linux-image",   required_argument, 0, LONG_OPT_LINUX_IMAGE},
+		{"mloader-image", required_argument, 0, LONG_OPT_MLOADER_IMAGE},
+		{"ramdisk-image", required_argument, 0, LONG_OPT_RAMDISK_IMAGE},
 		{NULL,            0,                 0, 0}
 	};
 	char *opt_string = "+a:B:c:C:d:F:g:hHIJ:kK:m:n:N:Op:qR:st:uU:vVw:W:x:";
@@ -840,6 +848,22 @@ void set_options(const int argc, char **argv)
 		case LONG_OPT_REBOOT:
 			opt.reboot = true;
 			break;
+		case LONG_OPT_BLRTS_IMAGE:
+			xfree(opt.blrtsimage);
+			opt.blrtsimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_LINUX_IMAGE:
+			xfree(opt.linuximage);
+			opt.linuximage = xstrdup(optarg);
+			break;
+		case LONG_OPT_MLOADER_IMAGE:
+			xfree(opt.mloaderimage);
+			opt.mloaderimage = xstrdup(optarg);
+			break;
+		case LONG_OPT_RAMDISK_IMAGE:
+			xfree(opt.ramdiskimage);
+			opt.ramdiskimage = xstrdup(optarg);
+			break;
 		default:
 			fatal("Unrecognized command line parameter %c",
 			      opt_char);
@@ -1205,6 +1229,14 @@ static void _opt_list()
 	xfree(str);
 	info("reboot         : %s", opt.reboot ? "no" : "yes");
 	info("rotate         : %s", opt.no_rotate ? "yes" : "no");
+	if (opt.blrtsimage)
+		info("BlrtsImage     : %s", opt.blrtsimage);
+	if (opt.linuximage)
+		info("LinuxImage     : %s", opt.linuximage);
+	if (opt.mloaderimage)
+		info("MloaderImage   : %s", opt.mloaderimage);
+	if (opt.ramdiskimage)
+		info("RamDiskImage   : %s", opt.ramdiskimage);
 	if (opt.begin) {
 		char time_str[32];
 		slurm_make_time_str(&opt.begin, time_str, sizeof(time_str));
@@ -1241,6 +1273,8 @@ static void _usage(void)
 "              [--account=name] [--dependency=jobid] [--comment=name]\n"
 #ifdef HAVE_BG		/* Blue gene specific options */
 "              [--geometry=XxYxZ] [--conn-type=type] [--no-rotate] [ --reboot]\n"
+"              [--blrts-image=path] [--linux-image=path]\n"
+"              [--mloader-image=path] [--ramdisk-image=path]\n"
 #endif
 "              [--mail-type=type] [--mail-user=user][--nice[=value]]\n"
 "              [--bell] [--no-bell] [--kill-command[=signal]]\n"
@@ -1336,6 +1370,10 @@ static void _help(void)
   "      --reboot                reboot nodes before starting job\n"
   "      --conn-type=type        constraint on type of connection, MESH or TORUS\n"
   "                              if not set, then tries to fit TORUS else MESH\n"
+  "      --blrts-image=path      path to blrts image for bluegene block.  Default if not set\n"
+  "      --linux-image=path      path to linux image for bluegene block.  Default if not set\n"
+  "      --mloader-image=path    path to mloader image for bluegene block.  Default if not set\n"
+  "      --ramdisk-image=path    path to ramdisk image for bluegene block.  Default if not set\n"
   "\n"
 #endif
 "Help options:\n"
diff --git a/src/salloc/opt.h b/src/salloc/opt.h
index ed974a070420471638596ab70d6814ba79926855..ea5fb69d57e73f39965790fba9e0c87af6a602d2 100644
--- a/src/salloc/opt.h
+++ b/src/salloc/opt.h
@@ -113,10 +113,17 @@ typedef struct salloc_options {
 	char *nodelist;		/* --nodelist=node1,node2,...	*/
 	char *exc_nodes;	/* --exclude=node1,node2,... -x	*/
 
+	/* BLUEGENE SPECIFIC */
 	uint16_t geometry[SYSTEM_DIMENSIONS]; /* --geometry, -g	*/
 	bool reboot;		/* --reboot			*/
 	bool no_rotate;		/* --no_rotate, -R		*/
 	int16_t conn_type;	/* --conn-type 			*/
+	char *blrtsimage;       /* --blrts-image BlrtsImage for block */
+	char *linuximage;       /* --linux-image LinuxImage for block */
+	char *mloaderimage;     /* --mloader-image mloaderImage for block */
+	char *ramdiskimage;     /* --ramdisk-image RamDiskImage for block */
+	/*********************/
+
 	time_t begin;		/* --begin			*/
 	uint16_t mail_type;	/* --mail-type			*/
 	char *mail_user;	/* --mail-user			*/
diff --git a/src/salloc/salloc.c b/src/salloc/salloc.c
index 6592c62a30e5b4cb4e0008861e7b33721fccc4a6..25262bdb0106da277cb5287a0c3e2f50a753022b 100644
--- a/src/salloc/salloc.c
+++ b/src/salloc/salloc.c
@@ -281,6 +281,14 @@ static int fill_job_desc_from_opts(job_desc_msg_t *desc)
 		desc->reboot = 1;
 	if (opt.no_rotate)
 		desc->rotate = 0;
+	if (opt.blrtsimage)
+		desc->blrtsimage = xstrdup(opt.blrtsimage);
+	if (opt.linuximage)
+		desc->linuximage = xstrdup(opt.linuximage);
+	if (opt.mloaderimage)
+		desc->mloaderimage = xstrdup(opt.mloaderimage);
+	if (opt.ramdiskimage)
+		desc->ramdiskimage = xstrdup(opt.ramdiskimage);
 
 	/* job constraints */
 	if (opt.mincpus > -1)
diff --git a/src/sbatch/opt.c b/src/sbatch/opt.c
index 0ab7e3b456cc012d9731d6540eeabb84960846a1..cf5f12aa785e0a73d64328997011ea0e47afb7f0 100644
--- a/src/sbatch/opt.c
+++ b/src/sbatch/opt.c
@@ -299,6 +299,7 @@ struct env_vars {
 	void *set_flag;
 };
 
+
 env_vars_t env_vars[] = {
   {"SBATCH_ACCOUNT",       OPT_STRING,     &opt.account,       NULL           },
   {"SBATCH_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL           },
@@ -741,31 +742,43 @@ static char *_get_argument(const char *line, int *skipped)
  */
 static void _opt_batch_script(const void *body, int size)
 {
-	char *magic_word = "#SBATCH";
-	int magic_word_len;
+	char *magic_word1 = "#SBATCH";
+	char *magic_word2 = "#SLURM";
+	int magic_word_len1, magic_word_len2;
 	int argc;
 	char **argv;
 	void *state = NULL;
 	char *line;
 	char *option;
 	char *ptr;
-	int skipped = 0;
+	int skipped = 0, warned = 0;
 	int i;
 
-	magic_word_len = strlen(magic_word);
+	magic_word_len1 = strlen(magic_word1);
+	magic_word_len2 = strlen(magic_word2);
+
 	/* getopt_long skips over the first argument, so fill it in */
 	argc = 1;
 	argv = xmalloc(sizeof(char *));
 	argv[0] = "sbatch";
 
 	while((line = _next_line(body, size, &state)) != NULL) {
-		if (strncmp(line, magic_word, magic_word_len) != 0) {
+		if (!strncmp(line, magic_word1, magic_word_len1))
+			ptr = line + magic_word_len1;
+		else if (!strncmp(line, magic_word2, magic_word_len2)) {
+			ptr = line + magic_word_len2;
+			if (!warned) {
+				error("Change from #SLURM to #SBATCH in your "
+				      "script and verify the options are "
+				      "valid in sbatch");
+				warned = 1;
+			}
+		} else {
 			xfree(line);
 			continue;
 		}
 
 		/* this line starts with the magic word */
-		ptr = line + magic_word_len;
 		while ((option = _get_argument(ptr, &skipped)) != NULL) {
 			debug2("Found in script, argument \"%s\"", option);
 			argc += 1;
@@ -1766,7 +1779,7 @@ static uint16_t _parse_pbs_mail_type(const char *arg)
 		|| strcasecmp(arg, "ae") == 0)
 		rc = MAIL_JOB_END |  MAIL_JOB_FAIL;
 	else
-		rc = 0;		/* failure */
+		rc = 0;		/* arg="n" or failure */
 
 	return rc;
 }
diff --git a/src/sbatch/opt.h b/src/sbatch/opt.h
index 330ecf7d07c4cb56baa30f686d00819482059374..6d2009f38205a55db66e54ba2a6a4d0ab8731e3c 100644
--- a/src/sbatch/opt.h
+++ b/src/sbatch/opt.h
@@ -121,10 +121,10 @@ typedef struct sbatch_options {
 	bool reboot;		/* --reboot			*/
 	bool no_rotate;		/* --no_rotate, -R		*/
 	uint16_t conn_type;	/* --conn-type 			*/
-	char *blrtsimage;       /* --blrtsimage BlrtsImage for block */
-	char *linuximage;       /* --linuximage LinuxImage for block */
-	char *mloaderimage;     /* --mloaderimage mloaderImage for block */
-	char *ramdiskimage;     /* --ramdiskimage RamDiskImage for block */
+	char *blrtsimage;       /* --blrts-image BlrtsImage for block */
+	char *linuximage;       /* --linux-image LinuxImage for block */
+	char *mloaderimage;     /* --mloader-image mloaderImage for block */
+	char *ramdiskimage;     /* --ramdisk-image RamDiskImage for block */
 	/*********************/
 
 	time_t begin;		/* --begin			*/
diff --git a/src/smap/partition_functions.c b/src/smap/partition_functions.c
index 06aaef5b271150166a420d6f12017663aa2da469..46a79c9d4155a0256efd4a546fda64754a3ec33f 100644
--- a/src/smap/partition_functions.c
+++ b/src/smap/partition_functions.c
@@ -837,9 +837,9 @@ static int _addto_nodelist(List nodelist, int *start, int *end)
 	int *coord = NULL;
 	int x,y,z;
 	
-	if(end[X] < DIM_SIZE[X]
-	   || end[Y] < DIM_SIZE[Y]
-	   || end[Z] < DIM_SIZE[Z]) {
+	if(end[X] >= DIM_SIZE[X]
+	   || end[Y] >= DIM_SIZE[Y]
+	   || end[Z] >= DIM_SIZE[Z]) {
 		fatal("It appears the slurm.conf file has changed since "
 		      "the last restart.\nThings are in an incompatible "
 		      "state, please restart the slurmctld.");