* @param molecule
	 *            a specified molecule
	 * @return 'true' if the action is done, 'false' if not
	 * @see org.concord.mw2d.models.Benzene
	 * @see org.concord.mw2d.models.ChainMolecule
	 * @see org.concord.mw2d.models.DiatomicMolecule
	 * @see org.concord.mw2d.models.TriatomicMolecule
	 */
	public boolean insertAMolecule(double x, double y, Molecule molecule) {
		if (model.getNumberOfParticles() >= atom.length - molecule.size()) {
			errorReminder.show(ErrorReminder.EXCEED_CAPACITY);
			return false;
		}
		int oldNOA = nAtom;
		molecule.init(model);
		molecule.translateTo(x, y);
		int noa = model.getNumberOfParticles();
		for (int i = oldNOA; i < noa; i++) {
			if (!boundary.contains(atom[i].getRx(), atom[i].getRy())) {
				errorReminder.show(ErrorReminder.OUT_OF_BOUND);
				model.setNumberOfParticles(oldNOA);
				nAtom = oldNOA;
				return false;
			}
		}
		if (intersects(molecule)) {
			errorReminder.show(ErrorReminder.OBJECT_OVERLAP);
			model.setNumberOfParticles(oldNOA);
			nAtom = oldNOA;
			return false;
		}
		bonds.addAll(molecule.buildBonds(model));
		bends.addAll(molecule.buildBends(model));
		molecules.add(molecule);
		// FIXME: the torque implementation is ugly
		int i = molecules.size() - 1;
		model.removeProperty("torque_mol" + i);
		model.removeProperty("rotor_mol" + i);
		nAtom = noa;
		molecule.setSelected(true);
		if (useJmol)
			notifyJmol();
		repaint();
		model.notifyChange();
		if (!doNotFireUndoEvent) {
			model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableInsertion(actionID, x, y)));
			updateUndoUIComponents();
		}
		return true;
	}