diff --git a/src/sinfo/opts.c b/src/sinfo/opts.c
index 28f7211ae49822b6dab8829c5f06eb69690ba5fb..10bacb106dc15ece1d5434edcdef8e1e1a7ab58a 100644
--- a/src/sinfo/opts.c
+++ b/src/sinfo/opts.c
@@ -36,7 +36,6 @@
 
 #include "src/sinfo/sinfo.h"
 
-#define OPT_SUMMARIZE 	0x01
 #define OPT_NODE_STATE 	0x02
 #define OPT_PARTITION	0x03
 #define OPT_NODE     	0x04
@@ -59,31 +58,29 @@ int parse_command_line(int argc, char *argv[])
 	   option tag, docstr, argstr } */
 
 	poptContext context;
-	int next_opt, curr_opt;
+	int curr_opt;
 	int rc = 0;
 
 	/* Declare the Options */
 	static const struct poptOption options[] = {
 		{"exact", 'e', POPT_ARG_NONE, &params.exact_match, OPT_EXACT,
-		 "group node only on exact match of configuration",NULL},
+		 "group nodes only on exact match of configuration",NULL},
 		{"iterate", 'i', POPT_ARG_INT, &params.iterate,
 		 OPT_ITERATE, "specify an interation period", "seconds"},
 		{"state", 't', POPT_ARG_STRING, &temp_state,
 		 OPT_NODE_STATE, "specify the what state of nodes to view",
 		 "node_state"},
-		{"partition", 'p', POPT_ARG_NONE, &params.partition_flag,
-		 OPT_PARTITION,
-		 "show partition information and optionally specify a specific partition",
-		 "PARTITION"},
-		{"node", 'n', POPT_ARG_NONE, &params.node_flag, OPT_NODE,
-		 "specify a specific node", "NODE"},
+		{"partition", 'p', POPT_ARG_STRING, &params.partition,
+		 OPT_PARTITION, "report on specific partition", "PARTITION"},
+		{"nodes", 'n', POPT_ARG_STRING, &params.nodes, OPT_NODE,
+		 "report on specific node(s)", "NODES"},
+		{"Node", 'N', POPT_ARG_NONE, &params.node_flag, OPT_FORMAT,
+		 "Node-centric format", NULL},
 		{"long", 'l', POPT_ARG_NONE, &params.long_output,
 		 OPT_FORMAT, "long output - displays more information",
 		 NULL},
 		{"summarize", 's', POPT_ARG_NONE, &params.summarize,
-		 OPT_VERBOSE,
-		 "summarize partitition information, do not show individual nodes",
-		 NULL},
+		 OPT_FORMAT,"report state summary only", NULL},
 		{"verbose", 'v', POPT_ARG_NONE, &params.verbose,
 		 OPT_VERBOSE, "verbosity level", "level"},
 		POPT_AUTOHELP 
@@ -94,28 +91,10 @@ int parse_command_line(int argc, char *argv[])
 	context = poptGetContext("sinfo", argc, (const char **) argv,
 				 options, POPT_CONTEXT_POSIXMEHARDER);
 
