void processMouseReleased(MouseEvent e) {

		super.processMouseReleased(e);

		if (model.getJob() != null && !model.getJob().isStopped()) {
			processUserFieldsUponKeyOrMouseReleased();
			return;
		}
		if (ModelerUtilities.isRightClick(e)) {
			popup(e);
			return;
		}
		int x = e.getX();
		int y = e.getY();

		/* actions without an ID */

		if (obsRectSelected > RectangularObstacle.INSIDE) {
			if (selectedComponent instanceof RectangularObstacle) {
				if (finalizeObstacleLocation((RectangularObstacle) selectedComponent)) {
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableResizing(selectedComponent)));
						updateUndoUIComponents();
					}
				}
				obsRectSelected = -1;
			}
		}

		/* actions with an ID */

		switch (actionID) {

		case SELE_ID:
			if (dragSelected) {
				boolean b = false;
				if (selectedComponent instanceof Molecule) {
					if (finalizeMoleculeLocation((Molecule) selectedComponent))
						b = true;
				} else if (selectedComponent instanceof Atom) {
					if (finalizeAtomLocation((Atom) selectedComponent, false)) {
						b = true;
					} else {
						errorReminder.show(ErrorReminder.OBJECT_OVERLAP);
					}
				} else if (selectedComponent instanceof RectangularObstacle) {
					if (finalizeObstacleLocation((RectangularObstacle) selectedComponent))
						b = true;
				} else if (selectedComponent instanceof Layered) {
					b = true;
					ModelComponent host = ((Layered) selectedComponent).getHost();
					if (host instanceof Atom) {
						b = finalizeAtomLocation((Atom) host, false);
						if (!b)
							errorReminder.show(ErrorReminder.OBJECT_OVERLAP);
					} else if (host instanceof RadialBond) {
						b = finalizeMoleculeLocation(((RadialBond) host).getMolecule());
					} else if (host instanceof RectangularObstacle) {
						b = finalizeObstacleLocation((RectangularObstacle) host);
					}
				}
				if (b) {
					model.notifyChange();
					setCursor(UserAction.getCursor(actionID));
					if (selectedComponent != null) {
						if (!doNotFireUndoEvent) {
							model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableMoving(selectedComponent)));
							updateUndoUIComponents();
						}
					}
				}
				dragSelected = false;
			}
			break;

		case ADDA_ID:
		case ADDB_ID:
		case ADDC_ID:
		case ADDD_ID:
			addAtomIndicator.x = addAtomIndicator.y = -1;
			repaint();
			break;

		case ADDI_ID:
		case WATE_ID:
		case BENZ_ID:
		case ADCH_ID:
			if (addObjectIndicator != null) {
				addObjectIndicator.setPainted(false);
				repaint();
			}
			break;

		case RCUR_ID:
		case SFRE_ID:
			if (e.getClickCount() > 1) {
				if (smartPoly != null && smartShape != null) {
					if (smartPoly.npoints >= 2) {
						int dx = x - smartPoly.xpoints[0];
						int dy = y - smartPoly.ypoints[0];
						populateSmartShape(dx * dx + dy * dy < 25);
						smartPoly = null;
					}
				}
				repaint();
			}
			break;

		case SCUR_ID:
			if (e.getClickCount() > 1) {
				if (smartPoly != null && smartShape != null) {
					if (smartPoly.npoints >= 3) {
						populateSmartShape(true);
						smartPoly = null;
					}
				}
				repaint();
			}
			break;

		case RCIR_ID:
		case SCIR_ID:
		case RREC_ID:
		case SREC_ID:
			if (e.getClickCount() > 1) {
				populateSmartShape(true);
				repaint();
			}
			break;

		case HEAT_ID:
			pointHeater.doWork(model, true);
			break;

		case COOL_ID:
			pointHeater.doWork(model, false);
			break;

		case MEAS_ID:
			if (readyToAdjustDistanceVector) {
				if (selectedComponent instanceof Atom && indexOfSelectedMeasurement >= 0) {
					if (x < 0 || x > getWidth() || y < 0 || y > getHeight()) {
						((Atom) selectedComponent).removeMeasurement(indexOfSelectedMeasurement);
						indexOfSelectedMeasurement = -1;
						setCursor(previousCursor);
						repaint();
					}
				}
				readyToAdjustDistanceVector = false;
			}
			break;

		case VELO_ID:
			if (readyToAdjustVelocityVector) {
				if (selectedComponent instanceof Atom) {
					Atom a = (Atom) selectedComponent;
					a.storeCurrentState();
					a.setVx((x - a.getRx()) / velocityFlavor.getLength());
					a.setVy((y - a.getRy()) / velocityFlavor.getLength());
					model.notifyChange();
					setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
					repaint();
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableResizing(selectedComponent)));
						updateUndoUIComponents();
					}
				}
				readyToAdjustVelocityVector = false;
			}
			break;

		case ROTA_ID:
			if (selectedComponent instanceof Rotatable) {
				if (rotationHandle >= 0) {
					Rotatable r = (Rotatable) selectedComponent;
					if (r.isSelectedToRotate()) {
						if (finalizeRotation()) {
							model.notifyChange();
							// r.setSelectedToRotate(false);
							if (selectedComponent != null && !doNotFireUndoEvent) {
								model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableMoving(selectedComponent)));
								updateUndoUIComponents();
							}
						}
					}
					rotationHandle = -1;
				} else {
					if (selectedComponent instanceof Molecule) {
						if (finalizeMoleculeLocation((Molecule) selectedComponent)) {
							model.notifyChange();
							if (selectedComponent != null) {
								if (!doNotFireUndoEvent) {
									model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableMoving(selectedComponent)));
									updateUndoUIComponents();
								}
							}
							dragSelected = false;
						} else {
							((Molecule) selectedComponent).setSelected(true);
						}
					}
				}
			}
			break;

		case DUPL_ID:
			if (selectedComponent instanceof Atom) {
				if (finalizeAtomDuplication()) {
					model.notifyChange();
					model.setNumberOfParticles(nAtom);
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableInsertion(UndoAction.INSERT_A_PARTICLE, x, y)));
						updateUndoUIComponents();
					}
				} else {
					errorReminder.show(ErrorReminder.OBJECT_OVERLAP);
				}
			} else if (selectedComponent instanceof Molecule) {
				if (finalizeMoleculeDuplication()) {
					model.notifyChange();
					model.setNumberOfParticles(nAtom);
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableInsertion(UndoAction.INSERT_A_MOLECULE, x, y, ((Molecule) selectedComponent).size())));
						updateUndoUIComponents();
					}
				}
			} else if (selectedComponent instanceof RectangularObstacle) {
				if (finalizeObstacleDuplication()) {
					model.notifyChange();
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableInsertion(ADOB_ID)));
						updateUndoUIComponents();
					}
				}
			} else if (selectedComponent instanceof Layered) {
				model.notifyChange();
				if (!doNotFireUndoEvent) {
					model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableLayeredComponentOperation(UndoAction.INSERT_LAYERED_COMPONENT, (Layered) selectedComponent)));
					updateUndoUIComponents();
				}
			}
			setSelectedComponent(null);
			break;

		case MARK_ID:
			for (int k = 0; k < nAtom; k++)
				atom[k].setMarked(selectedArea.contains(atom[k].getRx(), atom[k].getRy()));
			if (!molecules.isEmpty()) {
				Object obj = null;
				synchronized (molecules.getSynchronizationLock()) {
					for (Iterator it = molecules.iterator(); it.hasNext();) {
						obj = it.next();
						if (obj instanceof MolecularObject) {
							((MolecularObject) obj).setMarked(((MolecularObject) obj).intersects(selectedArea));
						}
					}
				}
			}
			selectedArea.setSize(0, 0);
			repaint();
			break;

		case FILA_ID:
			fillSelectedArea(Element.ID_NT);
			break;
		case FILB_ID:
			fillSelectedArea(Element.ID_PL);
			break;
		case FILC_ID:
			fillSelectedArea(Element.ID_WS);
			break;
		case FILD_ID:
			fillSelectedArea(Element.ID_CK);
			break;

		case COUN_ID:
			int n = 0,
			nNt = 0,
			nPl = 0,
			nWs = 0,
			nCk = 0,
			m = 0;
			for (int k = 0; k < nAtom; k++) {
				if (selectedArea.contains(atom[k].getRx(), atom[k].getRy())) {
					n++;
					switch (atom[k].getID()) {
					case Element.ID_NT:
						nNt++;
						break;
					case Element.ID_PL:
						nPl++;
						break;
					case Element.ID_WS:
						nWs++;
						break;
					case Element.ID_CK:
						nCk++;
						break;
					}
				}
			}
			if (!bonds.isEmpty()) {
				RadialBond rb = null;
				synchronized (bonds.getSynchronizationLock()) {
					for (Iterator it = bonds.iterator(); it.hasNext();) {
						rb = (RadialBond) it.next();
						if (selectedArea.contains(0.5 * (rb.getAtom1().getRx() + rb.getAtom2().getRx()), 0.5 * (rb.getAtom1().getRy() + rb.getAtom2().getRy())))
							m++;
					}
				}
			}
			if (n != 0 || m != 0) {
				String s = MDView.getInternationalText("CountingResult");
				String s1 = MDView.getInternationalText("SelectedAreaContains");
				String s2 = MDView.getInternationalText("Particle");
				JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this), (s1 != null ? s1 : "The selected area contains ") + n + (s2 != null ? s2 : " particles") + ":\n" + (nNt == 0 ? "" : nNt + " Nt, ") + (nPl == 0 ? "" : nPl + " Pl, ") + (nWs == 0 ? "" : nWs + " Ws, ") + (nCk == 0 ? "" : nCk + " Ck") + (m == 0 ? "" : '\n' + "and " + m + " bonds."), s != null ? s : "Counting result", JOptionPane.INFORMATION_MESSAGE);
			}
			selectedArea.setSize(0, 0);
			repaint();
			break;

		case DELE_ID:
			removeSelectedArea();
			break;

		case SBOU_ID:
			int handle = boundary.getHandle();
			if (handle == RectangularBoundary.UPPER_LEFT || handle == RectangularBoundary.UPPER_RIGHT || handle == RectangularBoundary.LOWER_LEFT || handle == RectangularBoundary.LOWER_RIGHT) {
				boundary.setHandle(-1);
				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				model.notifyChange();
				repaint();
			}
			break;

		case ADOB_ID:
			if (selectedArea.width > 0 && selectedArea.height > 0) {
				RectangularObstacle r2d = new RectangularObstacle(selectedArea);
				if (!intersects(r2d) && boundary.contains(r2d)) {
					obstacles.add(r2d);
					r2d.setSelected(true);
					model.notifyChange();
					if (!doNotFireUndoEvent) {
						model.getUndoManager().undoableEditHappened(new UndoableEditEvent(model, new UndoableInsertion(ADOB_ID)));
						updateUndoUIComponents();
					}
				} else {
					errorReminder.show(ErrorReminder.OBJECT_OVERLAP);
				}
				selectedArea.setSize(0, 0);
				repaint();
			}
			break;

		case MUTA_ID:
			Atom at = whichAtom(x, y);
			if (at != null) {
				at.setSelected(true);
				mutateSelectedAtom();
			}
			break;

		case DGBD_ID:
			bondAtom2 = whichAtom(x, y);
			if (bondAtom1 != null && bondAtom2 != null) {
				createABond(bondAtom1, bondAtom2);
			}
			bondAtom1 = bondAtom2 = null;
			break;

		}

		if (useJmol)
			refreshJmol();
		e.consume();

	}