public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			if (presentationName.equals("Translation")) {
				if (mc instanceof Atom)
					((Atom) mc).translateTo(x, y);
				else if (mc instanceof Molecule)
					((Molecule) mc).translateTo(x, y);
				else if (mc instanceof RectangularObstacle)
					((RectangularObstacle) mc).translateCenterTo(x, y);
				else if (mc instanceof Layered) {
					((Layered) mc).setLocation(x, y);
					ModelComponent host = ((Layered) mc).getHost();
					if (host instanceof Atom) {
						Atom a = (Atom) host;
						a.translateTo(((Layered) mc).getCenter());
					}
				}
			} else if (presentationName.equals("Rotation")) {
				if (mc instanceof Rotatable)
					redo((Rotatable) mc);
			}
			doNotFireUndoEvent = false;
			if (!mc.isSelected())
				mc.setSelected(true);
			model.notifyChange();
			if (useJmol)
				refreshJmol();
			repaint();
		}

	}

	private class UndoableResizing extends AbstractUndoableEdit {

		private ModelComponent mc;
		private double x, y, w, h;
		private String presentationName = "";

		UndoableResizing(ModelComponent mc) {
			this.mc = mc;
			if (mc instanceof RectangularObstacle) {
				x = ((RectangularObstacle) mc).getX();
				y = ((RectangularObstacle) mc).getY();
				w = ((RectangularObstacle) mc).getWidth();
				h = ((RectangularObstacle) mc).getHeight();
				presentationName = "Resizing Rectangular Obstacle";
			} else if (mc instanceof Atom) {
				if (actionID == VELO_ID) {
					x = ((Atom) mc).getVx();
					y = ((Atom) mc).getVy();
					presentationName = "Changing Velocity";
				}
			}
		}

		public String getPresentationName() {
			return presentationName;
		}

		public void undo() {
			super.undo();
			mc.restoreState();
			if (!mc.isSelected())
				mc.setSelected(true);
			model.notifyChange();
			repaint();
		}

		public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			if (mc instanceof RectangularObstacle) {
				((RectangularObstacle) mc).setRect(x, y, w, h);
			} else if (mc instanceof Atom) {
				((Atom) mc).setVx(x);
				((Atom) mc).setVy(y);
			}
			doNotFireUndoEvent = false;
			if (!mc.isSelected())
				mc.setSelected(true);
			model.notifyChange();
			repaint();
		}

	}

	/** Serializable state. */
	public static class State extends MDView.State {

		private byte displayStyle = StyleConstant.SPACE_FILLING;
		private int probeID = Element.ID_NT;
		private int efCellSize = 10;
		private byte efShadingMode = ElectricForceField.TRANSPARENCY_SHADING_MODE;
		private boolean shading, chargeShading, showVVectors, showVDWCircles, showVDWLines, showChargeLines, showSSLines, showBPLines, showPVectors, showAVectors, showFVectors, showContour, showExcitation = true, showEFieldLines, useJmol;
		private double probeCharge;
		private int[] elementColors; // an array to store the colors of the four adjustable elements
		private Color[] moColors; // an array to store the colors of the molecular surface objects
		private float vdwLinesRatio = 2.0f, vdwLineThickness = 1;
		private byte vdwCircleStyle = StyleConstant.VDW_DOTTED_CIRCLE;

		public State() {
			super();
			elementColors = new int[Element.getNumberOfElements()];
			Arrays.fill(elementColors, 0xffffff);
			elementColors[Element.ID_PL] = 0x00ff00;
			elementColors[Element.ID_WS] = 0x0000ff;
			elementColors[Element.ID_CK] = 0xff00ff;
			elementColors[Element.ID_MO] = 0xffc800;
			elementColors[Element.ID_SP] = 0xffff00;
			elementColors[Element.ID_A] = 0x7da7d9;
			elementColors[Element.ID_C] = 0xc4df9a;
			elementColors[Element.ID_G] = 0xfdc588;
			elementColors[Element.ID_T] = 0xfff699;
			elementColors[Element.ID_U] = 0xfff699;
		}

		public void setUseJmol(boolean b) {
			useJmol = b;
		}

		public boolean getUseJmol() {
			return useJmol;
		}

		public void setDisplayStyle(byte i) {
			displayStyle = i;
		}

		public byte getDisplayStyle() {
			return displayStyle;
		}

		public void setMonochromatic(boolean b) {
			useJmol = !b;
		}

		public boolean getMonochromatic() {
			return !useJmol;
		}

		public void setShowVDWLines(boolean b) {
			showVDWLines = b;
		}

		public boolean getShowVDWLines() {
			return showVDWLines;
		}

		public void setVDWLinesRatio(float ratio) {
			vdwLinesRatio = ratio;
		}

		public float getVDWLinesRatio() {
			return vdwLinesRatio;
		}

		public void setVDWLineThickness(float thickness) {
			vdwLineThickness = thickness;
		}

		public float getVDWLineThickness() {
			return vdwLineThickness;
		}

		public void setShowVDWCircles(boolean b) {
			showVDWCircles = b;
		}

		public boolean getShowVDWCircles() {
			return showVDWCircles;
		}

		public void setVDWCircleStyle(byte i) {
			vdwCircleStyle = i;
		}

		public byte getVDWCircleStyle() {
			return vdwCircleStyle;
		}

		public void setShowChargeLines(boolean b) {
			showChargeLines = b;
		}

		public boolean getShowChargeLines() {
			return showChargeLines;
		}

		public void setShowSSLines(boolean b) {
			showSSLines = b;
		}

		public boolean getShowSSLines() {
			return showSSLines;
		}

		public void setShowBPLines(boolean b) {
			showBPLines = b;
		}

		public boolean getShowBPLines() {
			return showBPLines;
		}

		public void setShowEFieldLines(boolean b) {
			showEFieldLines = b;
		}

		public boolean getShowEFieldLines() {
			return showEFieldLines;
		}

		public void setShading(boolean b) {
			shading = b;
		}

		public boolean getShading() {
			return shading;
		}

		public void setChargeShading(boolean b) {
			chargeShading = b;
		}

		public boolean getChargeShading() {
			return chargeShading;
		}

		public void setShowExcitation(boolean b) {
			showExcitation = b;
		}

		public boolean getShowExcitation() {
			return showExcitation;
		}

		public void setShowVVectors(boolean b) {
			showVVectors = b;
		}

		public boolean getShowVVectors() {
			return showVVectors;
		}

		public void setShowPVectors(boolean b) {
			showPVectors = b;
		}

		public boolean getShowPVectors() {
			return showPVectors;
		}

		public void setShowAVectors(boolean b) {
			showAVectors = b;
		}

		public boolean getShowAVectors() {
			return showAVectors;
		}

		public void setShowFVectors(boolean b) {
			showFVectors = b;
		}

		public boolean getShowFVectors() {
			return showFVectors;
		}

		public void setElementColors(int[] i) {
			elementColors = i;
		}

		public int[] getElementColors() {
			return elementColors;
		}

		public void setShowContour(boolean b) {
			showContour = b;
		}

		public boolean getShowContour() {
			return showContour;
		}

		public void setProbeID(int id) {
			probeID = id;
		}

		public int getProbeID() {
			return probeID;
		}

		public void setProbeCharge(double c) {
			probeCharge = c;
		}

		public double getProbeCharge() {
			return probeCharge;
		}

		public void setEFCellSize(int i) {
			efCellSize = i;
		}

		public int getEFCellSize() {
			return efCellSize;
		}

		public void setEFShadingMode(byte shadingMode) {
			efShadingMode = shadingMode;
		}

		public byte getEFShadingMode() {
			return efShadingMode;
		}

		public void setMolecularObjectColors(Color[] c) {
			moColors = c;
		}

		public Color[] getMolecularObjectColors() {
			return moColors;
		}