protected boolean evalCommand(String ci) throws InterruptedException {

		String ciLC = ci.toLowerCase();

		// skip
		if (ciLC.startsWith("define ") || ciLC.startsWith("static ") || ciLC.startsWith("cancel"))
			return true;

		// call external scripts
		if (ciLC.startsWith("external")) {
			String address = ci.substring(8).trim();
			if (address != null && !address.equals("")) {
				Matcher matcher = NNI.matcher(address);
				if (matcher.find()) {
					byte i = Byte.parseByte(address);
					String s = externalScripts.get(i);
					if (s == null) {
						out(ScriptEvent.FAILED, "External command error: " + ci);
						return false;
					}
					evaluateExternalClause(s);
				} else {
					evaluateExternalClause(readText(address, view));
				}
			}
			return true;
		}

		logicalStack.clear();

		if (!checkParenthesisBalance(ci))
			return false;

		// plot
		Matcher matcher = PLOT.matcher(ci);
		if (matcher.find()) {
			if (evaluatePlotClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// System.out.println("Before using definitions --> " + ci);
		// System.out.println(definition);
		// System.out.println("After using definitions ---> " + useDefinitions(ci));

		// get
		matcher = GET.matcher(ci);
		if (matcher.find()) {
			if (evaluateGetClause(ci.substring(matcher.end()).trim().toLowerCase()))
				return true;
		}

		// increment or decrement operator
		matcher = INCREMENT_DECREMENT.matcher(ci);
		if (matcher.find())
			return evaluateIncrementOperator(ci);

		matcher = SET_VAR.matcher(ci);
		if (!matcher.find()) {
			try {
				ci = replaceVariablesWithValues(useDefinitions(ci));
			} catch (EvaluationException ex) {
				ex.printStackTrace();
				return false;
			}
		}

		// System.out.println(ci);
		// System.out.println("-------------------------");

		// exit
		matcher = EXIT.matcher(ci);
		if (matcher.find()) {
			Object o = view.getClientProperty("close_full_screen");
			if (o instanceof Runnable) {
				((Runnable) o).run();
			}
			return true;
		}

		// load
		matcher = LOAD.matcher(ci);
		if (matcher.find()) {
			if (evaluateLoadClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// source
		matcher = SOURCE.matcher(ci);
		if (matcher.find()) {
			if (evaluateSourceClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// select
		matcher = SELECT.matcher(ci);
		if (matcher.find()) {
			if (evaluateSelectClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// background
		matcher = BACKGROUND.matcher(ci);
		if (matcher.find()) {
			if (evaluateBackgroundClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// mark selected objects with a specified color
		matcher = MARK_COLOR.matcher(ci);
		if (matcher.find()) {
			if (evaluateMarkClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// charge
		matcher = CHARGE.matcher(ci);
		if (matcher.find()) {
			if (evaluateChargeClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// restrain
		matcher = RESTRAIN.matcher(ci);
		if (matcher.find()) {
			if (evaluateRestrainClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// damp
		matcher = DAMP.matcher(ci);
		if (matcher.find()) {
			if (evaluateDampClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// heat
		matcher = HEAT.matcher(ci);
		if (matcher.find()) {
			if (evaluateHeatClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// trajectory
		matcher = TRAJECTORY.matcher(ci);
		if (matcher.find()) {
			if (evaluateTrajectoryClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// store
		matcher = STORE.matcher(ci);
		if (matcher.find()) {
			if (evaluateStoreClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// averageposition
		matcher = AVERAGE_POSITION.matcher(ci);
		if (matcher.find()) {
			if (evaluateAvposClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// averageforce
		matcher = AVERAGE_FORCE.matcher(ci);
		if (matcher.find()) {
			if (evaluateAvforClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// local area counter
		matcher = LAC.matcher(ci);
		if (matcher.find()) {
			if (evaluateLacClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// local area temperature
		matcher = LAT.matcher(ci);
		if (matcher.find()) {
			if (evaluateLatClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// local area pressure
		matcher = LAP.matcher(ci);
		if (matcher.find()) {
			if (evaluateLapClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// pcf
		matcher = PCF.matcher(ci);
		if (matcher.find()) {
			if (evaluatePcfClause(ci.substring(matcher.end()).trim().toLowerCase()))
				return true;
		}

		// tcf
		matcher = TCF.matcher(ci);
		if (matcher.find()) {
			if (evaluateTcfClause(ci.substring(matcher.end()).trim().toLowerCase()))
				return true;
		}

		// mvd
		matcher = MVD.matcher(ci);
		if (matcher.find()) {
			if (evaluateMvdClause(ci.substring(matcher.end()).trim().toLowerCase()))
				return true;
		}

		// show
		matcher = SHOW.matcher(ci);
		if (matcher.find()) {
			if (evaluateShowClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// set
		matcher = SET.matcher(ci);
		if (matcher.find()) {
			if (evaluateSetClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// add
		matcher = ADD.matcher(ci);
		if (matcher.find()) {
			if (evaluateAddClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// attach
		matcher = ATTACH.matcher(ci);
		if (matcher.find()) {
			if (evaluateAttachClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// sound
		matcher = SOUND.matcher(ci);
		if (matcher.find()) {
			if (evaluateSoundClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// mouse cursor
		matcher = CURSOR.matcher(ci);
		if (matcher.find()) {
			if (evaluateCursorClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// move
		matcher = MOVE.matcher(ci);
		if (matcher.find()) {
			if (evaluateMoveClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// rotate
		matcher = ROTATE.matcher(ci);
		if (matcher.find()) {
			if (evaluateRotateClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// delay
		matcher = DELAY.matcher(ci);
		if (matcher.find()) {
			if (evaluateDelayClause(ci.substring(matcher.end()).trim()))
				return true;
		}

		// print
		matcher = PRINT.matcher(ci);
		if (matcher.find()) {
			if (evaluatePrintClause(ci.substring(matcher.end()).trim().toLowerCase()))
				return true;
		}

		// show message
		matcher = MESSAGE.matcher(ci);
		if (matcher.find()) {
			String s = XMLCharacterDecoder.decode(ci.substring(matcher.end()).trim());
			String slc = s.toLowerCase();
			int a = slc.indexOf("<t>");
			int b = slc.indexOf("</t>");
			String info;
			if (a != -1 && b != -1) {
				info = s.substring(a, b + 4).trim();
				slc = info.toLowerCase();
				if (!slc.startsWith("<html>")) {
					info = "<html>" + info;
				}
				if (!slc.endsWith("</html>")) {
					info = info + "</html>";
				}
			} else {
				matcher = Compiler.HTML_EXTENSION.matcher(s);
				if (matcher.find()) {
					info = readText(s, view);
				} else {
					info = "Unknown text";
				}
			}
			final String info2 = format(info);
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					String codeBase = FileUtilities.getCodeBase((String) model.getProperty("url"));
					showMessageDialog(info2, codeBase, view);
				}
			});
			return true;
		}

		if (model instanceof MolecularModel) {

			// minimize
			matcher = MINIMIZE.matcher(ci);
			if (matcher.find()) {
				if (evaluateMinimizeClause(ci.substring(matcher.end()).trim()))
					return true;
			}

			// build radial bond
			matcher = BUILD_RBOND.matcher(ci);
			if (matcher.find()) {
				if (evaluateBuildBondClause(ci.substring(ci.startsWith("rbond") ? 5 : 4).trim()))
					return true;
			}

			// build angular bond
			matcher = BUILD_ABOND.matcher(ci);
			if (matcher.find()) {
				if (evaluateBuildBendClause(ci.substring(ci.startsWith("abond") ? 5 : 4).trim()))
					return true;
			}

			// transcribe
			matcher = TRANSCRIBE.matcher(ci);
			if (matcher.find()) {
				model.containerScriptCallback.setScript(ci);
				model.containerScriptCallback.execute();
				return true;
			}

			// translate
			matcher = TRANSLATE.matcher(ci);
			if (matcher.find()) {
				model.containerScriptCallback.setScript(ci);
				model.containerScriptCallback.execute();
				return true;
			}

		}

		out(ScriptEvent.FAILED, "Unrecognized command: " + ci);
		return false;

	}