Represents the search values related to an OpenSearch request and provides useful methods for managing and converting OpenSearch values.
 //---------------------------------------------------------------------------------------------------------------------
 /// <summary>Sets the parameter values based on the values of another instance.</summary>
 /// <remarks>Only matching parameters are taken into account. The match is made by the fully qualified identifier of the OpenSearch parameters. In the default case it is assumed that the namespace prefixes used for the identifiers refer to the same namespaces in both value sets, however, the namespaces can be verified fully.</remarks>
 /// <param name="source">The OpenSearchParameterValueSet that serves as source.</param>
 /// <param name="verifyNamespaces">If set to <c>true</c>, the parameters are matched by namespace URI and local name, rather than just prefix and local name. The default is <c>false</c>.</param>
 public void TranslateFrom(OpenSearchParameterValueSet source, bool verifyNamespaces = false)
 {
     foreach (string identifier in parametersByIdentifier.Keys) {
         OpenSearchParameterDefinition paramDef = parametersByIdentifier[identifier];
         string[] sourceValues;
         if (verifyNamespaces && paramDef.IdentifierNamespaceUri != null) {
             sourceValues = source.GetValuesByIdentifier(paramDef.IdentifierNamespaceUri, paramDef.IdentifierLocalName);
         } else {
             sourceValues = source.GetValuesByIdentifier(identifier);
         }
         if (sourceValues != null) this.values[parametersByIdentifier[identifier]] = sourceValues;
     }
 }
        //---------------------------------------------------------------------------------------------------------------------
        /// <summary>Creates an OpenSearchParameterValueSet instance based on the specified OpenSearch template and optional additional parameter information.</summary>
        /// <returns>A new OpenSearchParameterValueSet instance.</returns>
        /// <param name="template">An OpenSearch template URL.</param>
        /// <param name="origParams">An array of objects containing parameter information as defined by the OpenSearch Parameter extension.</returns>
        public static OpenSearchParameterValueSet FromOpenSearchDescription(string template, OpenSearchDescriptionUrlParameter[] origParams = null, XmlSerializerNamespaces namespaces = null)
        {
            OpenSearchParameterValueSet result = new OpenSearchParameterValueSet();

            Dictionary<string, OpenSearchDescriptionUrlParameter> tempParameters = new Dictionary<string, OpenSearchDescriptionUrlParameter>();
            Dictionary<string, string> tempNamespaces = null;
            if (origParams != null) {
                foreach (OpenSearchDescriptionUrlParameter origParam in origParams) tempParameters.Add(origParam.Name, origParam);
            }

            if (namespaces != null) {
                result.nameTable = new NameTable();
                tempNamespaces = new Dictionary<string, string>();
                foreach (XmlQualifiedName qn in namespaces.ToArray()) {
                    tempNamespaces.Add(qn.Name, result.nameTable.Add(qn.Namespace));
                }
            }

            // Make sure URL is valid
            Match match = urlRegex.Match(template);
            if (!match.Success) throw new OpenSearchException(String.Format("Invalid URL template: {0}", template));

            // Split by query string parameter and add parameter definitions to the internal dictionaries:
            // parameters can be settable (e.g. name={key}, name={prefix:key}) or fixed (name=value)
            string[] items = match.Groups[1].Value.Split('&');
            foreach (string item in items) {
                Match match2 = parameterDefinitionRegex.Match(item);
                if (!match2.Success) continue;
                string name = match2.Groups[1].Value;
                OpenSearchParameterDefinition paramDef;
                if (match2.Groups[3].Success) { // parameter is settable
                    string identifier = match2.Groups[3].Value;
                    string identifierNamespaceUri = null, identifierLocalName = null;
                    if (tempNamespaces != null) {
                        string[] parts = identifier.Split(':');
                        if (parts.Length == 2) {
                            identifierNamespaceUri = tempNamespaces.ContainsKey(parts[0]) ? tempNamespaces[parts[0]] : null;
                            if (identifierNamespaceUri != null) identifierLocalName = parts[1];
                        }
                    }
                    paramDef = new OpenSearchParameterDefinition(name, identifier, identifierNamespaceUri, identifierLocalName, tempParameters.ContainsKey(name) ? tempParameters[name] : null);
                    result.parametersByIdentifier[identifier] = paramDef;
                } else { // parameter is fixed
                    paramDef = new OpenSearchParameterDefinition(name);
                    result.values[paramDef] = new string[] {match2.Groups[2].Value};
                }
                result.parametersByName[paramDef.Name] = paramDef;
            }

            return result;
        }