private boolean loadPage(final String uri) throws IOException, SAXException, UnsupportedFormatException {

		Debugger.print("Start loading page: " + uri);

		if (uri == null)
			return false;

		final String uriLC = uri.toLowerCase();
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				deselect();
				setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			}
		});

		String queryString = null;
		if (FileUtilities.isRemote(uri))
			queryString = new URL(uri).getQuery();

		if (queryString != null) {

			// load results from the search engine
			if (uriLC.indexOf("/cgi-bin/htsearch?") != -1) {
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						renderHTMLContent(uri.replaceAll(";", "&"), false);
					}
				});
			} else {
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						renderHTMLContent(uri, true);
					}
				});
			}

		}

		// load a JSP page
		else if (uriLC.endsWith(".jsp")) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					renderHTMLContent(uri, true);
				}
			});
		}

		// load a CML page
		else if (uriLC.endsWith(".cml")) {
			boolean loadSuccess = false;
			if (FileUtilities.isRemote(uri) && uriLC.endsWith(".cml")) {
				loadSuccess = decoder.read(FileUtilities.httpEncode(uri));
			} else {
				loadSuccess = decoder.read(uri);
			}
			if (loadSuccess) {
				/* Critically important!!!! */
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						StyledDocument doc = decoder.getDocument();
						if (doc == null)
							return;
						if (getDocument() instanceof DefaultStyledDocument) {
							DefaultStyledDocument dsd = (DefaultStyledDocument) getDocument();
							// release dependency of document on listeners for it to be garbage-collected
							DocumentListener[] dl = dsd.getDocumentListeners();
							if (dl != null) {
								for (DocumentListener i : dl)
									doc.removeDocumentListener(i);
							}
							UndoableEditListener[] ue = dsd.getUndoableEditListeners();
							if (ue != null) {
								for (UndoableEditListener i : ue)
									doc.removeUndoableEditListener(i);
							}
						}
						// getDocument().removeUndoableEditListener(undoHandler);
						// getDocument().removeDocumentListener(editResponder);
						doc.addUndoableEditListener(undoHandler);
						doc.addDocumentListener(editResponder);
						setStyledDocument(doc);
						// notify Editor to update buttons accordingly
						notifyPageListeners(new PageEvent(Page.this, PageEvent.PAGE_READ_END));
					}
				});
			} else {
				System.err.println("XML decoder failed......");
			}
		}

		// load a plain text file or a script source file
		else if (uriLC.endsWith(".txt") || uriLC.endsWith(".mws")) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					try {
						readPlainTextFile(uri);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		}

		// load an image file
		else if (uriLC.endsWith(".gif") || uriLC.endsWith(".png") || uriLC.endsWith(".jpg") || uriLC.endsWith(".jpeg")) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					readImageFile(uri);
				}
			});
		}

		// load a molecule with Jmol
		else if (uriLC.endsWith(".pdb") || uriLC.endsWith(".xyz")) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					loadMoleculeFile(uri);
				}
			});
		}

		// load a plain molecular dynamics model
		else if (uriLC.endsWith(".gbl") || uriLC.endsWith(".mml")) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					loadMDModel(uri);
				}
			});
		}

		else if (uriLC.endsWith(".jnlp")) {
			ExternalClient.open(ExternalClient.JNLP_CLIENT, uri, Page.this);
			notifyPageListeners(new PageEvent(this, PageEvent.PAGE_READ_END));
		}

		else if (uriLC.endsWith(".html") || uriLC.endsWith(".htm")) {
			ExternalClient.open(ExternalClient.HTML_CLIENT, uri, Page.this);
			notifyPageListeners(new PageEvent(this, PageEvent.PAGE_READ_END));
		}

		// unrecognized format
		else {
			if (uri.endsWith("/") || uri.endsWith("\\")) {
				loadPage(uri + "index.cml");
				return true;
			}
			if (FileUtilities.isRemote(uri)) {
				ExternalClient.open(ExternalClient.HTML_CLIENT, uri, Page.this);
				notifyPageListeners(new PageEvent(this, PageEvent.PAGE_READ_END));
				return true;
			}
			throw new UnsupportedFormatException(uri);
		}

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			}
		});

		Debugger.print("Finish loading page");

		return true;

	}