void polyhedra() throws ScriptException {
		/*
		 * needsGenerating:
		 * 
		 * polyhedra [number of vertices and/or basis] [at most two selection sets] [optional type and/or edge]
		 * [optional design parameters]
		 * 
		 * OR else:
		 * 
		 * polyhedra [at most one selection set] [type-and/or-edge or on/off/delete]
		 */
		boolean needsGenerating = false;
		boolean onOffDelete = false;
		boolean typeSeen = false;
		boolean edgeParameterSeen = false;
		boolean isDesignParameter = false;
		int nAtomSets = 0;
		viewer.loadShape(JmolConstants.SHAPE_POLYHEDRA);
		viewer.setShapeProperty(JmolConstants.SHAPE_POLYHEDRA, "init", null);
		String setPropertyName = "centers";
		String decimalPropertyName = "radius_";
		String translucency = "";
		int color = Integer.MIN_VALUE;
		for (int i = 1; i < statementLength; ++i) {
			String propertyName = null;
			Object propertyValue = null;
			Token token = statement[i];
			switch (token.tok) {
			case Token.opEQ:
			case Token.opOr:
				continue;
			case Token.bonds:
				if (nAtomSets > 0)
					invalidParameterOrder();
				needsGenerating = true;
				propertyName = "bonds";
				break;
			case Token.radius:
				decimalPropertyName = "radius";
				continue;
			case Token.translucent:
				translucency = "translucent";
				continue;
			case Token.opaque:
				translucency = "opaque";
				continue;
			case Token.colorRGB:
				color = getArgbParam(i);
				continue;
			case Token.identifier:
				String str = (String) token.value;
				if ("collapsed".equalsIgnoreCase(str)) {
					propertyName = "collapsed";
					propertyValue = Boolean.TRUE;
					if (typeSeen)
						incompatibleArguments();
					typeSeen = true;
					break;
				}
				if ("flat".equalsIgnoreCase(str)) {
					propertyName = "collapsed";
					propertyValue = Boolean.FALSE;
					if (typeSeen)
						incompatibleArguments();
					typeSeen = true;
					break;
				}
				if ("edges".equalsIgnoreCase(str) || "noedges".equalsIgnoreCase(str)
						|| "frontedges".equalsIgnoreCase(str)) {
					if (edgeParameterSeen)
						incompatibleArguments();
					propertyName = (String) token.value;
					edgeParameterSeen = true;
					break;
				}
				if (!needsGenerating)
					insufficientArguments();
				if ("to".equalsIgnoreCase(str)) {
					if (nAtomSets > 1)
						invalidParameterOrder();
					if (statementLength > i + 2 && statement[i + 2].tok == Token.bitset) {
						propertyName = "toBitSet";
						propertyValue = statement[i + 2].value;
						i += 3;
						needsGenerating = true;
						break;
					}
					setPropertyName = "to";
					continue;
				}
				if ("faceCenterOffset".equalsIgnoreCase(str)) {
					decimalPropertyName = "faceCenterOffset";
					isDesignParameter = true;
					continue;
				}
				if ("distanceFactor".equalsIgnoreCase(str)) {
					decimalPropertyName = "distanceFactor";
					isDesignParameter = true;
					continue;
				}
				unrecognizedSubcommand(str);
			case Token.integer:
				if (nAtomSets > 0 && !isDesignParameter)
					invalidParameterOrder();
				// no reason not to allow integers when explicit
				if (decimalPropertyName == "radius_") {
					propertyName = "nVertices";
					propertyValue = new Integer(token.intValue);
					needsGenerating = true;
					break;
				}
			case Token.decimal:
				if (nAtomSets > 0 && !isDesignParameter)
					invalidParameterOrder();
				propertyName = (decimalPropertyName == "radius_" ? "radius" : decimalPropertyName);
				propertyValue = new Float(floatParameter(i));
				decimalPropertyName = "radius_";
				isDesignParameter = false;
				needsGenerating = true;
				break;
			case Token.delete:
			case Token.on:
			case Token.off:
				if (++i != statementLength || needsGenerating || nAtomSets > 1 || nAtomSets == 0
						&& setPropertyName == "to")
					incompatibleArguments();
				propertyName = (String) token.value;
				onOffDelete = true;
				break;
			case Token.expressionBegin:
				if (typeSeen)
					invalidParameterOrder();
				if (++nAtomSets > 2)
					badArgumentCount();
				if (setPropertyName == "to")
					needsGenerating = true;
				propertyName = setPropertyName;
				setPropertyName = "to";
				propertyValue = expression(statement, ++i);
				i = pcLastExpressionInstruction; // the for loop will increment i
				break;
			default:
				invalidArgument();
			}
			viewer.setShapeProperty(JmolConstants.SHAPE_POLYHEDRA, propertyName, propertyValue);
			if (onOffDelete)
				return;
		}
		if (!needsGenerating && !typeSeen && !edgeParameterSeen)
			insufficientArguments();
		if (needsGenerating)
			viewer.setShapeProperty(JmolConstants.SHAPE_POLYHEDRA, "generate", null);
		if (color != Integer.MIN_VALUE)
			viewer.setShapeProperty(JmolConstants.SHAPE_POLYHEDRA, "colorThis", new Integer(color));
		if (translucency.length() > 0)
			viewer.setShapeProperty(JmolConstants.SHAPE_POLYHEDRA, "translucencyThis", translucency);
	}