private boolean read(InputStream in) throws IOException, SAXException {

		if (in == null)
			return false;

		loadingTime = System.currentTimeMillis();

		if (saxParser == null) {
			try {
				saxParser = SAXParserFactory.newInstance().newSAXParser();
			}
			catch (ParserConfigurationException e) {
				e.printStackTrace();
			}
		}
		if (saxParser == null) {
			in.close();
			return false;
		}

		doc = new DefaultStyledDocument(); // do we really need to create a new instance?

		boolean success = true;
		boolean caughtUSE = false;
		boolean caughtIOE = false;
		boolean caughtSAX = false;
		String msg = null;

		// although this method throws exceptions, they must be handled within this method body in order to close I/O
		// channels, before they are propagated.

		try {
			saxParser.parse(new InputSource(in), saxHandler);
		}
		catch (SAXException e) {
			success = false;
			msg = e.getMessage();
			caughtSAX = true;
		}
		catch (IOException e) {
			success = false;
			msg = e.getMessage();
			if (e instanceof UnsupportedEncodingException) {
				caughtUSE = true;
			}
			else {
				caughtIOE = true;
			}
		}
		finally {
			in.close();
		}

		// propagate exceptions
		if (caughtUSE)
			throw new UnsupportedEncodingException(msg);
		if (caughtIOE)
			throw new IOException(msg);
		if (caughtSAX)
			throw new SAXException(msg);

		return success;

	}