@Override public void reflect(State s) {
		state = s;
		
		if (s.gameOver()) {
			// show end state, overlaid with scores and shit
			JFrame f = new JFrame();
			int[] players = s.players();
			f.setLayout(new GridLayout(0, players.length));
			// sigh. gridlayout insists on ltr, ttb child insertion
			for (int y = 0; y < 3; y++) {
				for (int handle: players) {
					final PlayerState ps = s.playerState(handle);
					Component c = null;
					switch (y) {
					case 0:
						c = new JLabel(ps.name);
						break;
					case 1:
						c = new JLabel(""+ps.finalScore());
						break;
					case 2:
						JList l = new JList(ps.missions.toArray());
						l.setCellRenderer(new ListCellRenderer() {
							@Override public Component getListCellRendererComponent(JList l, Object o, int i,
							                                                        boolean isSelected,
							                                                        boolean hasFocus) {
								Mission m = (Mission)o;
								JLabel c = new JLabel(m.value+" "+m.source+" - "+m.destination);
								c.setBackground(ps.missionCompleted(m)
								                  ? new java.awt.Color(0.5f, 0.5f, 1f)
								                  : new java.awt.Color(1f, 0.5f, 0.5f));
								c.setOpaque(true);
								return c;
							}
						});
						c = l;
						break;
					}
					f.add(c);
				}
			}
			f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			f.pack();
			f.setVisible(true);
		} else {
			players.reflect(s);
			decks.reflect(s);
			map.reflect(s);
			missions.reflect(s);
			hand.reflect(s);
		}
	}