private void showCrewEditor( final CrewSprite crewSprite ) {
		final String NAME = "Name";
		final String RACE = "Race";
		final String HEALTH = "Health";
		final String PILOT_SKILL = "Pilot Skill";
		final String ENGINE_SKILL = "Engine Skill";
		final String SHIELD_SKILL = "Shield Skill";
		final String WEAPON_SKILL = "Weapon Skill";
		final String REPAIR_SKILL = "Repair Skill";
		final String COMBAT_SKILL = "Combat Skill";
		final String REPAIRS = "Repairs";
		final String COMBAT_KILLS = "Combat Kills";
		final String PILOTED_EVASIONS = "Piloted Evasions";
		final String JUMPS_SURVIVED = "Jumps Survived";
		final String PLAYER_CONTROLLED = "Player Ctrl";
		final String ENEMY_DRONE = "Enemy Drone";
		final String GENDER = "Male";

		int pilotInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_PILOT;
		int engineInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_ENGINE;
		int shieldInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_SHIELD;
		int weaponInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_WEAPON;
		int repairInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_REPAIR;
		int combatInterval = SavedGameParser.CrewState.MASTERY_INTERVAL_COMBAT;

		int maxHealth = SavedGameParser.CrewState.getMaxHealth( crewSprite.getRace() );

		String title = "Crew";

		final FieldEditorPanel editorPanel = new FieldEditorPanel( false );
		editorPanel.addRow( NAME, FieldEditorPanel.ContentType.STRING );
		editorPanel.getString(NAME).setText( crewSprite.getName() );
		editorPanel.addRow( RACE, FieldEditorPanel.ContentType.COMBO );
		editorPanel.getCombo(RACE).addItem("battle");
		editorPanel.getCombo(RACE).addItem("crystal");
		editorPanel.getCombo(RACE).addItem("energy");
		editorPanel.getCombo(RACE).addItem("engi");
		editorPanel.getCombo(RACE).addItem("human");
		editorPanel.getCombo(RACE).addItem("mantis");
		editorPanel.getCombo(RACE).addItem("rock");
		editorPanel.getCombo(RACE).addItem("slug");
		editorPanel.getCombo(RACE).setSelectedItem( crewSprite.getRace() );
		editorPanel.addRow( HEALTH, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(HEALTH).setMaximum( maxHealth );
		editorPanel.getSlider(HEALTH).setValue( crewSprite.getHealth() );
		editorPanel.addRow( PILOT_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(PILOT_SKILL).setMaximum( pilotInterval*2 );
		editorPanel.getSlider(PILOT_SKILL).setValue( crewSprite.getPilotSkill() );
		editorPanel.addRow( ENGINE_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(ENGINE_SKILL).setMaximum( engineInterval*2 );
		editorPanel.getSlider(ENGINE_SKILL).setValue( crewSprite.getEngineSkill() );
		editorPanel.addRow( SHIELD_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(SHIELD_SKILL).setMaximum( shieldInterval*2 );
		editorPanel.getSlider(SHIELD_SKILL).setValue( crewSprite.getShieldSkill() );
		editorPanel.addRow( WEAPON_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(WEAPON_SKILL).setMaximum( weaponInterval*2 );
		editorPanel.getSlider(WEAPON_SKILL).setValue( crewSprite.getWeaponSkill() );
		editorPanel.addRow( REPAIR_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(REPAIR_SKILL).setMaximum( repairInterval*2 );
		editorPanel.getSlider(REPAIR_SKILL).setValue( crewSprite.getRepairSkill() );
		editorPanel.addRow( COMBAT_SKILL, FieldEditorPanel.ContentType.SLIDER );
		editorPanel.getSlider(COMBAT_SKILL).setMaximum( combatInterval*2 );
		editorPanel.getSlider(COMBAT_SKILL).setValue( crewSprite.getCombatSkill() );
		editorPanel.addBlankRow();
		editorPanel.addRow( REPAIRS, FieldEditorPanel.ContentType.INTEGER );
		editorPanel.getInt(REPAIRS).setText( ""+crewSprite.getRepairs() );
		editorPanel.addRow( COMBAT_KILLS, FieldEditorPanel.ContentType.INTEGER );
		editorPanel.getInt(COMBAT_KILLS).setText( ""+crewSprite.getCombatKills() );
		editorPanel.addRow( PILOTED_EVASIONS, FieldEditorPanel.ContentType.INTEGER );
		editorPanel.getInt(PILOTED_EVASIONS).setText( ""+crewSprite.getPilotedEvasions() );
		editorPanel.addRow( JUMPS_SURVIVED, FieldEditorPanel.ContentType.INTEGER );
		editorPanel.getInt(JUMPS_SURVIVED).setText( ""+crewSprite.getJumpsSurvived() );
		editorPanel.addRow( PLAYER_CONTROLLED, FieldEditorPanel.ContentType.BOOLEAN );
		editorPanel.getBoolean(PLAYER_CONTROLLED).setSelected( crewSprite.isPlayerControlled() );
		editorPanel.getBoolean(PLAYER_CONTROLLED).addMouseListener( new StatusbarMouseListener(frame, "Player controlled vs NPC.") );
		editorPanel.addRow( ENEMY_DRONE, FieldEditorPanel.ContentType.BOOLEAN );
		editorPanel.getBoolean(ENEMY_DRONE).setSelected( crewSprite.isEnemyBoardingDrone() );
		editorPanel.getBoolean(ENEMY_DRONE).addMouseListener( new StatusbarMouseListener(frame, "Turn into a boarding drone (clobbering other fields).") );
		editorPanel.addRow( GENDER, FieldEditorPanel.ContentType.BOOLEAN );
		editorPanel.getBoolean(GENDER).setSelected( crewSprite.isMale() );
		editorPanel.getBoolean(GENDER).addMouseListener( new StatusbarMouseListener(frame, "Only humans can be female (no effect on other races).") );

		sidePanel.add( editorPanel );

		final Runnable applyCallback = new Runnable() {
			public void run() {
				String newString;
				crewSprite.setName( editorPanel.getString(NAME).getText() );
				crewSprite.setRace( (String)editorPanel.getCombo(RACE).getSelectedItem() );
				crewSprite.setHealth( editorPanel.getSlider(HEALTH).getValue() );
				crewSprite.setPilotSkill( editorPanel.getSlider(PILOT_SKILL).getValue() );
				crewSprite.setEngineSkill( editorPanel.getSlider(ENGINE_SKILL).getValue() );
				crewSprite.setShieldSkill( editorPanel.getSlider(SHIELD_SKILL).getValue() );
				crewSprite.setWeaponSkill( editorPanel.getSlider(WEAPON_SKILL).getValue() );
				crewSprite.setRepairSkill( editorPanel.getSlider(REPAIR_SKILL).getValue() );
				crewSprite.setCombatSkill( editorPanel.getSlider(COMBAT_SKILL).getValue() );

				newString = editorPanel.getInt(REPAIRS).getText();
				try { crewSprite.setRepairs( Integer.parseInt(newString) ); }
				catch (NumberFormatException e) {}

				newString = editorPanel.getInt(COMBAT_KILLS).getText();
				try { crewSprite.setCombatKills( Integer.parseInt(newString) ); }
				catch (NumberFormatException e) {}

				newString = editorPanel.getInt(PILOTED_EVASIONS).getText();
				try { crewSprite.setPilotedEvasions( Integer.parseInt(newString) ); }
				catch (NumberFormatException e) {}

				newString = editorPanel.getInt(JUMPS_SURVIVED).getText();
				try { crewSprite.setJumpsSurvived( Integer.parseInt(newString) ); }
				catch (NumberFormatException e) {}

				crewSprite.setPlayerControlled( editorPanel.getBoolean(PLAYER_CONTROLLED).isSelected() );
				crewSprite.setEnemyBoardingDrone( editorPanel.getBoolean(ENEMY_DRONE).isSelected() );
				crewSprite.setMale( editorPanel.getBoolean(GENDER).isSelected() );

				crewSprite.makeSane();
				clearSidePanel();
			}
		};
		createSidePanel( title, editorPanel, applyCallback );

		addSidePanelSeparator(6);

		JButton moveBtn = new JButton("Move To...");
		moveBtn.setAlignmentX( Component.CENTER_ALIGNMENT );
		sidePanel.add(moveBtn);

		sidePanel.add( Box.createVerticalStrut(6) );

		JButton removeBtn = new JButton("Remove");
		removeBtn.setAlignmentX( Component.CENTER_ALIGNMENT );
		sidePanel.add(removeBtn);

		moveBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				moveCrew( crewSprite );
			}
		});

		removeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clearSidePanel();
				crewSprites.remove( crewSprite );
				shipPanel.remove( crewSprite );
			}
		});

		showSidePanel();
	}