docs: def do_list_modules(self, long_output=None,sort_order=None):
  		"""Display a list of loaded modules.
  
  		Config items:
  			- shutit.list_modules['long']
  			  If set, also print each module's run order value
  
  			- shutit.list_modules['sort']
  			  Select the column by which the list is ordered:
  				- id: sort the list by module id
  				- run_order: sort the list by module run order
  
  		The output is also saved to ['build']['log_config_path']/module_order.txt
  
  		Dependencies: operator
  		"""
  		shutit_global.shutit_global_object.yield_to_draw()
  		cfg = self.cfg
  		# list of module ids and other details
  		# will also contain column headers
  		table_list = []
  		if long_output is None:
  			long_output = self.list_modules['long']
  		if sort_order is None:
  			sort_order = self.list_modules['sort']
  		if long_output:
  			# --long table: sort modules by run order
  			table_list.append(["Order","Module ID","Description","Run Order","Built","Compatible"])
  			#table_list.append(["Order","Module ID","Description","Run Order","Built"])
  		else:
  			# "short" table ==> sort module by module_id
  			#table_list.append(["Module ID","Description","Built"])
  			table_list.append(["Module ID","Description","Built","Compatible"])
  
  		if sort_order == 'run_order':
  			d = {}
  			for m in self.shutit_modules:
  				d.update({m.module_id:m.run_order})
  			# sort dict by run_order; see http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value
  			b = sorted(d.items(), key=operator.itemgetter(1))
  			count = 0
  			# now b is a list of tuples (module_id, run_order)
  			for pair in b:
  				# module_id is the first item of the tuple
  				k = pair[0]
  				for m in self.shutit_modules:
  					if m.module_id == k:
  						count += 1
  						compatible = True
  						if not cfg[m.module_id]['shutit.core.module.build']:
  							cfg[m.module_id]['shutit.core.module.build'] = True
  							compatible = self.determine_compatibility(m.module_id) == 0
  							cfg[m.module_id]['shutit.core.module.build'] = False
  						if long_output:
  							table_list.append([str(count),m.module_id,m.description,str(m.run_order),str(cfg[m.module_id]['shutit.core.module.build']),str(compatible)])
  							#table_list.append([str(count),m.module_id,m.description,str(m.run_order),str(cfg[m.module_id]['shutit.core.module.build'])])
  						else:
  							table_list.append([m.module_id,m.description,str(cfg[m.module_id]['shutit.core.module.build']),str(compatible)])
  		elif sort_order == 'id':
  			l = []
  			for m in self.shutit_modules:
  				l.append(m.module_id)
  			l.sort()
  			for k in l:
  				for m in self.shutit_modules:
  					if m.module_id == k:
  						count = 1
  						compatible = True
  						if not cfg[m.module_id]['shutit.core.module.build']:
  							cfg[m.module_id]['shutit.core.module.build'] = True
  							compatible = self.determine_compatibility(m.module_id) == 0
  						if long_output:
  							table_list.append([str(count),m.module_id,m.description,str(m.run_order),str(cfg[m.module_id]['shutit.core.module.build']),str(compatible)])
  							#table_list.append([str(count),m.module_id,m.description,str(m.run_order),str(cfg[m.module_id]['shutit.core.module.build'])])
  						else:
  							#table_list.append([m.module_id,m.description,str(cfg[m.module_id]['shutit.core.module.build'])])
  							table_list.append([m.module_id,m.description,str(cfg[m.module_id]['shutit.core.module.build']),str(compatible)])
  
  		# format table for display
  		table = texttable.Texttable()
  		table.add_rows(table_list)
  		# Base length of table on length of strings
  		colwidths = []
  		for item in table_list:
  			for n in range(0,len(item)):
  				# default to 10 chars
  				colwidths.append(10)
  			break
  		for item in table_list:
  			for n in range(0,len(item)-1):
  				if len(str(item[n])) > colwidths[n]:
  					colwidths[n] = len(str(item[n]))
  		table.set_cols_width(colwidths)
  		msg = table.draw()
  		shutit_global.shutit_global_object.shutit_print('\n' + msg)