public String listSpace(MOB mob, List<String> commands)
	{
		final Session viewerS=mob.session();
		if(viewerS==null)
			return "";
		StringBuilder str=new StringBuilder("");
		String listWhat=commands.get(0).toString().toUpperCase().trim();
		Filterer<SpaceObject> filter=null;
		for(final SpaceFilterCode code : SpaceFilterCode.values())
		{
			if(code.toString().toUpperCase().startsWith(listWhat))
			{
				filter=new Filterer<SpaceObject>()
				{
					@Override
					public boolean passesFilter(SpaceObject obj)
					{
						switch(code)
						{
						case SPACE:
							return true;
						case BODIES:
							return (obj instanceof Area) 
								&& (!(obj instanceof SpaceShip)) 
								&& (obj.radius() > (SpaceObject.Distance.MoonRadius.dm + 10000L));
						case SHIPS:
							return (obj instanceof SpaceShip);
						case STARS:
							return (obj instanceof Physical) 
								&& (!(obj instanceof SpaceShip)) 
								&& CMLib.flags().isOnFire((Physical) obj);
						case MOONS:
							return (obj instanceof Area) 
								&& (!(obj instanceof SpaceShip)) 
								&& (obj.radius() <= (SpaceObject.Distance.MoonRadius.dm + 10000L));
						}
						return false;
					}
				};
				break;
			}
		}
		
		if((commands.size()<=1)
		||(filter==null)
		||commands.get(1).toString().equals("?")
		||commands.get(1).toString().equals(L("help")))
		{
			str.append(L("List what in space? Try one of the following:\n\r"));
			str.append(L("LIST SPACE ALL - List everything in space everywhere!!\n\r"));
			str.append(L("LIST SPACE WITHIN [DISTANCE] - List within distance of current planet.\n\r"));
			str.append(L("LIST SPACE AROUND [X],[Y],[Z] - List all within 1 solar system of coords.\n\r"));
			str.append(L("LIST SPACE AROUND [NAME] - List all within 1 solar system of named object.\n\r"));
			str.append(L("LIST SPACE AROUND [NAME] WITHIN [DISTANCE] - List all within [distance] of named object.\n\r"));
			str.append(L("\n\r[DISTANCE] can be in DM (decameters), KM (kilometers), AU (astro units), or SU (solar system units.\n\r"));
			str.append(L("Instead of LIST SPACE you can also specify BODIES, MOONS, STARS, or SPACESHIPS.\n\r"));
			return str.toString();
		}
		final List<SpaceObject> objs=new ArrayList<SpaceObject>();
		for(Enumeration<SpaceObject> objEnum=CMLib.map().getSpaceObjects();objEnum.hasMoreElements();)
		{
			final SpaceObject obj=objEnum.nextElement();
			if(!filter.passesFilter(obj))
				continue;
			objs.add(obj);
		}
		final String[] keywords=CMLib.lang().sessionTranslation(new String[]{"ALL","WITHIN","DISTANCE"});
		final String[] sortcols=CMLib.lang().sessionTranslation(new String[]{"TYPE","RADIUS","COORDINATES","SPEED","MASS","NAME","COORDSX","COORDSY","COORDSZ"});
		Long withinDistance=null;
		long[] centerPoint=null;
		final SpaceObject SO=CMLib.map().getSpaceObject(mob, false);
		for(int i=1;i<commands.size();i++)
		{
			String s=commands.get(i).toUpperCase();
			if(L("ALL").startsWith(s))
				continue;
			else
			if(L("AROUND").startsWith(s))
			{
				if(i<commands.size()-1)
				{
					i++;
					int end=i;
					while((end<commands.size()-1)&&(!CMStrings.contains(keywords, commands.get(end).toString().toUpperCase())))
						end++;
					if(end==i)
					{
						return L("\n\rBad AROUND parm: '@x1' -- no coordinates or object specified.\n\r","");
					}
					else
					{
						String around=CMParms.combine(commands,i,end);
						List<String> listStr=CMParms.parseCommas(around,true);
						long[] coords=null;
						if(listStr.size()==3)
						{
							long[] valL=new long[3];
							for(int x=0;x<3;x++)
							{
								Long newValue=CMLib.english().parseSpaceDistance(listStr.get(x));
								if(newValue==null)
									break;
								else
								{
									valL[i]=newValue.longValue();
									if(i==2)
										coords=valL;
								}
							}
						}
						if(coords==null)
						{
							SpaceObject SO2=CMLib.map().findSpaceObject(around, true);
							if(SO2==null)
								SO2=CMLib.map().findSpaceObject(around, true);
							if(SO2!=null)
								coords=SO2.coordinates();
						}
						if(coords==null)
						{
							return L("\n\rBad AROUND parm: '@x1' -- bad coordinates or object specified.\n\r",around);
						}
						centerPoint=coords;
						i=end-1;
					}
				}
				else
				{
					return L("\n\rBad AROUND parm: '@x1' -- no coordinates or object specified.\n\r","");
				}
			}
			else
			if(L("WITHIN").startsWith(s))
			{
				if(i<commands.size()-1)
				{
					i++;
					int end=i;
					while((end<commands.size()-1)&&(!CMStrings.contains(keywords, commands.get(end).toString().toUpperCase())))
						end++;
					if(end==i)
					{
						return L("\n\rBad WITHIN parm: '@x1' -- no valid distance specified.\n\r","");
					}
					else
					{
						String within=CMParms.combine(commands,i,end);
						Long distance=CMLib.english().parseSpaceDistance(within);
						if(distance==null)
						{
							return L("\n\rBad WITHIN parm: '@x1' -- no valid distance specified.\n\r",within);
						}
						withinDistance=distance;
						i=end-1;
					}
				}
				else
				{
					return L("\n\rBad WITHIN parm: '@x1' -- no distance specified.\n\r","");
				}
			}
			else
			if(L("ORDERBY").startsWith(s))
			{
				if(i<commands.size()-1)
				{
					i++;
					s=commands.get(i);
					int end=i;
					while((end<commands.size()-1)&&(CMStrings.contains(sortcols, commands.get(end).toString().toUpperCase())))
						end++;
					if(end==i)
					{
						return L("\n\rBad ORDERBY parm: '@x1' ORDERBY -- no column specified.  Try @x2.\n\r",commands.get(i).toString(),CMParms.toListString(sortcols));
					}
					for(int x=end-1;x>=i;x--)
					{
						final int[][] b=new int[][]{{0,1,2}};
						int dex=CMParms.indexOf(sortcols, commands.get(x).toString().toUpperCase());
						switch(dex)
						{
						case 0:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									return getSpaceObjectType(o1).compareTo(getSpaceObjectType(o2));
								}
							});
							break;
						case 1:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									return Long.valueOf(o1 == null ? 0 : o1.radius()).compareTo(Long.valueOf(o2 == null ? 0 : o2.radius()));
								}
							});
							break;
						case 3:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									return Double.valueOf(o1 == null ? 0 : o1.speed()).compareTo(Double.valueOf(o2 == null ? 0 : o2.speed()));
								}
							});
							break;
						case 4:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									return Long.valueOf(o1 == null ? 0 : o1.getMass()).compareTo(Long.valueOf(o2 == null ? 0 : o2.getMass()));
								}
							});
							break;
						case 5:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									return (o1==null?"":o1.name()).compareToIgnoreCase(o2==null?"":o2.name());
								}
							});
							break;
						case 8:
							b[0] = new int[] { 2, 0, 1 };
							//$FALL-THROUGH$
						case 7:
							if (x == 7)
								b[0] = new int[] { 1, 2, 0 };
							//$FALL-THROUGH$
						case 6: 
							//$FALL-THROUGH$
						case 2:
							Collections.sort(objs, new Comparator<SpaceObject>()
							{
								@Override
								public int compare(SpaceObject o1, SpaceObject o2)
								{
									int i = Long.valueOf(o1 == null ? Long.MIN_VALUE : o1.coordinates()[b[0][0]])
											.compareTo(Long.valueOf(o2 == null ? Long.MIN_VALUE : o2.coordinates()[b[0][0]]));
									if (i != 0)
									{
										i = Long.valueOf(o1 == null ? Long.MIN_VALUE : o1.coordinates()[b[0][1]])
											.compareTo(Long.valueOf(o2 == null ? Long.MIN_VALUE : o2.coordinates()[b[0][1]]));
									}
									if (i != 0)
									{
										i = Long.valueOf(o1 == null ? Long.MIN_VALUE : o1.coordinates()[b[0][2]])
											.compareTo(Long.valueOf(o2 == null ? Long.MIN_VALUE : o2.coordinates()[b[0][2]]));
									}
									return i;
								}
							});
							break;
						}
					}
					i=end-1;
				}
				else
				{
					return L("\n\rBad ORDERBY parm: '@x1' ORDERBY -- no column specified.  Try @x2.\n\r","",CMParms.toListString(sortcols));
				}
			}
		}
		
		if((centerPoint!=null)||(withinDistance!=null))
		{
			if(centerPoint==null)
			{
				if(SO!=null)
					centerPoint=SO.coordinates();
				else
					centerPoint=new long[]{0,0,0};
			}
			if(withinDistance==null)
				withinDistance=Long.valueOf(SpaceObject.Distance.SolarSystemRadius.dm+1000000);
			final List<SpaceObject> objs2=CMLib.map().getSpaceObjectsByCenterpointWithin(centerPoint, 0, withinDistance.longValue());
			for(final Iterator<SpaceObject> i=objs.iterator();i.hasNext();)
			{
				final SpaceObject obj=i.next();
				if(!objs2.contains(obj))
					i.remove();
			}
		}
		
		final int COL_LEN1, COL_LEN2, COL_LEN3, COL_LEN4, COL_LEN5;
		str.append(CMStrings.padRight(L("Typ"),COL_LEN1=CMLib.lister().fixColWidth(3.0,viewerS))+" ");
		str.append(CMStrings.padRight(L("Radius"),COL_LEN2=CMLib.lister().fixColWidth(7.0,viewerS))+" ");
		str.append(CMStrings.padRight(L("Coordinates"),COL_LEN3=CMLib.lister().fixColWidth(25.0,viewerS))+" ");
		str.append(CMStrings.padRight(L("Speed"),COL_LEN4=CMLib.lister().fixColWidth(10.0,viewerS))+" ");
		str.append(CMStrings.padRight(L("Mass"),COL_LEN5=CMLib.lister().fixColWidth(7.0,viewerS))+" ");
		str.append(L("Name\n\r"));
		for(SpaceObject obj : objs)
		{
			str.append(CMStrings.padRight(getSpaceObjectType(obj),COL_LEN1)+" ");
			str.append(CMStrings.padRight(CMLib.english().sizeDescShort(obj.radius()),COL_LEN2)+" ");
			str.append(CMStrings.padRight(CMLib.english().coordDescShort(obj.coordinates()),COL_LEN3)+" ");
			str.append(CMStrings.padRight(CMLib.english().speedDescShort(obj.speed()),COL_LEN4)+" ");
			str.append(CMStrings.padRight(shortenNumber(obj.getMass(),COL_LEN5),COL_LEN5)+" ");
			str.append(obj.name()+"\n\r");
		}
		return str.toString();
	}