-	poptSetOtherOptionHelp(context, "[-elns]");
-
-	next_opt = poptGetNextOpt(context);
-
-	while (next_opt > -1) {
-		const char *opt_arg = NULL;
-		curr_opt = next_opt;
-		next_opt = poptGetNextOpt(context);
-
-		switch (curr_opt) {
-		case OPT_PARTITION:
-			if ((opt_arg = poptGetArg(context)) != NULL) {
-				params.partition = (char *) opt_arg;
-			}
-			break;
+	poptSetOtherOptionHelp(context, "[-elNsv]");
 
-		case OPT_NODE:
-			if ((opt_arg = poptGetArg(context)) != NULL) {
-				params.node = (char *) opt_arg;
-			}
-			break;
-		case OPT_NODE_STATE:
+	while ((curr_opt = poptGetNextOpt(context)) > 0) {
+		if (curr_opt == OPT_NODE_STATE) {
 			params.state_flag = true;
 			if (_parse_state(temp_state, &params.state)
 			    == SLURM_ERROR) {
@@ -124,31 +103,13 @@ int parse_command_line(int argc, char *argv[])
 					argv[0], temp_state);
 				exit(1);
 			}
-			break;
-
-		default:
-			break;
-		}
-		if ((opt_arg = poptGetArg(context)) != NULL) {
-			fprintf(stderr, "%s: %s \"%s\"\n", argv[0],
-				poptStrerror(POPT_ERROR_BADOPT), opt_arg);
-			exit(1);
 		}
-		if (curr_opt < 0) {
-			fprintf(stderr, "%s: \"%s\" %s\n", argv[0],
-				poptBadOption(context,
-					      POPT_BADOPTION_NOALIAS),
-				poptStrerror(next_opt));
-
-			exit(1);
-		}
-
 	}
-	if (next_opt < -1) {
+	if (curr_opt < -1) {
 		const char *bad_opt;
 		bad_opt = poptBadOption(context, POPT_BADOPTION_NOALIAS);
 		fprintf(stderr, "bad argument %s: %s\n", bad_opt,
-			poptStrerror(next_opt));
+			poptStrerror(curr_opt));
 		fprintf(stderr, "Try \"%s --help\" for more information\n",
 			argv[0]);
 		exit(1);
@@ -201,18 +162,22 @@ static int _parse_state(char *str, enum node_states *states)
 /* print the parameters specified */
 void print_options( void )
 {
+	char *node_state;
+	
+	if (params.state_flag)
+		node_state = node_state_string(params.state);
+	else
+		node_state = "N/A";
+
 	printf("-----------------------------\n");
-	printf("partition(%s) = %s\n",
-	       (params.partition_flag ? "true" : "false"),
-	       params.partition);
-	printf("node(%s)  = %s\n", (params.node_flag ? "true" : "false"),
-	       params.node);
-	printf("state(%s) = %s\n", (params.state_flag ? "true" : "false"),
-	       node_state_string(params.state));
-	printf("summarize = %s\n", params.summarize ? "true" : "false");
-	printf("exact     = %d\n", params.exact_match);
-	printf("verbose   = %d\n", params.verbose);
-	printf("long output = %s\n",
-	       params.long_output ? "true" : "false");
+	printf("exact       = %d\n", params.exact_match);
+	printf("long format = %s\n", params.long_output ? "true" : "false");
+	printf("nodes       = %s\n", params.nodes ? params.nodes : "N/A");
+	printf("Node format = %s\n", params.node_flag   ? "true" : "false");
+	printf("partition   = %s\n", params.partition ? 
+				     params.partition: "N/A");
+	printf("state       = %s\n", node_state);
+	printf("summarize   = %s\n", params.summarize   ? "true" : "false");
+	printf("verbose     = %d\n", params.verbose);
 	printf("-----------------------------\n\n");
 }
diff --git a/src/sinfo/sinfo.c b/src/sinfo/sinfo.c
index 3dd2f29c8efe19259898806e2ca6f41853ea985c..dd920c4290958623e91856d787190d8e16b355a1 100644
--- a/src/sinfo/sinfo.c
+++ b/src/sinfo/sinfo.c
@@ -28,49 +28,47 @@
 #include "src/common/hostlist.h"
 #include "src/common/list.h"
 
-#define NODE_SIZE_CPUS		4
-#define NODE_SIZE_CPUS_LONG	4
-#define NODE_SIZE_DISK		8
-#define NODE_SIZE_DISK_LONG	8
-#define NODE_SIZE_FEATURES	0
-#define NODE_SIZE_MEM		6
-#define NODE_SIZE_MEM_LONG	6
-#define NODE_SIZE_NAME		15
-#define NODE_SIZE_PART		10
+#define NODE_SIZE_PART		9
 #define NODE_SIZE_STATE		6
 #define NODE_SIZE_STATE_LONG	11
+#define NODE_SIZE_NODES		5
+#define NODE_SIZE_CPUS		4
+#define NODE_SIZE_MEM		6
+#define NODE_SIZE_DISK		8
 #define NODE_SIZE_WEIGHT	6
+#define NODE_SIZE_FEATURES	8
+#define NODE_SIZE_NAME		9
 
-#define PART_SIZE_CPUS		4
-#define PART_SIZE_CPUS_LONG	6
-#define PART_SIZE_DISK		8
-#define PART_SIZE_DISK_LONG	15
-#define PART_SIZE_MEM		6
-#define PART_SIZE_MEM_LONG	11
 #define PART_SIZE_NODES		0
 #define PART_SIZE_NUM		5
-#define PART_SIZE_PART		10
+#define PART_SIZE_PART		9
 #define PART_SIZE_STATE		6
 #define PART_SIZE_STATE_LONG	11
+#define PART_SIZE_AVAIL		5
+#define PART_SIZE_TIME		8
+#define PART_SIZE_JOB_SIZE	8
+#define PART_SIZE_ROOT_ONLY	4
+#define PART_SIZE_SHARE		5
+#define PART_SIZE_GROUPS	20
 
 /********************
  * Global Variables *
  ********************/
 static char *command_name;
 struct sinfo_parameters params =
-    {	partition_flag:false, partition:NULL, state_flag:false,
-	node_flag:false, node:NULL, summarize:false, long_output:false,
+    {	partition:NULL, state_flag:false,
+	node_flag:false, nodes:NULL, summarize:false, long_output:false,
 	line_wrap:false, verbose:false, iterate:0, exact_match:false
 };
 static int node_sz_cpus, node_sz_name, node_sz_mem, node_sz_state;
 static int node_sz_disk, node_sz_part, node_sz_weight, node_sz_features;
+static int node_sz_nodes;
 static int part_sz_num, part_sz_nodes, part_sz_part, part_sz_state;
-static int part_sz_cpus, part_sz_disk, part_sz_mem;
-static const char equal_string[] = 
-    "================================================================================\n";
-static const char dash_line[] =
-    "------------------------------------------------------------------------\n";
-
+static int part_sz_avail, part_sz_time, part_sz_job_nodes;
+static int part_sz_root, part_sz_share, part_size_groups;
+static const char dash_line_20[] = "--------------------";
+static const char dash_line_40[] = "----------------------------------------";
+ 
 /************
  * Funtions *
  ************/
@@ -81,31 +79,37 @@ static int _query_server(partition_info_msg_t ** part_pptr,
 /* Node Functions */
 static void _display_all_nodes(node_info_msg_t * node_msg, int node_rec_cnt);
 static void _display_node_info_header(void);
-static void _display_nodes_list(List nodes);
-static void _display_nodes_list_long(List nodes);
+static void _display_node_info(List nodes);
 static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt);
+static bool _exact_node_match(node_info_t *node1, node_info_t *node2);
 static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt);
-static char *_node_name_string_from_list(List nodes, char *buffer);
-static void _swap_char(char *from, char *to);
+static void _node_cpus_string_from_list(List nodes, char *buffer);
+static void _node_mem_string_from_list(List nodes, char *buffer);
+static void _node_disk_string_from_list(List nodes, char *buffer);
+static void _node_weight_string_from_list(List nodes, char *buffer);
+static char *_node_name_string_from_list(List nodes, char *buffer, 
+					 int *node_count);
+static void _swap_char(char **from, char **to);
 static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node);
 
 /* Partition Functions */
-static void _display_all_partition_info_long(List partitions);
 static void _display_all_partition_summary(partition_info_msg_t * part_ptr,
 					   node_info_msg_t * node_ptr, 
 					   int node_rec_cnt);
-static void _display_partition_info_long(struct partition_summary
-					 *partition);
 static void _display_partition_node_info(struct partition_summary
-					 *partition, bool print_name);
+					 *partition);
+static void _display_all_partition_info(List partitions);
+static void _print_summary_header(void);
+static void _display_partition_node_summary(struct partition_summary 
+					    *partition);
 static void _display_partition_summaries(List partitions);
 
 /* Misc Display functions */
-static int  _build_min_max_string(char *buffer, int max, int min);
+static int  _build_min_max_string(char *buffer, int max, int min, bool range);
 static void _print_date(void);
 static int  _print_int(int number, int width, bool right);
 static int  _print_str(char *number, int width, bool right);
-static void _set_node_field_sizes(void);
+static void _set_node_field_sizes(List nodes);
 static void _set_part_field_sizes(void);
 
 /* Display partition functions */
