void encode(XMLEncoder out) throws Exception {

		// remove dependencies on non-serializable fields to serialize objects
		Component savedAncestor = view.getAncestor();
		view.setAncestor(null);
		for (Atom a : atom) {
			a.setSelected(false);
		}

		AtomisticView.State vs = new AtomisticView.State();
		vs.setPropertyDialogEnabled(view.isPropertyDialogEnabled());
		vs.setRenderingMethod(view.getRenderingMethod());
		vs.setUseJmol(view.getUseJmol());
		vs.setElementColors(view.getElementColors());
		vs.setBackground(view.getBackground());
		vs.setMarkColor(view.getMarkColor().getRGB());
		vs.setDrawCharge(view.getDrawCharge());
		vs.setDrawExternalForce(view.getDrawExternalForce());
		vs.setShowParticleIndex(view.getShowParticleIndex());
		vs.setShowMirrorImages(view.getShowMirrorImages());
		vs.setShowClock(view.getShowClock());
		vs.setShowHeatBath(view.getShowHeatBath());
		vs.setColorCode(view.getColorCoding());
		vs.setEnergizer(view.getEnergizer());
		vs.setDisplayStyle(view.getDisplayStyle());
		vs.setRestraintStyle(view.getRestraintStyle());
		vs.setTrajectoryStyle(view.getTrajectoryStyle());
		if (view.getFillMode() != FillMode.getNoFillMode())
			vs.setFillMode(view.getFillMode());
		vs.setShading(view.shadingShown());
		vs.setChargeShading(view.chargeShadingShown());
		vs.setShowVVectors(view.velocityVectorShown());
		vs.setShowPVectors(view.momentumVectorShown());
		vs.setShowAVectors(view.accelerationVectorShown());
		vs.setShowFVectors(view.forceVectorShown());
		vs.setShowContour(view.contourPlotShown());
		vs.setShowVDWCircles(view.vdwCirclesShown());
		vs.setVDWCircleStyle(view.getVDWCircleStyle());
		vs.setShowVDWLines(view.vdwLinesShown());
		vs.setVDWLinesRatio(view.getVDWLinesRatio());
		vs.setVDWLineThickness(view.getVdwLineThickness());
		vs.setShowChargeLines(view.chargeLinesShown());
		vs.setShowSSLines(view.ssLinesShown());
		vs.setShowBPLines(view.bpLinesShown());
		vs.setShowEFieldLines(view.eFieldLinesShown());
		vs.setEFCellSize(view.getEFCellSize());
		vs.setEFShadingMode(view.getEFShadingMode());
		vs.setVelocityFlavor(view.getVelocityFlavor());
		vs.setMomentumFlavor(view.getMomentumFlavor());
		vs.setAccelerationFlavor(view.getAccelerationFlavor());
		vs.setForceFlavor(view.getForceFlavor());
		vs.setShowExcitation(view.excitationShown());
		if (vs.getShowContour()) {
			vs.setProbeID(view.getProbeAtom().id);
			vs.setProbeCharge(view.getProbeAtom().getCharge());
		}
		ImageComponent[] im = view.getImages();
		if (im.length > 0) {
			ImageComponent.Delegate[] icd = new ImageComponent.Delegate[im.length];
			for (int i = 0; i < im.length; i++)
				icd[i] = new ImageComponent.Delegate(im[i]);
			vs.setImages(icd);
		}
		TextBoxComponent[] tb = view.getTextBoxes();
		if (tb.length > 0) {
			TextBoxComponent.Delegate[] tbd = new TextBoxComponent.Delegate[tb.length];
			for (int i = 0; i < tb.length; i++)
				tbd[i] = new TextBoxComponent.Delegate(tb[i]);
			vs.setTextBoxes(tbd);
		}
		LineComponent[] lc = view.getLines();
		if (lc.length > 0) {
			LineComponent.Delegate[] lcd = new LineComponent.Delegate[lc.length];
			for (int i = 0; i < lc.length; i++)
				lcd[i] = new LineComponent.Delegate(lc[i]);
			vs.setLines(lcd);
		}
		RectangleComponent[] rc = view.getRectangles();
		if (rc.length > 0) {
			RectangleComponent.Delegate[] rcd = new RectangleComponent.Delegate[rc.length];
			for (int i = 0; i < rc.length; i++)
				rcd[i] = new RectangleComponent.Delegate(rc[i]);
			vs.setRectangles(rcd);
		}
		TriangleComponent[] tc = view.getTriangles();
		if (tc.length > 0) {
			TriangleComponent.Delegate[] tcd = new TriangleComponent.Delegate[tc.length];
			for (int i = 0; i < tc.length; i++)
				tcd[i] = new TriangleComponent.Delegate(tc[i]);
			vs.setTriangles(tcd);
		}
		EllipseComponent[] ec = view.getEllipses();
		if (ec.length > 0) {
			EllipseComponent.Delegate[] ecd = new EllipseComponent.Delegate[ec.length];
			for (int i = 0; i < ec.length; i++)
				ecd[i] = new EllipseComponent.Delegate(ec[i]);
			vs.setEllipses(ecd);
		}
		Color[] c = getMolecularObjectColors();
		if (c != null)
			vs.setMolecularObjectColors(c);

		State state = new State(numberOfAtoms);
		if (job != null)
			state.addTasks(job.getCustomTasks());
		state.setLJBetweenBondPairs(ljBetweenBondPairs);
		state.setInterCoulomb(interCoulomb);
		state.setUniverse(universe);
		state.setProperties(properties);
		state.setFields(fields);
		state.setCutOff(rCutOff);
		state.setCutOffShift(cutOffShift);
		state.setRList(rList);
		state.setTimeStep(timeStep);
		state.setScript(initializationScript);
		state.setFrameInterval(movieUpdater.getInterval());
		state.setViewRefreshInterval(paintView.getInterval());
		state.setMoEpsilon(mo.getEpsilon());
		state.setMoMass(mo.getMass());
		state.setPhotonEnabled(isSubatomicEnabled());
		state.setLightSource(lightSource);
		state.setQuantumRule(quantumRule);
		state.setReminderEnabled(isReminderEnabled());
		if (isReminderEnabled()) {
			state.setRepeatReminder(reminder.getLifetime() == Loadable.ETERNAL);
			state.setReminderInterval(reminder.getInterval());
			state.setReminderMessage(reminderMessage);
		}
		state.setAtomFlowEnabled(isAtomFlowEnabled());
		if (isAtomFlowEnabled()) {
			state.setFlowInSide(getFlowInSide());
			state.setFlowOutSide(getFlowOutSide());
			byte[] type = getFlowInType();
			Byte[] type2 = new Byte[type.length];
			for (byte i = 0; i < type.length; i++)
				type2[i] = new Byte(type[i]);
			state.setFlowInType(type2);
			type = getFlowOutType();
			type2 = new Byte[type.length];
			for (byte i = 0; i < type.length; i++)
				type2[i] = new Byte(type[i]);
			state.setFlowOutType(type2);
			state.setFlowInterval(getFlowInterval());
		}

		if (subatomicEnabled) {
			// save the excited states of the electrons of the atoms
			ExcitedStates excitedStates = new ExcitedStates();
			for (int i = 0; i < numberOfAtoms; i++) {
				if (atom[i].isExcitable()) {
					List<Electron> electrons = atom[i].getElectrons();
					if (electrons != null && !electrons.isEmpty()) {
						for (Electron e : electrons) {
							int levelIndex = e.getEnergyLevelIndex();
							if (levelIndex == -1)
								continue;
							excitedStates.getExcitationMap().put(i, new int[] { electrons.indexOf(e), levelIndex });
						}
					}
				}
			}
			state.setExcitedStates(excitedStates);
		}

		// write out the boundary
		RectangularBoundary.Delegate rectBound = boundary.createDelegate();
		state.setBoundary(rectBound);

		if (heatBath != null) {
			heatBath.setModel(null);
			state.setHeatBath(heatBath);
		}

		monitor.setProgressMessage("Writing model...");
		monitor.setMaximum(getNumberOfParticles() + 8);

		out.writeObject(nt);
		out.writeObject(pl);
		out.writeObject(ws);
		out.writeObject(ck);
		out.writeObject(affinity);

		if (obstacles != null && !obstacles.isEmpty())
			state.setObstacles(obstacles.getList());
		Object prop = removeProperty("old url"); // hack to remove temporary properties
		out.writeObject(state);
		out.writeObject(vs);
		out.flush();
		if (prop != null)
			putProperty("old url", prop); // add temporary properties back

		for (int i = 0; i < numberOfAtoms; i++) {
			monitor.setProgressMessage("Writing atom " + i + "...");
			out.writeObject(atom[i]);
			out.flush();
		}

		encodeBonds(out);

		// restore non-serializable fields for serialized objects
		view.setAncestor(savedAncestor);
		if (heatBath != null)
			heatBath.setModel(this);

	}