diff --git a/NEWS b/NEWS
index 8297d66d6f2999d7d429409e5654f6dbb0125b20..9e91621fbcd79e22453c82ca85ceb58ed23a25c9 100644
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,8 @@ documents those changes that are of interest to users and admins.
  -- Changed getpwent to getpwent_r in the slurmctld and slurmd
  -- Increase timeout on most slurmdbd communications to 60 secs (time for
     substantial database updates).
+ -- Treat srun option of --begin= with a value of now without a numeric
+    component as a failure (e.g. "--begin=now+hours").
 
 * Changes in SLURM 1.3.6
 ========================
@@ -477,6 +479,7 @@ documents those changes that are of interest to users and admins.
  -- For PMI only (MPICH2/MVAPICH2) base address to send messages to (the srun)
     upon the address from which slurmd gets the task launch request rather then
     "hostname" where srun executes.
+ -- Make test for StateSaveLocation directory more comprehensive.
 
 * Changes in SLURM 1.2.33
 =========================
diff --git a/auxdir/x_ac_gtk.m4 b/auxdir/x_ac_gtk.m4
index ecdf3cf47504c54fe7a24737577a19d1718d1322..7ab71b2d081362073e49fcafb46ace4be1fd5aad 100644
--- a/auxdir/x_ac_gtk.m4
+++ b/auxdir/x_ac_gtk.m4
@@ -46,7 +46,7 @@ AC_DEFUN([X_AC_GTK],
 #    fi
 
 
-### Check for gtk2.6 package
+### Check for gtk2.7.1 package
     if test "$ac_have_gtk" == "yes" ; then
         $HAVEPKGCONFIG --exists gtk+-2.0
         if ! test $? -eq 0 ; then
@@ -60,8 +60,8 @@ AC_DEFUN([X_AC_GTK],
     	   gtk_config_micro_version=`$HAVEPKGCONFIG --modversion gtk+-2.0 | \
              sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
 
-	   if test $gtk_config_major_version -lt 2 || test $gtk_config_minor_version -lt 6 ; then
-	   	AC_MSG_WARN([*** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.6.0 installed for sview.])
+	   if test $gtk_config_major_version -lt 2 || test $gtk_config_minor_version -lt 7 || test $gtk_config_micro_version -lt 1; then
+	   	AC_MSG_WARN([*** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.7.1 installed for sview.])
             	ac_have_gtk="no"
 	   fi
         fi
diff --git a/configure b/configure
index 67d4bfd2c48ce3300699c7e6278d9b2734c77adb..00ef5f35adfa7d27dc85c7820cfe319b4da50222 100755
--- a/configure
+++ b/configure
@@ -25271,7 +25271,7 @@ echo "$as_me: WARNING: *** pkg-config not found. Cannot probe for libglade-2.0 o
 #    fi
 
 
-### Check for gtk2.6 package
+### Check for gtk2.8 package
     if test "$ac_have_gtk" == "yes" ; then
         $HAVEPKGCONFIG --exists gtk+-2.0
         if ! test $? -eq 0 ; then
@@ -25286,9 +25286,9 @@ echo "$as_me: WARNING: *** gtk+-2.0 is not available." >&2;}
     	   gtk_config_micro_version=`$HAVEPKGCONFIG --modversion gtk+-2.0 | \
              sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
 
-	   if test $gtk_config_major_version -lt 2 || test $gtk_config_minor_version -lt 6 ; then
-	   	{ echo "$as_me:$LINENO: WARNING: *** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.6.0 installed for sview." >&5
-echo "$as_me: WARNING: *** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.6.0 installed for sview." >&2;}
+	   if test $gtk_config_major_version -lt 2 || test $gtk_config_minor_version -lt 7 || test $gtk_config_micro_version -lt 1; then
+	   	{ echo "$as_me:$LINENO: WARNING: *** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.7.1 installed for sview." >&5
+echo "$as_me: WARNING: *** gtk+-$gtk_config_major_version.$gtk_config_minor_version.$gtk_config_micro_version available, we need >= gtk+-2.7.1 installed for sview." >&2;}
             	ac_have_gtk="no"
 	   fi
         fi
diff --git a/doc/man/man1/sacctmgr.1 b/doc/man/man1/sacctmgr.1
index 383728ed253c081a5c59b63f79c0b5de4e43ea6f..94947cebb5afd592e170ff05650e77d0aba326ec 100644
--- a/doc/man/man1/sacctmgr.1
+++ b/doc/man/man1/sacctmgr.1
@@ -45,13 +45,22 @@ This is equivalent to the \fBoneliner\fR command.
 
 .TP
 \fB\-p\fR, \fB\-\-parsable\fR
-Output will be '|' delimited.
+Output will be '|' delimited with a '|' at the end.
+
+.TP
+\fB\-P\fR, \fB\-\-parsable2\fR
+Output will be '|' delimited without a '|' at the end.
 
 .TP
 \fB\-q\fR, \fB\-\-quiet\fR
 Print no messages other than error messages.
 This is equivalent to the \fBquiet\fR command.
 
+.TP
+\fB\-r\fR, \fB\-\-readonly\fR
+Makes it so the running sacctmgr can not modify accounting information.
+This is equivalent to the \fBreadonly\fR command.
+
 .TP
 \fB\-s\fR, \fB\-\-associations\fR
 Use with show or list to display associations with the entity.
diff --git a/doc/man/man1/sreport.1 b/doc/man/man1/sreport.1
index ac0d0b7d575c4618ebffa378daa052d22ea33a1c..e07f8c0cf474e049622441c7162e168c67dba5a3 100644
--- a/doc/man/man1/sreport.1
+++ b/doc/man/man1/sreport.1
@@ -33,7 +33,11 @@ This is equivalent to the \fBquiet\fR command.
 
 .TP
 \fB\-p\fR, \fB\-\-parsable\fR
-Make output '|' delimited.
+Output will be '|' delimited with a '|' at the end.
+
+.TP
+\fB\-P\fR, \fB\-\-parsable2\fR
+Output will be '|' delimited without a '|' at the end.
 
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
diff --git a/src/common/parse_time.c b/src/common/parse_time.c
index e72f2c93e455f3e69936a8bac89ad03e9ddcda9f..33c0e7f42b7c09351f5a0d77d965660ca027742d 100644
--- a/src/common/parse_time.c
+++ b/src/common/parse_time.c
@@ -60,6 +60,7 @@ static int _get_delta(char *time_str, int *pos, long *delta)
 {
 	int offset;
 	long cnt = 0;
+	int digit = 0;
 
 	offset = (*pos) + 1;
 	for ( ; ((time_str[offset]!='\0')&&(time_str[offset]!='\n')); offset++) {
@@ -87,10 +88,15 @@ static int _get_delta(char *time_str, int *pos, long *delta)
 		}
 		if ((time_str[offset] >= '0') && (time_str[offset] <= '9')) {
 			cnt = (cnt * 10) + (time_str[offset] - '0');
+			digit++;
 			continue;
 		}
 		goto prob;
 	}
+
+	if (!digit)	/* No numbers after the '=' */
+		return -1;
+
 	*pos = offset - 1;
 	*delta = cnt;
 	return 0;
diff --git a/src/common/print_fields.c b/src/common/print_fields.c
index cb5d3ed858ee86d58160686406ba45c4dec099d8..e95864f0651d030ea372ee984942d9a069a3d4c3 100644
--- a/src/common/print_fields.c
+++ b/src/common/print_fields.c
@@ -67,16 +67,24 @@ extern void print_fields_header(List print_fields_list)
 {
 	ListIterator itr = NULL;
 	print_field_t *field = NULL;
-
+	int curr_inx = 1;
+	int field_count = 0;
 	if(!print_fields_list || !print_fields_have_header) 
 		return;
 
+	field_count = list_count(print_fields_list);
+
 	itr = list_iterator_create(print_fields_list);
 	while((field = list_next(itr))) {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && (curr_inx == field_count))
+			printf("%s", field->name);	
+		else if(print_fields_parsable_print)
 			printf("%s|", field->name);
 		else
 			printf("%-*.*s ", field->len, field->len, field->name);
+		curr_inx++;
 	}
 	list_iterator_reset(itr);
 	printf("\n");
@@ -90,7 +98,7 @@ extern void print_fields_header(List print_fields_list)
 	printf("\n");	
 }
 
-extern void print_fields_date(print_field_t *field, time_t value)
+extern void print_fields_date(print_field_t *field, time_t value, int last)
 {
 	char temp_char[field->len];
 	time_t now = value;
@@ -98,13 +106,16 @@ extern void print_fields_date(print_field_t *field, time_t value)
 	if(!now)
 		now = time(NULL);
 	slurm_make_time_str(&value, (char *)temp_char, field->len);
-	if(print_fields_parsable_print)
+	if(print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
+	   && last)
+		printf("%s", temp_char);	
+	else if(print_fields_parsable_print)
 		printf("%s|", temp_char);
 	else 
 		printf("%-*.*s ", field->len, field->len, temp_char);
 }
 
-extern void print_fields_str(print_field_t *field, char *value)
+extern void print_fields_str(print_field_t *field, char *value, int last)
 {
 	char temp_char[field->len];
 	char *print_this = NULL;
@@ -116,7 +127,10 @@ extern void print_fields_str(print_field_t *field, char *value)
 			print_this = " ";
 	}
 	
-	if(print_fields_parsable_print)
+	if(print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
+	   && last)
+		printf("%s", value);	
+	else if(print_fields_parsable_print)
 		printf("%s|", value);
 	else {
 		if(!print_this) {
@@ -130,32 +144,48 @@ extern void print_fields_str(print_field_t *field, char *value)
 	}
 }
 
-extern void print_fields_uint32(print_field_t *field, uint32_t value)
+extern void print_fields_uint32(print_field_t *field, uint32_t value, int last)
 {
 	/* (value == unset)  || (value == cleared) */
 	if((value == NO_VAL) || (value == INFINITE)) {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			;
+		else if(print_fields_parsable_print)
 			printf("|");	
 		else				
 			printf("%*s ", field->len, " ");
 	} else {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			printf("%u", value);	
+		else if(print_fields_parsable_print)
 			printf("%u|", value);	
 		else
 			printf("%*u ", field->len, value);
 	}
 }
 
-extern void print_fields_uint64(print_field_t *field, uint64_t value)
+extern void print_fields_uint64(print_field_t *field, uint64_t value, int last)
 {
 	/* (value == unset)  || (value == cleared) */
 	if((value == NO_VAL) || (value == INFINITE)) {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			;
+		else if(print_fields_parsable_print)
 			printf("|");	
 		else				
 			printf("%*s ", field->len, " ");
 	} else {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			printf("%llu", (long long unsigned) value);	
+		else if(print_fields_parsable_print)
 			printf("%llu|", (long long unsigned) value);	
 		else
 			printf("%*llu ", field->len, 
@@ -163,25 +193,33 @@ extern void print_fields_uint64(print_field_t *field, uint64_t value)
 	}
 }
 
-extern void print_fields_time(print_field_t *field, uint32_t value)
+extern void print_fields_time(print_field_t *field, uint32_t value, int last)
 {
 	/* (value == unset)  || (value == cleared) */
 	if((value == NO_VAL) || (value == INFINITE)) {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			;
+		else if(print_fields_parsable_print)
 			printf("|");	
 		else
 			printf("%*s ", field->len, " ");
 	} else {
 		char time_buf[32];
 		mins2time_str((time_t) value, time_buf, sizeof(time_buf));
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			printf("%s", time_buf);
+		else if(print_fields_parsable_print)
 			printf("%s|", time_buf);
 		else
 			printf("%*s ", field->len, time_buf);
 	}
 }
 
-extern void print_fields_char_list(print_field_t *field, List value)
+extern void print_fields_char_list(print_field_t *field, List value, int last)
 {
 	ListIterator itr = NULL;
 	char *print_this = NULL;
@@ -204,7 +242,10 @@ extern void print_fields_char_list(print_field_t *field, List value)
 		list_iterator_destroy(itr);
 	}
 	
-	if(print_fields_parsable_print)
+	if(print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
+	   && last)
+		printf("%s", print_this);
+	else if(print_fields_parsable_print)
 		printf("%s|", print_this);
 	else {
 		if(strlen(print_this) > field->len) 
diff --git a/src/common/print_fields.h b/src/common/print_fields.h
index 37ade380f5e27b6327168cacc60d5ef60ec30bc3..36eed4add7d8a55b48a30c0b67c1f897a5fb81bc 100644
--- a/src/common/print_fields.h
+++ b/src/common/print_fields.h
@@ -74,17 +74,25 @@ typedef struct {
 	uint16_t type; /* defined in the local function */
 } print_field_t;
 
+enum {
+	PRINT_FIELDS_PARSABLE_NOT = 0,
+	PRINT_FIELDS_PARSABLE_ENDING,
+	PRINT_FIELDS_PARSABLE_NO_ENDING
+};
+
 extern int print_fields_parsable_print;
 extern int print_fields_have_header;
 
 extern void destroy_print_field(void *object);
 extern void print_fields_header(List print_fields_list);
-extern void print_fields_date(print_field_t *field, time_t value);
-extern void print_fields_str(print_field_t *field, char *value);
-extern void print_fields_uint32(print_field_t *field, uint32_t value);
-extern void print_fields_uint64(print_field_t *field, uint64_t value);
-extern void print_fields_time(print_field_t *field, uint32_t value);
-extern void print_fields_char_list(print_field_t *field, List value);
+extern void print_fields_date(print_field_t *field, time_t value, int last);
+extern void print_fields_str(print_field_t *field, char *value, int last);
+extern void print_fields_uint32(
+	print_field_t *field, uint32_t value, int last);
+extern void print_fields_uint64(
+	print_field_t *field, uint64_t value, int last);
+extern void print_fields_time(print_field_t *field, uint32_t value, int last);
+extern void print_fields_char_list(print_field_t *field, List value, int last);
 
 #define print_fields_uint print_fields_uint32
 #endif
diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c
index 6265ce45ab20deb7f55f8499d0e5a21b33c85447..fdac0c483ea238ad58f545d40c6ef7d500f148ac 100644
--- a/src/common/slurm_accounting_storage.c
+++ b/src/common/slurm_accounting_storage.c
@@ -2322,39 +2322,39 @@ extern acct_admin_level_t str_2_acct_admin_level(char *level)
 
 extern void log_assoc_rec(acct_association_rec_t *assoc_ptr)
 {
-	debug("association rec id          : %u", assoc_ptr->id);
-	debug("  acct                      : %s", assoc_ptr->acct);
-	debug("  cluster                   : %s", assoc_ptr->cluster);
+	debug2("association rec id          : %u", assoc_ptr->id);
+	debug2("  acct                      : %s", assoc_ptr->acct);
+	debug2("  cluster                   : %s", assoc_ptr->cluster);
 	if(assoc_ptr->fairshare == INFINITE)
-		debug("  fairshare                 : NONE");
+		debug2("  fairshare                 : NONE");
 	else
-		debug("  fairshare                 : %u",
-		      assoc_ptr->fairshare);
+		debug2("  fairshare                 : %u",
+		       assoc_ptr->fairshare);
 	if(assoc_ptr->max_cpu_secs_per_job == INFINITE)
-		debug("  max_cpu_secs_per_job      : NONE");
+		debug2("  max_cpu_secs_per_job      : NONE");
 	else
-		debug("  max_cpu_secs_per_job      : %d",
-		      assoc_ptr->max_cpu_secs_per_job);
+		debug2("  max_cpu_secs_per_job      : %d",
+		       assoc_ptr->max_cpu_secs_per_job);
 	if(assoc_ptr->max_jobs == INFINITE)
-		debug("  max_jobs                  : NONE");
+		debug2("  max_jobs                  : NONE");
 	else
-		debug("  max_jobs                  : %u", assoc_ptr->max_jobs);
+		debug2("  max_jobs                  : %u", assoc_ptr->max_jobs);
 	if(assoc_ptr->max_nodes_per_job == INFINITE)
-		debug("  max_nodes_per_job         : NONE");
+		debug2("  max_nodes_per_job         : NONE");
 	else
-		debug("  max_nodes_per_job         : %d",
-		      assoc_ptr->max_nodes_per_job);
+		debug2("  max_nodes_per_job         : %d",
+		       assoc_ptr->max_nodes_per_job);
 	if(assoc_ptr->max_wall_duration_per_job == INFINITE)
-		debug("  max_wall_duration_per_job : NONE");
+		debug2("  max_wall_duration_per_job : NONE");
 	else
-		debug("  max_wall_duration_per_job : %d", 
-		      assoc_ptr->max_wall_duration_per_job);
-	debug("  parent_acct               : %s", assoc_ptr->parent_acct);
-	debug("  partition                 : %s", assoc_ptr->partition);
-	debug("  user                      : %s(%u)",
-	      assoc_ptr->user, assoc_ptr->uid);
-	debug("  used_jobs                 : %u", assoc_ptr->used_jobs);
-	debug("  used_share                : %u", assoc_ptr->used_share);
+		debug2("  max_wall_duration_per_job : %d", 
+		       assoc_ptr->max_wall_duration_per_job);
+	debug2("  parent_acct               : %s", assoc_ptr->parent_acct);
+	debug2("  partition                 : %s", assoc_ptr->partition);
+	debug2("  user                      : %s(%u)",
+	       assoc_ptr->user, assoc_ptr->uid);
+	debug2("  used_jobs                 : %u", assoc_ptr->used_jobs);
+	debug2("  used_share                : %u", assoc_ptr->used_share);
 }
 
 /*
diff --git a/src/common/uid.c b/src/common/uid.c
index 8a1838ce9d0bafa9695e1579df00958fedda8fe8..f6b38b37bd31d8672283da4b7d94fb40f851d718 100644
--- a/src/common/uid.c
+++ b/src/common/uid.c
@@ -49,16 +49,14 @@ uid_t
 uid_from_string (char *name)
 {
 	struct passwd pwd, *result;
-	size_t bufsize;
-	char *buffer, *p = NULL;
+	char buffer[PW_BUF_SIZE], *p = NULL;
 	int rc;
 	uid_t uid = (uid_t) strtoul (name, &p, 10);
 
-	bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
-	buffer = xmalloc(bufsize);
 	if (*p != '\0') {
 		while (1) {
-			rc = getpwnam_r(name, &pwd, buffer, bufsize, &result);
+			rc = getpwnam_r(name, &pwd, buffer, PW_BUF_SIZE, 
+					&result);
 			if (rc == EINTR)
 				continue;
 			if (rc != 0)
@@ -71,7 +69,8 @@ uid_from_string (char *name)
 			uid = result->pw_uid;
 	} else {
 		while (1) {
-			rc = getpwuid_r(uid, &pwd, buffer, bufsize, &result);
+			rc = getpwuid_r(uid, &pwd, buffer, PW_BUF_SIZE, 
+					&result);
 			if (rc == EINTR)
 				continue;
 			if (rc != 0)
@@ -82,7 +81,6 @@ uid_from_string (char *name)
 			uid = (uid_t) -1;
 		/* else uid is already correct */
 	}
-	xfree(buffer);
 	return uid; 
 }
 
@@ -90,18 +88,15 @@ char *
 uid_to_string (uid_t uid)
 {
 	struct passwd pwd, *result;
-	size_t bufsize;
-	char *buffer, *ustring;
+	char buffer[PW_BUF_SIZE], *ustring;
 	int rc;
 
 	/* Suse Linux does not handle multiple users with UID=0 well */
 	if (uid == 0)
 		return xstrdup("root");
 
-	bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
-	buffer = xmalloc(bufsize);
 	while (1) {
-		rc = getpwuid_r(uid, &pwd, buffer, bufsize, &result);
+		rc = getpwuid_r(uid, &pwd, buffer, PW_BUF_SIZE, &result);
 		if (rc == EINTR)
 			continue;
 		if (rc != 0)
@@ -112,7 +107,6 @@ uid_to_string (uid_t uid)
 		ustring = xstrdup(result->pw_name);
 	else
 		ustring = xstrdup("nobody");
-	xfree(buffer);
 	return ustring;
 }
 
@@ -120,16 +114,14 @@ gid_t
 gid_from_string (char *name)
 {
 	struct group grp, *result;
-	size_t bufsize;
-	char *buffer, *p = NULL;
+	char buffer[PW_BUF_SIZE], *p = NULL;
 	int rc;
 	gid_t gid = (gid_t) strtoul (name, &p, 10);
 
-	bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
-	buffer = xmalloc(bufsize);
 	if (*p != '\0') {
 		while (1) {
-			rc = getgrnam_r(name, &grp, buffer, bufsize, &result);
+			rc = getgrnam_r(name, &grp, buffer, PW_BUF_SIZE, 
+					&result);
 			if (rc == EINTR)
 				continue;
 			if (rc != 0)
@@ -142,7 +134,8 @@ gid_from_string (char *name)
 			gid = result->gr_gid;
 	} else {
 		while (1) {
-			rc = getgrgid_r(gid, &grp, buffer, bufsize, &result);
+			rc = getgrgid_r(gid, &grp, buffer, PW_BUF_SIZE, 
+					&result);
 			if (rc == EINTR)
 				continue;
 			if (rc != 0)
@@ -153,7 +146,6 @@ gid_from_string (char *name)
 			gid = (gid_t) -1;
 		/* else gid is already correct */
 	}
-	xfree(buffer);
 	return gid; 
 }
 
@@ -161,14 +153,11 @@ char *
 gid_to_string (gid_t gid)
 {
 	struct group grp, *result;
-	size_t bufsize;
-	char *buffer, *gstring;
+	char buffer[PW_BUF_SIZE], *gstring;
 	int rc;
 
-	bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
-	buffer = xmalloc(bufsize);
 	while (1) {
-		rc = getgrgid_r(gid, &grp, buffer, bufsize, &result);
+		rc = getgrgid_r(gid, &grp, buffer, PW_BUF_SIZE, &result);
 		if (rc == EINTR)
 			continue;
 		if (rc != 0)
@@ -179,6 +168,5 @@ gid_to_string (gid_t gid)
 		gstring = xstrdup(result->gr_name);
 	else
 		gstring = xstrdup("nobody");
-	xfree(buffer);
 	return gstring;
 }
diff --git a/src/common/uid.h b/src/common/uid.h
index 91e5d9a9f449fcd36f8e74da261c5047df894dd0..0779a711f8a37bf0d46e6f3d14a1d3f3996c46a6 100644
--- a/src/common/uid.h
+++ b/src/common/uid.h
@@ -42,6 +42,14 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+/*
+ * In an ideal world, we could use sysconf(_SC_GETPW_R_SIZE_MAX) to get the 
+ * maximum buffer size neede for getpwnam_r(), but if there is no maximum
+ * value configured, the value returned is 1024, which can too small.
+ * Diito for _SC_GETGR_R_SIZE_MAX. Use 64k byte buffer by default.
+ */
+#define PW_BUF_SIZE 65536
+
 /*
  * Return validated uid_t for string in ``name'' which contains
  *  either the UID number or user name
diff --git a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c
index 22c52c03330edf32655b3884420c73a264d47931..fff6191be6e44f4316064714b9fcf967e206bedd 100644
--- a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c
+++ b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c
@@ -186,7 +186,12 @@ extern int init ( void )
 		      "Please use a database plugin");
 	}
 
-	if(first) {
+	/* This check for the slurm user id is a quick and dirty patch
+	 * to see if the controller is calling this, since we open the
+	 * file in append mode sacct could fail on it if the file
+	 * isn't world writable.
+	 */
+	if(first && (getuid() == slurm_get_slurm_user_id())) {
 		debug2("jobacct_init() called");
 		log_file = slurm_get_accounting_storage_loc();
 		if(!log_file)
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index c6b95f1afa3f26019b7b20170fac25f08ba02c33..095e3fe2f555f2ec3f5e13214913836bca9d4a34 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -5641,7 +5641,8 @@ empty:
 				assoc_table, row[ASSOC_REQ_ACCT],
 				row[ASSOC_REQ_CLUSTER],
 				without_parent_limits);
-			
+			debug4("%d(%d) query\n%s",
+			       mysql_conn->conn, __LINE__, query);
 			if(!(result2 = mysql_db_query_ret(
 				     mysql_conn->db_conn, query, 1))) {
 				xfree(query);
@@ -5661,7 +5662,7 @@ empty:
 					parent_mnpj =
 						atoi(row2[ASSOC2_REQ_MNPJ]);
 				else
-					parent_mwpj = INFINITE;
+					parent_mnpj = INFINITE;
 				
 				if(row2[ASSOC2_REQ_MWPJ])
 					parent_mwpj =
diff --git a/src/sacctmgr/account_functions.c b/src/sacctmgr/account_functions.c
index 65dc397cec72a3ce0e4da557cf107de14f1d610e..068ee3ecc79af7b567e15f57abc036b6276f81f1 100644
--- a/src/sacctmgr/account_functions.c
+++ b/src/sacctmgr/account_functions.c
@@ -84,7 +84,7 @@ static int _set_cond(int *start, int argc, char *argv[],
 			}
 			if(slurm_addto_char_list(
 				   acct_cond->assoc_cond->acct_list,
-				   argv[i]+end))
+				   argv[i]+end)) 
 				u_set = 1;
 		} else if (!strncasecmp (argv[i], "Clusters", 1)) {
 			if(!acct_cond->assoc_cond->cluster_list) {
@@ -706,6 +706,8 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 	char *object;
 	List qos_list = NULL;
 
+	int field_count = 0;
+
 	print_field_t *field = NULL;
 
 	List format_list = list_create(slurm_destroy_char);
@@ -755,7 +757,8 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 	itr = list_iterator_create(format_list);
 	while((object = list_next(itr))) {
 		field = xmalloc(sizeof(print_field_t));
-		if(!strncasecmp("Account", object, 1)) {
+		if(!strncasecmp("Account", object, 1)
+		   || !strncasecmp("Name", object, 2)) {
 			field->type = PRINT_ACCOUNT;
 			field->name = xstrdup("Account");
 			field->len = 10;
@@ -866,65 +869,90 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 	itr2 = list_iterator_create(print_fields_list);
 	print_fields_header(print_fields_list);
 
+	field_count = list_count(print_fields_list);
+
 	while((acct = list_next(itr))) {
 		if(acct->assoc_list && list_count(acct->assoc_list)) {
 			ListIterator itr3 =
 				list_iterator_create(acct->assoc_list);
 			
 			while((assoc = list_next(itr3))) {
+				int curr_inx = 1;
 				while((field = list_next(itr2))) {
 					switch(field->type) {
 					case PRINT_ACCOUNT:
 						field->print_routine(
-							field, acct->name);
+							field, acct->name,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_CLUSTER:
 						field->print_routine(
-							field, assoc->cluster);
+							field, assoc->cluster,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_COORDS:
 						field->print_routine(
 							field,
-							acct->coordinators);
+							acct->coordinators,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_DESC:
 						field->print_routine(
 							field, 
-							acct->description);
+							acct->description,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_FAIRSHARE:
 						field->print_routine(
 							field, 
-							assoc->fairshare);
+							assoc->fairshare,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_ID:
 						field->print_routine(
-							field, assoc->id);
+							field, assoc->id,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXC:
 						field->print_routine(
 							field, assoc->
-							max_cpu_secs_per_job);
+							max_cpu_secs_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXJ:
 						field->print_routine(
-							field, assoc->max_jobs);
+							field, assoc->max_jobs,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXN:
 						field->print_routine(
 							field, assoc->
-							max_nodes_per_job);
+							max_nodes_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXW:
 						field->print_routine(
 							field, 
 							assoc->
-							max_wall_duration_per_job);
+							max_wall_duration_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_ORG:
 						field->print_routine(
 							field, 
-							acct->organization);
+							acct->organization,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_QOS:
 						if(!qos_list) {
@@ -936,7 +964,9 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 						field->print_routine(
 							field, 
 							qos_list,
-							acct->qos_list);
+							acct->qos_list,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_QOS_RAW:
 						if(!qos_list) {
@@ -948,82 +978,116 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 						field->print_routine(
 							field,
 							qos_list,
-							acct->qos_list);
+							acct->qos_list,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PID:
 						field->print_routine(
 							field, 
-							assoc->parent_id);
+							assoc->parent_id,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PNAME:
 						field->print_routine(
 							field, 
-							assoc->parent_acct);
+							assoc->parent_acct,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PART:
 						field->print_routine(
 							field, 
-							assoc->partition);
+							assoc->partition,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_USER:
 						field->print_routine(
-							field, assoc->user);
+							field, assoc->user,
+							(curr_inx == 
+							 field_count));
 						break;
 					default:
 						break;
 					}
+					curr_inx++;
 				}
 				list_iterator_reset(itr2);
 				printf("\n");
 			}
 			list_iterator_destroy(itr3);		
 		} else {
+			int curr_inx = 1;
 			while((field = list_next(itr2))) {
 				switch(field->type) {
 				case PRINT_ACCOUNT:
 					field->print_routine(
-						field, acct->name);
+						field, acct->name,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_CLUSTER:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_COORDS:
 					field->print_routine(
 						field,
-						acct->coordinators);
+						acct->coordinators,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_DESC:
 					field->print_routine(
-						field, acct->description);
+						field, acct->description,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_FAIRSHARE:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_ID:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_MAXC:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_MAXJ:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_MAXN:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_MAXW:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_ORG:
 					field->print_routine(
-						field, acct->organization);
+						field, acct->organization,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_QOS:
 					if(!qos_list) {
@@ -1034,7 +1098,9 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 					}
 					field->print_routine(
 						field, qos_list,
-						acct->qos_list);
+						acct->qos_list,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_QOS_RAW:
 					if(!qos_list) {
@@ -1045,27 +1111,38 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 					}
 					field->print_routine(
 						field, qos_list,
-						acct->qos_list);
+						acct->qos_list,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_PID:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_PNAME:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_PART:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				case PRINT_USER:
 					field->print_routine(
-						field, NULL);
+						field, NULL,
+							(curr_inx == 
+							 field_count));
 					break;
 				default:
 					break;
 				}
+				curr_inx++;
 			}
 			list_iterator_reset(itr2);
 			printf("\n");
@@ -1164,14 +1241,6 @@ extern int sacctmgr_modify_account(int argc, char *argv[])
 
 assoc_start:
 	if(rec_set == 3 || rec_set == 2) { // process the association changes
-		if(cond_set == 1) {
-			exit_code=1;
-			fprintf(stderr, 
-				" There was a problem with your "
-				"'where' options.\n");
-			rc = SLURM_ERROR;
-			goto assoc_end;
-		}
 		ret_list = acct_storage_g_modify_associations(
 			db_conn, my_uid, acct_cond->assoc_cond, assoc);
 
@@ -1196,7 +1265,6 @@ assoc_start:
 			list_destroy(ret_list);
 	}
 
-assoc_end:
 	notice_thread_fini();
 	if(set) {
 		if(commit_check("Would you like to commit changes?")) 
@@ -1258,7 +1326,7 @@ extern int sacctmgr_delete_account(int argc, char *argv[])
 	if(set == 1) {
 		ret_list = acct_storage_g_remove_accounts(
 			db_conn, my_uid, acct_cond);		
-	} else if(set == 2) {
+	} else if(set == 2 || set == 3) {
 		ret_list = acct_storage_g_remove_associations(
 			db_conn, my_uid, acct_cond->assoc_cond);
 	}
@@ -1270,7 +1338,7 @@ extern int sacctmgr_delete_account(int argc, char *argv[])
 		ListIterator itr = list_iterator_create(ret_list);
 		if(set == 1) {
 			printf(" Deleting accounts...\n");
-		} else if(set == 2) {
+		} else if(set == 2 || set == 3) {
 			printf(" Deleting account associations...\n");
 		}
 		while((object = list_next(itr))) {
diff --git a/src/sacctmgr/cluster_functions.c b/src/sacctmgr/cluster_functions.c
index 3a39ddb3211c33b77298c6968c7f36b4140c7f54..1eeea8540b9aa393468e6af719725c8795094fbe 100644
--- a/src/sacctmgr/cluster_functions.c
+++ b/src/sacctmgr/cluster_functions.c
@@ -54,7 +54,8 @@ static int _set_cond(int *start, int argc, char *argv[],
 			break;
 		} else if(!end && !strncasecmp(argv[i], "where", 5)) {
 			continue;
-		} else if(!end || !strncasecmp (argv[i], "Names", 1)) {
+		} else if(!end || !strncasecmp (argv[i], "Names", 1)
+			  || !strncasecmp (argv[i], "Clusters", 1)) {
 			if(cluster_list) {
 				if(slurm_addto_char_list(cluster_list,
 							 argv[i]+end))
@@ -329,6 +330,8 @@ extern int sacctmgr_list_cluster(int argc, char *argv[])
 	acct_cluster_rec_t *cluster = NULL;
 	char *object;
 
+	int field_count = 0;
+
 	print_field_t *field = NULL;
 
 	List format_list = list_create(slurm_destroy_char);
@@ -365,7 +368,8 @@ extern int sacctmgr_list_cluster(int argc, char *argv[])
 	itr = list_iterator_create(format_list);
 	while((object = list_next(itr))) {
 		field = xmalloc(sizeof(print_field_t));
-		if(!strncasecmp("Cluster", object, 2)) {
+		if(!strncasecmp("Cluster", object, 2)
+		   || !strncasecmp("Name", object, 2)) {
 			field->type = PRINT_CLUSTER;
 			field->name = xstrdup("Cluster");
 			field->len = 10;
@@ -436,50 +440,62 @@ extern int sacctmgr_list_cluster(int argc, char *argv[])
 	itr2 = list_iterator_create(print_fields_list);
 	print_fields_header(print_fields_list);
 
+	field_count = list_count(print_fields_list);
+
 	while((cluster = list_next(itr))) {
+		int curr_inx = 1;
 		while((field = list_next(itr2))) {
 			switch(field->type) {
 			case PRINT_CLUSTER:
 				field->print_routine(field,
-						     cluster->name);
+						     cluster->name,
+						     (curr_inx == field_count));
 				break;
 			case PRINT_CHOST:
 				field->print_routine(field,
-						     cluster->control_host);
+						     cluster->control_host,
+						     (curr_inx == field_count));
 				break;
 			case PRINT_CPORT:
 				field->print_routine(field,
-						     cluster->control_port);
+						     cluster->control_port,
+						     (curr_inx == field_count));
 				break;
 			case PRINT_FAIRSHARE:
 				field->print_routine(
 					field,
-					cluster->default_fairshare);
+					cluster->default_fairshare,
+					(curr_inx == field_count));
 				break;
 			case PRINT_MAXC:
 				field->print_routine(
 					field,
-					cluster->default_max_cpu_secs_per_job);
+					cluster->default_max_cpu_secs_per_job,
+					(curr_inx == field_count));
 				break;
 			case PRINT_MAXJ:
 				field->print_routine(
 					field, 
-					cluster->default_max_jobs);
+					cluster->default_max_jobs,
+					(curr_inx == field_count));
 				break;
 			case PRINT_MAXN:
 				field->print_routine(
 					field,
-					cluster->default_max_nodes_per_job);
+					cluster->default_max_nodes_per_job,
+					(curr_inx == field_count));
 				break;
 			case PRINT_MAXW:
 				field->print_routine(
 					field,
 					cluster->
-					default_max_wall_duration_per_job);
+					default_max_wall_duration_per_job,
+					(curr_inx == field_count));
 				break;
 			default:
 				break;
 			}
+			curr_inx++;
 		}
 		list_iterator_reset(itr2);
 		printf("\n");
diff --git a/src/sacctmgr/common.c b/src/sacctmgr/common.c
index 23320d49515b54a2f1a54c5147e06942ea66658a..0f5d2db96d35137efc7a6e4d878f419e8634ba00 100644
--- a/src/sacctmgr/common.c
+++ b/src/sacctmgr/common.c
@@ -46,8 +46,8 @@ static pthread_t lock_warning_thread;
 
 static void *_print_lock_warn(void *no_data)
 {
-	sleep(2);
-	printf(" Waiting for lock from other user.\n");
+	sleep(5);
+	printf(" Database is busy or waiting for lock from other user.\n");
 
 	return NULL;
 }
@@ -655,7 +655,8 @@ end_it:
 	return count;
 } 
 
-extern void sacctmgr_print_coord_list(print_field_t *field, List value)
+extern void sacctmgr_print_coord_list(
+	print_field_t *field, List value, int last)
 {
 	ListIterator itr = NULL;
 	char *print_this = NULL;
@@ -679,7 +680,10 @@ extern void sacctmgr_print_coord_list(print_field_t *field, List value)
 		list_iterator_destroy(itr);
 	}
 	
-	if(print_fields_parsable_print)
+	if(print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
+	   && last)
+		printf("%s", print_this);
+	else if(print_fields_parsable_print)
 		printf("%s|", print_this);
 	else {
 		if(strlen(print_this) > field->len) 
@@ -691,13 +695,16 @@ extern void sacctmgr_print_coord_list(print_field_t *field, List value)
 }
 
 extern void sacctmgr_print_qos_list(print_field_t *field, List qos_list,
-				    List value)
+				    List value, int last)
 {
 	char *print_this = NULL;
 
 	print_this = get_qos_complete_str(qos_list, value);
 	
-	if(print_fields_parsable_print)
+	if(print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
+	   && last)
+		printf("%s", print_this);
+	else if(print_fields_parsable_print)
 		printf("%s|", print_this);
 	else {
 		if(strlen(print_this) > field->len) 
diff --git a/src/sacctmgr/file_functions.c b/src/sacctmgr/file_functions.c
index 65ab75dac8496d9ecc9d56619cc63b63a3f6b510..2724f0842f424293d278b3a7ff35b642db823000 100644
--- a/src/sacctmgr/file_functions.c
+++ b/src/sacctmgr/file_functions.c
@@ -211,7 +211,7 @@ static sacctmgr_file_opts_t *_parse_options(char *options)
 	file_opts->max_jobs = INFINITE;
 	file_opts->max_nodes_per_job = INFINITE;
 	file_opts->max_wall_duration_per_job = INFINITE;
-	file_opts->admin = ACCT_ADMIN_NONE;
+	file_opts->admin = ACCT_ADMIN_NOTSET;
 
 	while(options[i]) {
 		quote = 0;
@@ -887,7 +887,9 @@ static int _mod_user(sacctmgr_file_opts_t *file_opts,
 		}
 	}
 									
-	if(user->admin_level != file_opts->admin) {
+	if(user->admin_level != ACCT_ADMIN_NOTSET
+	   && file_opts->admin != ACCT_ADMIN_NOTSET
+	   && user->admin_level != file_opts->admin) {
 		printf(" Changed User '%s' "
 		       "AdminLevel '%s' -> '%s'\n",
 		       user->name,
diff --git a/src/sacctmgr/sacctmgr.c b/src/sacctmgr/sacctmgr.c
index afc94c20d6b784c4e338d860291ce9834b135259..ab7d69b86b699510eb77ed107a6347b7a0c9b6c2 100644
--- a/src/sacctmgr/sacctmgr.c
+++ b/src/sacctmgr/sacctmgr.c
@@ -49,6 +49,7 @@ int exit_flag;		/* program to terminate if =1 */
 int input_words;	/* number of words of input permitted */
 int one_liner;		/* one record per line if =1 */
 int quiet_flag;		/* quiet=1, verbose=-1, normal=0 */
+int readonly_flag;      /* make it so you can only run list commands */
 int verbosity;		/* count of -v options */
 int rollback_flag;       /* immediate execute=1, else = 0 */
 int with_assoc_flag = 0;
@@ -79,7 +80,9 @@ main (int argc, char *argv[])
 		{"oneliner", 0, 0, 'o'},
 		{"no_header", 0, 0, 'n'},
 		{"parsable", 0, 0, 'p'},
+		{"parsable2", 0, 0, 'P'},
 		{"quiet",    0, 0, 'q'},
+		{"readonly", 0, 0, 'r'},
 		{"associations", 0, 0, 's'},
 		{"usage",    0, 0, 'h'},
 		{"verbose",  0, 0, 'v'},
@@ -93,10 +96,11 @@ main (int argc, char *argv[])
 	exit_flag         = 0;
 	input_field_count = 0;
 	quiet_flag        = 0;
+	readonly_flag     = 0;
 	verbosity         = 0;
 	log_init("sacctmgr", opts, SYSLOG_FACILITY_DAEMON, NULL);
 
-	while((opt_char = getopt_long(argc, argv, "hionpqsvV",
+	while((opt_char = getopt_long(argc, argv, "hionpPqrsvV",
 			long_options, &option_index)) != -1) {
 		switch (opt_char) {
 		case (int)'?':
@@ -118,11 +122,19 @@ main (int argc, char *argv[])
 			print_fields_have_header = 0;
 			break;
 		case (int)'p':
-			print_fields_parsable_print = 1;
+			print_fields_parsable_print = 
+			PRINT_FIELDS_PARSABLE_ENDING;
+			break;
+		case (int)'P':
+			print_fields_parsable_print =
+			PRINT_FIELDS_PARSABLE_NO_ENDING;
 			break;
 		case (int)'q':
 			quiet_flag = 1;
 			break;
+		case (int)'r':
+			readonly_flag = 1;
+			break;
 		case (int)'s':
 			with_assoc_flag = 1;
 			break;
@@ -409,6 +421,14 @@ _process_command (int argc, char *argv[])
 				 argv[0]);
 		}		
 		quiet_flag = -1;
+	} else if (strncasecmp (argv[0], "readonly", 4) == 0) {
+		if (argc > 1) {
+			exit_code = 1;
+			fprintf (stderr,
+				 "too many arguments for %s keyword\n",
+				 argv[0]);
+		}		
+		readonly_flag = 1;
 	} else if (strncasecmp (argv[0], "rollup", 2) == 0) {
 		time_t my_time = 0;
 		if (argc > 2) {
@@ -454,6 +474,12 @@ static void _add_it (int argc, char *argv[])
 {
 	int error_code = SLURM_SUCCESS;
 
+	if(readonly_flag) {
+		exit_code = 1;
+		fprintf(stderr, "Can't run this command in readonly mode.\n");
+		return;		
+	}
+
 	/* First identify the entity to add */
 	if (strncasecmp (argv[0], "Account", 1) == 0) {
 		error_code = sacctmgr_add_account((argc - 1), &argv[1]);
@@ -525,6 +551,13 @@ static void _modify_it (int argc, char *argv[])
 {
 	int error_code = SLURM_SUCCESS;
 
+
+	if(readonly_flag) {
+		exit_code = 1;
+		fprintf(stderr, "Can't run this command in readonly mode.\n");
+		return;		
+	}
+
 	/* First identify the entity to modify */
 	if (strncasecmp (argv[0], "Account", 1) == 0) {
 		error_code = sacctmgr_modify_account((argc - 1), &argv[1]);
@@ -554,6 +587,12 @@ static void _delete_it (int argc, char *argv[])
 {
 	int error_code = SLURM_SUCCESS;
 
+	if(readonly_flag) {
+		exit_code = 1;
+		fprintf(stderr, "Can't run this command in readonly mode.\n");
+		return;		
+	}
+
 	/* First identify the entity to delete */
 	if (strncasecmp (argv[0], "Account", 1) == 0) {
 		error_code = sacctmgr_delete_account((argc - 1), &argv[1]);
@@ -587,8 +626,10 @@ sacctmgr [<OPTION>] [<COMMAND>]                                            \n\
      -i or --immediate: commit changes immediately                         \n\
      -n or --no_header: no header will be added to the beginning of output \n\
      -o or --oneliner: equivalent to \"oneliner\" command                  \n\
-     -p or --parsable: output will be '|' delimited                        \n\
+     -p or --parsable: output will be '|' delimited with a '|' at the end  \n\
+     -P or --parsable2: output will be '|' delimited without a '|' at the end\n\
      -q or --quiet: equivalent to \"quiet\" command                        \n\
+     -r or --readonly: equivalent to \"readonly\" command                  \n\
      -s or --associations: equivalent to \"associations\" command          \n\
      -v or --verbose: equivalent to \"verbose\" command                    \n\
      -V or --version: equivalent to \"version\" command                    \n\
@@ -608,9 +649,11 @@ sacctmgr [<OPTION>] [<COMMAND>]                                            \n\
                               is display all.                              \n\
      modify <ENTITY> <SPECS>  modify entity                                \n\
      oneliner                 report output one record per line.           \n\
+     parsable                 output will be | delimited with an ending '|'\n\
+     parsable2                output will be | delimited without an ending '|'\n\
+     readonly                 makes it so no modification can happen.      \n\
      quiet                    print no messages other than error messages. \n\
      quit                     terminate this command.                      \n\
-     parsable                 output will be | delimited                   \n\
      show                     same as list                                 \n\
      verbose                  enable detailed logging.                     \n\
      version                  display tool version number.                 \n\
diff --git a/src/sacctmgr/sacctmgr.h b/src/sacctmgr/sacctmgr.h
index b935efa51b0c21ca75837f7e8c8f3d3d19d3aee3..4fc865fd422c89d58a69debb18cd95227d30d84f 100644
--- a/src/sacctmgr/sacctmgr.h
+++ b/src/sacctmgr/sacctmgr.h
@@ -101,6 +101,7 @@ extern int one_liner;	/* one record per line if =1 */
 extern int quiet_flag;	/* quiet=1, verbose=-1, normal=0 */
 extern int rollback_flag;/* immediate execute=0, else = 1 */
 extern int with_assoc_flag;/* show acct/user associations flag */
+extern int readonly_flag; /* make it so you can only run list commands */
 extern void *db_conn;
 extern uint32_t my_uid;
 
@@ -146,9 +147,10 @@ extern int commit_check(char *warning);
 extern int get_uint(char *in_value, uint32_t *out_value, char *type);
 extern int addto_qos_char_list(List char_list, List qos_list, char *names, 
 			       int option);
-extern void sacctmgr_print_coord_list(print_field_t *field, List value);
+extern void sacctmgr_print_coord_list(
+	print_field_t *field, List value, int last);
 extern void sacctmgr_print_qos_list(print_field_t *field, List qos_list,
-				    List value);
+				    List value, int last);
 extern char *get_qos_complete_str(List qos_list, List num_qos_list);
 extern int sort_coord_list(acct_coord_rec_t *coord_a,
 			   acct_coord_rec_t *coord_b);
diff --git a/src/sacctmgr/user_functions.c b/src/sacctmgr/user_functions.c
index 8faa0b90b304b1091a672e0ca316216694130b93..0888a0234eb250f48dbb85b24efe365f6677d1b0 100644
--- a/src/sacctmgr/user_functions.c
+++ b/src/sacctmgr/user_functions.c
@@ -83,7 +83,7 @@ static int _set_cond(int *start, int argc, char *argv[],
 			}
 			if(slurm_addto_char_list(
 				   user_cond->assoc_cond->user_list,
-				   argv[i]+end))
+				   argv[i]+end)) 
 				u_set = 1;
 		} else if (!strncasecmp (argv[i], "Account", 2)) {
 			if(!user_cond->assoc_cond->acct_list) {
@@ -858,6 +858,7 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 	List qos_list = NULL;
 
 	print_field_t *field = NULL;
+	int field_count = 0;
 
 	List format_list = list_create(slurm_destroy_char);
 	List print_fields_list; /* types are of print_field_t */
@@ -981,7 +982,8 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 			field->name = xstrdup("Partition");
 			field->len = 10;
 			field->print_routine = print_fields_str;
-		} else if(!strncasecmp("User", object, 1)) {
+		} else if(!strncasecmp("User", object, 1)
+			  || !strncasecmp("Name", object, 2)) {
 			field->type = PRINT_USER;
 			field->name = xstrdup("User");
 			field->len = 10;
@@ -1017,73 +1019,100 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 	itr2 = list_iterator_create(print_fields_list);
 	print_fields_header(print_fields_list);
 
+	field_count = list_count(print_fields_list);
+
 	while((user = list_next(itr))) {
 		if(user->assoc_list && list_count(user->assoc_list)) {
 			ListIterator itr3 =
 				list_iterator_create(user->assoc_list);
 			
 			while((assoc = list_next(itr3))) {
+				int curr_inx = 1;
 				while((field = list_next(itr2))) {
 					switch(field->type) {
 					case PRINT_ACCOUNT:
 						field->print_routine(
 							field, 
-							assoc->acct);
+							assoc->acct,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_ADMIN:
 						field->print_routine(
 							field,
 							acct_admin_level_str(
 								user->
-								admin_level));
+								admin_level),
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_CLUSTER:
 						field->print_routine(
 							field,
-							assoc->cluster);
+							assoc->cluster,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_COORDS:
 						field->print_routine(
 							field,
-							user->coord_accts);
+							user->coord_accts,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_DACCT:
 						field->print_routine(
 							field,
-							user->default_acct);
+							user->default_acct,
+							(curr_inx == 
+							 field_count),
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_FAIRSHARE:
 						field->print_routine(
 							field,
-							assoc->fairshare);
+							assoc->fairshare,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_ID:
 						field->print_routine(
 							field,
-							assoc->id);
+							assoc->id,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXC:
 						field->print_routine(
 							field,
 							assoc->
-							max_cpu_secs_per_job);
+							max_cpu_secs_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXJ:
 						field->print_routine(
 							field, 
-							assoc->max_jobs);
+							assoc->max_jobs,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXN:
 						field->print_routine(
 							field,
 							assoc->
-							max_nodes_per_job);
+							max_nodes_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_MAXW:
 						field->print_routine(
 							field,
 							assoc->
-							max_wall_duration_per_job);
+							max_wall_duration_per_job,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_QOS:
 						if(!qos_list) {
@@ -1095,7 +1124,9 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 						field->print_routine(
 							field,
 							qos_list,
-							user->qos_list);
+							user->qos_list,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_QOS_RAW:
 						if(!qos_list) {
@@ -1107,94 +1138,117 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 						field->print_routine(
 							field,
 							qos_list,
-							user->qos_list);
+							user->qos_list,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PID:
 						field->print_routine(
 							field,
-							assoc->parent_id);
+							assoc->parent_id,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PNAME:
 						field->print_routine(
 							field,
-							assoc->parent_acct);
+							assoc->parent_acct,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_PART:
 						field->print_routine(
 							field,
-							assoc->partition);
+							assoc->partition,
+							(curr_inx == 
+							 field_count));
 						break;
 					case PRINT_USER:
 						field->print_routine(
 							field,
-							user->name);
+							user->name,
+							(curr_inx == 
+							 field_count));
 						break;
 					default:
 						break;
 					}
+					curr_inx++;
 				}
 				list_iterator_reset(itr2);
 				printf("\n");
 			}
 			list_iterator_destroy(itr3);				
 		} else {
+			int curr_inx = 1;
 			while((field = list_next(itr2))) {
 				switch(field->type) {
 				case PRINT_ACCOUNT:
 					field->print_routine(
 						field, 
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_ADMIN:
 					field->print_routine(
 						field,
 						acct_admin_level_str(
-							user->admin_level));
+							user->admin_level),
+						(curr_inx == field_count));
 					break;
 				case PRINT_CLUSTER:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_COORDS:
 					field->print_routine(
 						field,
-						user->coord_accts);
+						user->coord_accts,
+						(curr_inx == field_count));
 					break;
 				case PRINT_DACCT:
 					field->print_routine(
 						field,
-						user->default_acct);
+						user->default_acct,
+						(curr_inx == field_count));
 					break;
 				case PRINT_FAIRSHARE:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_ID:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_MAXC:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_MAXJ:
 					field->print_routine(
 						field, 
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_MAXN:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_MAXW:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_QOS:
 					if(!qos_list) {
@@ -1205,7 +1259,8 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 					}
 					field->print_routine(
 						field, qos_list,
-						user->qos_list);
+						user->qos_list,
+						(curr_inx == field_count));
 					break;
 				case PRINT_QOS_RAW:
 					if(!qos_list) {
@@ -1216,26 +1271,31 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 					}
 					field->print_routine(
 						field, qos_list,
-						user->qos_list);
+						user->qos_list,
+						(curr_inx == field_count));
 					break;
 				case PRINT_PID:
 					field->print_routine(
 						field,
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_PART:
 					field->print_routine(
 						field, 
-						NULL);
+						NULL,
+						(curr_inx == field_count));
 					break;
 				case PRINT_USER:
 					field->print_routine(
 						field, 
-						user->name);
+						user->name,
+						(curr_inx == field_count));
 					break;
 				default:
 					break;
 				}
+			curr_inx++;
 			}
 			list_iterator_reset(itr2);
 			printf("\n");
@@ -1352,14 +1412,6 @@ extern int sacctmgr_modify_user(int argc, char *argv[])
 
 assoc_start:
 	if(rec_set == 3 || rec_set == 2) { // process the association changes
-		if(cond_set == 1) {
-			rc = SLURM_ERROR;
-			exit_code=1;
-			fprintf(stderr, 
-				" There was a problem with your "
-				"'where' options.\n");
-			goto assoc_end;
-		}
 		ret_list = acct_storage_g_modify_associations(
 			db_conn, my_uid, user_cond->assoc_cond, assoc);
 
@@ -1384,8 +1436,6 @@ assoc_start:
 			list_destroy(ret_list);
 	}
 
-assoc_end:
-
 	notice_thread_fini();
 	if(set) {
 		if(commit_check("Would you like to commit changes?")) 
@@ -1428,7 +1478,7 @@ extern int sacctmgr_delete_user(int argc, char *argv[])
 	if(set == 1) {
 		ret_list = acct_storage_g_remove_users(
 			db_conn, my_uid, user_cond);		
-	} else if(set == 2) {
+	} else if(set == 2 || set == 3) {
 		ret_list = acct_storage_g_remove_associations(
 			db_conn, my_uid, user_cond->assoc_cond);
 	}
@@ -1441,7 +1491,7 @@ extern int sacctmgr_delete_user(int argc, char *argv[])
 		ListIterator itr = list_iterator_create(ret_list);
 		if(set == 1) {
 			printf(" Deleting users...\n");
-		} else if(set == 2) {
+		} else if(set == 2 || set == 3) {
 			printf(" Deleting user associations...\n");
 		}
 		while((object = list_next(itr))) {
diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index 70c6a2c8f7e7268b150bb1a5870f392b4ed14569..7e28c7b63ef7d2fc08bddbfc0788ee2738afb3c4 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -263,8 +263,7 @@ int main(int argc, char *argv[])
 	/* 
 	 * Create StateSaveLocation directory if necessary.
 	 */
-	if (set_slurmctld_state_loc() < 0)
-		fatal("Unable to initialize StateSaveLocation");
+	set_slurmctld_state_loc();
 
 	if (daemonize) {
 		slurmctld_config.daemonize = 1;
@@ -1591,25 +1590,26 @@ _init_pidfile(void)
 /*
  * set_slurmctld_state_loc - create state directory as needed and "cd" to it
  */
-extern int
+extern void
 set_slurmctld_state_loc(void)
 {
-	char *tmp;
-
-	if ((mkdir(slurmctld_conf.state_save_location, 0755) < 0) && 
-	    (errno != EEXIST)) {
-		fatal("mkdir(%s): %m", slurmctld_conf.state_save_location);
-		return SLURM_ERROR;
-	}
+	int rc;
+	struct stat st;
+	const char *path = slurmctld_conf.state_save_location;
 
-	tmp = xstrdup(slurmctld_conf.state_save_location);
-	xstrcat(tmp, "/slurm_mkdir_test");
-	if ((mkdir(tmp, 0755) < 0) && (errno != EEXIST)) {
-		fatal("mkdir(%s): %m", tmp);
-		return SLURM_ERROR;
+	/* 
+	 * If state save location does not exist, try to create it.
+	 *  Otherwise, ensure path is a directory as expected, and that
+	 *  we have permission to write to it.
+	 */
+	if (((rc = stat(path, &st)) < 0) && (errno == ENOENT)) {
+		if (mkdir(path, 0755) < 0)
+			fatal("mkdir(%s): %m", path);
 	}
-	(void) unlink(tmp);
-	xfree(tmp);
-
-	return SLURM_SUCCESS;
+	else if (rc < 0)
+		fatal("Unable to stat state save loc: %s: %m", path);
+	else if (!S_ISDIR(st.st_mode))
+		fatal("State save loc: %s: Not a directory!", path);
+	else if (access(path, R_OK|W_OK|X_OK) < 0)
+		fatal("Incorrect permissions on state save loc: %s", path);
 }
diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c
index 6bd647e22aba63b9016e8d0740c87438d6b39ff7..1119ecb196503f01eb6a2caec3f948e978333f2c 100644
--- a/src/slurmctld/partition_mgr.c
+++ b/src/slurmctld/partition_mgr.c
@@ -1053,9 +1053,8 @@ uid_t *_get_groups_members(char *group_names)
  */
 uid_t *_get_group_members(char *group_name)
 {
-	size_t grp_bufsize;
-	char *grp_buffer;
-	char buf[BUF_SIZE];
+	char grp_buffer[PW_BUF_SIZE];
+	char pw_buffer[PW_BUF_SIZE];
   	struct group grp,  *grp_result = NULL;
 	struct passwd pw, *pwd_result = NULL;
 	uid_t *group_uids, my_uid;
@@ -1065,14 +1064,15 @@ uid_t *_get_group_members(char *group_name)
 	FILE *fp = NULL;
 #endif
 
-	grp_bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
-	grp_buffer = xmalloc(grp_bufsize);
-	if (getgrnam_r(group_name, &grp, grp_buffer, grp_bufsize, 
-		       &grp_result)) {
+	/* We need to check for !grp_result, since it appears some 
+	 * versions of this function do not return an error on failure.
+	 */
+	if (getgrnam_r(group_name, &grp, grp_buffer, PW_BUF_SIZE, 
+		       &grp_result) || (grp_result == NULL)) {
 		error("Could not find configured group %s", group_name);
-		xfree(grp_buffer);
 		return NULL;
 	}
+
 	my_gid = grp_result->gr_gid;
 
 	for (uid_cnt=0; ; uid_cnt++) {
@@ -1092,14 +1092,13 @@ uid_t *_get_group_members(char *group_name)
 			group_uids[j++] = my_uid;
 		}
 	}
-	xfree(grp_buffer);
 
 	setpwent();
 #ifdef HAVE_AIX
-	while (!getpwent_r(&pw, buf, BUF_SIZE, &fp)) {
+	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) {
 		pwd_result = &pw;
 #else
-	while (!getpwent_r(&pw, buf, BUF_SIZE, &pwd_result)) {
+	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) {
 #endif
  		if (pwd_result->pw_gid != my_gid)
 			continue;
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index cc519cd48695f54fe20ff0f9a00d8aa18dbb80c4..b8ab227157b76d5491006374243a224627a65944 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -1324,7 +1324,7 @@ extern void set_node_down (char *name, char *reason);
 /*
  * set_slurmctld_state_loc - create state directory as needed and "cd" to it
  */
-extern int set_slurmctld_state_loc(void);
+extern void set_slurmctld_state_loc(void);
 
 /* set_slurmd_addr - establish the slurm_addr for the slurmd on each node
  *	Uses common data structures. */
diff --git a/src/slurmd/slurmd/req.c b/src/slurmd/slurmd/req.c
index 0f7f67ea2ef416a68093f4c4101b8891aa927d3d..19d660dff4ccc5d660d0f3d57ac62f8beae55dd1 100644
--- a/src/slurmd/slurmd/req.c
+++ b/src/slurmd/slurmd/req.c
@@ -70,6 +70,7 @@
 #include "src/common/xstring.h"
 #include "src/common/xmalloc.h"
 #include "src/common/list.h"
+#include "src/common/uid.h"
 #include "src/common/util-net.h"
 #include "src/common/forward.h"
 #include "src/common/read_config.h"
@@ -332,8 +333,7 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req,
 	int parent_rank, children, depth, max_depth;
 	char *parent_alias = NULL;
 	slurm_addr parent_addr = {0};
-	size_t pwd_bufsize;
-	char *pwd_buffer;
+	char pwd_buffer[PW_BUF_SIZE];
 	struct passwd pwd, *pwd_result;
 
 	slurm_msg_t_init(&msg);
@@ -459,14 +459,11 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req,
 	
 	/* send cached group ids array for the relevant uid */
 	debug3("_send_slurmstepd_init: call to getpwuid_r");
-	pwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
-	pwd_buffer = xmalloc(pwd_bufsize);
-	if (getpwuid_r(uid, &pwd, pwd_buffer, pwd_bufsize, &pwd_result) ||
+	if (getpwuid_r(uid, &pwd, pwd_buffer, PW_BUF_SIZE, &pwd_result) ||
 	    (pwd_result == NULL)) {
 		error("_send_slurmstepd_init getpwuid_r: %m");
 		len = 0;
 		safe_write(fd, &len, sizeof(int));
-		xfree(pwd_buffer);
 		return -1;
 	}
 	debug3("_send_slurmstepd_init: return from getpwuid_r");
@@ -484,7 +481,6 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req,
 		len = 0;
 		safe_write(fd, &len, sizeof(int));
 	}
-	xfree(pwd_buffer);
 	return 0;
 
 rwfail:
@@ -904,10 +900,9 @@ _prolog_error(batch_job_launch_msg_t *req, int rc)
 static void
 _get_user_env(batch_job_launch_msg_t *req)
 {
-	struct passwd pwd, *pwd_ptr;
-	char *pwd_buf = NULL;
+	struct passwd pwd, *pwd_ptr = NULL;
+	char pwd_buf[PW_BUF_SIZE];
 	char **new_env;
-	size_t buf_size;
 	int i;
 
 	for (i=0; i<req->argc; i++) {
@@ -917,9 +912,8 @@ _get_user_env(batch_job_launch_msg_t *req)
 	if (i >= req->argc)
 		return;		/* don't need to load env */
 
-	buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
-	pwd_buf = xmalloc(buf_size);
-	if (getpwuid_r(req->uid, &pwd, pwd_buf, buf_size, &pwd_ptr)) {
+	if (getpwuid_r(req->uid, &pwd, pwd_buf, PW_BUF_SIZE, &pwd_ptr) ||
+	    (pwd_ptr == NULL)) {
 		error("getpwuid_r(%u):%m", req->uid);
 	} else {
 		verbose("get env for user %s here", pwd.pw_name);
@@ -939,7 +933,6 @@ _get_user_env(batch_job_launch_msg_t *req)
 			      "running only with passed environment");
 		}
 	}
-	xfree(pwd_buf);
 }
 
 /* The RPC currently contains a memory size limit, but we load the 
@@ -3198,11 +3191,12 @@ init_gids_cache(int cache)
 	orig_gids = (gid_t *)xmalloc(ngids * sizeof(gid_t));
 	getgroups(ngids, orig_gids);
 
-	setpwent();
 #ifdef HAVE_AIX
+	setpwent(&fp);
 	while (!getpwent_r(&pw, buf, BUF_SIZE, &fp)) {
 		pwd = &pw;
 #else
+	setpwent();
 	while (!getpwent_r(&pw, buf, BUF_SIZE, &pwd)) {
 #endif
 		if (_gids_cache_lookup(pwd->pw_name, pwd->pw_gid))
@@ -3218,7 +3212,11 @@ init_gids_cache(int cache)
 			continue;
 		_gids_cache_register(pwd->pw_name, pwd->pw_gid, gids);
 	}
+#ifdef HAVE_AIX
+	endpwent_r(&fp);
+#else
 	endpwent();
+#endif
 
 	setgroups(ngids, orig_gids);		
 	xfree(orig_gids);
diff --git a/src/sreport/cluster_reports.c b/src/sreport/cluster_reports.c
index 8c39260dc7c1814a2965b064d08f5a8640e69632..752eb59e787a7ad6cfbbc7bd6d7916710a03df81 100644
--- a/src/sreport/cluster_reports.c
+++ b/src/sreport/cluster_reports.c
@@ -265,6 +265,7 @@ extern int cluster_utilization(int argc, char *argv[])
 	List cluster_list = NULL; 
 
 	List format_list = list_create(slurm_destroy_char);
+	int field_count = 0;
 
 	print_fields_list = list_create(destroy_print_field);
 
@@ -285,11 +286,14 @@ extern int cluster_utilization(int argc, char *argv[])
 
 	print_fields_header(print_fields_list);
 
+	field_count = list_count(print_fields_list);
+
 	while((cluster = list_next(itr))) {
 		cluster_accounting_rec_t *accting = NULL;
 		cluster_accounting_rec_t total_acct;
 		uint64_t total_reported = 0;
 		uint64_t local_total_time = 0;
+		int curr_inx = 1;
 
 		if(!cluster->accounting_list
 		   || !list_count(cluster->accounting_list))
@@ -317,45 +321,62 @@ extern int cluster_utilization(int argc, char *argv[])
 			switch(field->type) {
 			case PRINT_CLUSTER_NAME:
 				field->print_routine(field,
-						     cluster->name);		
+						     cluster->name,
+						     (curr_inx == 
+						      field_count));		
 				break;
 			case PRINT_CLUSTER_CPUS:
 				field->print_routine(field,
-						     total_acct.cpu_count);
+						     total_acct.cpu_count,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_ACPU:
 				field->print_routine(field,
 						     total_acct.alloc_secs,
-						     total_reported);
+						     total_reported,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_DCPU:
 				field->print_routine(field,
 						     total_acct.down_secs,
-						     total_reported);
+						     total_reported,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_ICPU:
 				field->print_routine(field,
 						     total_acct.idle_secs,
-						     total_reported);
+						     total_reported,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_RCPU:
 				field->print_routine(field,
 						     total_acct.resv_secs,
-						     total_reported);
+						     total_reported,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_OCPU:
 					field->print_routine(field,
 						     total_acct.over_secs,
-						     total_reported);
+						     total_reported,
+						     (curr_inx == 
+						      field_count));
 				break;
 			case PRINT_CLUSTER_TOTAL:
 				field->print_routine(field,
 						     total_reported,
-						     local_total_time);
+						     local_total_time,
+						     (curr_inx == 
+						      field_count));
 				break;
 			default:
 				break;
 			}
+			curr_inx++;
 		}
 		list_iterator_reset(itr2);
 		printf("\n");
diff --git a/src/sreport/common.c b/src/sreport/common.c
index 9df97591b305d113835d4b41d8be46034fb73660..256306c00e5229f74ad91b7c2f59217d15fe1baf 100644
--- a/src/sreport/common.c
+++ b/src/sreport/common.c
@@ -40,14 +40,18 @@
 #include "sreport.h"
 
 extern void sreport_print_time(print_field_t *field,
-			       uint64_t value, uint64_t total_time)
+			       uint64_t value, uint64_t total_time, int last)
 {
 	if(!total_time)
 		total_time = 1;
 
 	/* (value == unset)  || (value == cleared) */
 	if((value == NO_VAL) || (value == INFINITE)) {
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			;
+		else if(print_fields_parsable_print)
 			printf("|");	
 		else				
 			printf("%-*s ", field->len, " ");
@@ -75,7 +79,11 @@ extern void sreport_print_time(print_field_t *field,
 			break;
 		}
 		
-		if(print_fields_parsable_print)
+		if(print_fields_parsable_print 
+		   == PRINT_FIELDS_PARSABLE_NO_ENDING
+		   && last)
+			printf("%s", output);
+		else if(print_fields_parsable_print)
 			printf("%s|", output);	
 		else
 			printf("%*s ", field->len, output);
diff --git a/src/sreport/job_reports.c b/src/sreport/job_reports.c
index 654ca7b02fa4c480f63908940f5b1297aa0a069b..d8d024530556fb81594ee4b867654f1e5d63b9fb 100644
--- a/src/sreport/job_reports.c
+++ b/src/sreport/job_reports.c
@@ -714,16 +714,18 @@ no_assocs:
 	while((cluster_group = list_next(cluster_itr))) {
 		acct_itr = list_iterator_create(cluster_group->acct_list);
 		while((acct_group = list_next(acct_itr))) {
+			
 			while((field = list_next(itr))) {
 				switch(field->type) {
 				case PRINT_JOB_CLUSTER:
 					field->print_routine(
 						field,
-						cluster_group->cluster);
+						cluster_group->cluster, 0);
 					break;
 				case PRINT_JOB_ACCOUNT:
 					field->print_routine(field,
-							     acct_group->acct);
+							     acct_group->acct,
+							     0);
 					break;
 				default:
 					break;
@@ -748,7 +750,7 @@ no_assocs:
 			list_iterator_destroy(local_itr);
 			total_field.print_routine(&total_field,
 						  acct_group->cpu_secs,
-						  cluster_group->cpu_secs);
+						  cluster_group->cpu_secs, 1);
 			
 			printf("\n");
 		}
diff --git a/src/sreport/sreport.c b/src/sreport/sreport.c
index 08715ad0e8ea6ab9d5504a57a8cb17d264608c00..74e7153e891430f5968d5a011d17941de1a2ab3d 100644
--- a/src/sreport/sreport.c
+++ b/src/sreport/sreport.c
@@ -80,6 +80,7 @@ main (int argc, char *argv[])
 		{"immediate",0, 0, 'i'},
 		{"no_header", 0, 0, 'n'},
 		{"parsable", 0, 0, 'p'},
+		{"parsable2", 0, 0, 'P'},
 		{"quiet",    0, 0, 'q'},
 		{"usage",    0, 0, 'h'},
 		{"verbose",  0, 0, 'v'},
@@ -94,7 +95,7 @@ main (int argc, char *argv[])
 	quiet_flag        = 0;
 	log_init("sreport", opts, SYSLOG_FACILITY_DAEMON, NULL);
 
-	while((opt_char = getopt_long(argc, argv, "ahnpqt:vV",
+	while((opt_char = getopt_long(argc, argv, "ahnpPqt:vV",
 			long_options, &option_index)) != -1) {
 		switch (opt_char) {
 		case (int)'?':
@@ -113,7 +114,12 @@ main (int argc, char *argv[])
 			print_fields_have_header = 0;
 			break;
 		case (int)'p':
-			print_fields_parsable_print = 1;
+			print_fields_parsable_print = 
+			PRINT_FIELDS_PARSABLE_ENDING;
+			break;
+		case (int)'P':
+			print_fields_parsable_print =
+			PRINT_FIELDS_PARSABLE_NO_ENDING;
 			break;
 		case (int)'q':
 			quiet_flag = 1;
@@ -494,7 +500,8 @@ sreport [<OPTION>] [<COMMAND>]                                             \n\
      -h or --help: equivalent to \"help\" command                          \n\
      -n or --no_header: equivalent to \"no_header\" command                \n\
      -q or --quiet: equivalent to \"quiet\" command                        \n\
-     -p or --parsable: equivalent to \"parsable\" command                  \n\
+     -p or --parsable: output will be '|' delimited with a '|' at the end  \n\
+     -P or --parsable2: output will be '|' delimited without a '|' at the end\n\
      -v or --verbose: equivalent to \"verbose\" command                    \n\
      -V or --version: equivalent to \"version\" command                    \n\
                                                                            \n\
@@ -505,7 +512,9 @@ sreport [<OPTION>] [<COMMAND>]                                             \n\
     Valid <COMMAND> values are:                                            \n\
      exit                     terminate sreport                            \n\
      help                     print this description of use.               \n\
-     quiet                    print no messages other than error messages. \n\
+     parsable                 output will be | delimited with an ending '|'\n\
+     parsable2                output will be | delimited without an ending '|'\n\
+    quiet                    print no messages other than error messages. \n\
      quit                     terminate this command.                      \n\
      verbose                  enable detailed logging.                     \n\
      version                  display tool version number.                 \n\
diff --git a/src/sreport/sreport.h b/src/sreport/sreport.h
index d8f25640da3666761d2f6fb60b6267374fa90273..bd450fb78e737b24d3252fc9f963dd83cf603fed 100644
--- a/src/sreport/sreport.h
+++ b/src/sreport/sreport.h
@@ -103,7 +103,7 @@ extern uint32_t my_uid;
 extern int all_clusters_flag;
 
 extern void sreport_print_time(print_field_t *field,
-			       uint64_t value, uint64_t total_time);
+			       uint64_t value, uint64_t total_time, int last);
 extern int parse_option_end(char *option);
 extern char *strip_quotes(char *option, int *increased);
 extern int set_start_end_time(time_t *start, time_t *end);
diff --git a/src/sreport/user_reports.c b/src/sreport/user_reports.c
index a1496a48fe5e5b897fede185dc339829edc4cac9..4e2347787b4a15ecbdb890081e4692e9762aa349 100644
--- a/src/sreport/user_reports.c
+++ b/src/sreport/user_reports.c
@@ -282,6 +282,7 @@ extern int user_top(int argc, char *argv[])
 	local_user_rec_t *local_user = NULL;
 	local_cluster_rec_t *local_cluster = NULL;
 	print_field_t *field = NULL;
+	int field_count = 0;
 
 	print_fields_list = list_create(destroy_print_field);
 
@@ -423,6 +424,8 @@ extern int user_top(int argc, char *argv[])
 	itr2 = list_iterator_create(print_fields_list);
 	print_fields_header(print_fields_list);
 
+	field_count = list_count(print_fields_list);
+
 	list_iterator_reset(cluster_itr);
 	while((local_cluster = list_next(cluster_itr))) {
 		list_sort(local_cluster->user_list, (ListCmpF)_sort_user_dec);
@@ -430,6 +433,7 @@ extern int user_top(int argc, char *argv[])
 		itr = list_iterator_create(local_cluster->user_list);
 		while((local_user = list_next(itr))) {
 			int count = 0;
+			int curr_inx = 1;
 			while((field = list_next(itr2))) {
 				char *tmp_char = NULL;
 				struct passwd *pwd = NULL;
@@ -449,17 +453,21 @@ extern int user_top(int argc, char *argv[])
 					list_iterator_destroy(itr3);
 					field->print_routine(
 						field,
-						tmp_char);
+						tmp_char,
+						(curr_inx == field_count));
 					xfree(tmp_char);
 					break;
 				case PRINT_USER_CLUSTER:
 					field->print_routine(
 						field,
-						local_cluster->name);
+						local_cluster->name,
+						(curr_inx == field_count));
 					break;
 				case PRINT_USER_LOGIN:
 					field->print_routine(field,
-							     local_user->name);
+							     local_user->name,
+							     (curr_inx == 
+							      field_count));
 					break;
 				case PRINT_USER_PROPER:
 					pwd = getpwnam(local_user->name);
@@ -467,21 +475,25 @@ extern int user_top(int argc, char *argv[])
 						tmp_char = strtok(pwd->pw_gecos,
 								  ",");
 						if(!tmp_char)
-							tmp_char =
+							tmp_char = 
 								pwd->pw_gecos;
 					}
 					field->print_routine(field,
-							     tmp_char);
+							     tmp_char,
+							     (curr_inx == 
+							      field_count));
 					break;
 				case PRINT_USER_USED:
 					field->print_routine(
 						field,
 						local_user->cpu_secs,
-						local_cluster->cpu_secs);
+						local_cluster->cpu_secs,
+						(curr_inx == field_count));
 					break;
 				default:
 					break;
 				}
+				curr_inx++;
 			}
 			list_iterator_reset(itr2);
 			printf("\n");
diff --git a/testsuite/expect/README b/testsuite/expect/README
index e1dba8ce456db60d32f98fb7bbd4eaa56577ba05..6d2bbda326dc661c4bbba3f1283253e323c3fdec 100644
--- a/testsuite/expect/README
+++ b/testsuite/expect/README
@@ -291,6 +291,8 @@ test7.9    Test that no files are open in spawned tasks (except stdin,
            stdout, and stderr) to insure successful checkpoint/restart.
 test7.10   Test if we can trick SLURM into using the wrong user ID 
            through an LD_PRELOAD option.
+test7.11   Test of SPANK plugin.
+
 
 test8.#    Test of Blue Gene specific functionality.
 =================================================
@@ -302,6 +304,7 @@ test8.5    Confirm we can make a 32, 128, and 512 cnode block.
 test8.6    Stress test Dynamic mode block creation.
 test8.7    Test of Blue Gene scheduling with sched/wik2 plugin.
 
+
 test9.#    System stress testing. Exercises all commands and daemons.
 =====================================================================
 test9.1    Stress test of stdin broadcast.
diff --git a/testsuite/expect/globals b/testsuite/expect/globals
index c97adf14a1fc3e05462da8d68ff3877ef6aa8ab2..aac8121947dd10c8eb27beeda55824d4d7fa9c7e 100755
--- a/testsuite/expect/globals
+++ b/testsuite/expect/globals
@@ -814,7 +814,7 @@ proc test_super_user { } {
 			wait
 		}
 	}
-	spawn $scontrol show control
+	spawn $scontrol show config
 	set slurm_user ""
 	expect {
 		-re "SlurmUser *= ($alpha_numeric_under)" {
diff --git a/testsuite/expect/test1.29 b/testsuite/expect/test1.29
index c055e47dcc2d49c4b9cb05acf6474b1d166afe6c..7da4c0dd001341e2c0502e13fc6f0afeb7d7e82a 100755
--- a/testsuite/expect/test1.29
+++ b/testsuite/expect/test1.29
@@ -61,7 +61,7 @@ if {[test_front_end] != 0 && [test_super_user] == 0} {
 # of the ulimit program is inconsistent across systems.
 #
 exec $bin_rm -f $file_prog_get $file_err $file_in $file_out
-exec $bin_make -f /dev/null $file_prog_get
+exec $bin_cc -O ${file_prog_get}.c -o $file_prog_get
 exec $bin_chmod 700 $file_prog_get
 
 #
diff --git a/testsuite/expect/test1.32 b/testsuite/expect/test1.32
index 9275a8bee37f4a211638afa0cd2ad08c745ac543..c2957a4820e31a293820bf28a3b3326b4c11fb83 100755
--- a/testsuite/expect/test1.32
+++ b/testsuite/expect/test1.32
@@ -54,7 +54,7 @@ if { [test_xcpu] } {
 # Delete left-over program and rebuild it
 #
 exec $bin_rm -f $file_prog
-exec $bin_make -f /dev/null $file_prog
+exec $bin_cc -O ${file_prog}.c -o $file_prog
 exec $bin_chmod 700 $file_prog
 
 #
diff --git a/testsuite/expect/test1.34 b/testsuite/expect/test1.34
index 9a7f0e83a767b0f33f8072bfca70f99291aa36ec..87485a9deeba64de31d648d6402f85629ab15fe6 100755
--- a/testsuite/expect/test1.34
+++ b/testsuite/expect/test1.34
@@ -58,9 +58,9 @@ set matches 0
 set timeout $max_job_delay
 set srun_pid [spawn $srun -n1 -O $test_prog]
 expect {
-	-re "Segmentation.*core dumped" {
-		send_user "This error was expected, no worries\n"
-		incr matches
+	-re "Segmentation fault" {
+		send_user "\nThis error was expected, no worries\n"
+		set matches 1
 		exp_continue
 	}
 	timeout {
diff --git a/testsuite/expect/test1.38 b/testsuite/expect/test1.38
index 3df3239762fd695035d8da70247f3c6e7d54edca..dcbc3b17d5aa5231aa1147e03fa55f7c09a79dbf 100755
--- a/testsuite/expect/test1.38
+++ b/testsuite/expect/test1.38
@@ -91,7 +91,7 @@ expect {
 		exec $bin_kill -INT $srun_pid
 		exp_continue
 	}
-	-re "Force Terminated" {
+	-re "Force Terminated job $number" {
 		incr matches
 		exp_continue
 	}
diff --git a/testsuite/expect/test1.46 b/testsuite/expect/test1.46
index 57abc964a4d73224f07dfe5f51dab3f5360ae439..0938ed86bfae9ed9afc6031da990c5098cde61f0 100755
--- a/testsuite/expect/test1.46
+++ b/testsuite/expect/test1.46
@@ -66,7 +66,7 @@ main()
 close $fd
 # Add delay due to sporatic error "Clock skew detected"
 exec $bin_sleep 1
-exec $bin_make -f /dev/null $file_in
+exec $bin_cc -O -o $file_in ${file_in}.c
 exec $bin_chmod 700 $file_in
 
 #
diff --git a/testsuite/expect/test12.2 b/testsuite/expect/test12.2
index e4d9a66e344a89f804bc14aeea6f0a4c29fe69b0..2abedee55db0151cd75bdf4b57dd27aa611c305b 100755
--- a/testsuite/expect/test12.2
+++ b/testsuite/expect/test12.2
@@ -97,7 +97,7 @@ if {$supported_storage == 0} {
 #
 exec $bin_rm -f $file_prog
 exec $bin_rm -f $file_in $file_out $file_err
-exec $bin_make -f /dev/null $file_prog
+exec $bin_cc -O -o $file_prog ${file_prog}.c
 exec $bin_chmod 700 $file_prog
 
 make_bash_script $file_in "
@@ -145,20 +145,24 @@ set mem_task -1
 set ave_used -1
 spawn $sstat --noheader --job=$job_id.0 --fields vsize
 expect {
-	-re "($float)(\[KM\]*)/.*($number) - ($float)(\[KM\]*)" {
+	-re "($float)(\[KMG\]*)/.*($number) - ($float)(\[KMG\]*)" {
 		set mem_used  $expect_out(1,string)
 		set scale1    $expect_out(2,string)
 		set mem_task  $expect_out(3,string)
 		set ave_used  $expect_out(4,string)
 		set scale2    $expect_out(5,string)
-		if {[string compare $scale1 "M"] == 0} {
+		if {[string compare $scale1 "G"] == 0} {
+			 set mem_used [expr $mem_used * 1024 * 1024]
+		} elseif {[string compare $scale1 "M"] == 0} {
 			set mem_used [expr $mem_used * 1024]
 		} elseif {[string compare $scale1 "K"] == 0} {
 			set mem_used [expr $mem_used * 1]
 		} else {
 			 set mem_used [expr $mem_used / 1024]
 		}
-		if {[string compare $scale2 "M"] == 0} {
+		if {[string compare $scale2 "G"] == 0} {
+			set ave_used [expr $ave_used * 1024 * 1024]
+		} elseif {[string compare $scale2 "M"] == 0} {
 			set ave_used [expr $ave_used * 1024]
 		} elseif {[string compare $scale2 "K"] == 0} {
                         set ave_used [expr $ave_used * 1]
@@ -280,20 +284,24 @@ set mem_task -1
 set ave_used -1
 spawn $sacct --noheader  --job=$job_id.0 --fields vsize
 expect {
-	-re "($float)(\[KM\]*)/.*($number) - ($float)(\[KM\]*)" {
+	-re "($float)(\[KMG\]*)/.*($number) - ($float)(\[KMG\]*)" {
 		set mem_used  $expect_out(1,string)
 		set scale1    $expect_out(2,string)
 		set mem_task  $expect_out(3,string)
 		set ave_used  $expect_out(4,string)
 		set scale2    $expect_out(5,string)
-		if {[string compare $scale1 "M"] == 0} {
+		if {[string compare $scale1 "G"] == 0} {
+			set mem_used [expr $mem_used * 1024 * 1024]
+		} elseif {[string compare $scale1 "M"] == 0} {
 			set mem_used [expr $mem_used * 1024]
 		} elseif {[string compare $scale1 "K"] == 0} {
 			set mem_used [expr $mem_used * 1]
 		} else {
 			 set mem_used [expr $mem_used / 1024]
 		}
-		if {[string compare $scale2 "M"] == 0} {
+		if {[string compare $scale2 "G"] == 0} {
+			set ave_used [expr $ave_used * 1024 * 1024]
+		} elseif {[string compare $scale2 "M"] == 0} {
 			set ave_used [expr $ave_used * 1024]
 		} elseif {[string compare $scale2 "K"] == 0} {
                         set ave_used [expr $ave_used * 1]
@@ -343,7 +351,7 @@ if {$aix == 1 && $exit_code == 1} {
 }
 
 if {$exit_code == 0} {
-	exec rm -f $file_prog
+	exec rm -f $file_prog $file_in $file_out $file_err
 	send_user "\nSUCCESS\n"
 }
 exit $exit_code
diff --git a/testsuite/expect/test16.4 b/testsuite/expect/test16.4
index eede3faef05f49b28dd05399046f16096adbacb0..217c4ed48fde3049458f3c778d90bac0fa5576ab 100755
--- a/testsuite/expect/test16.4
+++ b/testsuite/expect/test16.4
@@ -49,7 +49,7 @@ if { [test_xcpu] } {
 # Delete left-over program and rebuild it
 #
 exec $bin_rm -f $file_prog
-exec $bin_make -f /dev/null $file_prog
+exec $bin_cc -O -o $file_prog ${file_prog}.c
 exec $bin_chmod 700 $file_prog
 
 #
diff --git a/testsuite/expect/test17.15 b/testsuite/expect/test17.15
index 2bfa3b89a240f61bb08d0d54b632b00316f3003c..7bbf9bb320e5916cbdb15fd2726f9677cc5c3a23 100755
--- a/testsuite/expect/test17.15
+++ b/testsuite/expect/test17.15
@@ -56,7 +56,7 @@ print_header $test_id
 # of the ulimit program is inconsistent across systems.
 #
 exec $bin_rm -f $file_prog_get $file_err $file_in $file_out
-exec $bin_make -f /dev/null $file_prog_get
+exec $bin_cc -O -o $file_prog_get ${file_prog_get}.c
 
 #
 # Get our current limits and adjust targets accordingly
diff --git a/testsuite/expect/test21.14 b/testsuite/expect/test21.14
index 41146bf62193f3e4971964cd295d764d2c6076e2..9fc70080c5aa31a4b7edf4757a0b0db5a946f99f 100755
--- a/testsuite/expect/test21.14
+++ b/testsuite/expect/test21.14
@@ -1,7 +1,8 @@
 #!/usr/bin/expect
 ############################################################################
 # Purpose: Test of SLURM functionality
-#          sacctmgr modify multiple accounts
+#          sacctmgr modify accounts, descriptions, limits, 
+#          and parents down and up the tree
 #
 # Output:  "TEST: #.#" followed by "SUCCESS" if test was successful, OR
 #          "FAILURE: ..." otherwise with an explanation of the failure, OR
@@ -33,28 +34,6 @@ source ./globals
 
 set test_id     "21.14"
 set exit_code   0
-set acmatches   0
-set aamatches   0
-set ammatches   0
-set almatches   0
-set aclmatches  0
-set lmatches    0
-set lamatches   0
-set damatches   0
-set dcmatches   0
-set not_support 0
-set add		add
-set lis		list
-set del		delete
-set mod		modify
-set nams	Names
-set nam		Name
-set fs		Fairshare
-set mc		MaxCPUSecs
-set mj		MaxJobs
-set mn		MaxNodes
-set mw		MaxWall
-set clu		cluster
 set tc1		tcluster1
 set tc2		tcluster2
 set tc3		tcluster3
@@ -65,7 +44,7 @@ set mc2		700000
 set mj1		50
 set mj2		70
 set mn1		300
-set mn2		70
+set mn2		700
 set mw1		01:00:00
 set mw2		00:07:00
 set acc		account
@@ -86,6 +65,7 @@ set par		parent
 
 print_header $test_id
 
+set timeout 60
 
 #
 # Check accounting config and bail if not found.
@@ -94,247 +74,667 @@ if { [test_account_storage] == 0 } {
 	send_user "\nWARNING: This test can't be run without a usable AccountStorageType\n"
 	exit 0
 }
- 
+
+
 #
 # Use sacctmgr to create a cluster
-#
-set sadd_pid [spawn $sacctmgr -i add $clu $nams=$tc1,$tc2 $fs=$fs1 $mc=$mc1 $mj=$mj1 $mn=$mn1 $mw=$mw1]
-expect {
-	-re "Adding Cluster" {
-		incr acmatches
-		exp_continue
+#	
+proc _add_cluster {name} {
+        global sacctmgr timeout
+
+	set exit_code 0
+	set matches 0
+
+	if { ![string length $name] } {
+		send_user "FAILURE: we need a name to add\n"
+		return 1
 	}
+
+	set my_pid [spawn $sacctmgr -i add cluster $name]
+	expect {
+		-re "(There was a problem|Unknown condition|Bad format on|Bad MaxWall|Unknown option)" {
+			send_user "FAILURE: there was a problem with the sacctmgr command\n"
+			incr exit_code 1
+		}
+		-re "Problem getting" {
+			send_user "FAILURE: there was a problem getting information from the database\n"
+			incr exit_code 1
+		}
+		-re "Problem adding" {
+			send_user "FAILURE: there was an unknwon problem\n"
+			incr exit_code 1
+		}
+		-re "No associations" {
+			send_user "FAILURE: your command didn't return anything\n"
+			incr exit_code 1
+		}
+		-re "Adding Cluster" {
+			incr matches
+			exp_continue
+		}
 		timeout {
-		send_user "\nFAILURE: sacctmgr add not responding\n"
-		slow_kill $sadd_pid
-		set exit_code 1
+			send_user "\nFAILURE: sacctmgr add not responding\n"
+			slow_kill $my_pid
+			exit_code 1
+		}
+		eof {
+			wait
+		}
 	}
-	eof {
-		wait
+
+	if {$matches != 1} {
+		send_user "\nFAILURE:  sacctmgr had a problem adding clusters
+	got $matches\n"
+		incr exit_code 1
 	}
-}
 
-if {$acmatches != 1} {
-	send_user "\nFAILURE:  sacctmgr had a problem adding clusters
-	got $acmatches\n"
-	set exit_code 1
+	if { ![check_acct_associations] } {
+		send_user "\nFAILURE:  Our associations don't line up\n"
+		incr exit_code 1
+	}
+	
+	return $exit_code
 }
 
-if { ![check_acct_associations] } {
-	send_user "\nFAILURE:  Our associations don't line up\n"
-	set exit_code 1
+#
+# Use sacctmgr to remove the test cluster
+#
+proc _remove_cluster {name} {
+        global sacctmgr timeout
+
+	set exit_code 0
+	set matches 0
+	set nothing 0
+
+	if { ![string length $name] } {
+		send_user "FAILURE: we need a name to remove\n"
+		return 1
+	}
+
+	set my_pid [spawn $sacctmgr -i delete cluster $name]
+	expect {
+		-re "(There was a problem|Unknown condition|Bad format on|Bad MaxWall|Unknown option)" {
+			send_user "FAILURE: there was a problem with the sacctmgr command\n"
+			incr exit_code 1
+		}
+		-re "Problem getting" {
+			send_user "FAILURE: there was a problem getting information from the database\n"
+			incr exit_code 1
+		}
+		-re "Problem adding" {
+			send_user "FAILURE: there was an unknwon problem\n"
+			incr exit_code 1
+		}
+		-re "No associations" {
+			send_user "FAILURE: your command didn't return anything\n"
+			incr exit_code 1
+		}
+		-re "Deleting clusters" {
+			incr matches
+			exp_continue
+		}
+		-re " Nothing deleted" {
+			incr matches
+			set nothing 1
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sacctmgr delete not responding\n"
+			slow_kill $my_pid
+			incr exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+	
+	if {$matches != 1} {
+		send_user "\nFAILURE: sacctmgr had a problem deleting cluster got $matches\n"
+		incr exit_code 1
+	}
+	if { !$nothing } {
+		if { ![check_acct_associations] } {
+			send_user "\nFAILURE:  Our associations don't line up\n"
+			incr exit_code 1
+		}
+	}
+
+	return $exit_code
 }
 
 #
 # Use sacctmgr to add an account
 #
-set sadel_pid [spawn $sacctmgr -i $add $acc $clu=$tc1,$tc2 $des="$ds1" $fs=$fs1 $mc=$mc1 $mj=$mj1 $mn=$mn1 $mw=$mw1 $nams=$nm1,$nm2,$nm3 $org="$or1" $qs=$qs1]
-expect {
-	-re "Adding Account" {
-		incr aamatches
-		exp_continue
+proc _add_acct { cluster name } {
+        global sacctmgr timeout
+
+	set exit_code 0
+	set matches 0
+
+	if { ![string length $name] } {
+		send_user "FAILURE: we need a name to add\n"
+		return 1
 	}
-	timeout {
-		send_user "\nFAILURE: sacctmgr add not responding\n"
-		slow_kill $sadd_pid
-		set exit_code 1
+
+	set command "$name"
+
+	if { [string length $cluster] } {
+		set command "$command cluster=$cluster"
 	}
-	eof {
-		wait
+
+	set my_pid [eval spawn $sacctmgr -i add account $command]
+	expect {
+		-re "(There was a problem|Unknown condition|Bad format on|Bad MaxWall|Unknown option)" {
+			send_user "FAILURE: there was a problem with the sacctmgr command\n"
+			incr exit_code 1
+		}
+		-re "Problem getting" {
+			send_user "FAILURE: there was a problem getting information from the database\n"
+			incr exit_code 1
+		}
+		-re "Problem adding" {
+			send_user "FAILURE: there was an unknwon problem\n"
+			incr exit_code 1
+		}
+		-re "No associations" {
+			send_user "FAILURE: your command didn't return anything\n"
+			incr exit_code 1
+		}
+		-re "Adding Account" {
+			incr matches
+			exp_continue
+		}
+		-re "Associations" {
+			incr matches
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sacctmgr add not responding\n"
+			slow_kill $my_pid
+			incr exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	if {$matches != 2} {
+		send_user "\nFAILURE:  sacctmgr had a problem adding account.
+	got $matches\n"
+		incr exit_code 1
+	}
+
+	if { ![check_acct_associations] } {
+		send_user "\nFAILURE:  Our associations don't line up\n"
+		incr exit_code 1
 	}
+	return $exit_code
 }
 
-if {$aamatches != 1} {
-	send_user "\nFAILURE:  sacctmgr had a problem adding account.
-	got $aamatches\n"
-	set exit_code 1
+#
+# Use sacctmgr to remove an account
+#
+proc _remove_acct { cluster name } {
+        global sacctmgr timeout
+
+	set exit_code 0
+	set matches 0
+	set nothing 1
+	set check "Deleting account"
+
+	if { ![string length $name] } {
+		send_user "FAILURE: we need a name to remove\n"
+		return 1
+	}
+
+	set command "$name"
+
+	if { [string length $cluster] } {
+		set command "$command cluster=$cluster"
+		set check "Deleting account associations"
+	}
+
+	set my_pid [eval spawn $sacctmgr -i delete account $command]
+	expect {
+		-re "(There was a problem|Unknown condition|Bad format on|Bad MaxWall|Unknown option)" {
+			send_user "FAILURE: there was a problem with the sacctmgr command\n"
+			incr exit_code 1
+		}
+		-re "Problem getting" {
+			send_user "FAILURE: there was a problem getting information from the database\n"
+			incr exit_code 1
+		}
+		-re "Problem adding" {
+			send_user "FAILURE: there was an unknwon problem\n"
+			incr exit_code 1
+		}
+		-re "No associations" {
+			send_user "FAILURE: your command didn't return anything\n"
+			incr exit_code 1
+		}
+		-re "$check" {
+			incr matches
+			exp_continue
+		}
+		-re " Nothing deleted" {
+			incr matches
+			set nothing 1
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sacctmgr add not responding\n"
+			slow_kill $my_pid
+			incr exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	if {$matches != 1} {
+		send_user "\nFAILURE:  sacctmgr had a problem deleting account.
+	got $matches\n"
+		incr exit_code 1
+	}
+
+	if { !$nothing } {
+		if { ![check_acct_associations] } {
+			send_user "\nFAILURE:  Our associations don't line up\n"
+			incr exit_code 1
+		}
+	}
+
+	return $exit_code
 }
 
 #
-# Use sacctmgr to list the test accounts
+# Use sacctmgr to modify an account
 #
-set ac_list_pid [spawn $sacctmgr -n list $acc withassoc]
-expect {
-	-re "$nm1 *$ds1 *$or1 *$qs1 *$tc1 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
-		exp_continue
+proc _mod_acct { cluster name desc org parent fs maxcpu maxjob maxnodes maxwall wdesc worg} {
+	global sacctmgr timeout
+	
+	set exit_code 0
+	set matches 0
+	set expected 0
+	set acct_stuff 0
+	set assoc_stuff 0
+
+	if { ![string length $name] } {
+		send_user "FAILURE: we need a name to modify\n"
+		return 1
 	}
-	-re "$nm1 *$ds1 *$or1 *$qs1 *$tc2 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
-		exp_continue
+
+	#set up the where
+	set wcommand "where $name"
+
+	if { [string length $cluster] } {
+		set wcommand "$wcommand cluster=$cluster"
 	}
-	-re "$nm2 *$ds1 *$or1 *$qs1 *$tc1 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
-		exp_continue
+
+	if { [string length $wdesc] } {
+		set wcommand "$wcommand description='$wdesc'"
 	}
-	-re "$nm2 *$ds1 *$or1 *$qs1 *$tc2 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
-		exp_continue
+
+	if { [string length $worg] } {
+		set wcommand "$wcommand organization='$worg'"
 	}
-	-re "$nm3 *$ds1 *$or1 *$qs1 *$tc1 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
-		exp_continue
+
+	#set up the set
+	set scommand "set"
+	if { [string length $parent] } {
+		set scommand "$scommand parent=$parent"
+		set assoc_stuff 1
+	}
+
+	if { [string length $fs] } {
+		set scommand "$scommand fairshare=$fs"
+		set assoc_stuff 1
+	}
+
+	if { [string length $maxcpu] } {
+		set scommand "$scommand maxc=$maxcpu"
+		set assoc_stuff 1
+	}
+
+	if { [string length $maxjob] } {
+		set scommand "$scommand maxj=$maxjob"
+		set assoc_stuff 1
+	}
+
+	if { [string length $maxnodes] } {
+		set scommand "$scommand maxn=$maxnodes"
+		set assoc_stuff 1
+	}
+
+	if { [string length $maxwall] } {
+		set scommand "$scommand maxw=$maxwall"
+		set assoc_stuff 1
+	}
+
+	if { [string length $desc] } {
+		set scommand "$scommand description='$desc'"
+		set acct_stuff 1
+	}
+
+	if { [string length $org] } {
+		set scommand "$scommand organization='$org'"
+		set acct_stuff 1
+	}
+
+	incr expected $acct_stuff
+	incr expected $assoc_stuff
+
+	set my_pid [eval spawn $sacctmgr -i modify account $scommand $wcommand ]
+	expect {
+		-re "(There was a problem|Unknown condition|Bad format on|Bad MaxWall|Unknown option)" {
+			send_user "FAILURE: there was a problem with the sacctmgr command\n"
+			incr exit_code 1
+		}
+		-re "Problem getting" {
+			send_user "FAILURE: there was a problem getting information from the database\n"
+			incr exit_code 1
+		}
+		-re "Problem adding" {
+			send_user "FAILURE: there was an unknwon problem\n"
+			incr exit_code 1
+		}
+		-re "No associations" {
+			send_user "FAILURE: your command didn't return anything\n"
+			incr exit_code 1
+		}
+		-re "Modified accounts" {
+			incr matches
+			exp_continue
+		}
+		-re "Modified account associations" {
+			incr matches
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sacctmgr add not responding\n"
+			slow_kill $my_pid
+			incr exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	if {$matches != $expected} {
+		send_user "\nFAILURE:  sacctmgr had a problem modifying account.
+	got $matches needed $expected\n"
+		incr exit_code 1
+	}
+	
+	if { ![check_acct_associations] } {
+		send_user "\nFAILURE:  Our associations don't line up\n"
+		incr exit_code 1
 	}
-	-re "$nm3 *$ds1 *$or1 *$qs1 *$tc2 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lmatches
+	return $exit_code
+}
+
+#make sure we have a clean system
+_remove_cluster "$tc1,$tc2"
+_remove_acct "" "$nm1,$nm2,$nm3"
+
+#add cluster
+incr exit_code [_add_cluster "$tc1,$tc2"]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
+}
+
+#add accounts
+incr exit_code [_add_acct "$tc1,$tc2" "$nm1,$nm2,$nm3"]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
+}
+
+# OK This is the real test, first test change the desc and org of the accounts 
+incr exit_code [_mod_acct "" "$nm1,$nm2,$nm3" $ds2 $or2 "" "" "" "" "" "" "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
+}
+
+#
+# Use sacctmgr to list the test account modifications
+#
+set matches 0
+set my_pid [spawn $sacctmgr -n -p list account acc=$nm1,$nm2,$nm3 format="Account,Desc,Org"]
+expect {
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
+	}
+	-re "($nm1|$nm2|$nm3)\\\|$ds2\\\|$or2\\\|" {
+		incr matches
 		exp_continue
 	}
 	timeout {
 		send_user "\nFAILURE: sacctmgr list associations not responding\n"
-		slow_kill $ac_list_pid
-		set exit_code 1
+		slow_kill $my_pid
+		incr exit_code 1
 	}
 	eof {
 		wait
 	}
 }
-
-if {$lmatches != 6} {
-	send_user "\nFAILURE:  Accounts addition not correct.\n"
-	set exit_code 1
+if {$matches != 3} {
+	send_user "\nFAILURE:  Account modification 1 incorrect with only $matches.\n"
+	incr exit_code 1
 }
 
-if { ![check_acct_associations] } {
-	send_user "\nFAILURE:  Our associations don't line up\n"
-	set exit_code 1
+# Next, test change the limits of the accounts 
+incr exit_code [_mod_acct "" "$nm1,$nm2,$nm3" "" "" "" $fs2 $mc2 $mj2 $mn2 $mw2 "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
 }
 
 #
-# Use sacctmgr to modify an account
+# Use sacctmgr to list the test account modifications
 #
-set sadel_pid [spawn $sacctmgr -i $mod $acc set $des="$ds2" $fs=$fs2 $mc=$mc2 $mj=$mj2 $mn=$mn2 $mw=$mw2 $org="$or2" $par=$nm1 where $des="$ds1" $nams=$nm2,$nm3 $org="$or1" ]
+set matches 0
+set my_pid [spawn $sacctmgr -n -p list assoc acc=$nm1,$nm2,$nm3 format="Account,Cluster,Fairshare,MaxC,MaxJ,MaxN,MaxW"]
 expect {
-	-re "Modified accounts" {
-		incr ammatches
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
+	}
+	-re "($nm1|$nm2|$nm3)\\\|($tc1|$tc2)\\\|$fs2\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\|" {
+		incr matches
 		exp_continue
 	}
 	timeout {
-		send_user "\nFAILURE: sacctmgr add not responding\n"
-		slow_kill $sadd_pid
-		set exit_code 1
+		send_user "\nFAILURE: sacctmgr list associations not responding\n"
+		slow_kill $my_pid
+		incr exit_code 1
 	}
 	eof {
 		wait
 	}
 }
-
-if {$ammatches != 1} {
-	send_user "\nFAILURE:  sacctmgr had a problem modifying account.
-	got $ammatches\n"
-	set exit_code 1
+if {$matches != 6} {
+	send_user "\nFAILURE:  Account modification 2 incorrect with only $matches.\n"
+	incr exit_code 1
 }
 
-if { ![check_acct_associations] } {
-	send_user "\nFAILURE:  Our associations don't line up\n"
-	set exit_code 1
+# Next, test change the desc and limits of the accounts 
+incr exit_code [_mod_acct "" "$nm1,$nm3" $ds1 $or1 "" -1 -1 -1 -1 -1 "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
 }
 
 #
 # Use sacctmgr to list the test account modifications
 #
-set ac_list_pid [spawn $sacctmgr -n list $acc withassoc]
+set matches 0
+set my_pid [eval spawn $sacctmgr -n -p list acct withassoc acc=$nm1,$nm2,$nm3 format="Account,Desc,Org,Cluster,Fairshare,MaxC,MaxJ,MaxN,MaxW"]
 expect {
-	-re "$nm1 *$ds1 *$or1 *$qs1 *$tc1 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lamatches
-		exp_continue
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
 	}
-	-re "$nm1 *$ds1 *$or1 *$qs1 *$tc2 *root *$fs1 *$mc1 *$mj1 *$mn1 *$mw1" {
-		incr lamatches
+	# Any time you use () around something you need to combine all 
+	# those things together since you can miss some and they be thrown away
+	-re "(($nm1|$nm3)\\\|$ds1\\\|$or1\\\|($tc1|$tc2)\\\|1\\\|\\\|\\\|\\\|\\\||$nm2\\\|$ds2\\\|$or2\\\|($tc1|$tc2)\\\|$fs2\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\|)" {
+		incr matches
 		exp_continue
 	}
-	-re "$nm2 *$ds2 *$or2 *$qs1 *$tc1 *$nm1 *$fs2 *$mc2 *$mj2 *$mn2 *$mw2" {
-		incr lamatches
-		exp_continue
+	timeout {
+		send_user "\nFAILURE: sacctmgr list associations not responding\n"
+		slow_kill $my_pid
+		incr exit_code 1
 	}
-	-re "$nm2 *$ds2 *$or2 *$qs1 *$tc2 *$nm1 *$fs2 *$mc2 *$mj2 *$mn2 *$mw2" {
-		incr lamatches
-		exp_continue
+	eof {
+		wait
 	}
-	-re "$nm3 *$ds2 *$or2 *$qs1 *$tc1 *$nm1 *$fs2 *$mc2 *$mj2 *$mn2 *$mw2" {
-		incr lamatches
+}
+
+if {$matches != 6} {
+	send_user "\nFAILURE:  Account modification 2 incorrect with $matches.\n"
+	incr exit_code 1
+}
+
+# Next, test change the parent of $n3 to be $n2 on $tc1 sibling to be a child
+incr exit_code [_mod_acct "$tc1" "$nm3" "" "" "$nm2" "" "" "" "" "" "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
+}
+
+#
+# Use sacctmgr to list the test account modifications
+#
+set matches 0
+set my_pid [eval spawn $sacctmgr -n -p list assoc acc=$nm3 format="Account,ParentN,Cluster,Fairshare,MaxC,MaxJ,MaxN,MaxW"]
+expect {
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
+	}
+	-re "$nm3\\\|$nm2\\\|$tc1\\\|1\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\|" {
+		incr matches
 		exp_continue
 	}
-	-re "$nm3 *$ds2 *$or2 *$qs1 *$tc2 *$nm1 *$fs2 *$mc2 *$mj2 *$mn2 *$mw2" {
-		incr lamatches
+	-re "$nm3\\\|root\\\|$tc2\\\|1\\\|\\\|\\\|\\\|\\\|" {
+		incr matches
 		exp_continue
 	}
 	timeout {
 		send_user "\nFAILURE: sacctmgr list associations not responding\n"
-		slow_kill $ac_list_pid
-		set exit_code 1
+		slow_kill $my_pid
+		incr exit_code 1
 	}
 	eof {
 		wait
 	}
 }
+if {$matches != 2} {
+	send_user "\nFAILURE:  Account modification 3 incorrect with $matches.\n"
+	incr exit_code 1
+}
 
-if {$lamatches != 6} {
-	send_user "\nFAILURE:  Account modification incorrect.\n"
-	set exit_code 1
+# Next, test change the parent of $n2 to be $n3 on $tc1 
+# making the child the parent
+incr exit_code [_mod_acct "$tc1" "$nm2" "" "" "$nm3" "" "" "" "" "" "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
 }
 
 #
-# Use sacctmgr to delete the test account
+# Use sacctmgr to list the test account modifications
 #
-set sadel_pid [spawn $sacctmgr -i $del $acc $nm1,$nm2,$nm3]
+set matches 0
+set my_pid [eval spawn $sacctmgr -n -p list assoc acc=$nm3,$nm2 format="Account,ParentN,Cluster,Fairshare,MaxC,MaxJ,MaxN,MaxW"]
 expect {
-	-re "Deleting account" {
-		incr damatches
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
+	}
+	-re "($nm2\\\|root\\\|$tc2\\\|$fs2\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\||$nm2\\\|$nm3\\\|$tc1\\\|$fs2\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\||$nm3\\\|root\\\|($tc1|$tc2)\\\|1\\\|\\\|\\\|\\\|\\\|)" {
+		incr matches
 		exp_continue
 	}
 	timeout {
-		send_user "\nFAILURE: sacctmgr delete not responding\n"
-		slow_kill $sadel_pid
-		set exit_code 1
+		send_user "\nFAILURE: sacctmgr list associations not responding\n"
+		slow_kill $my_pid
+		incr exit_code 1
 	}
 	eof {
 		wait
 	}
 }
-
-if {$damatches != 1} {
-	send_user "\nFAILURE: sacctmgr had a problem deleting cluster got $damatches\n"
-	set exit_code 1
+if {$matches != 4} {
+	send_user "\nFAILURE:  Account modification 3 incorrect with $matches.\n"
+	incr exit_code 1
 }
 
-if { ![check_acct_associations] } {
-	send_user "\nFAILURE:  Our associations don't line up\n"
-	set exit_code 1
+
+# Next, test change the parent of $n3 to be $n2 on $tc1 again 
+# only this time the parent will become the child instead of it being a sibling.
+incr exit_code [_mod_acct "$tc1" "$nm3" "" "" "$nm2" "" "" "" "" "" "" ""]
+if { $exit_code } {
+	_remove_acct "" "$nm1,$nm2,$nm3"
+	_remove_cluster "$tc1,$tc2"
+	exit $exit_code
 }
 
 #
-# Use sacctmgr to delete the test cluster
+# Use sacctmgr to list the test account modifications
 #
-set sadel_pid [spawn $sacctmgr -i $del $clu $tc1,$tc2]
+set matches 0
+set my_pid [eval spawn $sacctmgr -n -p list assoc acc=$nm3,$nm2 format="Account,ParentN,Cluster,Fairshare,MaxC,MaxJ,MaxN,MaxW"]
 expect {
-	-re "Deleting clusters" {
-		incr dcmatches
+	-re "There was a problem" {
+	        send_user "FAILURE: there was a problem with the sacctmgr command\n"
+	    	incr exit_code 1
+	}
+	-re "($nm2\\\|root\\\|($tc1|$tc2)\\\|$fs2\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\||$nm3\\\|$nm2\\\|$tc1\\\|1\\\|$mc2\\\|$mj2\\\|$mn2\\\|$mw2\\\||$nm3\\\|root\\\|$tc2\\\|1\\\|\\\|\\\|\\\|\\\|)" {
+		incr matches
 		exp_continue
 	}
 	timeout {
-		send_user "\nFAILURE: sacctmgr delete not responding\n"
-		slow_kill $sadel_pid
-		set exit_code 1
+		send_user "\nFAILURE: sacctmgr list associations not responding\n"
+		slow_kill $my_pid
+		incr exit_code 1
 	}
 	eof {
 		wait
 	}
 }
-
-if {$dcmatches != 1} {
-	send_user "\nFAILURE: sacctmgr had a problem deleting cluster got $dcmatches\n"
-	set exit_code 1
+if {$matches != 4} {
+	send_user "\nFAILURE:  Account modification 3 incorrect with $matches.\n"
+	incr exit_code 1
 }
 
-if { ![check_acct_associations] } {
-	send_user "\nFAILURE:  Our associations don't line up\n"
-	set exit_code 1
-}
+
+
+
+
+
+
+# This is the end below here
+
+incr exit_code [_remove_acct "$tc1,$tc2" "$nm1,$nm2,$nm3"]
+incr exit_code [_remove_acct "" "$nm1,$nm2,$nm3"]
+incr exit_code [_remove_cluster "$tc1,$tc2"]
 
 if {$exit_code == 0} {
 	send_user "\nSUCCESS\n"
-		} else {
+} else {
 	send_user "\nFAILURE\n"
-		}
-
+}
 exit $exit_code
+
diff --git a/testsuite/expect/test21.17 b/testsuite/expect/test21.17
index 6eff09152b6b01abeaf0d7f0e3eff3dcc00669b2..013e5a60b25c92c1273bdf17217bd8f7fda59d9c 100755
--- a/testsuite/expect/test21.17
+++ b/testsuite/expect/test21.17
@@ -295,7 +295,7 @@ expect {
 }
 
 if {$dlumatches != 8} {
-	send_user "\nFAILURE: sacctmgr had a problem listing user got $dumatches\n"
+	send_user "\nFAILURE: sacctmgr had a problem listing user got $dumatches of 8\n"
 	set exit_code 1
 }
 
@@ -383,8 +383,8 @@ if { ![check_acct_associations] } {
 
 if {$exit_code == 0} {
 	send_user "\nSUCCESS\n"
-		} else {
+} else {
 	send_user "\nFAILURE\n"
-		}
+}
 
 exit $exit_code
diff --git a/testsuite/expect/test6.13 b/testsuite/expect/test6.13
index 9f41d43af601d79cc66e9524abf5dd4dedc29572..a2945d5bfbdc7281ed72eaf868b40efdde1bc39e 100755
--- a/testsuite/expect/test6.13
+++ b/testsuite/expect/test6.13
@@ -46,7 +46,7 @@ print_header $test_id
 # of the ulimit program is inconsistent across systems.
 #
 exec rm -f $file_prog $file_in $file_out
-exec cc -o $file_prog $file_prog.c
+exec $bin_cc -O -o $file_prog ${file_prog}.c
 make_bash_script $file_in "
  $srun ./$file_prog
 "
diff --git a/testsuite/expect/test7.1 b/testsuite/expect/test7.1
index ab4923b0fd6ea4c2da6ed246ea3612da9f59b42f..0c47af57e09f180f71b8680d168d2ccc01cb9e61 100755
--- a/testsuite/expect/test7.1
+++ b/testsuite/expect/test7.1
@@ -54,7 +54,7 @@ expect {
 		exp_continue
 	}
 	timeout {
-		send_user "\nFAILURE: srun not responding\n"
+		send_user "\nFAILURE: sbatch not responding\n"
 		slow_kill $sbatch_pid
 		exit 1
 	}
@@ -69,7 +69,7 @@ expect {
                 exp_continue
         }
         timeout {
-                send_user "\nFAILURE: srun not responding\n"
+                send_user "\nFAILURE: sbatch not responding\n"
                 slow_kill $sbatch_pid
                 exit 1
         }
diff --git a/testsuite/expect/test7.11 b/testsuite/expect/test7.11
new file mode 100755
index 0000000000000000000000000000000000000000..fc8998ba80fba6434822d37a65b9561d85d2886a
--- /dev/null
+++ b/testsuite/expect/test7.11
@@ -0,0 +1,253 @@
+#!/usr/bin/expect
+############################################################################
+# Purpose: Test of SLURM functionality
+#          Test of SPANK plugin
+#
+# Output:  "TEST: #.#" followed by "SUCCESS" if test was successful, OR
+#          "FAILURE: ..." otherwise with an explanation of the failure, OR
+#          anything else indicates a failure mode that must be investigated.
+############################################################################
+# Copyright (C) 2008 Lawrence Livermore National Security.
+# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+# Written by Morris Jette <jette1@llnl.gov>
+# LLNL-CODE-402394.
+# 
+# This file is part of SLURM, a resource management program.
+# For details, see <http://www.llnl.gov/linux/slurm/>.
+#  
+# SLURM is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+# 
+# SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with SLURM; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+############################################################################
+source ./globals
+
+set test_id	    "7.11"
+set cwd		    "[$bin_pwd]"
+set exit_code	    0
+set file_in         "${cwd}/test${test_id}.in"
+set file_out	    "${cwd}/test${test_id}.out"
+set file_prog	    "${cwd}/test${test_id}.prog"
+set orig_spank_conf "${cwd}/test${test_id}.orig_conf"
+set new_spank_conf  "${cwd}/test${test_id}.new_conf"
+set spank_out       "${cwd}/test${test_id}.spank.out"
+
+print_header $test_id
+
+if {[test_super_user] == 0} {
+	send_user "\nWARNING: This test must be run as SlurmUser\n"
+	exit 0
+}
+if {[test_aix] == 1} {
+	send_user "WARNING: Test is incompatible with AIX\n"
+	exit 0
+}
+
+#
+# Build the plugin
+#
+exec $bin_rm -f ${file_prog}.so
+exec $bin_cc -shared -I${slurm_dir}/include -o ${file_prog}.so ${file_prog}.c
+
+#
+# Locate slurm.conf's directory, copy the original plugstack.conf file
+# and create an updated one using our new plugin
+#
+log_user 0
+set config_dir ""
+spawn $scontrol show config
+expect {
+	-re "SLURM_CONFIG_FILE.*= (/.*)/slurm.conf" {
+		set config_dir $expect_out(1,string)
+		exp_continue
+	}
+	eof {
+		wait
+	}
+}
+log_user 1
+if {[string compare $config_dir ""] == 0} {
+	send_user "\nFAILURE: Could not locate slurm.conf directory\n"
+	exit 1
+}
+set spank_conf_file ${config_dir}/plugstack.conf
+exec $bin_rm -f $orig_spank_conf $new_spank_conf $file_out $spank_out
+if {[file exists $spank_conf_file]} {
+	spawn $bin_cat $spank_conf_file
+	expect {
+		-re "test${test_id}" {
+			send_user "\nFAILURE: spank plugin includes vestigial test${test_id}\n"
+			send_user "   You probably should manually remove it from $spank_conf_file.\n"
+			send_user "   It was probably left over from some previous test failure.\n"
+			exit 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	exec $bin_cp $spank_conf_file $orig_spank_conf
+	exec $bin_cp $spank_conf_file $new_spank_conf
+} else {
+	exec $bin_cp /dev/null $new_spank_conf
+}
+
+exec $bin_echo "required ${file_prog}.so ${spank_out}" >>$new_spank_conf
+spawn $bin_cp $new_spank_conf $spank_conf_file
+expect {
+	-re "Permission denied" {
+		send_user "\nWARNING: User lacks permission to update plugstack_conf file\n"
+		exit 0
+	}
+	eof {
+		wait
+	}
+}
+
+#
+# Test of srun help message
+#
+set matches 0
+set srun_pid [spawn $srun --help]
+expect {
+	-re "Component of slurm test suite" {
+		incr matches
+		exp_continue
+	}
+	timeout {
+		send_user "\nFAILURE: srun not responding\n"
+		slow_kill $srun_pid
+		set exit_code 1
+	}
+	eof {
+		wait
+	}
+}
+if {$matches != 1} {
+	send_user "\nFAILURE: spank help message not in srun help message\n"
+	set exit_code 1
+}
+
+#
+# Test of locally logged messages().
+# We update the plugstatck.conf in this script since NFS delays may 
+# prevent it from having the same state as the submit host. 
+#
+make_bash_script $file_in "
+  $bin_cp $new_spank_conf $spank_conf_file
+  $srun --test_suite=5 $bin_uname
+  if test -f $orig_spank_conf
+  then
+    $bin_cp $orig_spank_conf $spank_conf_file
+  fi
+"
+spawn $sbatch -N1 -t1 -o $file_out $file_in
+expect {
+	-re timeout {
+		send_user "\nFAILURE: sbatch not responding\n"
+		set exit_code 1
+	}
+	eof {
+		wait
+	}
+}
+
+# NOTE: spank logs from sbatch and srun would be intermingled here
+if {[wait_for_file $file_out] == 0} {
+	send_user "\n\n"
+	set match1 0
+	set match2 0
+	set match3 0
+	spawn $bin_cat $file_out
+	expect {
+		-re "error" {
+			send_user "\nFAILURE: some error happened\n"
+			set exit_code 1
+			exp_continue
+		}
+		-re "_test_opt_process: test_suite: opt_arg=5" {
+			set match1 1
+			exp_continue
+		}
+		-re "slurm_spank_local_user_init" {
+			set match2 1
+			exp_continue
+		}
+		-re "slurm_spank_exit: opt_arg=5" {
+			set match3 1
+			exp_continue
+		}
+		eof {
+			wait
+		}
+	}
+	if {[expr $match1 + $match2 + $match3] != 3} {
+		send_user "\nFAILURE: local (srun) spank plugin failure\n"
+		set exit_code 1
+	} else {
+		send_user "\nlocal (srun) spank plugin success\n"
+	}
+} else {
+	set exit_code 1
+}
+
+#
+# Test for slurmd output in file
+#
+if {[wait_for_file $spank_out] == 0} {
+	send_user "\n\n"
+	set matches 0
+	spawn $bin_cat $spank_out
+	expect {
+		-re "slurm_spank_task_init: opt_arg=5" {
+			incr matches
+			exp_continue
+		}
+		-re "spank_get_item: my_uid=" {
+			incr matches
+			exp_continue
+		}
+		-re "slurm_spank_exit: opt_arg=5" {
+			incr matches
+			exp_continue
+		}
+		eof {
+			wait
+		}
+	}
+	if {$matches != 3} {
+		send_user "\nFAILURE: remote (slurmd) spank plugin failure\n"
+		set exit_code 1
+	} else {
+		send_user "\n remote (slurmd) spank plugin success\n"
+	}
+} else {
+	send_user "\nWARNING: This can be caused by the plugstack.conf file not\n"
+	send_user "      being propagated to the compute node or not being in a\n"
+	send_user "      shared file system.\n"
+	set exit_code 1
+}
+
+#
+# Restore the original plugstack
+#
+if {[file exists $orig_spank_conf]} {
+	exec $bin_cp $orig_spank_conf $spank_conf_file
+} else {
+	exec $bin_rm -f $spank_conf_file
+}
+
+if {$exit_code == 0} {
+	exec $bin_rm -f $orig_spank_conf $new_spank_conf $file_out $spank_out ${file_prog}.so
+	send_user "\nSUCCESS\n"
+}
+exit $exit_code
diff --git a/testsuite/expect/test7.11.prog.c b/testsuite/expect/test7.11.prog.c
new file mode 100644
index 0000000000000000000000000000000000000000..91496061745cce14356d3fb7060853a9e57188da
--- /dev/null
+++ b/testsuite/expect/test7.11.prog.c
@@ -0,0 +1,120 @@
+/*****************************************************************************\
+ *  prog7.11.prog.c - SPANK plugin for testing purposes
+ *****************************************************************************
+ *  Copyright (C) 2008 Lawrence Livermore National Security.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Morris Jette <jette1@llnl.gov>
+ *  LLNL-CODE-402394.
+ *  
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://www.llnl.gov/linux/slurm/>.
+ *  
+ *  SLURM is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *  
+ *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+ *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ *  details.
+ *  
+ *  You should have received a copy of the GNU General Public License along
+ *  with SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+\*****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+
+#include <slurm/spank.h>
+
+/*
+ * All spank plugins must define this macro for the SLURM plugin loader.
+ */
+SPANK_PLUGIN(test_suite, 1);
+
+static int opt_arg = 0;
+static char *opt_out_file = NULL;
+
+static int _test_opt_process(int val, const char *optarg, int remote);
+
+/*
+ *  Provide a --renice=[prio] option to srun:
+ */
+struct spank_option spank_options[] =
+{
+	{ "test_suite", "[opt_arg]", "Component of slurm test suite.", 2, 0,
+		_test_opt_process
+	},
+	SPANK_OPTIONS_TABLE_END
+};
+
+static int _test_opt_process(int val, const char *optarg, int remote)
+{
+	opt_arg = atoi(optarg);
+	if (!remote)
+		slurm_info("_test_opt_process: test_suite: opt_arg=%d", opt_arg);
+
+	return (0);
+}
+
+/*  Called from both srun and slurmd */
+int slurm_spank_init(spank_t sp, int ac, char **av)
+{
+	if (spank_remote(sp) && (ac == 1))
+		opt_out_file = strdup(av[0]);
+
+	return (0);
+}
+
+/* Called from both srun and slurmd, not tested here
+int slurm_spank_init_post_opt(spank_t sp, int ac, char **av) */
+
+/* Called from srun only */
+slurm_spank_local_user_init(spank_t sp, int ac, char **av)
+{
+	slurm_info("slurm_spank_local_user_init");
+
+	return (0);
+}
+
+/* Called from slurmd only */
+int slurm_spank_task_init(spank_t sp, int ac, char **av)
+{
+	uid_t my_uid;
+
+	if (opt_out_file && opt_arg) {
+		FILE *fp = fopen(opt_out_file, "a");
+		if (!fp)
+			return (-1);
+		fprintf(fp, "slurm_spank_task_init: opt_arg=%d\n", opt_arg);
+		if (spank_get_item(sp, S_JOB_UID, &my_uid) == ESPANK_SUCCESS)
+			fprintf(fp, "spank_get_item: my_uid=%d\n", my_uid);
+		fclose(fp);
+	}
+	return (0);
+}
+
+/* Called from slurmd only, not tested here
+int slurm_spank_task_post_fork(spank_t sp, int ac, char **av) */
+
+/* Called from slurmd only, not tested here
+int slurm_spank_task_exit(spank_t sp, int ac, char **av) */
+
+/* Called from both srun and slurmd */
+int slurm_spank_exit(spank_t sp, int ac, char **av)
+{
+	if (opt_out_file && opt_arg) {
+		FILE *fp = fopen(opt_out_file, "a");
+		if (!fp)
+			return (-1);
+		fprintf(fp, "slurm_spank_exit: opt_arg=%d\n", opt_arg);
+		fclose(fp);
+	} else if (opt_arg)
+		slurm_info("slurm_spank_exit: opt_arg=%d", opt_arg);
+	return (0);
+}
diff --git a/testsuite/expect/test7.3 b/testsuite/expect/test7.3
index 2fe04f5df123caf17d041353461470dc06a3416d..03619fb34fb74d02318710567bd3d8d24cde98d5 100755
--- a/testsuite/expect/test7.3
+++ b/testsuite/expect/test7.3
@@ -50,7 +50,7 @@ if {[test_front_end] != 0} {
 #
 file delete $io_prog $test_prog
 
-exec $bin_make -f /dev/null $io_prog
+exec $bin_cc -O -o $io_prog ${io_prog}.c
 exec $bin_chmod 700 $io_prog
 
 send_user "slurm_dir is $slurm_dir\n"
diff --git a/testsuite/expect/test7.9 b/testsuite/expect/test7.9
index e58d5243a5952d95a26a3f5024c35d2136354ea0..1915f4d2dd34b7b480331187be70755f03b87485 100755
--- a/testsuite/expect/test7.9
+++ b/testsuite/expect/test7.9
@@ -92,7 +92,7 @@ if {$invalid == 1} {
 # of the ulimit program is inconsistent across systems.
 #
 exec $bin_rm -f $file_prog $file_in $file_out
-exec $bin_make -f /dev/null $file_prog
+exec $bin_cc -O -o $file_prog ${file_prog}.c
 
 make_bash_script $file_in "
   $bin_echo 'testing within script'