@@ -115,7 +119,7 @@ static struct node_state_summary *_find_node_state_summary(
 static List _setup_partition_summary(partition_info_msg_t * part_ptr, 
 				     node_info_msg_t * node_ptr, 
 				     int node_rec_cnt);
-static void _print_partition_header(bool no_name);
+static void _print_partition_header(void);
 
 
 int main(int argc, char *argv[])
@@ -140,9 +144,8 @@ int main(int argc, char *argv[])
 
 		_filter_nodes(node_msg, &node_rec_cnt);
 
-		if (params.node_flag)
+		if (params.node_flag && (!params.summarize))
 			_display_all_nodes(node_msg, node_rec_cnt);
-
 		else
 			_display_all_partition_summary(partition_msg,
 						       node_msg, node_rec_cnt);
@@ -216,19 +219,20 @@ static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt)
 	int i, new_rec_cnt = 0;
 	hostlist_t hosts = NULL;
 
-	if ((params.node	== NULL) && 
-	    (params.partition 	== NULL) && 
-	    (!params.state_flag)) {
+	if (((params.nodes == NULL) && 
+	     (params.partition 	== NULL) && 
+	     (!params.state_flag)) ||
+	     params.summarize) {
 		/* Nothing to filter out */
 		*node_rec_cnt = node_msg->record_count;
 		return;
 	}
 
-	if (params.node)
-		hosts = hostlist_create(params.node);
+	if (params.nodes)
+		hosts = hostlist_create(params.nodes);
 
 	for (i = 0; i < node_msg->record_count; i++) {
-		if (params.node && hostlist_find
+		if (params.nodes && hostlist_find
 		      (hosts, node_msg->node_array[i].name) == -1)
 			continue;
 		if (params.partition && strcmp
@@ -251,25 +255,27 @@ static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt)
 	*node_rec_cnt = new_rec_cnt;
 }
 
-static void _swap_char(char *from, char *to) 
+static void _swap_char(char **from, char **to) 
 {
 	char *tmp;
-	tmp  = to;
-	to   = from;
- 	from = tmp;
+	tmp   = *to;
+	*to   = *from;
+ 	*from = tmp;
 }
 
 /* Swap *char values, just overwrite the numbers in moving node info */
 static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node)
 {
-	_swap_char(from_node->name,      to_node->name);
-	_swap_char(from_node->features,  to_node->features);
-	_swap_char(from_node->partition, to_node->partition);
-	to_node->node_state	= from_node->node_state;
-	to_node->cpus		= from_node->cpus;
-	to_node->real_memory	= from_node->real_memory;
-	to_node->tmp_disk	= from_node->tmp_disk;
-	to_node->weight	= from_node->weight;
+	if (from_node != to_node) {
+		_swap_char(&from_node->name,      &to_node->name);
+		_swap_char(&from_node->features,  &to_node->features);
+		_swap_char(&from_node->partition, &to_node->partition);
+		to_node->node_state	= from_node->node_state;
+		to_node->cpus		= from_node->cpus;
+		to_node->real_memory	= from_node->real_memory;
+		to_node->tmp_disk	= from_node->tmp_disk;
+		to_node->weight	= from_node->weight;
+	}
 }
 
 
@@ -279,75 +285,88 @@ static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node)
 
 static void _display_all_nodes(node_info_msg_t * node_msg, int node_rec_cnt)
 {
-	_set_node_field_sizes();
-	_display_node_info_header();
-
-	if (params.long_output == true) {
-		List nodes = list_create(NULL);
-		int i;
-
-		for (i = 0; i < node_rec_cnt; i++)
-			list_append(nodes, &node_msg->node_array[i]);
+	List nodes = _group_node_list(node_msg, node_rec_cnt);
+	ListIterator i = list_iterator_create(nodes);
+	List current;
 
-		_display_nodes_list_long(nodes);
-		list_destroy(nodes);
-	} else {
-		List nodes = _group_node_list(node_msg, node_rec_cnt);
-		ListIterator i = list_iterator_create(nodes);
-		List current;
+	_set_node_field_sizes(nodes);
+	_display_node_info_header();
 
-		while ((current = list_next(i)) != NULL) {
-			_display_nodes_list(current);
-			list_destroy(current);
-		}
-		list_iterator_destroy(i);
-		list_destroy(nodes);
+	while ((current = list_next(i)) != NULL) {
+		_display_node_info(current);
+		list_destroy(current);
 	}
+	list_iterator_destroy(i);
+	list_destroy(nodes);
 }
 
-static void _set_node_field_sizes(void)
+static void _set_node_field_sizes(List nodes)
 {
+	int node_cnt, len;
+	char node_names[64];
+	List current;
+	ListIterator i = list_iterator_create(nodes);
+
 	node_sz_features  = NODE_SIZE_FEATURES;
-	node_sz_name      = NODE_SIZE_NAME;
 	node_sz_part      = NODE_SIZE_PART;
 	node_sz_weight    = NODE_SIZE_WEIGHT;
-	if (params.long_output) {
-		node_sz_cpus	= NODE_SIZE_CPUS_LONG;
-		node_sz_disk	= NODE_SIZE_DISK_LONG;
-		node_sz_mem	= NODE_SIZE_MEM_LONG;
+	node_sz_cpus	  = NODE_SIZE_CPUS;
+	node_sz_disk	  = NODE_SIZE_DISK;
+	node_sz_mem	  = NODE_SIZE_MEM;
+	node_sz_nodes     = NODE_SIZE_NODES;
+	if (params.long_output)
 		node_sz_state	= NODE_SIZE_STATE_LONG;
-	} else {
-		node_sz_cpus	= NODE_SIZE_CPUS;
-		node_sz_disk	= NODE_SIZE_DISK;
-		node_sz_mem	= NODE_SIZE_MEM;
+	else
 		node_sz_state	= NODE_SIZE_STATE;
+
+	node_sz_name      = NODE_SIZE_NAME;
+	while ((current = list_next(i)) != NULL) {
+		_node_name_string_from_list(current, node_names, &node_cnt);
+		len = strlen(node_names);
+		if (len > node_sz_name)
+			node_sz_name = len;
 	}
+	list_iterator_destroy(i);
 }
 
 static void _display_node_info_header()
 {
-	_print_str("NODES", node_sz_name, false);
-	printf(" ");
-	_print_str("STATE", node_sz_state, false);
-	printf(" ");
-	_print_str("CPUS", node_sz_cpus, true);
-	printf(" ");
-	_print_str("MEMORY", node_sz_mem, true);
+	_print_str("NODE_LIST", node_sz_name, false);
 	printf(" ");
-	_print_str("TMP_DISK", node_sz_disk, true);
-	printf(" ");
-	_print_str("WEIGHT", node_sz_weight, true);
+	_print_str("NODES", node_sz_nodes, false);
 	printf(" ");
 	_print_str("PARTITION", node_sz_part, false);
 	printf(" ");
-	_print_str("FEATURES", node_sz_features, false);
-	printf("\n");
-	printf(dash_line);
+	_print_str("STATE", node_sz_state, false);
+
+	if (params.long_output) {
+		printf(" ");
+		_print_str("CPUS", node_sz_cpus, true);
+		printf(" ");
+		_print_str("MEMORY", node_sz_mem, true);
+		printf(" ");
+		_print_str("TMP_DISK", node_sz_disk, true);
+		printf(" ");
+		_print_str("WEIGHT", node_sz_weight, true);
+		printf(" ");
+		_print_str("FEATURES", node_sz_features, false);
+	}
+	printf("\n%s%s\n", dash_line_40, dash_line_40);
+
 }
 
-static void _display_node_info(node_info_t * node, char *name)
+static void _display_node_info(List nodes)
 {
-	_print_str(name, node_sz_name, false);
+	char node_names[64];
+	int node_cnt;
+	node_info_t *node = list_peek(nodes);
+
+	_node_name_string_from_list(nodes, node_names, &node_cnt);
+	_print_str(node_names, node_sz_name, false);
+	printf(" ");
+	_print_int(node_cnt, node_sz_nodes, true);
+	printf(" ");
+	_print_str(node->partition, node_sz_part, false);
 	printf(" ");
 	if (params.long_output)
 		_print_str(node_state_string(node->node_state), 
@@ -355,49 +374,36 @@ static void _display_node_info(node_info_t * node, char *name)
 	else
 		_print_str(node_state_string_compact(node->node_state), 
 			   node_sz_state, false);
-	printf(" ");
-	_print_int(node->cpus, node_sz_cpus, true);
-	printf(" ");
-	_print_int(node->real_memory, node_sz_mem, true);
-	printf(" ");
-	_print_int(node->tmp_disk, node_sz_disk, true);
-	printf(" ");
-	_print_int(node->weight, node_sz_weight, true);
-	printf(" ");
-	_print_str(node->partition, node_sz_part, false);
-	printf(" ");
-	_print_str(node->features, node_sz_features, false);
-	printf("\n");
-}
-
-static void _display_nodes_list(List nodes)
-{
-	/*int console_width = atoi( getenv( "COLUMNS" ) ); */
-	char node_names[32];
-	node_info_t *curr = list_peek(nodes);
-	_node_name_string_from_list(nodes, node_names);
 
-	_display_node_info(curr, node_names);
-}
+	if (params.long_output) {
+		int tmp_feature_size;
+		char str_buf[64];
 
-static void _display_nodes_list_long(List nodes)
-{
-	/*int console_width = atoi( getenv( "COLUMNS" ) ); */
-	int count = 0;
-	ListIterator i = list_iterator_create(nodes);
-	node_info_t *curr = NULL;
+		printf(" ");
+		_node_cpus_string_from_list(nodes, str_buf);
+		_print_str(str_buf, node_sz_cpus, true);
+		printf(" ");
+		_node_mem_string_from_list(nodes, str_buf);
+		_print_str(str_buf, node_sz_mem, true);
+		printf(" ");
+		_node_disk_string_from_list(nodes, str_buf);
+		_print_str(str_buf, node_sz_disk, true);
+		printf(" ");
+		_node_weight_string_from_list(nodes, str_buf);
+		_print_str(str_buf, node_sz_weight, true);
 
-	while ((curr = list_next(i)) != NULL) {
-		if (params.partition != NULL
-		    && strcmp(params.partition, curr->partition))
-			continue;
-		_display_node_info(curr, curr->name);
-		count++;
+		printf(" ");
+		tmp_feature_size = node_sz_features;
+		if (node->features && 
+		    (strlen(node->features) > tmp_feature_size))
+			tmp_feature_size = 0;
+		_print_str(node->features, tmp_feature_size, false);
 	}
-	printf("-- %8d NODES LISTED --\n\n", count);
 
+	printf("\n");
 }
 
+
 /* group similar nodes together, return a list of lists containing nodes 
  * with similar configurations */
 static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt)
@@ -413,36 +419,18 @@ static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt)
 		list_i = list_iterator_create(node_lists);
 		while ((curr_list = list_next(list_i)) != NULL) {
 			node_info_t *curr = list_peek(curr_list);
-			bool feature_test;
-			bool part_test;
-
-			if (curr->features != NULL
-			    && nodes[i].features != NULL)
-				feature_test =
-				    strcmp(nodes[i].features,
-					   curr->features) ? false : true;
-			else if (curr->features == nodes[i].features)
-				feature_test = true;
-			else
-				feature_test = false;
-			if (curr->partition != NULL
-			    && nodes[i].partition != NULL)
-				part_test =
-				    strcmp(nodes[i].partition,
-					   curr->partition) ? false : true;
-			else if (curr->partition == nodes[i].partition)
-				part_test = true;
-			else
-				part_test = false;
-
-			if (feature_test && part_test &&
-			    nodes[i].node_state  == curr->node_state &&
-			    nodes[i].cpus        == curr->cpus &&
-			    nodes[i].real_memory == curr->real_memory &&
-			    nodes[i].tmp_disk    == curr->tmp_disk) {
-				list_append(curr_list, &(nodes[i]));
-				break;
-			}
+
+			if ((curr->partition    != NULL) &&
+			    (nodes[i].partition != NULL) && 
+			    (strcmp(nodes[i].partition, 
+				    curr->partition) != 0))
+				continue;
+
+			if (!_exact_node_match(curr, &nodes[i]))
+				continue;
+
+			list_append(curr_list, &(nodes[i]));
+			break;
 		}
 		list_iterator_destroy(list_i);
 
@@ -456,6 +444,28 @@ static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt)
 	return node_lists;
 }
 
