gt: 			if (loc != null) {
context: /*
   * Copyright 2009-2015 Contributors (see credits.txt)
   *
   * This file is part of jEveAssets.
   *
   * jEveAssets is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * jEveAssets is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with jEveAssets; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   *
   */
  package net.nikr.eve.jeveasset.gui.tabs.routing;
  
  import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.MouseAdapter;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseWheelEvent;
  import java.awt.event.MouseWheelListener;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Set;
  import java.util.SortedSet;
  import java.util.TreeSet;
  import javax.swing.BorderFactory;
  import javax.swing.DefaultComboBoxModel;
  import javax.swing.GroupLayout;
  import javax.swing.JButton;
  import javax.swing.JComboBox;
  import javax.swing.JLabel;
  import javax.swing.JList;
  import javax.swing.JMenuItem;
  import javax.swing.JOptionPane;
  import javax.swing.JPanel;
  import javax.swing.JProgressBar;
  import javax.swing.JScrollPane;
  import javax.swing.JTabbedPane;
  import javax.swing.JTextArea;
  import javax.swing.JTextField;
  import javax.swing.JToolBar;
  import javax.swing.SwingConstants;
  import javax.swing.SwingUtilities;
  import javax.swing.SwingWorker;
  import javax.swing.event.ListSelectionEvent;
  import javax.swing.event.ListSelectionListener;
  import net.nikr.eve.jeveasset.Program;
  import net.nikr.eve.jeveasset.SplashUpdater;
  import net.nikr.eve.jeveasset.data.Jump;
  import net.nikr.eve.jeveasset.data.MyLocation;
  import net.nikr.eve.jeveasset.data.Settings;
  import net.nikr.eve.jeveasset.data.SolarSystem;
  import net.nikr.eve.jeveasset.data.StaticData;
  import net.nikr.eve.jeveasset.gui.images.Images;
  import net.nikr.eve.jeveasset.gui.shared.Formater;
  import net.nikr.eve.jeveasset.gui.shared.components.JDropDownButton;
  import net.nikr.eve.jeveasset.gui.shared.components.JMainTab;
  import net.nikr.eve.jeveasset.gui.tabs.assets.MyAsset;
  import net.nikr.eve.jeveasset.gui.tabs.overview.OverviewGroup;
  import net.nikr.eve.jeveasset.gui.tabs.overview.OverviewLocation;
  import net.nikr.eve.jeveasset.gui.tabs.overview.OverviewLocation.LocationType;
  import net.nikr.eve.jeveasset.i18n.General;
  import net.nikr.eve.jeveasset.i18n.TabsRouting;
  import net.nikr.eve.jeveasset.io.shared.ApiIdConverter;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import uk.me.candle.eve.graph.DisconnectedGraphException;
  import uk.me.candle.eve.graph.Edge;
  import uk.me.candle.eve.graph.Graph;
  import uk.me.candle.eve.graph.Node;
  import uk.me.candle.eve.graph.distances.Jumps;
  import uk.me.candle.eve.routing.Progress;
  import uk.me.candle.eve.routing.RoutingAlgorithm;
  import uk.me.candle.eve.routing.cancel.CancelService;
  
  /**
   *
   * @author Candle
   */
  public class RoutingTab extends JMainTab  {
  
  	private static final  Logger LOG = LoggerFactory.getLogger(RoutingTab.class);
  
  	private enum RoutingAction {
  		ADD,
  		REMOVE,
  		ADD_SYSTEM,
  		SOURCE,
  		ALGORITHM,
  		ALGORITHM_HELP,
  		CALCULATE,
  		AVOID_ADD,
  		AVOID_REMOVE,
  		AVOID_CLEAR,
  		AVOID_SAVE,
  		AVOID_LOAD,
  		AVOID_MANAGE,
  		SAVE
  	}
  	//Routing
  	private JLabel jAlgorithmLabel;
  	private JComboBox jAlgorithm;
  	private JButton jAlgorithmInfo;
  	private JLabel jFilterLabel;
  	private JLabel jFilterSecurityIcon;
  	private JLabel jFilterSecurity;
  	private JLabel jFilterSystemIcon;
  	private JLabel jFilterSystem;
  	private JLabel jSourceLabel;
  	private JComboBox jSource;
  	private JLabel jStartLabel;
  	private JTextField jStart;
  	private MoveJList<SolarSystem> jAvailable;
  	private JLabel jAvailableRemaining;
  	private JButton jAdd;
  	private JButton jRemove;
  	private JButton jAddSystem;
  	private MoveJList<SolarSystem> jWaypoints;
  	private JLabel jWaypointsRemaining;
  	//Filter
  	private JList jAvoid;
  	private EditableListModel<SolarSystem> avoidModel = new EditableListModel<SolarSystem>();
  	private JButton jAvoidAdd;
  	private JButton jAvoidRemove;
  	private JButton jAvoidClear;
  	private JButton jAvoidSave;
  	private JDropDownButton jAvoidLoad;
  	private JLabel jSecurityIcon;
  	private JComboBox jSecurityMinimum;
  	private JLabel jSecuritySeparatorLabel;
  	private JComboBox jSecurityMaximum;
  	//Progress
  	private JProgressBar jProgress;
  	private JButton jCalculate;
  	//Result
  	private JTextArea jResult;
  	private JTextArea jFullResult;
  	private JTextArea jInfo;
  	//Dialogs
  	private JSystemDialog jSystemDialog;
  	private JSaveSystemList jSaveSystemList;
  	private JManageSystemList jManageSystemList;
  
  	private ListenerClass listener;
  	private RouteFind routeFind;
  
  	//Data
  	protected Graph filteredGraph;
  	private double lastSecMin = 0.0;
  	private double lastSecMax = 1.0;
  	private List<Long> lastAvoid = new ArrayList<Long>();
  	private boolean uiEnabled = true;
  	/**
  	 *
  	 * @param load does nothing except change the signature.
  	 */
  	protected RoutingTab(final boolean load) {
  		super(load);
  	}
  
  	public RoutingTab(final Program program) {
  		super(program, TabsRouting.get().routingTitle(), Images.TOOL_ROUTING.getIcon(), true);
  
  		listener = new ListenerClass();
  
  		jSystemDialog = new JSystemDialog(program);
  		jSaveSystemList = new JSaveSystemList(program);
  		jManageSystemList = new JManageSystemList(this, program);
  
  	//Routing
  		JPanel jRoutingPanel = new JPanel();
  		GroupLayout routingLayout = new GroupLayout(jRoutingPanel);
  		jRoutingPanel.setLayout(routingLayout);
  		routingLayout.setAutoCreateGaps(true);
  		routingLayout.setAutoCreateContainerGaps(true);
  
  		jAlgorithmLabel = new JLabel(TabsRouting.get().algorithm());
  
  		jAlgorithm = new JComboBox(RoutingAlgorithmContainer.getRegisteredList().toArray());
  		jAlgorithm.setSelectedIndex(0);
  		jAlgorithm.setActionCommand(RoutingAction.ALGORITHM.name());
  		jAlgorithm.addActionListener(listener);
  
  		jAlgorithmInfo = new JButton(Images.MISC_HELP.getIcon());
  		jAlgorithmInfo.setActionCommand(RoutingAction.ALGORITHM_HELP.name());
  		jAlgorithmInfo.addActionListener(listener);
  
  		jFilterLabel = new JLabel(TabsRouting.get().filters());
  		jFilterSecurityIcon = new JLabel();
  		jFilterSecurity = new JLabel();
  		jFilterSystemIcon = new JLabel(Images.LOC_SYSTEM.getIcon());
  		jFilterSystem = new JLabel();
  		jFilterSystem.setIconTextGap(4);
  
  		jSourceLabel = new JLabel(TabsRouting.get().source());
  
  		jSource = new JComboBox();
  		jSource.setActionCommand(RoutingAction.SOURCE.name());
  		jSource.addActionListener(listener);
  
  		//Start system
  		jStartLabel = new JLabel(TabsRouting.get().startSystem());
  
  		jStart = new JTextField();
  		jStart.setEditable(false);
  		jStart.setFocusable(false);
  
  		Comparator<SolarSystem> comp = new Comparator<SolarSystem>() {
  			@Override
  			public int compare(final SolarSystem o1, final SolarSystem o2) {
  				return o1.getName().compareToIgnoreCase(o2.getName());
  			}
  		};
  
  		jAvailable = new MoveJList<SolarSystem>(new EditableListModel<SolarSystem>());
  		jAvailable.getEditableModel().setSortComparator(comp);
  		jAvailable.addMouseListener(listener);
  		jAvailable.addListSelectionListener(listener);
  
  		jAvailableRemaining = new JLabel();
  
  		jAdd = new JButton(TabsRouting.get().add());
  		jAdd.setActionCommand(RoutingAction.ADD.name());
  		jAdd.addActionListener(listener);
  
  		jRemove = new JButton(TabsRouting.get().remove());
  		jRemove.setActionCommand(RoutingAction.REMOVE.name());
  		jRemove.addActionListener(listener);
  
  		jAddSystem = new JButton(TabsRouting.get().addSystem());
  		jAddSystem.setActionCommand(RoutingAction.ADD_SYSTEM.name());
  		jAddSystem.addActionListener(listener);
  
  		jWaypoints = new MoveJList<SolarSystem>(new EditableListModel<SolarSystem>());
  		jWaypoints.getEditableModel().setSortComparator(comp);
  		jWaypoints.addMouseListener(listener);
  		jWaypoints.addListSelectionListener(listener);
  
  		jWaypointsRemaining = new JLabel();
  
  		JScrollPane jAvailableScroll = new JScrollPane(jAvailable);
  		JScrollPane jWaypointsScroll = new JScrollPane(jWaypoints);
  
  		routingLayout.setHorizontalGroup(
  			routingLayout.createSequentialGroup()
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  					.addGroup(routingLayout.createSequentialGroup()
  						.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  							.addComponent(jAlgorithmLabel)
  							.addComponent(jSourceLabel)
  						)
  						.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  							.addGroup(routingLayout.createSequentialGroup()
  								.addComponent(jAlgorithm)
  								.addGap(10)
  								.addComponent(jAlgorithmInfo)
  							)
  							.addComponent(jSource)
  						)	
  					)
  					.addComponent(jAvailableScroll, 300, 300, Short.MAX_VALUE)
  					.addComponent(jAvailableRemaining, 300, 300, Short.MAX_VALUE)
  				)
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  					.addComponent(jAdd, 80, 80, 80)
  					.addComponent(jRemove, 80, 80, 80)
  					.addComponent(jAddSystem, 80, 80, 80)
  				)
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  					.addGroup(routingLayout.createSequentialGroup()
  						.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  							.addComponent(jStartLabel)
  							.addComponent(jFilterLabel)
  						)
  						.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
  							.addGroup(routingLayout.createSequentialGroup()
  								.addComponent(jFilterSecurityIcon)
  								.addGap(0)
  								.addComponent(jFilterSecurity)
  								.addGap(20)
  								.addComponent(jFilterSystemIcon)
  								.addGap(4)
  								.addComponent(jFilterSystem)
  							)
  							.addComponent(jStart)
  						)
  					)
  					.addComponent(jWaypointsScroll, 300, 300, Short.MAX_VALUE)
  					.addComponent(jWaypointsRemaining, 300, 300, Short.MAX_VALUE)
  				)
  		);
  		routingLayout.setVerticalGroup(
  			routingLayout.createSequentialGroup()
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  					.addComponent(jAlgorithmLabel, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jAlgorithm, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jAlgorithmInfo, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jFilterLabel, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jFilterSecurityIcon, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jFilterSecurity, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jFilterSystemIcon, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jFilterSystem, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				)
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  					.addComponent(jSourceLabel, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jSource, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jStartLabel, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jStart, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				)
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
  					.addComponent(jAvailableScroll, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  					.addComponent(jWaypointsScroll, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  					.addGroup(routingLayout.createSequentialGroup()
  						.addComponent(jAdd, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  						.addComponent(jRemove, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  						.addComponent(jAddSystem, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					)
  				)
  				.addGroup(routingLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  					.addComponent(jAvailableRemaining, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  					.addComponent(jWaypointsRemaining, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				)
  		);
  	//Filters
  		JPanel jFilterPanel = new JPanel();
  		GroupLayout filterLayout = new GroupLayout(jFilterPanel);
  		jFilterPanel.setLayout(filterLayout);
  		filterLayout.setAutoCreateGaps(true);
  		filterLayout.setAutoCreateContainerGaps(true);
  
  		JPanel jAvoidPanel = new JPanel();
  		jAvoidPanel.setBorder(BorderFactory.createTitledBorder(TabsRouting.get().avoid()));
  		GroupLayout avoidLayout = new GroupLayout(jAvoidPanel);
  		jAvoidPanel.setLayout(avoidLayout);
  		avoidLayout.setAutoCreateGaps(true);
  		avoidLayout.setAutoCreateContainerGaps(true);
  
  		JPanel jSecurityPanel = new JPanel();
  		jSecurityPanel.setBorder(BorderFactory.createTitledBorder(TabsRouting.get().security()));
  		GroupLayout securityLayout = new GroupLayout(jSecurityPanel);
  		jSecurityPanel.setLayout(securityLayout);
  		securityLayout.setAutoCreateGaps(true);
  		securityLayout.setAutoCreateContainerGaps(true);
  
  		avoidModel.setSortComparator(comp);
  		avoidModel.addAll(Settings.get().getRoutingSettings().getAvoid().values());
  
  		jAvoid = new JList(avoidModel);
  		jAvoid.addMouseListener(listener);
  		jAvoid.addListSelectionListener(listener);
  
  		JToolBar jToolBar = new JToolBar(SwingConstants.VERTICAL);
  		jToolBar.setFloatable(false);
  
  		jAvoidAdd = new JButton(TabsRouting.get().avoidAdd(), Images.EDIT_ADD.getIcon());
  		jAvoidAdd.setActionCommand(RoutingAction.AVOID_ADD.name());
  		jAvoidAdd.addActionListener(listener);
  		jAvoidAdd.setMinimumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidAdd.setMaximumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidAdd.setHorizontalAlignment(SwingConstants.LEFT);
  		jToolBar.add(jAvoidAdd);
  
  		jAvoidRemove = new JButton(TabsRouting.get().avoidRemove(), Images.EDIT_DELETE.getIcon());
  		jAvoidRemove.setActionCommand(RoutingAction.AVOID_REMOVE.name());
  		jAvoidRemove.addActionListener(listener);
  		jAvoidRemove.setMinimumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidRemove.setMaximumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidRemove.setHorizontalAlignment(SwingConstants.LEFT);
  		jAvoidRemove.setEnabled(false);
  		jToolBar.add(jAvoidRemove);
  
  		jAvoidClear = new JButton(TabsRouting.get().avoidClear(), Images.FILTER_CLEAR.getIcon());
  		jAvoidClear.setActionCommand(RoutingAction.AVOID_CLEAR.name());
  		jAvoidClear.addActionListener(listener);
  		jAvoidClear.setMinimumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidClear.setMaximumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidClear.setHorizontalAlignment(SwingConstants.LEFT);
  		jToolBar.add(jAvoidClear);
  
  		jAvoidSave = new JButton(TabsRouting.get().avoidSave(), Images.FILTER_SAVE.getIcon());
  		jAvoidSave.setActionCommand(RoutingAction.AVOID_SAVE.name());
  		jAvoidSave.addActionListener(listener);
  		jAvoidSave.setMinimumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidSave.setMaximumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidSave.setHorizontalAlignment(SwingConstants.LEFT);
  		jToolBar.add(jAvoidSave);
  	
  		jAvoidLoad = new JDropDownButton(TabsRouting.get().avoidLoad(), Images.FILTER_LOAD.getIcon());
  		jAvoidLoad.setMinimumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidLoad.setMaximumSize(new Dimension(100, Program.BUTTONS_HEIGHT));
  		jAvoidLoad.setHorizontalAlignment(SwingConstants.LEFT);
  		jToolBar.add(jAvoidLoad);
  
  		JScrollPane jAvoidScroll = new JScrollPane(jAvoid);
  
  		Double[] security = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};
  
  		jSecurityIcon = new JLabel();
  
  		jSecurityMinimum = new JComboBox(security);
  		jSecurityMinimum.setSelectedItem(Settings.get().getRoutingSettings().getSecMin());
  		jSecurityMinimum.setActionCommand(RoutingAction.SAVE.name());
  		jSecurityMinimum.addActionListener(listener);
  
  		jSecuritySeparatorLabel = new JLabel(" - ");
  
  		jSecurityMaximum = new JComboBox(security);
  		jSecurityMaximum.setSelectedItem(Settings.get().getRoutingSettings().getSecMax());
  		jSecurityMaximum.setActionCommand(RoutingAction.SAVE.name());
  		jSecurityMaximum.addActionListener(listener);
  
  		updateFilterLabels();
  		updateSavedFilters();
  
  		avoidLayout.setHorizontalGroup(
  			avoidLayout.createSequentialGroup()
  				.addComponent(jAvoidScroll, 300, 300, 300)
  				.addComponent(jToolBar)
  		);
  		avoidLayout.setVerticalGroup(
  			avoidLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  				.addComponent(jAvoidScroll, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
  				.addComponent(jToolBar)
  		);
  		securityLayout.setHorizontalGroup(
  			securityLayout.createSequentialGroup()
  				.addComponent(jSecurityIcon)
  				.addComponent(jSecurityMinimum, 80, 80, Short.MAX_VALUE)
  				.addComponent(jSecuritySeparatorLabel)
  				.addComponent(jSecurityMaximum, 80, 80, Short.MAX_VALUE)
  		);
  		securityLayout.setVerticalGroup(
  			securityLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  				.addComponent(jSecurityIcon, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				.addComponent(jSecurityMinimum, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				.addComponent(jSecuritySeparatorLabel, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)	
  				.addComponent(jSecurityMaximum, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  		);
  		filterLayout.setHorizontalGroup(
  			filterLayout.createSequentialGroup()
  				.addComponent(jAvoidPanel)
  				.addComponent(jSecurityPanel)
  		);
  		filterLayout.setVerticalGroup(
  			filterLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  				.addComponent(jAvoidPanel)
  				.addComponent(jSecurityPanel)
  		);
  	//Progress
  		jProgress = new JProgressBar();
  		jProgress.setValue(0);
  		jProgress.setMaximum(100);
  		jProgress.setMinimum(0);
  
  		jCalculate = new JButton(TabsRouting.get().calculate());
  		jCalculate.setActionCommand(RoutingAction.CALCULATE.name());
  		jCalculate.addActionListener(listener);
  	//Result
  		jResult = new JTextArea();
  		jResult.setEditable(false);
  		jResult.setFont(jPanel.getFont());
  
  		jFullResult = new JTextArea();
  		jFullResult.setEditable(false);
  		jFullResult.setFont(jPanel.getFont());
  
  		jInfo = new JTextArea();
  		jInfo.setEditable(false);
  		jInfo.setFont(jPanel.getFont());
  
  		final JScrollPane jResultScroll = new JScrollPane(jResult, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
  		JScrollPane jFullResultScroll = new JScrollPane(jFullResult, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
  		jFullResultScroll.getVerticalScrollBar().setModel(jResultScroll.getVerticalScrollBar().getModel());
  		jFullResultScroll.setWheelScrollingEnabled(false);
  		jFullResultScroll.addMouseWheelListener(new MouseWheelListener() {
  			@Override
  			public void mouseWheelMoved(MouseWheelEvent e) {
  				jResultScroll.dispatchEvent(e);
  			}
  		});
  		JScrollPane jInfoScroll = new JScrollPane(jInfo);
  
  		JTabbedPane jResultTabs = new JTabbedPane();
  		jResultTabs.addTab(TabsRouting.get().resultTabShort(), jResultScroll);
  		jResultTabs.addTab(TabsRouting.get().resultTabFull(), jFullResultScroll);
  		jResultTabs.addTab(TabsRouting.get().resultTabInfo(), jInfoScroll);
  
  		JTabbedPane jSystemTabs = new JTabbedPane();
  		jSystemTabs.addTab(TabsRouting.get().routingTab(), jRoutingPanel);
  		jSystemTabs.addTab(TabsRouting.get().filtersTab(), jFilterPanel);
  
  		// widths are defined in here.
  		layout.setHorizontalGroup(
  			layout.createParallelGroup(GroupLayout.Alignment.LEADING)
  				.addComponent(jSystemTabs)
  				.addGroup(layout.createSequentialGroup()
  					.addComponent(jProgress, GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
  					.addComponent(jCalculate, 120, 120, 120)
  				)
  				.addComponent(jResultTabs)
  			);
  		// heights are defined here.
  		layout.setVerticalGroup(
  			layout.createSequentialGroup()
  				.addComponent(jSystemTabs, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
  				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  					.addComponent(jProgress, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)	
  					.addComponent(jCalculate, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT, Program.BUTTONS_HEIGHT)
  				)
  				.addComponent(jResultTabs)
  				
  		);
  		buildGraph(true); //Build default Graph (0.0/All sec - no avoids)
  		jSystemDialog.updateData(filteredGraph.getNodes()); //Will be replaced by valid systems by processRouteInner()
  	}
  
  	@Override
  	public void clearData() {
  		RoutingAlgorithm.setCache(false); //Clear cache
  	}
  
  	@Override
  	public void updateData() {
  		//Do everything the constructor does...
  		jAvailable.getEditableModel().clear();
  		jWaypoints.getEditableModel().clear();
  		List<SourceItem> sources = new ArrayList<SourceItem>();
  		for (Entry<String, OverviewGroup> entry : Settings.get().getOverviewGroups().entrySet()) {
  			sources.add(new SourceItem(entry.getKey(), true));
  		}
  		Collections.sort(sources);
  		sources.add(0, new SourceItem(TabsRouting.get().filteredAssets()));
  		sources.add(0, new SourceItem(General.get().all()));
  		jSource.setModel(new DefaultComboBoxModel(sources.toArray()));
  		jAlgorithm.setSelectedIndex(0);
  		jResult.setText(TabsRouting.get().emptyResult());
  		jResult.setCaretPosition(0);
  		jResult.setEnabled(false);
  		jFullResult.setText(TabsRouting.get().emptyResult());
  		jFullResult.setCaretPosition(0);
  		jFullResult.setEnabled(false);
  		jInfo.setText(TabsRouting.get().emptyResult());
  		jInfo.setCaretPosition(0);
  		jInfo.setEnabled(false);
  		
  		updateRemaining();
  		processFilteredAssets();
  	}
  
  	public void addSystems(int max) {
  		Set<SolarSystem> allLocs = new HashSet<SolarSystem>();
  		allLocs.addAll(jAvailable.getEditableModel().getAll());
  		allLocs.addAll(jWaypoints.getEditableModel().getAll());
  		int count = 0;
  		for (MyLocation location : StaticData.get().getLocations().values()) {
  			if (count >= max) {
  				break;
  			}
  			if (location.getSecurityObject().getDouble() < (Double)jSecurityMinimum.getSelectedItem()) {
  				continue;
  			}
  			SolarSystem loc = findNodeForLocation(filteredGraph, location.getSystemID());
  			if (loc != null) {
  				boolean add = allLocs.add(loc);
  				if (add) {
  					count++;
  				}
  			} else {
  				LOG.debug("ignoring {}", location);
  			}
  		}
  		jAvailable.getEditableModel().clear();
  		jWaypoints.getEditableModel().clear();
  		jAvailable.getEditableModel().addAll(allLocs);
  		updateRemaining();
  	}
  
  	private void updateRemaining() {
  		updateWaypointsRemaining();
  		updateAvailableRemaining();
  		validateLists();
  	}
  
  	private void updateWaypointsRemaining() {
  		int max = ((RoutingAlgorithmContainer) jAlgorithm.getSelectedItem()).getWaypointLimit();
  		int cur = jWaypoints.getModel().getSize();
  		if (max < cur) {
  			jWaypointsRemaining.setForeground(Color.RED);
  		} else if (max == cur) {
  			jWaypointsRemaining.setForeground(Color.BLUE);
  		} else {
  			jWaypointsRemaining.setForeground(Color.BLACK);
  		}
  		jWaypointsRemaining.setText(TabsRouting.get().allowed(cur, max));
  	}
  
  	private void updateAvailableRemaining() {
  		int cur = jAvailable.getModel().getSize();
  		int tot = cur + jWaypoints.getModel().getSize();
  		jAvailableRemaining.setText(TabsRouting.get().total(cur, tot));
  	}
  
  	protected final void buildGraph(boolean all) {
  		// build the graph.
  		// filter the solarsystems based on the settings.
  		if (filteredGraph != null) {
  			filteredGraph.clear();
  		}
  		filteredGraph = new Graph(new Jumps());
  		double secMin;
  		double secMax;
  		if (jSecurityMinimum != null) {
  			secMin = (Double) jSecurityMinimum.getSelectedItem();
  		} else {
  			secMin = 0.0f;
  		}
  		if (jSecurityMaximum != null) {
  			secMax = (Double) jSecurityMaximum.getSelectedItem();
  		} else {
  			secMax = 1.0f;
  		}
  		int count = 0;
  		Map<Long, SolarSystem> systemCache = new HashMap<Long, SolarSystem>();
  		for (Jump jump : StaticData.get().getJumps()) { // this way we exclude the locations that are unreachable.
  			count++;
  			SplashUpdater.setSubProgress((int) (count * 100.0 / StaticData.get().getJumps().size()));
  
  			SolarSystem from = systemCache.get(jump.getFrom().getSystemID());
  			SolarSystem to = systemCache.get(jump.getTo().getSystemID());
  			if (from == null) {
  				from = new SolarSystem(jump.getFrom());
  				systemCache.put(from.getSystemID(), from);
  			}
  			if (to == null) {
  				to = new SolarSystem(jump.getTo());
  				systemCache.put(to.getSystemID(), to);
  			}
  			if (all || (jump.getFrom().getSecurityObject().getDouble() >= secMin
  						&& jump.getTo().getSecurityObject().getDouble() >= secMin
  						&& jump.getFrom().getSecurityObject().getDouble() <= secMax
  						&& jump.getTo().getSecurityObject().getDouble() <= secMax
  						&& !Settings.get().getRoutingSettings().getAvoid().keySet().contains(jump.getFrom().getSystemID())
  						&& !Settings.get().getRoutingSettings().getAvoid().keySet().contains(jump.getTo().getSystemID())
  					)) {
  				filteredGraph.addEdge(new Edge(from, to));
  			}
  		}
  		SplashUpdater.setSubProgress(100);
  		systemCache.clear();
  	}
  
  	protected void processFilteredAssets() {
  		// select the active places.
  		SortedSet<SolarSystem> allLocs = new TreeSet<SolarSystem>(new Comparator<SolarSystem>() {
  			@Override
  			public int compare(final SolarSystem o1, final SolarSystem o2) {
  				String n1 = o1.getName();
  				String n2 = o2.getName();
  				return n1.compareToIgnoreCase(n2);
  			}
  		});
  		jAvailable.getEditableModel().addAll(allLocs);
  		List<MyAsset> assets;
  		SourceItem source = (SourceItem) jSource.getSelectedItem();
  		if (source.getName().equals(General.get().all())) { //ALL
  			assets = new ArrayList<MyAsset>(program.getAssetList());
  		} else if (source.getName().equals(TabsRouting.get().filteredAssets())) { //FILTERS
  			assets = program.getAssetsTab().getFilteredAssets();
  		} else { //OVERVIEW GROUP
  			assets = new ArrayList<MyAsset>();
  			OverviewGroup group = Settings.get().getOverviewGroups().get(source.getName());
  			for (OverviewLocation location : group.getLocations()) {
  				for (MyAsset asset : program.getAssetList()) {
  					if ((location.getName().equals(asset.getLocation().getLocation()))
  						|| (location.getType() == LocationType.TYPE_SYSTEM && location.getName().equals(asset.getLocation().getSystem()))
  						|| (location.getType() == LocationType.TYPE_REGION && location.getName().equals(asset.getLocation().getRegion()))
  						) {
  						assets.add(asset);
  					}
  				}
  			}
  		}
  		for (MyAsset ea : assets) {
  			SolarSystem loc = findNodeForLocation(filteredGraph, ea.getLocation().getSystemID());
  