diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/AuthorizeTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/AuthorizeTagHandler.java
new file mode 100644
index 000000000..b8f32aa1d
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/AuthorizeTagHandler.java
@@ -0,0 +1,143 @@
+package net.sourceforge.guacamole.net.basic.xml.user_mapping;
+
+/*
+ * Guacamole - Clientless Remote Desktop
+ * Copyright (C) 2010 Michael Jumper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import net.sourceforge.guacamole.net.basic.auth.Authorization;
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "authorize" element.
+ *
+ * @author Mike Jumper
+ */
+public class AuthorizeTagHandler implements TagHandler {
+
+ /**
+ * The Authorization corresponding to the "authorize" tag being handled
+ * by this tag handler. The data of this Authorization will be populated
+ * as the tag is parsed.
+ */
+ private Authorization authorization = new Authorization();
+
+ /**
+ * The default GuacamoleConfiguration to use if "param" or "protocol"
+ * tags occur outside a "connection" tag.
+ */
+ private GuacamoleConfiguration default_config = null;
+
+ /**
+ * Creates a new handler for an "authorize" tag having the given
+ * attributes.
+ *
+ * @param attributes The attributes of the "authorize" tag.
+ * @throws SAXException If the attributes given are not valid.
+ */
+ public AuthorizeTagHandler(Attributes attributes) throws SAXException {
+
+ // Init username and password
+ authorization.setUsername(attributes.getValue("username"));
+ authorization.setPassword(attributes.getValue("password"));
+
+ // Get encoding
+ String encoding = attributes.getValue("encoding");
+ if (encoding != null) {
+
+ // If "md5", use MD5 encoding
+ if (encoding.equals("md5"))
+ authorization.setEncoding(Authorization.Encoding.MD5);
+
+ // If "plain", use plain text
+ else if (encoding.equals("plain"))
+ authorization.setEncoding(Authorization.Encoding.PLAIN_TEXT);
+
+ // Otherwise, bad encoding
+ else
+ throw new SAXException(
+ "Invalid encoding: '" + encoding + "'");
+
+ }
+
+ }
+
+ @Override
+ public TagHandler childElement(String localName, Attributes attributes) throws SAXException {
+
+ // "connection" tag
+ if (localName.equals("connection")) {
+
+ // Get tag handler for connection tag
+ ConnectionTagHandler tagHandler = new ConnectionTagHandler(attributes);
+
+ // Store configuration stub
+ GuacamoleConfiguration config_stub = tagHandler.asGuacamoleConfiguration();
+ authorization.addConfiguration(tagHandler.getName(), config_stub);
+
+ return tagHandler;
+ }
+
+ // "param" tag
+ if (localName.equals("param")) {
+
+ // Create default config if it doesn't exist
+ if (default_config == null) {
+ default_config = new GuacamoleConfiguration();
+ authorization.addConfiguration("DEFAULT", default_config);
+ }
+
+ return new ParamTagHandler(default_config, attributes);
+ }
+
+ // "protocol" tag
+ if (localName.equals("protocol")) {
+
+ // Create default config if it doesn't exist
+ if (default_config == null) {
+ default_config = new GuacamoleConfiguration();
+ authorization.addConfiguration("DEFAULT", default_config);
+ }
+
+ return new ProtocolTagHandler(default_config);
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+ /**
+ * Returns an Authorization backed by the data of this authorize tag
+ * handler. This Authorization is guaranteed to at least have the username,
+ * password, and encoding available. Any associated configurations will be
+ * added dynamically as the authorize tag is parsed.
+ *
+ * @return An Authorization backed by the data of this authorize tag
+ * handler.
+ */
+ public Authorization asAuthorization() {
+ return authorization;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ConnectionTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ConnectionTagHandler.java
new file mode 100644
index 000000000..d676ad072
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ConnectionTagHandler.java
@@ -0,0 +1,94 @@
+package net.sourceforge.guacamole.net.basic.xml.user_mapping;
+
+/*
+ * Guacamole - Clientless Remote Desktop
+ * Copyright (C) 2010 Michael Jumper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "connection" element.
+ *
+ * @author Mike Jumper
+ */
+public class ConnectionTagHandler implements TagHandler {
+
+ /**
+ * The GuacamoleConfiguration backing this tag handler.
+ */
+ private GuacamoleConfiguration config = new GuacamoleConfiguration();
+
+ /**
+ * The name associated with the connection being parsed.
+ */
+ private String name;
+
+ /**
+ * Creates a new handler for an "connection" tag having the given
+ * attributes.
+ *
+ * @param attributes The attributes of the "connection" tag.
+ * @throws SAXException If the attributes given are not valid.
+ */
+ public ConnectionTagHandler(Attributes attributes) throws SAXException {
+ name = attributes.getValue("name");
+ }
+
+ @Override
+ public TagHandler childElement(String localName, Attributes attributes) throws SAXException {
+
+ if (localName.equals("param"))
+ return new ParamTagHandler(config, attributes);
+
+ if (localName.equals("protocol"))
+ return new ProtocolTagHandler(config);
+
+ return null;
+
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+ /**
+ * Returns a GuacamoleConfiguration whose contents are populated from data
+ * within this connection element and child elements. This
+ * GuacamoleConfiguration will continue to be modified as the user mapping
+ * is parsed.
+ *
+ * @return A GuacamoleConfiguration whose contents are populated from data
+ * within this connection element.
+ */
+ public GuacamoleConfiguration asGuacamoleConfiguration() {
+ return config;
+ }
+
+ /**
+ * Returns the name associated with this connection.
+ *
+ * @return The name associated with this connection.
+ */
+ public String getName() {
+ return name;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ParamTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ParamTagHandler.java
new file mode 100644
index 000000000..e29824f3a
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ParamTagHandler.java
@@ -0,0 +1,62 @@
+package net.sourceforge.guacamole.net.basic.xml.user_mapping;
+
+/*
+ * Guacamole - Clientless Remote Desktop
+ * Copyright (C) 2010 Michael Jumper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "param" element.
+ *
+ * @author Mike Jumper
+ */
+public class ParamTagHandler implements TagHandler {
+
+ /**
+ * The GuacamoleConfiguration which will be populated with data from
+ * the tag handled by this tag handler.
+ */
+ private GuacamoleConfiguration config;
+
+ /**
+ * Creates a new handler for an "param" tag having the given
+ * attributes.
+ *
+ * @param config The GuacamoleConfiguration to update with the data parsed
+ * from the "protocol" tag.
+ * @param attributes The attributes of the "param" tag.
+ * @throws SAXException If the attributes given are not valid.
+ */
+ public ParamTagHandler(GuacamoleConfiguration config,
+ Attributes attributes) throws SAXException {
+ }
+
+ @Override
+ public TagHandler childElement(String localName, Attributes attributes) throws SAXException {
+ throw new SAXException("The 'param' tag can contain no elements.");
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ProtocolTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ProtocolTagHandler.java
new file mode 100644
index 000000000..ee0faef41
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/ProtocolTagHandler.java
@@ -0,0 +1,61 @@
+package net.sourceforge.guacamole.net.basic.xml.user_mapping;
+
+/*
+ * Guacamole - Clientless Remote Desktop
+ * Copyright (C) 2010 Michael Jumper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "protocol" element.
+ *
+ * @author Mike Jumper
+ */
+public class ProtocolTagHandler implements TagHandler {
+
+ /**
+ * The GuacamoleConfiguration which will be populated with data from
+ * the tag handled by this tag handler.
+ */
+ private GuacamoleConfiguration config;
+
+ /**
+ * Creates a new handler for a "protocol" tag having the given
+ * attributes.
+ *
+ * @param config The GuacamoleConfiguration to update with the data parsed
+ * from the "protocol" tag.
+ * @throws SAXException If the attributes given are not valid.
+ */
+ public ProtocolTagHandler(GuacamoleConfiguration config) throws SAXException {
+ this.config = config;
+ }
+
+ @Override
+ public TagHandler childElement(String localName, Attributes attributes) throws SAXException {
+ throw new SAXException("The 'protocol' tag can contain no elements.");
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ config.setProtocol(textContent);
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/UserMappingTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/UserMappingTagHandler.java
new file mode 100644
index 000000000..09c5d92d4
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/user_mapping/UserMappingTagHandler.java
@@ -0,0 +1,81 @@
+package net.sourceforge.guacamole.net.basic.xml.user_mapping;
+
+/*
+ * Guacamole - Clientless Remote Desktop
+ * Copyright (C) 2010 Michael Jumper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import net.sourceforge.guacamole.net.basic.auth.Authorization;
+import net.sourceforge.guacamole.net.basic.auth.UserMapping;
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "user-mapping" element.
+ *
+ * @author Mike Jumper
+ */
+public class UserMappingTagHandler implements TagHandler {
+
+ /**
+ * The UserMapping which will contain all data parsed by this tag handler.
+ */
+ private UserMapping user_mapping = new UserMapping();
+
+ @Override
+ public TagHandler childElement(String localName, Attributes attributes) throws SAXException {
+
+ // Start parsing of authorize tags, add to list of all authorizations
+ if (localName.equals("authorize")) {
+
+ // Get tag handler for authorize tag
+ AuthorizeTagHandler tagHandler =
+ new AuthorizeTagHandler(attributes);
+
+ // Store authorization stub in map of authorizations
+ Authorization auth_stub = tagHandler.asAuthorization();
+ user_mapping.addAuthorization(auth_stub);
+
+ return tagHandler;
+
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+ /**
+ * Returns a user mapping containing all authorizations and configurations
+ * parsed so far. This user mapping will be backed by the data being parsed,
+ * thus any additional authorizations or configurations will be available
+ * in the object returned by this function even after this function has
+ * returned, once the data corresponding to those authorizations or
+ * configurations has been parsed.
+ *
+ * @return A user mapping containing all authorizations and configurations
+ * parsed so far.
+ */
+ public UserMapping asUserMapping() {
+ return user_mapping;
+ }
+
+}