diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolInfo.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolInfo.java
new file mode 100644
index 000000000..996fee8a5
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolInfo.java
@@ -0,0 +1,99 @@
+
+package net.sourceforge.guacamole.net.basic;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Describes a protocol and all parameters associated with it, as required by
+ * a protocol plugin for guacd. This class allows known parameters for a
+ * protocol to be exposed to the user as friendly fields.
+ *
+ * @author Michael Jumper
+ */
+public class ProtocolInfo {
+
+ /**
+ * The human-readable title associated with this protocol.
+ */
+ private String title;
+
+ /**
+ * The unique name associated with this protocol.
+ */
+ private String name;
+
+ /**
+ * A collection of all associated protocol parameters.
+ */
+ private Collection parameters =
+ new ArrayList();
+
+ /**
+ * Returns the human-readable title associated with this protocol.
+ *
+ * @return The human-readable title associated with this protocol.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the human-readable title associated with this protocol.
+ *
+ * @param title The human-readable title to associate with this protocol.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Returns the unique name of this protocol. The protocol name is the
+ * value required by the corresponding protocol plugin for guacd.
+ *
+ * @return The unique name of this protocol.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the unique name of this protocol. The protocol name is the value
+ * required by the corresponding protocol plugin for guacd.
+ *
+ * @param name The unique name of this protocol.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns a mutable collection of the protocol parameters associated with
+ * this protocol. Changes to this collection affect the parameters exposed
+ * to the user.
+ *
+ * @return A mutable collection of protocol parameters.
+ */
+ public Collection getParameters() {
+ return parameters;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameter.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameter.java
new file mode 100644
index 000000000..69b3729a7
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameter.java
@@ -0,0 +1,148 @@
+
+package net.sourceforge.guacamole.net.basic;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Represents a parameter of a protocol.
+ *
+ * @author Michael Jumper
+ */
+public class ProtocolParameter {
+
+ /**
+ * All possible types of protocol parameter.
+ */
+ public enum Type {
+
+ /**
+ * A text parameter, accepting arbitrary values.
+ */
+ TEXT,
+
+ /**
+ * A password parameter, whose value is sensitive and must be hidden.
+ */
+ PASSWORD,
+
+ /**
+ * A numeric parameter, whose value must contain only digits.
+ */
+ NUMERIC,
+
+ /**
+ * A boolean parameter, whose value is either blank or "true".
+ */
+ BOOLEAN,
+
+ /**
+ * An enumerated parameter, whose legal values are fully enumerated
+ * by a provided, finite list.
+ */
+ ENUM
+ }
+
+ /**
+ * The unique name that identifies this parameter to the protocol plugin.
+ */
+ private String name;
+
+ /**
+ * A human-readable name to be presented to the user.
+ */
+ private String title;
+
+ /**
+ * The type of this field.
+ */
+ private Type type;
+
+ /**
+ * A collection of all associated parameter options.
+ */
+ private Collection options =
+ new ArrayList();
+
+ /**
+ * Returns the name associated with this protocol parameter.
+ * @return The name associated with this protocol parameter.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name associated with this protocol parameter. This name must
+ * uniquely identify this parameter among the others accepted by the
+ * corresponding protocol.
+ *
+ * @param name The name to assign to this protocol parameter.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the title associated with this protocol parameter.
+ * @return The title associated with this protocol parameter.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the title associated with this protocol parameter. The title must
+ * be a human-readable string which describes accurately this parameter.
+ *
+ * @param title A human-readable string describing this parameter.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Returns the type of this parameter.
+ * @return The type of this parameter.
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * Sets the type of this parameter.
+ * @param type The type of this parameter.
+ */
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns a mutable collection of protocol parameter options. Changes to
+ * this collection directly affect the available options.
+ *
+ * @return A mutable collection of parameter options.
+ */
+ public Collection getOptions() {
+ return options;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameterOption.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameterOption.java
new file mode 100644
index 000000000..5416e6ad9
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/ProtocolParameterOption.java
@@ -0,0 +1,76 @@
+
+package net.sourceforge.guacamole.net.basic;
+
+/*
+ * 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 .
+ */
+
+/**
+ * Describes an available legal value for an enumerated protocol parameter.
+ *
+ * @author Michael Jumper
+ */
+public class ProtocolParameterOption {
+
+ /**
+ * The value that will be sent to the client plugin if this option is
+ * chosen.
+ */
+ private String value;
+
+ /**
+ * A human-readable title describing the effect of the value.
+ */
+ private String title;
+
+ /**
+ * Returns the value that will be sent to the client plugin if this option
+ * is chosen.
+ *
+ * @return The value that will be sent if this option is chosen.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value that will be sent to the client plugin if this option is
+ * chosen.
+ *
+ * @param value The value to send if this option is chosen.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the human-readable title describing the effect of this option.
+ * @return The human-readable title describing the effect of this option.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the human-readable title describing the effect of this option.
+ * @param title A human-readable title describing the effect of this option.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/OptionTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/OptionTagHandler.java
new file mode 100644
index 000000000..d7768eee3
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/OptionTagHandler.java
@@ -0,0 +1,61 @@
+package net.sourceforge.guacamole.net.basic.xml.protocol;
+
+/*
+ * 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.ProtocolParameterOption;
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "option" element.
+ *
+ * @author Mike Jumper
+ */
+public class OptionTagHandler implements TagHandler {
+
+ /**
+ * The option backing this option tag.
+ */
+ private ProtocolParameterOption option = new ProtocolParameterOption();
+
+ @Override
+ public void init(Attributes attributes) throws SAXException {
+ option.setValue(attributes.getValue("value"));
+ }
+
+ @Override
+ public TagHandler childElement(String localName) throws SAXException {
+ throw new SAXException("The 'param' tag can contain no elements.");
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ option.setTitle(textContent);
+ }
+
+ /**
+ * Returns the ProtocolParameterOption backing this tag.
+ * @return The ProtocolParameterOption backing this tag.
+ */
+ public ProtocolParameterOption asProtocolParameterOption() {
+ return option;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ParamTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ParamTagHandler.java
new file mode 100644
index 000000000..627e26038
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ParamTagHandler.java
@@ -0,0 +1,106 @@
+package net.sourceforge.guacamole.net.basic.xml.protocol;
+
+/*
+ * 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.ProtocolParameter;
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "param" element.
+ *
+ * @author Mike Jumper
+ */
+public class ParamTagHandler implements TagHandler {
+
+ /**
+ * The ProtocolParameter backing this tag handler.
+ */
+ private ProtocolParameter protocolParameter = new ProtocolParameter();
+
+ @Override
+ public void init(Attributes attributes) throws SAXException {
+
+ protocolParameter.setName(attributes.getValue("name"));
+ protocolParameter.setTitle(attributes.getValue("title"));
+
+ // Parse type
+ String type = attributes.getValue("type");
+
+ // Text field
+ if ("text".equals(type))
+ protocolParameter.setType(ProtocolParameter.Type.TEXT);
+
+ // Numeric field
+ else if ("numeric".equals(type))
+ protocolParameter.setType(ProtocolParameter.Type.NUMERIC);
+
+ // Password field
+ else if ("password".equals(type))
+ protocolParameter.setType(ProtocolParameter.Type.PASSWORD);
+
+ // Enumerated field
+ else if ("enum".equals(type))
+ protocolParameter.setType(ProtocolParameter.Type.ENUM);
+
+ // Boolean field
+ else if ("boolean".equals(type))
+ protocolParameter.setType(ProtocolParameter.Type.BOOLEAN);
+
+ // Otherwise, fail with unrecognized type
+ else
+ throw new SAXException("Invalid parameter type: " + type);
+
+ }
+
+ @Override
+ public TagHandler childElement(String localName) throws SAXException {
+
+ // Start parsing of option tags
+ if (localName.equals("option")) {
+
+ // Get tag handler for option tag
+ OptionTagHandler tagHandler = new OptionTagHandler();
+
+ // Store stub in options collection
+ protocolParameter.getOptions().add(
+ tagHandler.asProtocolParameterOption());
+ return tagHandler;
+
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+ /**
+ * Returns the ProtocolParameter backing this tag.
+ * @return The ProtocolParameter backing this tag.
+ */
+ public ProtocolParameter asProtocolParameter() {
+ return protocolParameter;
+ }
+
+}
diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ProtocolTagHandler.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ProtocolTagHandler.java
new file mode 100644
index 000000000..4ff90bd5f
--- /dev/null
+++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/basic/xml/protocol/ProtocolTagHandler.java
@@ -0,0 +1,77 @@
+package net.sourceforge.guacamole.net.basic.xml.protocol;
+
+/*
+ * 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.ProtocolInfo;
+import net.sourceforge.guacamole.net.basic.xml.TagHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * TagHandler for the "protocol" element.
+ *
+ * @author Mike Jumper
+ */
+public class ProtocolTagHandler implements TagHandler {
+
+ /**
+ * The ProtocolInfo object which will contain all data parsed by this tag
+ * handler.
+ */
+ private ProtocolInfo info = new ProtocolInfo();
+
+ @Override
+ public void init(Attributes attributes) throws SAXException {
+ info.setName(attributes.getValue("name"));
+ info.setTitle(attributes.getValue("title"));
+ }
+
+ @Override
+ public TagHandler childElement(String localName) throws SAXException {
+
+ // Start parsing of param tags, add to list of all parameters
+ if (localName.equals("param")) {
+
+ // Get tag handler for param tag
+ ParamTagHandler tagHandler = new ParamTagHandler();
+
+ // Store stub in parameters collection
+ info.getParameters().add(tagHandler.asProtocolParameter());
+ return tagHandler;
+
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public void complete(String textContent) throws SAXException {
+ // Do nothing
+ }
+
+ /**
+ * Returns the ProtocolInfo backing this tag.
+ * @return The ProtocolInfo backing this tag.
+ */
+ public ProtocolInfo asProtocolInfo() {
+ return info;
+ }
+
+}