/**
	 * Clean up chemical model ,removing duplicates empty molecules etc
	 * 
	 * @param chemModel
	 * @param avoidOverlap
	 * @throws CDKException
	 */
	public static void cleanUpChemModel(final IChemModel chemModel,
			final boolean avoidOverlap, final AbstractJChemPaintPanel panel)
			throws CDKException {
		JChemPaint.setReactionIDs(chemModel);
		JChemPaint.replaceReferencesWithClones(chemModel);

		// check the model is not completely empty
		if (ChemModelManipulator.getBondCount(chemModel) == 0
				&& ChemModelManipulator.getAtomCount(chemModel) == 0) {
			throw new CDKException(
					"Structure does not have bonds or atoms. Cannot depict structure.");
		}
		JChemPaint.removeDuplicateAtomContainers(chemModel);
		JChemPaint.checkCoordinates(chemModel);
		JChemPaint.removeEmptyAtomContainers(chemModel);

		if (avoidOverlap) {
			try {
				ControllerHub.avoidOverlap(chemModel);
			} catch (final Exception e) {
				JOptionPane.showMessageDialog(panel,
						GT._("Structure could not be generated"));
				throw new CDKException("Cannot depict structure");
			}
		}

		// We update implicit Hs in any case
		final CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher
				.getInstance(chemModel.getBuilder());
		for (final IAtomContainer container : ChemModelManipulator
				.getAllAtomContainers(chemModel)) {
			for (final IAtom atom : container.atoms()) {
				if (!(atom instanceof IPseudoAtom)) {
					try {
						final IAtomType type = matcher.findMatchingAtomType(
								container, atom);
						if (type != null
								&& type.getFormalNeighbourCount() != null) {
							final int connectedAtomCount = container
									.getConnectedAtomsCount(atom);
							atom.setImplicitHydrogenCount(type
									.getFormalNeighbourCount()
									- connectedAtomCount);
						}
					} catch (final CDKException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	private static void checkCoordinates(final IChemModel chemModel)
			throws CDKException {
		for (final IAtomContainer next : ChemModelManipulator
				.getAllAtomContainers(chemModel)) {
			if (!GeometryTools.get2DCoordinateCoverage(next).equals(
					GeometryTools.CoordinateCoverage.FULL)) {
				final String error = GT._("Not all atoms have 2D coordinates."
						+ " JCP can only show full 2D specified structures."
						+ " Shall we lay out the structure?");
				final int answer = JOptionPane.showConfirmDialog(null, error,
						"No 2D coordinates", JOptionPane.YES_NO_OPTION);

				if (answer == JOptionPane.NO_OPTION) {
					throw new CDKException(
							GT._("Cannot display without 2D coordinates"));
				} else {
					// CreateCoordinatesForFileDialog frame =
					// new CreateCoordinatesForFileDialog(chemModel);
					// frame.pack();
					// frame.show();

					WaitDialog.showDialog();
					final List<IAtomContainer> acs = ChemModelManipulator
							.getAllAtomContainers(chemModel);
					generate2dCoordinates(acs);
					WaitDialog.hideDialog();
					return;
				}
			}
		}

		/*
		 * Add implicit hydrogens (in ControllerParameters,
		 * autoUpdateImplicitHydrogens is true by default, so we need to do that
		 * anyway)
		 */
		final CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(chemModel
				.getBuilder());
		for (final IAtomContainer molecule : ChemModelManipulator
				.getAllAtomContainers(chemModel)) {
			if (molecule != null) {
				try {
					hAdder.addImplicitHydrogens(molecule);
				} catch (final CDKException e) {
					// do nothing
				}
			}
		}
	}