+/* Return true if all of the nodes' configurations match */
+static bool _exact_node_match(node_info_t *node1, node_info_t *node2)
+{
+	if (node1->node_state  != node2->node_state)
+		return false;
+	else if ((!params.exact_match) || (!params.long_output))
+		return true;
+
+	if (node1->features && node2->features &&
+	    strcmp(node1->features, node2->features))
+		return false;
+	else if (node1->features != node2->features)
+		return false;
+
+	if ((node1->cpus        != node2->cpus)        ||
+	    (node1->real_memory != node2->real_memory) ||
+	    (node1->tmp_disk    != node2->tmp_disk))
+		return false;
+	else
+		return true;
+}
+
 /*****************************************************************************
  *                     DISPLAY PARTITION INFO FUNCTIONS
  *****************************************************************************/
@@ -478,6 +488,9 @@ static struct partition_summary *_find_partition_summary(List l, char *name)
 	return current;
 }
 
+/* Return a pointer to the node in the supplied list that contains 
+ * the same configuration (just node_state at present). If none 
+ * found then return NULL */
 static struct node_state_summary *
 _find_node_state_summary(List l, node_info_t *ninfo)
 {
@@ -485,13 +498,8 @@ _find_node_state_summary(List l, node_info_t *ninfo)
 	struct node_state_summary *current;
 
 	while ((current = list_next(i)) != NULL) {
-		if (ninfo->node_state != current->state)
-			continue;
-		if (params.exact_match == 0)
-			break;
-		if ((ninfo->cpus        == current->cpu_min) &&
-		    (ninfo->real_memory == current->ram_min) &&
-		    (ninfo->tmp_disk    == current->disk_min))
+		if ((params.summarize) ||
+		    (ninfo->node_state == current->state))
 			break;
 	}
 
@@ -499,9 +507,12 @@ _find_node_state_summary(List l, node_info_t *ninfo)
 	return current;
 }
 
