Ejemplo n.º 1
0
    public GraphNode <T> AddVertex(T _value)
    {
        var node = new GraphNode <T>(_value);

        Nodes.AddLast(node);
        return(node);
    }
Ejemplo n.º 2
0
        private void Add(Entity entity)
        {
            var item = CreateFromEntity(entity);

            nodeEntityMap.Add(item, entity);

            var node = new LinkedListNode <T>(item);

            entityNodeMap.Add(entity, node);
            Nodes.AddLast(node);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Connects the nodes at the first and last position, using the route given by the (optional) positions in between.
        /// If there is already a node at a given position, it is reused, otherwise new nodes are created.
        /// </summary>
        /// <param name="positions">The positions.</param>
        public void ConnectNodes(IEnumerable <Point> positions)
        {
            RoadGraphNode lastNode = null;

            foreach (var point in positions)
            {
                var node = FindNode(point);
                if (node == null)
                {
                    node = new RoadGraphNode(point, true, false);
                    Nodes.AddLast(node);
                }
                if (lastNode != null)
                {
                    node.LinkTo(lastNode);
                }
                lastNode = node;
            }
        }
Ejemplo n.º 4
0
        private async void GetFormHandler(object Sender, IqEventArgs e)
        {
            try
            {
                LinkedList <IThingReference> Nodes = null;
                XmlElement E;
                string     ServiceToken = XML.Attribute(e.Query, "st");
                string     DeviceToken  = XML.Attribute(e.Query, "dt");
                string     UserToken    = XML.Attribute(e.Query, "ut");

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    if (E.LocalName == "nd")
                    {
                        if (Nodes is null)
                        {
                            Nodes = new LinkedList <IThingReference>();
                        }

                        string NodeId    = XML.Attribute(E, "id");
                        string SourceId  = XML.Attribute(E, "src");
                        string Partition = XML.Attribute(E, "pt");

                        if (this.OnGetNode is null)
                        {
                            Nodes.AddLast(new ThingReference(NodeId, SourceId, Partition));
                        }
                        else
                        {
                            IThingReference Ref = await this.OnGetNode(NodeId, SourceId, Partition);

                            if (Ref is null)
                            {
                                throw new ItemNotFoundException("Node not found.", e.IQ);
                            }

                            Nodes.AddLast(Ref);
                        }
                    }
                }

                ControlParameter[] Parameters;

                if (Nodes is null)
                {
                    Parameters = await this.GetControlParameters(null);

                    if (Parameters is null)
                    {
                        NotFound(e);
                        return;
                    }
                }
                else
                {
                    Dictionary <string, ControlParameter> Parameters1;
                    Dictionary <string, ControlParameter> Parameters2;
                    LinkedList <string> ToRemove = null;

                    Parameters  = null;
                    Parameters1 = null;

                    foreach (IThingReference Node in Nodes)
                    {
                        if (Parameters1 is null)
                        {
                            Parameters = await this.GetControlParameters(Node);

                            if (Parameters is null)
                            {
                                NotFound(e);
                                return;
                            }

                            Parameters1 = new Dictionary <string, ControlParameter>();

                            foreach (ControlParameter P in Parameters)
                            {
                                Parameters1[P.Name] = P;
                            }
                        }
                        else
                        {
                            Parameters2 = await this.GetControlParametersByName(Node);

                            if (Parameters2 is null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (KeyValuePair <string, ControlParameter> P in Parameters1)
                            {
                                if (!Parameters2.TryGetValue(P.Key, out ControlParameter P2) || !P.Value.Equals(P2))
                                {
                                    if (ToRemove is null)
                                    {
                                        ToRemove = new LinkedList <string>();
                                    }

                                    ToRemove.AddLast(P.Key);
                                }
                            }

                            if (ToRemove != null)
                            {
                                foreach (string Key in ToRemove)
                                {
                                    Parameters1.Remove(Key);
                                }

                                ToRemove = null;
                            }
                        }
                    }

                    List <ControlParameter> Left = new List <ControlParameter>();

                    foreach (ControlParameter P in Parameters)
                    {
                        if (Parameters1.ContainsKey(P.Name))
                        {
                            Left.Add(P);
                        }
                    }

                    Parameters = Left.ToArray();
                }

                if (this.provisioningClient != null)
                {
                    int      i, c = Parameters.Length;
                    string[] ParameterNames = new string[c];

                    for (i = 0; i < c; i++)
                    {
                        ParameterNames[i] = Parameters[i].Name;
                    }

                    this.provisioningClient.CanControl(e.FromBareJid, Nodes, ParameterNames,
                                                       ServiceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       DeviceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       UserToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       (sender2, e2) =>
                    {
                        if (e2.Ok && e2.CanControl)
                        {
                            if (e2.ParameterNames != null)
                            {
                                List <ControlParameter> Parameters2 = new List <ControlParameter>();

                                foreach (ControlParameter P in Parameters)
                                {
                                    if (Array.IndexOf <string>(e2.ParameterNames, P.Name) >= 0)
                                    {
                                        Parameters2.Add(P);
                                    }
                                }

                                Parameters = Parameters2.ToArray();

                                if (Parameters.Length == 0)
                                {
                                    e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                              "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                                    return;
                                }
                            }

                            this.ReturnForm(e, Parameters, Nodes);
                        }
                        else
                        {
                            e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                      "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                        }
                    }, null);
                }
                else
                {
                    this.ReturnForm(e, Parameters, Nodes);
                }
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }
Ejemplo n.º 5
0
        private async void SetHandler(object Sender, IqEventArgs e)
        {
            try
            {
                string ServiceToken = XML.Attribute(e.Query, "st");
                string DeviceToken  = XML.Attribute(e.Query, "dt");
                string UserToken    = XML.Attribute(e.Query, "ut");

                LinkedList <IThingReference>    Nodes          = null;
                SortedDictionary <string, bool> ParameterNames = this.provisioningClient is null ? null : new SortedDictionary <string, bool>();
                LinkedList <ControlOperation>   Operations     = new LinkedList <ControlOperation>();
                ControlParameter Parameter;
                DataForm         Form = null;
                XmlElement       E;
                string           Name;

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    switch (E.LocalName)
                    {
                    case "nd":
                        if (Nodes is null)
                        {
                            Nodes = new LinkedList <IThingReference>();
                        }

                        string NodeId    = XML.Attribute(E, "id");
                        string SourceId  = XML.Attribute(E, "src");
                        string Partition = XML.Attribute(E, "pt");

                        if (this.OnGetNode is null)
                        {
                            Nodes.AddLast(new ThingReference(NodeId, SourceId, Partition));
                        }
                        else
                        {
                            IThingReference Ref = await this.OnGetNode(NodeId, SourceId, Partition);

                            if (Ref is null)
                            {
                                throw new ItemNotFoundException("Node not found.", e.IQ);
                            }

                            Nodes.AddLast(Ref);
                        }
                        break;

                    case "b":
                    case "cl":
                    case "d":
                    case "dt":
                    case "db":
                    case "dr":
                    case "e":
                    case "i":
                    case "l":
                    case "s":
                    case "t":
                        if (ParameterNames != null)
                        {
                            ParameterNames[XML.Attribute(E, "n")] = true;
                        }
                        break;

                    case "x":
                        Form = new DataForm(this.client, E, null, null, e.From, e.To);
                        if (Form.Type != FormType.Submit)
                        {
                            ParameterBadRequest(e);
                            return;
                        }

                        if (ParameterNames != null)
                        {
                            foreach (Field Field in Form.Fields)
                            {
                                ParameterNames[Field.Var] = true;
                            }
                        }
                        break;

                    default:
                        ParameterBadRequest(e);
                        return;
                    }
                }

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    switch (E.LocalName)
                    {
                    case "b":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            BooleanControlParameter BooleanControlParameter = Parameter as BooleanControlParameter;
                            if (BooleanControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new BooleanControlOperation(Node, BooleanControlParameter, XML.Attribute(E, "v", false), e));
                        }
                        break;

                    case "cl":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            ColorControlParameter ColorControlParameter = Parameter as ColorControlParameter;
                            if (ColorControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new ColorControlOperation(Node, ColorControlParameter, XML.Attribute(E, "v"), e));
                        }
                        break;

                    case "d":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DateControlParameter DateControlParameter = Parameter as DateControlParameter;
                            if (DateControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DateControlOperation(Node, DateControlParameter, XML.Attribute(E, "v", DateTime.MinValue), e));
                        }
                        break;

                    case "dt":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DateTimeControlParameter DateTimeControlParameter = Parameter as DateTimeControlParameter;
                            if (DateTimeControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DateTimeControlOperation(Node, DateTimeControlParameter, XML.Attribute(E, "v", DateTime.MinValue), e));
                        }
                        break;

                    case "db":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DoubleControlParameter DoubleControlParameter = Parameter as DoubleControlParameter;
                            if (DoubleControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DoubleControlOperation(Node, DoubleControlParameter, XML.Attribute(E, "v", 0.0), e));
                        }
                        break;

                    case "dr":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DurationControlParameter DurationControlParameter = Parameter as DurationControlParameter;
                            if (DurationControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DurationControlOperation(Node, DurationControlParameter, XML.Attribute(E, "v", Duration.Zero), e));
                        }
                        break;

                    case "e":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            string StringValue = XML.Attribute(E, "v");

                            if (Parameter is EnumControlParameter EnumControlParameter)
                            {
                                Type T = Types.GetType(XML.Attribute(E, "t"));
                                if (T is null)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Type not found.</paramError></error>");
                                    return;
                                }

                                if (!T.GetTypeInfo().IsEnum)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Type is not an enumeration.</paramError></error>");
                                    return;
                                }

                                Enum Value;

                                try
                                {
                                    Value = (Enum)Enum.Parse(T, StringValue);
                                }
                                catch (Exception)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Value not valid element of enumeration.</paramError></error>");
                                    return;
                                }

                                Operations.AddLast(new EnumControlOperation(Node, EnumControlParameter, Value, e));
                            }
                            else if (Parameter is StringControlParameter StringControlParameter)
                            {
                                Operations.AddLast(new StringControlOperation(Node, StringControlParameter, StringValue, e));
                            }
                            else if (Parameter is MultiLineTextControlParameter MultiLineTextControlParameter)
                            {
                                Operations.AddLast(new MultiLineTextControlOperation(Node, MultiLineTextControlParameter, StringValue, e));
                            }
                            else
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }
                        }
                        break;

                    case "i":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            Int32ControlParameter Int32ControlParameter = Parameter as Int32ControlParameter;
                            if (Int32ControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new Int32ControlOperation(Node, Int32ControlParameter, XML.Attribute(E, "v", 0), e));
                        }
                        break;

                    case "l":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            Int64ControlParameter Int64ControlParameter = Parameter as Int64ControlParameter;
                            if (Int64ControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new Int64ControlOperation(Node, Int64ControlParameter, XML.Attribute(E, "v", 0L), e));
                        }
                        break;

                    case "s":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            if (Parameter is StringControlParameter StringControlParameter)
                            {
                                Operations.AddLast(new StringControlOperation(Node, StringControlParameter, XML.Attribute(E, "v"), e));
                            }
                            else if (Parameter is MultiLineTextControlParameter MultiLineTextControlParameter)
                            {
                                Operations.AddLast(new MultiLineTextControlOperation(Node, MultiLineTextControlParameter, XML.Attribute(E, "v"), e));
                            }
                            else
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }
                        }
                        break;

                    case "t":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            TimeControlParameter TimeControlParameter = Parameter as TimeControlParameter;
                            if (TimeControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new TimeControlOperation(Node, TimeControlParameter, XML.Attribute(E, "v", TimeSpan.Zero), e));
                        }
                        break;

                    case "x":
                        Dictionary <string, ControlParameter> Parameters;

                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameters = await this.GetControlParametersByName(Node);

                            if (Parameters is null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (Field Field in Form.Fields)
                            {
                                if (!Parameters.TryGetValue(Field.Var, out Parameter))
                                {
                                    ParameterNotFound(Field.Var, e);
                                    return;
                                }

                                Operations.AddLast(new FormControlOperation(Node, Parameter, Field.ValueString, e));
                            }
                        }
                        break;
                    }
                }

                if (this.provisioningClient != null)
                {
                    string[] ParameterNames2 = new string[ParameterNames.Count];
                    ParameterNames.Keys.CopyTo(ParameterNames2, 0);

                    this.provisioningClient.CanControl(e.FromBareJid, Nodes, ParameterNames2,
                                                       ServiceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       DeviceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       UserToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       (sender2, e2) =>
                    {
                        if (e2.Ok && e2.CanControl)
                        {
                            LinkedList <ControlOperation> Operations2 = null;
                            bool Restricted;

                            if (e2.Nodes != null || e2.ParameterNames != null)
                            {
                                Dictionary <IThingReference, bool> AllowedNodes = null;
                                Dictionary <string, bool> AllowedParameterNames = null;

                                Operations2 = new LinkedList <ControlOperation>();
                                Restricted  = false;

                                if (e2.Nodes != null)
                                {
                                    AllowedNodes = new Dictionary <IThingReference, bool>();
                                    foreach (IThingReference Node in e2.Nodes)
                                    {
                                        AllowedNodes[Node] = true;
                                    }
                                }

                                if (e2.ParameterNames != null)
                                {
                                    AllowedParameterNames = new Dictionary <string, bool>();
                                    foreach (string ParameterName in e2.ParameterNames)
                                    {
                                        AllowedParameterNames[ParameterName] = true;
                                    }
                                }

                                foreach (ControlOperation Operation in Operations)
                                {
                                    if (AllowedNodes != null && !AllowedNodes.ContainsKey(Operation.Node ?? ThingReference.Empty))
                                    {
                                        Restricted = true;
                                        continue;
                                    }

                                    if (AllowedParameterNames != null && !AllowedParameterNames.ContainsKey(Operation.ParameterName))
                                    {
                                        Restricted = true;
                                        continue;
                                    }

                                    Operations2.AddLast(Operation);
                                }
                            }
                            else
                            {
                                Restricted = false;
                            }

                            if (Restricted)
                            {
                                this.PerformOperations(Operations2, e, e2.Nodes, e2.ParameterNames);
                            }
                            else
                            {
                                this.PerformOperations(Operations, e, null, null);
                            }
                        }
                        else
                        {
                            e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                      "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                        }
                    }, null);
                }
                else
                {
                    this.PerformOperations(Operations, e, null, null);
                }
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }
Ejemplo n.º 6
0
        private async void GetFormHandler(object Sender, IqEventArgs e)
        {
            try
            {
                LinkedList <ThingReference> Nodes = null;
                XmlElement E;

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E == null)
                    {
                        continue;
                    }

                    if (E.LocalName == "nd")
                    {
                        if (Nodes == null)
                        {
                            Nodes = new LinkedList <ThingReference>();
                        }

                        Nodes.AddLast(new ThingReference(
                                          XML.Attribute(E, "id"),
                                          XML.Attribute(E, "src"),
                                          XML.Attribute(E, "pt")));
                    }
                }

                ControlParameter[] Parameters;

                if (Nodes == null)
                {
                    Parameters = await this.GetControlParameters(null);

                    if (Parameters == null)
                    {
                        NotFound(e);
                        return;
                    }
                }
                else
                {
                    Dictionary <string, ControlParameter> Parameters1;
                    Dictionary <string, ControlParameter> Parameters2;
                    LinkedList <string> ToRemove = null;

                    Parameters  = null;
                    Parameters1 = null;

                    foreach (ThingReference Node in Nodes)
                    {
                        if (Parameters1 == null)
                        {
                            Parameters = await this.GetControlParameters(Node);

                            if (Parameters == null)
                            {
                                NotFound(e);
                                return;
                            }

                            Parameters1 = new Dictionary <string, ControlParameter>();

                            foreach (ControlParameter P in Parameters)
                            {
                                Parameters1[P.Name] = P;
                            }
                        }
                        else
                        {
                            Parameters2 = await this.GetControlParametersByName(Node);

                            if (Parameters2 == null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (KeyValuePair <string, ControlParameter> P in Parameters1)
                            {
                                if (!Parameters2.TryGetValue(P.Key, out ControlParameter P2) || !P.Value.Equals(P2))
                                {
                                    if (ToRemove == null)
                                    {
                                        ToRemove = new LinkedList <string>();
                                    }

                                    ToRemove.AddLast(P.Key);
                                }
                            }

                            if (ToRemove != null)
                            {
                                foreach (string Key in ToRemove)
                                {
                                    Parameters1.Remove(Key);
                                }

                                ToRemove = null;
                            }
                        }
                    }

                    List <ControlParameter> Left = new List <ControlParameter>();

                    foreach (ControlParameter P in Parameters)
                    {
                        if (Parameters1.ContainsKey(P.Name))
                        {
                            Left.Add(P);
                        }
                    }

                    Parameters = Left.ToArray();
                }

                StringBuilder  Xml    = new StringBuilder();
                XmlWriter      Output = XmlWriter.Create(Xml, XML.WriterSettings(false, true));
                ThingReference FirstNode;

                Output.WriteStartElement("x", XmppClient.NamespaceData);
                Output.WriteAttributeString("xmlns", "xdv", null, XmppClient.NamespaceDataValidate);
                Output.WriteAttributeString("xmlns", "xdl", null, XmppClient.NamespaceDataLayout);
                Output.WriteAttributeString("xmlns", "xdd", null, XmppClient.NamespaceDynamicForms);

                if (Nodes == null)
                {
                    FirstNode = null;
                    Output.WriteElementString("title", this.client.BareJID);
                }
                else
                {
                    FirstNode = Nodes.First.Value;

                    if (Nodes.First.Next == null)
                    {
                        Output.WriteElementString("title", Nodes.First.Value.NodeId);
                    }
                    else
                    {
                        Output.WriteElementString("title", Nodes.Count.ToString() + " nodes");
                    }
                }

                LinkedList <string> PagesInOrder = new LinkedList <string>();
                Dictionary <string, LinkedList <ControlParameter> > ParametersPerPage = new Dictionary <string, LinkedList <ControlParameter> >();

                foreach (ControlParameter P in Parameters)
                {
                    if (!ParametersPerPage.TryGetValue(P.Page, out LinkedList <ControlParameter> List))
                    {
                        PagesInOrder.AddLast(P.Page);
                        List = new LinkedList <ControlParameter>();
                        ParametersPerPage[P.Page] = List;
                    }

                    List.AddLast(P);
                }

                foreach (string Page in PagesInOrder)
                {
                    Output.WriteStartElement("xdl", "page", null);
                    Output.WriteAttributeString("label", Page);

                    foreach (ControlParameter P in ParametersPerPage[Page])
                    {
                        Output.WriteStartElement("xdl", "fieldref", null);
                        Output.WriteAttributeString("var", P.Name);
                        Output.WriteEndElement();
                    }

                    Output.WriteEndElement();
                }

                foreach (ControlParameter P in Parameters)
                {
                    P.ExportToForm(Output, FirstNode);
                }

                Output.WriteEndElement();
                Output.Flush();

                e.IqResult(Xml.ToString());
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }