private boolean evaluateAddClause(String str) {

		Matcher matcher = null;

		if (model instanceof AtomicModel) {

			matcher = ATOM.matcher(str);
			if (matcher.find()) {
				str = str.substring(matcher.end()).trim();
				float x = 1, y = 1;
				String s1 = null;
				int space = str.indexOf(" ");
				if (space < 0) {
					s1 = str.substring(0).trim();
					RectangularBoundary boundary = model.getBoundary();
					x = (float) (Math.random() * boundary.width + boundary.x);
					y = (float) (Math.random() * boundary.height + boundary.y);
				} else {
					s1 = str.substring(0, space).trim();
					String s2 = str.substring(space + 1).trim();
					float[] r = parseCoordinates(s2);
					if (r != null) {
						x = r[0];
						y = r[1];
					} else {
						out(ScriptEvent.FAILED, "Error: Cannot parse " + str);
						return false;
					}
				}
				double a = parseMathExpression(s1);
				if (Double.isNaN(a))
					return false;
				int id = (int) Math.round(a);
				if (((AtomisticView) view).insertAnAtom(x, y, id, true, false)) {
					view.repaint();
					notifyChange();
				} else {
					out(ScriptEvent.HARMLESS, "Cannot insert an atom to the specified location: " + str);
				}
				return true;
			}

			matcher = OBSTACLE.matcher(str);
			if (matcher.find()) {
				str = str.substring(matcher.end()).trim();
				float[] x = parseArray(4, str);
				if (x != null) {
					for (int i = 0; i < 4; i++)
						x[i] *= IR_CONVERTER;
					RectangularObstacle obs = new RectangularObstacle(x[0], x[1], x[2], x[3]);
					if (((AtomisticView) view).intersects(obs)) {
						out(ScriptEvent.FAILED, "Cannot add an obstacle of the specified size to the specified location: " + str);
					} else {
						model.obstacles.add(obs);
					}
					return true;
				}
			}

			matcher = ELECTRON.matcher(str);
			if (matcher.find()) {
				str = str.substring(matcher.end()).trim();
				String[] t = str.split(REGEX_WHITESPACE);
				float[] x = parseArray(2, t);
				if (x != null) {
					Atom a = ((AtomicModel) model).getAtom(Math.round(x[0]));
					Electron e = a.getElectron(0);
					if (e == null) {
						e = new Electron(a);
						ElectronicStructure es = ((AtomicModel) model).getElement(a.id).getElectronicStructure();
						EnergyLevel el = es.getEnergyLevel(Math.round(x[1]));
						e.setEnergyLevel(el);
						a.addElectron(e);
						model.notifyUpdateListeners(new UpdateEvent(model));
					}
					return true;
				}
			}

		}

		matcher = IMAGE.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			matcher = IMAGE_EXTENSION.matcher(str);
			if (matcher.find()) {
				String address = str.substring(0, matcher.end()).trim();
				if (FileUtilities.isRelative(address)) {
					String base = (String) model.getProperty("url");
					if (base == null) {
						out(ScriptEvent.FAILED, "No directory has been specified. Save the page first.");
						return false;
					}
					address = FileUtilities.getCodeBase(base) + address;
					if (System.getProperty("os.name").startsWith("Windows"))
						address = address.replace('\\', '/');
				}
				address = useDefinitions(address);
				ImageComponent ic = null;
				try {
					ic = new ImageComponent(address);
				} catch (Exception e) {
					e.printStackTrace();
					final String errorAddress = address;
					EventQueue.invokeLater(new Runnable() {
						public void run() {
							JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(view), "Image " + errorAddress + " was not found.", "Image not found", JOptionPane.ERROR_MESSAGE);
						}
					});
					return false;
				}
				str = str.substring(matcher.end()).trim();
				int i = str.indexOf(",");
				if (i >= 0) {
					float[] x = parseCoordinates(str);
					if (x != null) {
						ic.setLocation(x[0], x[1]);
						view.addLayeredComponent(ic);
						view.repaint();
						return true;
					}
				} else {
					str = str.toLowerCase();
					if (str.startsWith("atomno")) {
						i = str.indexOf("=");
						if (i >= 0) {
							str = str.substring(i + 1);
							double z = parseMathExpression(str);
							if (!Double.isNaN(z)) {
								ic.setHost(model.getParticle((int) Math.round(z)));
								view.addLayeredComponent(ic);
								view.repaint();
								return true;
							}
						}
					}
				}
			}
		}

		matcher = TEXTBOX.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			matcher = TEXT_EXTENSION.matcher(str);
			if (matcher.find()) {
				String address = str.substring(0, matcher.end()).trim();
				if (FileUtilities.isRelative(address)) {
					String base = (String) model.getProperty("url");
					if (base == null) {
						out(ScriptEvent.FAILED, "No directory has been specified. Save the page first.");
						return false;
					}
					address = FileUtilities.getCodeBase(base) + address;
					if (System.getProperty("os.name").startsWith("Windows"))
						address = address.replace('\\', '/');
				}
				TextBoxComponent t = null;
				try {
					t = new TextBoxComponent(readText(address, view));
				} catch (InterruptedException e) {
				}
				if (t != null) {
					str = str.substring(matcher.end()).trim();
					float[] x = parseCoordinates(str);
					if (x != null) {
						t.setLocation(x[0], x[1]);
						view.addLayeredComponent(t);
						view.repaint();
						return true;
					}
				}
			} else {
				String slc = str.toLowerCase();
				int a = slc.indexOf("<t>");
				int b = slc.indexOf("</t>");
				if (a != -1 && b != -1) {
					TextBoxComponent t = new TextBoxComponent(str.substring(a + 3, b));
					view.addLayeredComponent(t);
					str = str.substring(b + 4).trim();
					float[] x = parseCoordinates(str);
					if (x != null) {
						t.setLocation(x[0], x[1]);
						view.repaint();
						return true;
					}
					out(ScriptEvent.FAILED, "Coordinate error: " + str);
					return false;
				}
				Action act = view.getActionMap().get("Input Text Box");
				float[] x = parseCoordinates(str);
				if (x == null) {
					out(ScriptEvent.FAILED, "Coordinate error: " + str);
					return false;
				}
				act.putValue("x", (int) x[0]);
				act.putValue("y", (int) x[1]);
				act.putValue("callout", Boolean.FALSE);
				act.actionPerformed(null);
				act.putValue("x", null);
				act.putValue("y", null);
				act.putValue("callout", null);
				return true;
			}
		}

		matcher = LINE.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			float[] x = parseArray(4, str);
			if (x != null) {
				for (int i = 0; i < 4; i++)
					x[i] *= IR_CONVERTER;
				LineComponent line = new LineComponent();
				line.setEndPoint1(x[0], x[1]);
				line.setEndPoint2(x[2], x[3]);
				view.addLayeredComponent(line);
				return true;
			}
		}

		matcher = RECTANGLE.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			float[] x = parseArray(4, str);
			if (x != null) {
				for (int i = 0; i < 4; i++)
					x[i] *= IR_CONVERTER;
				RectangleComponent rect = new RectangleComponent();
				rect.setRect(x[0], x[1], x[2], x[3]);
				view.addLayeredComponent(rect);
				return true;
			}
		}

		matcher = ELLIPSE.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			float[] x = parseArray(4, str);
			if (x != null) {
				for (int i = 0; i < 4; i++)
					x[i] *= IR_CONVERTER;
				EllipseComponent ellipse = new EllipseComponent();
				ellipse.setOval(x[0], x[1], x[2], x[3]);
				view.addLayeredComponent(ellipse);
				return true;
			}
		}

		matcher = TRIANGLE.matcher(str);
		if (matcher.find()) {
			str = str.substring(matcher.end()).trim();
			float[] x = parseArray(6, str);
			if (x != null) {
				for (int i = 0; i < 6; i++)
					x[i] *= IR_CONVERTER;
				TriangleComponent triangle = new TriangleComponent();
				triangle.setVertex(0, x[0], x[1]);
				triangle.setVertex(1, x[2], x[3]);
				triangle.setVertex(2, x[4], x[5]);
				view.addLayeredComponent(triangle);
				return true;
			}
		}

		out(ScriptEvent.FAILED, "Unrecognized type of object to add: " + str);
		return false;

	}