+/* Construct a list of partitions containing the configuration 
+ * of that partition along with configuration about the nodes 
+ * in that partition */
 static List
 _setup_partition_summary(partition_info_msg_t * part_ptr,
-			node_info_msg_t * node_ptr, int node_rec_cnt)
+			 node_info_msg_t * node_ptr, int node_rec_cnt)
 {
 	int i = 0;
 	List partitions = list_create(NULL);
@@ -524,7 +535,8 @@ _setup_partition_summary(partition_info_msg_t * part_ptr,
 
 		if (ninfo->partition == NULL) {
 			if (params.verbose)
-				printf("Node %s is not in any partition\n\n", 
+				fprintf(stderr, 
+					"Node %s is not in any partition\n\n", 
 					ninfo->name);
 			continue;
 		}
@@ -532,28 +544,15 @@ _setup_partition_summary(partition_info_msg_t * part_ptr,
 						   ninfo->partition);
 		if (part_sum == NULL) {
 			/* This should never happen */
-			printf
-			    ("Couldn't find partition %s, notify system administators\n",
-			     ninfo->partition);
+			fprintf(stderr, "Couldn't find partition %s", 
+				ninfo->partition);
+			fprintf(stderr,"Please notify system administators\n");
 			continue;
 		}
 
-		if ((node_sum = 
-		     _find_node_state_summary(part_sum->states, ninfo))) {
-			node_sum->state =
-			    (enum node_states) ninfo->node_state;
-			node_sum->cpu_max =
-			    MAX(ninfo->cpus, node_sum->cpu_max);
-			node_sum->cpu_min =
-			    MIN(ninfo->cpus, node_sum->cpu_min);
-			node_sum->ram_max =
-			    MAX(ninfo->real_memory, node_sum->ram_max);
-			node_sum->ram_min =
-			    MIN(ninfo->real_memory, node_sum->ram_min);
-			node_sum->disk_max =
-			    MAX(ninfo->tmp_disk, node_sum->disk_max);
-			node_sum->disk_min =
-			    MIN(ninfo->tmp_disk, node_sum->disk_min);
+		if ((node_sum = _find_node_state_summary(part_sum->states, 
+							 ninfo))) {
+			node_sum->state = (enum node_states) ninfo->node_state;
 			hostlist_push(node_sum->nodes, ninfo->name);
 			node_sum->node_count++;
 		} else {
@@ -561,12 +560,6 @@ _setup_partition_summary(partition_info_msg_t * part_ptr,
 			    malloc(sizeof(struct node_state_summary));
 			node_sum->state =
 			    (enum node_states) ninfo->node_state;
-			node_sum->cpu_max = ninfo->cpus;
-			node_sum->cpu_min = ninfo->cpus;
-			node_sum->ram_max = ninfo->real_memory;
-			node_sum->ram_min = ninfo->real_memory;
-			node_sum->disk_max = ninfo->tmp_disk;
-			node_sum->disk_min = ninfo->tmp_disk;
 			node_sum->node_count = 1;
 			node_sum->nodes = hostlist_create(ninfo->name);
 			list_append(part_sum->states, node_sum);
@@ -583,10 +576,10 @@ _display_all_partition_summary(partition_info_msg_t * part_ptr,
 	List partitions = _setup_partition_summary(part_ptr, 
 						   node_ptr, node_rec_cnt);
 	_set_part_field_sizes();
-	if (params.long_output)
-		_display_all_partition_info_long(partitions);
-	else
+	if (params.summarize)
 		_display_partition_summaries(partitions);
+	else
+		_display_all_partition_info(partitions);
 	list_destroy(partitions);
 }
 
@@ -595,94 +588,177 @@ static void _set_part_field_sizes(void)
 	part_sz_part  = PART_SIZE_PART;
 	part_sz_num   = PART_SIZE_NUM;
 	part_sz_nodes = PART_SIZE_NODES;
-	if (params.long_output) {
-		part_sz_cpus	= PART_SIZE_CPUS_LONG;
-		part_sz_disk	= PART_SIZE_DISK_LONG;
-		part_sz_mem	= PART_SIZE_MEM_LONG;
+	if (params.long_output)
 		part_sz_state	= PART_SIZE_STATE_LONG;
-	} else {
-		part_sz_cpus	= PART_SIZE_CPUS;
-		part_sz_disk	= PART_SIZE_DISK;
-		part_sz_mem	= PART_SIZE_MEM;
+	else
 		part_sz_state	= PART_SIZE_STATE;
-	}
+	part_sz_avail		= PART_SIZE_AVAIL;
+	part_sz_time		= PART_SIZE_TIME;
+	part_sz_job_nodes	= PART_SIZE_JOB_SIZE;
+	part_sz_root		= PART_SIZE_ROOT_ONLY;
+	part_sz_share		= PART_SIZE_SHARE;
+	part_size_groups	= PART_SIZE_GROUPS;
 }
 
 /* Formating for partiton display headers... */
-static void _print_partition_header(bool no_name)
+static void _print_summary_header(void)
 {
-	if (no_name == true)
-		printf("\t");
-	else {
-		_print_str("PARTITION", part_sz_part, false);
-		printf(" ");
-	}
+	_print_str("PARTITION", part_sz_part, false);
+	printf(" ");
+	_print_str("AVAIL", part_sz_avail, false);
+	printf(" ");
 	_print_str("NODES", part_sz_num, true);
 	printf(" ");
-	_print_str("STATE", part_sz_state, false);
+	_print_str("NODE_LIST", part_sz_nodes, false);
+	printf("\n%s%s\n", dash_line_40, dash_line_20);
+}
+
+static void
+_display_partition_node_summary(struct partition_summary *partition)
+{
+	int  line_cnt = 0;
+	char name_buf[64], part_name[64];
+
+	ListIterator node_i = list_iterator_create(partition->states);
+	struct node_state_summary *state_sum = NULL;
+
+	strcpy(part_name, partition->info->name);
+	if (partition->info->default_part)
+		strcat(part_name, "*");
+
+	while ((state_sum = list_next(node_i)) != NULL) {
+		line_cnt++;
+		hostlist_ranged_string(state_sum->nodes, 64, name_buf);
+		_print_str(part_name, part_sz_part, false);
+		printf(" ");
+		_print_str(partition->info->state_up ? "UP" : "DOWN", 
+			   part_sz_avail, false);
+		printf(" ");
+		_print_int(state_sum->node_count, part_sz_num, true);
+		printf(" ");
+		_print_str(name_buf, part_sz_nodes, false);
+		printf("\n");
+	}
+	list_iterator_destroy(node_i);
+
+	if (line_cnt == 0) {
+		_print_str(part_name, part_sz_part, false);
+		printf(" ");
+		_print_str(partition->info->state_up ? "UP" : "DOWN", 
+			   part_sz_avail, false);
+		printf(" ");
+		_print_int(0, part_sz_num, true);
+		printf("\n");
+	}
+}
+
+static void _display_partition_summaries(List partitions)
+{
+	struct partition_summary *partition;
+	ListIterator part_i = list_iterator_create(partitions);
+
+	_print_summary_header();
+	while ((partition = list_next(part_i)) != NULL) {
+		if (params.partition == NULL
+		    || strcmp(partition->info->name,
+			      params.partition) == 0)
+			_display_partition_node_summary(partition);
+	}
+	list_iterator_destroy(part_i);
+}
+
+
+/* Formating for partiton display headers... */
+static void _print_partition_header(void)
+{
+	_print_str("PARTITION", part_sz_part, false);
 	printf(" ");
-	_print_str("CPUS", part_sz_cpus, true);
+	_print_str("AVAIL", part_sz_avail, false);
 	printf(" ");
-	_print_str("MEMORY", part_sz_mem, true);
+	_print_str("NODES", part_sz_num, true);
 	printf(" ");
-	_print_str("TMP_DISK", part_sz_disk, true);
+	_print_str("STATE", part_sz_state, false);
+	if (params.long_output) {
+		printf(" ");
+		_print_str("MAX_TIME", part_sz_time, true);
+		printf(" ");
+		_print_str("JOB_SIZE", part_sz_job_nodes, true);
+		printf(" ");
+		_print_str("ROOT", part_sz_root, false);
+		printf(" ");
+		_print_str("SHARE", part_sz_share, false);
+		printf(" ");
+		_print_str("GROUPS", part_size_groups, false);
+	}
 	printf(" ");
-	_print_str("NODES", part_sz_nodes, false);
-	printf("\n");
-	if (no_name == true)
-		printf("\t%s", dash_line);
+	_print_str("NODE_LIST", part_sz_nodes, false);
+	if (params.long_output)
+		printf("\n%s%s%s\n", dash_line_40, dash_line_40, dash_line_20);
 	else
-		printf("%s", dash_line);
+		printf("\n%s%s\n", dash_line_40, dash_line_40);
 }
 
-static void _display_partition_summaries(List partitions)
+static void _display_all_partition_info(List partitions)
 {
 	struct partition_summary *partition;
 	ListIterator part_i = list_iterator_create(partitions);
 
-	_print_partition_header(false);
+	_print_partition_header();
 	while ((partition = list_next(part_i)) != NULL) {
 		if (params.partition == NULL
 		    || strcmp(partition->info->name,
 			      params.partition) == 0)
-			_display_partition_node_info(partition, true);
+			_display_partition_node_info(partition);
 	}
 	list_iterator_destroy(part_i);
 }
 
 
 static void
-_display_partition_node_info(struct partition_summary *partition,
-			     bool print_name)
+_display_partition_node_info(struct partition_summary *partition)
 {
 	char *no_name = "";
-	char cpu_buf[64];
-	char ram_buf[64];
-	char disk_buf[64];
-	char name_buf[64];
+	char name_buf[64], part_name[64], part_time[20], part_job_size[30];
+	char part_root[10], part_share[10], *part_groups;
 	int  line_cnt = 0;
 
-
 	ListIterator node_i = list_iterator_create(partition->states);
 	struct node_state_summary *state_sum = NULL;
-	char *part_name = partition->info->name;
+	char *part_state = partition->info->state_up ? "UP" : "DOWN";
+
+	strcpy(part_name, partition->info->name);
+	if (partition->info->default_part)
+		strcat(part_name, "*");
+	if (partition->info->max_time == -1)
+		strcpy(part_time, "NONE");
+	else
+		sprintf(part_time, "%d", partition->info->max_time);
+	(void) _build_min_max_string(part_job_size, 
+				     partition->info->min_nodes, 
+				     partition->info->max_nodes, true);
+	if (partition->info->root_only)
+		strcpy(part_root, "YES");
+	else
+		strcpy(part_root, "NO");
+	if (partition->info->shared == 2)
+		strcpy(part_share, "FORCE");
+	else if(partition->info->shared)
+		strcpy(part_share, "YES");
+	else
+		strcpy(part_share, "NO");
+	if (partition->info->allow_groups)
+		part_groups = partition->info->allow_groups;
+	else 
+		part_groups = "ALL";
 
 	while ((state_sum = list_next(node_i)) != NULL) {
 		line_cnt++;
-		_build_min_max_string(ram_buf, state_sum->ram_min,
-				      state_sum->ram_max);
-		_build_min_max_string(disk_buf, state_sum->disk_min,
-				      state_sum->disk_max);
-		_build_min_max_string(cpu_buf, state_sum->cpu_min,
-				      state_sum->cpu_max);
 		hostlist_ranged_string(state_sum->nodes, 64, name_buf);
 
-		if (print_name == true) {
-			_print_str(part_name, part_sz_part, false);
-			printf(" ");
-		} else
-			printf("\t");
-
+		_print_str(part_name, part_sz_part, false);
+		printf(" ");
+		_print_str(part_state, part_sz_avail, false);
+		printf(" ");
 		_print_int(state_sum->node_count, part_sz_num, true);
 		printf(" ");
 		if (params.long_output)
@@ -691,90 +767,62 @@ _display_partition_node_info(struct partition_summary *partition,
 		else
 			_print_str(node_state_string_compact(state_sum->state),
 				   part_sz_state, false);
-		printf(" ");
-		_print_str(cpu_buf, part_sz_cpus, true);
-		printf(" ");
-		_print_str(ram_buf, part_sz_mem, true);
-		printf(" ");
-		_print_str(disk_buf, part_sz_disk, true);
+		if (params.long_output) {
+			printf(" ");
+			_print_str(part_time, part_sz_time, true);
+			printf(" ");
+			_print_str(part_job_size, part_sz_job_nodes, true);
+			printf(" ");
+			_print_str(part_root, part_sz_root, false);
+			printf(" ");
+			_print_str(part_share, part_sz_share, false);
+			printf(" ");
+			_print_str(part_groups, part_size_groups, false);
+		}
 		printf(" ");
 		_print_str(name_buf, part_sz_nodes, false);
 		printf("\n");
-		part_name = no_name;
+		strcpy(part_name,	"");
+		strcpy(part_time,	"");
+		strcpy(part_job_size,	"");
+		strcpy(part_root,	"");
+		strcpy(part_share,	"");
+		part_state  = no_name;
+		part_groups = no_name;
 	}
 	list_iterator_destroy(node_i);
 
 	if (line_cnt == 0) {
-		if (print_name == true) {
-			_print_str(part_name, part_sz_part, false);
-			printf(" ");
-		} else
-			printf("\t");
-		_print_int(0, part_sz_num, true);
+		_print_str(part_name, part_sz_part, false);
 		printf(" ");
-		_print_str("N/A", part_sz_state, false);
-		printf(" ");
-		_print_str("0", part_sz_cpus, true);
+		_print_str(part_state, part_sz_avail, false);
 		printf(" ");
-		_print_str("0", part_sz_mem, true);
+		_print_int(0, part_sz_num, true);
 		printf(" ");
-		_print_str("0", part_sz_disk, true);
+		_print_str("N/A", part_sz_state, false);
+		if (params.long_output) {
+			printf(" ");
+			_print_str(part_time, part_sz_time, true);
+			printf(" ");
+			_print_str(part_job_size, part_sz_job_nodes, true);
+			printf(" ");
+			_print_str(part_root, part_sz_root, false);
+			printf(" ");
+			_print_str(part_share, part_sz_share, false);
+			printf(" ");
+			_print_str(part_groups, part_size_groups, false);
+		}
 		printf(" ");
 		_print_str("", part_sz_nodes, false);
 		printf("\n");
 	}
 }
 
-static void _display_all_partition_info_long(List partitions)
-{
-	struct partition_summary *partition;
-	ListIterator part_i = list_iterator_create(partitions);
-
-	printf("PARTITION INFORMATION\n");
-	while ((partition = list_next(part_i)) != NULL) {
-		if (params.partition == NULL
-		    || strcmp(partition->info->name,
-			      params.partition) == 0)
-			_display_partition_info_long(partition);
-		printf("\n");
-	}
-	printf("%s", equal_string);
-	list_iterator_destroy(part_i);
-}
-
-void _display_partition_info_long(struct partition_summary *partition)
-{
-	partition_info_t *part = partition->info;
-
-	printf("%s", equal_string);
-	printf("%s\n", part->name);
-	printf("\tcurrent state     = %s\n",
-	       part->state_up ? "UP" : "DOWN");
-	printf("\tdefault partition = %s\n",
-	       part->default_part ? "YES" : "NO");
-	printf("\ttotal nodes       = %d\n", part->total_nodes);
-	printf("\ttotal cpus        = %d\n", part->total_cpus);
-	if (part->max_time == -1)
-		printf("\tmax jobtime       = NONE\n");
-	else
-		printf("\tmax jobtime       = %d\n", part->max_time);
-	printf("\tmax nodes/job     = %d\n", part->max_nodes);
-	printf("\troot only         = %s\n",
-	       part->root_only ? "YES" : "NO");
-	printf("\tshare nodes       = %s\n",
-	       part->shared == 2 ? "ALWAYS" : part->shared ? "YES" : "NO");
-
-	printf("\n");
-	_print_partition_header(true);
-	_display_partition_node_info(partition, false);
-
-}
-
-static int _build_min_max_string(char *buffer, int min, int max)
+static int _build_min_max_string(char *buffer, int min, int max, bool range)
 {
 	if (max == min)
 		return sprintf(buffer, "%d", max);
-	else if (params.long_output)
+	else if (range)
 		return sprintf(buffer, "%d-%d", min, max);
 	else
 		return sprintf(buffer, "%d+", min);
@@ -827,20 +875,140 @@ static void _print_date(void)
  *	prefix[001-100] type format.
  * IN nodes - list of node_info_t* to analyze
  * OUT buffer - a char buffer to store the string in.
+ * OUT node_count - count of nodes found
  * RET on success return buffer, NULL on failure
  */
-
-static char *_node_name_string_from_list(List nodes, char *buffer)
+static char *_node_name_string_from_list(List nodes, char *buffer,
+					 int *node_count)
 {
 	node_info_t *curr_node = NULL;
 	ListIterator i = list_iterator_create(nodes);
 	hostlist_t list = hostlist_create(NULL);
 
-	while ((curr_node = list_next(i)) != NULL)
+	*node_count = 0;
+	while ((curr_node = list_next(i)) != NULL) {
 		hostlist_push(list, curr_node->name);
+		(*node_count)++;
+	}
 	list_iterator_destroy(i);
 
 	hostlist_ranged_string(list, 32, buffer);
 	hostlist_destroy(list);
 	return buffer;
 }
+
+/* _node_cpus_string_from_list - analyzes a list of node_info_t* and 
+ * 	fills in a buffer with CPU count, "123+" if a range.
+ * IN nodes - list of node_info_t* to analyze
+ * OUT buffer - a char buffer to store the string in.
+ */
+static void _node_cpus_string_from_list(List nodes, char *buffer)
+{
+	node_info_t *curr_node = NULL;
+	int min_cpus=0, max_cpus=0;
+	bool first = true;
+	ListIterator i = list_iterator_create(nodes);
+
+	while ((curr_node = list_next(i)) != NULL) {
+		if (first) {
+			first = false;
+			min_cpus = max_cpus = curr_node->cpus;
+		} 
+		else if (min_cpus > curr_node->cpus)
+			min_cpus = curr_node->cpus;
+		else if (max_cpus < curr_node->cpus)
+			max_cpus = curr_node->cpus;
+	}
+	list_iterator_destroy(i);
+	if (first)
+		strcpy(buffer, "");
+	else
+		_build_min_max_string(buffer, min_cpus, max_cpus, false);
+}
+
+/* _node_mem_string_from_list - analyzes a list of node_info_t* and 
+ * 	fills in a buffer with real memory size, "123+" if a range.
+ * IN nodes - list of node_info_t* to analyze
+ * OUT buffer - a char buffer to store the string in.
+ */
+static void _node_mem_string_from_list(List nodes, char *buffer)
+{
+	node_info_t *curr_node = NULL;
+	int min_mem=0, max_mem=0;
+	bool first = true;
+	ListIterator i = list_iterator_create(nodes);
+
+	while ((curr_node = list_next(i)) != NULL) {
+		if (first) {
+			first = false;
+			min_mem = max_mem = curr_node->real_memory;
+		} 
+		else if (min_mem > curr_node->real_memory)
+			min_mem = curr_node->real_memory;
+		else if (max_mem < curr_node->real_memory)
+			max_mem = curr_node->real_memory;
+	}
+	list_iterator_destroy(i);
+	if (first)
+		strcpy(buffer, "");
+	else
+		_build_min_max_string(buffer, min_mem, max_mem, false);
+}
+
+/* _node_disk_string_from_list - analyzes a list of node_info_t* and 
+ * 	fills in a buffer with temporary disk size, "123+" if a range.
+ * IN nodes - list of node_info_t* to analyze
+ * OUT buffer - a char buffer to store the string in.
+ */
+static void _node_disk_string_from_list(List nodes, char *buffer)
+{
+	node_info_t *curr_node = NULL;
+	int min_disk=0, max_disk=0;
+	bool first = true;
+	ListIterator i = list_iterator_create(nodes);
+
+	while ((curr_node = list_next(i)) != NULL) {
+		if (first) {
+			first = false;
+			min_disk = max_disk = curr_node->tmp_disk;
+		} 
+		else if (min_disk > curr_node->tmp_disk)
+			min_disk = curr_node->tmp_disk;
+		else if (max_disk < curr_node->tmp_disk)
+			max_disk = curr_node->tmp_disk;
+	}
+	list_iterator_destroy(i);
+	if (first)
+		strcpy(buffer, "");
+	else
+		_build_min_max_string(buffer, min_disk, max_disk, false);
+}
+
+/* _node_weight_string_from_list - analyzes a list of node_info_t* and 
+ * 	fills in a buffer with their weights, "123+" if a range.
+ * IN nodes - list of node_info_t* to analyze
+ * OUT buffer - a char buffer to store the string in.
+ */
+static void _node_weight_string_from_list(List nodes, char *buffer)
+{
+	node_info_t *curr_node = NULL;
+	int min_weight=0, max_weight=0;
+	bool first = true;
+	ListIterator i = list_iterator_create(nodes);
+
+	while ((curr_node = list_next(i)) != NULL) {
+		if (first) {
+			first = false;
+			min_weight = max_weight = curr_node->weight;
+		} 
+		else if (min_weight > curr_node->weight)
+			min_weight = curr_node->weight;
+		else if (min_weight < curr_node->weight)
+			max_weight = curr_node->weight;
+	}
+	list_iterator_destroy(i);
+	if (first)
+		strcpy(buffer, "");
+	else
+		_build_min_max_string(buffer, min_weight, max_weight, false);
+}
diff --git a/src/sinfo/sinfo.h b/src/sinfo/sinfo.h
index a94992ae8bf56bb447d91abde192bfe882ad1753..33da21faf05b859302b787d6caa7230152acb69c 100644
--- a/src/sinfo/sinfo.h
+++ b/src/sinfo/sinfo.h
@@ -57,12 +57,11 @@
 #define MIN(x,y) (((x)<(y))?(x):(y))
 
 struct sinfo_parameters {
-	bool partition_flag;
 	char* partition;
 	bool state_flag;
 	enum node_states state;
 	bool node_flag;
-	char* node;
+	char* nodes;
 	bool summarize;
 	bool long_output;
 	bool line_wrap;
@@ -75,12 +74,6 @@ struct node_state_summary {
 	hostlist_t nodes;
 	enum node_states state;
 	uint32_t node_count;
-	uint32_t cpu_min;
-	uint32_t cpu_max;
-	uint32_t ram_min;
-	uint32_t ram_max;
-	uint32_t disk_min;
-	uint32_t disk_max;
 };
 
 struct partition_summary {