private BitSet parseLogicalExpression(String str, byte type) {

		if (AND_NOT.matcher(str).find() || OR_NOT.matcher(str).find()) {
			out(ScriptEvent.FAILED, "Illegal usage: " + str + ". Add parentheses to the not expression.");
			return null;
		}

		str = str.trim();

		if (str.toLowerCase().indexOf("within") != -1) {
			translateInfixToPostfix(translateWithinClauses(str));
		}
		else {
			translateInfixToPostfix(str);
		}

		// evaluate the postfix expression

		logicalStack.clear(); // make sure that the stack is empty before it is reused.

		int n = postfix.size();
		for (int i = 0; i < n; i++) {
			String s = postfix.get(i).trim();
			if (s.equalsIgnoreCase("not")) {
				BitSet bs = (BitSet) logicalStack.pop();
				bs.flip(0, getNumberOfObjects(type));
				logicalStack.push(bs);
			}
			else if (s.equalsIgnoreCase("or") || s.equalsIgnoreCase("and")) {
				BitSet bs1 = null, bs2 = null;
				try {
					bs2 = (BitSet) logicalStack.pop();
					bs1 = (BitSet) logicalStack.pop();
				}
				catch (EmptyStackException e) {
					e.printStackTrace();
					continue;
				}
				BitSet bs = new BitSet();
				if (s.equalsIgnoreCase("or")) {
					bs.or(bs2);
					bs.or(bs1);
				}
				else if (s.equalsIgnoreCase("and")) {
					bs.or(bs2);
					bs.and(bs1);
				}
				logicalStack.push(bs);
			}
			else {
				BitSet bs = null;
				if (s.toLowerCase().indexOf("within") != -1) {
					boolean startsWithNot = false;
					if (s.toLowerCase().startsWith("not")) {
						startsWithNot = true;
						s = s.substring(3).trim();
					}
					if (withinMap != null && withinMap.containsKey(s)) {
						s = withinMap.get(s);
					}
					if (startsWithNot)
						s = "not " + s;
				}
				switch (type) {
				case BY_ATOM:
					bs = selectAtoms(s);
					break;
				case BY_ELEMENT:
					bs = selectElements(s);
					break;
				case BY_RBOND:
					bs = selectRBonds(s);
					break;
				case BY_ABOND:
					bs = selectABonds(s);
					break;
				case BY_TBOND:
					bs = selectTBonds(s);
					break;
				case BY_MOLECULE:
					break;
				}
				if (bs != null) {
					logicalStack.push(bs);
				}
				else {
					System.err.println("null bitset");
				}
			}
		}

		BitSet bs = (BitSet) logicalStack.pop();
		switch (type) {
		case BY_ATOM:
		case BY_ELEMENT:
			model.setAtomSelectionSet(bs);
			break;
		case BY_RBOND:
			model.setRBondSelectionSet(bs);
			break;
		case BY_ABOND:
			model.setABondSelectionSet(bs);
			break;
		case BY_TBOND:
			model.setTBondSelectionSet(bs);
			break;
		case BY_MOLECULE:
			break;
		}

		return bs;

	}