(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.MetadataServices / MetaDataExporter.cs
blob0c8c4785a19a04a1e7caf0e3d01e6e2770e60f64
1 //
2 // System.Runtime.Remoting.MetadataServices.MetaDataExporter
3 //
4 // Authors:
5 // Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // (C) 2003 Novell, Inc
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
32 using System.IO;
33 using System.Text;
34 using System.Xml;
35 using System.Reflection;
36 using System.Net;
37 using System.Runtime.Remoting;
38 using System.Runtime.Remoting.Metadata;
39 using System.Runtime.Serialization;
41 namespace System.Runtime.Remoting.MetadataServices
43 internal class MetaDataExporter
45 public void ExportTypes (ServiceType[] servicetypes, SdlType sdltype, XmlTextWriter tw)
47 if (sdltype == SdlType.Sdl) // Obsolete, we don't support this
48 throw new NotSupportedException ();
50 if (servicetypes.Length == 0) return;
51 Type maint = servicetypes [0].ObjectType;
53 Hashtable dataTypes = new Hashtable ();
54 ArrayList services = new ArrayList ();
55 FindTypes (servicetypes, dataTypes, services);
57 if (services.Count > 0)
58 maint = ((ServiceType) services[0]).ObjectType;
60 string serviceNs = GetXmlNamespace (maint, null);
62 tw.Formatting = Formatting.Indented;
63 tw.WriteStartElement ("definitions", MetaData.WsdlNamespace);
64 tw.WriteAttributeString ("name", maint.Name);
65 tw.WriteAttributeString ("targetNamespace", serviceNs);
66 tw.WriteAttributeString ("xmlns", MetaData.XmlnsNamespace, MetaData.WsdlNamespace);
67 tw.WriteAttributeString ("xmlns", "tns", MetaData.XmlnsNamespace, serviceNs);
68 tw.WriteAttributeString ("xmlns", "xsd", MetaData.XmlnsNamespace, MetaData.SchemaNamespace);
69 tw.WriteAttributeString ("xmlns", "xsi", MetaData.XmlnsNamespace, MetaData.SchemaInstanceNamespace);
70 tw.WriteAttributeString ("xmlns", "suds", MetaData.XmlnsNamespace, MetaData.SudsNamespace);
71 tw.WriteAttributeString ("xmlns", "wsdl", MetaData.XmlnsNamespace, MetaData.WsdlNamespace);
72 tw.WriteAttributeString ("xmlns", "soapenc", MetaData.XmlnsNamespace, MetaData.SoapEncodingNamespace);
73 tw.WriteAttributeString ("xmlns", "soap", MetaData.XmlnsNamespace, MetaData.SoapNamespace);
75 int nums = 0;
76 foreach (DictionaryEntry entry in dataTypes)
78 string ns = (string) entry.Key;
79 if (tw.LookupPrefix (ns) != null) continue;
80 tw.WriteAttributeString ("xmlns", "ns"+nums, MetaData.XmlnsNamespace, ns);
81 nums++;
84 // Schema
86 if (dataTypes.Count > 0)
88 tw.WriteStartElement ("types", MetaData.WsdlNamespace);
89 foreach (DictionaryEntry entry in dataTypes)
91 SchemaInfo sinfo = (SchemaInfo) entry.Value;
92 if (sinfo == null || sinfo.Types.Count == 0) continue;
94 tw.WriteStartElement ("s", "schema", MetaData.SchemaNamespace);
95 tw.WriteAttributeString ("targetNamespace", (string) entry.Key);
96 tw.WriteAttributeString ("elementFormDefault", "unqualified");
97 tw.WriteAttributeString ("attributeFormDefault", "unqualified");
99 foreach (string ns in sinfo.Imports)
101 if (ns == (string) entry.Key) continue;
102 tw.WriteStartElement ("import", MetaData.SchemaNamespace);
103 tw.WriteAttributeString ("namespace", ns);
104 tw.WriteEndElement ();
107 foreach (Type type in sinfo.Types)
108 WriteDataTypeSchema (tw, type);
110 tw.WriteEndElement ();
112 tw.WriteEndElement ();
115 // Bindings
117 /* foreach (ServiceType st in servicetypes)
118 WriteServiceBinding (tw, st);
120 foreach (ServiceType st in services)
121 WriteServiceBinding (tw, st, dataTypes);
123 // Service element
125 tw.WriteStartElement ("service", MetaData.WsdlNamespace);
126 if (services.Count > 0)
127 tw.WriteAttributeString ("name", GetServiceName (maint));
128 else
129 tw.WriteAttributeString ("name", "Service");
131 foreach (ServiceType st in services)
133 WriteServiceType (tw, st);
135 tw.WriteEndElement ();
137 // Closing
139 tw.WriteEndElement ();
140 tw.Flush ();
143 void WriteServiceType (XmlTextWriter tw, ServiceType st)
145 tw.WriteStartElement ("port", MetaData.WsdlNamespace);
146 tw.WriteAttributeString ("name", GetPortName (st.ObjectType));
147 tw.WriteAttributeString ("binding", "tns:" + GetBindingName (st.ObjectType));
149 if (st.Url != null)
151 tw.WriteStartElement ("soap","address", MetaData.SoapNamespace);
152 tw.WriteAttributeString ("location", st.Url);
153 tw.WriteEndElement ();
156 tw.WriteEndElement ();
159 void WriteServiceBinding (XmlTextWriter tw, ServiceType st, Hashtable dataTypes)
161 Type type = st.ObjectType;
162 string typeName = type.Name;
163 MethodInfo[] mets = type.GetMethods (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
164 bool isService = IsService (type);
166 // Messages
168 if (isService)
170 foreach (MethodInfo met in mets)
172 if (met.DeclaringType.Assembly == typeof(object).Assembly) continue;
174 ParameterInfo[] pars = met.GetParameters ();
175 tw.WriteStartElement ("message", MetaData.WsdlNamespace);
176 tw.WriteAttributeString ("name", typeName + "." + met.Name + "Input");
177 foreach (ParameterInfo par in pars)
179 if (!par.ParameterType.IsByRef)
180 WritePart (tw, par.Name, par.ParameterType, type);
182 tw.WriteEndElement (); // message
184 tw.WriteStartElement ("message", MetaData.WsdlNamespace);
185 tw.WriteAttributeString ("name", typeName + "." + met.Name + "Output");
187 if (met.ReturnType != typeof(void))
188 WritePart (tw, "return", met.ReturnType, type);
190 foreach (ParameterInfo par in pars)
192 if (par.ParameterType.IsByRef || par.IsOut)
193 WritePart (tw, par.Name, par.ParameterType, type);
195 tw.WriteEndElement (); // message
199 // Port type
201 tw.WriteStartElement ("portType", MetaData.WsdlNamespace);
202 tw.WriteAttributeString ("name", typeName + "PortType");
204 if (isService)
206 foreach (MethodInfo met in mets)
208 if (met.DeclaringType.Assembly == typeof(object).Assembly) continue;
210 tw.WriteStartElement ("operation", MetaData.WsdlNamespace);
211 tw.WriteAttributeString ("name", met.Name);
213 StringBuilder sb = new StringBuilder ();
214 ParameterInfo[] pars = met.GetParameters ();
215 foreach (ParameterInfo par in pars)
217 if (sb.Length != 0) sb.Append (" ");
218 sb.Append (par.Name);
220 tw.WriteAttributeString ("parameterOrder", sb.ToString ());
222 tw.WriteStartElement ("input", MetaData.WsdlNamespace);
223 tw.WriteAttributeString ("name", met.Name + "Request");
224 tw.WriteAttributeString ("message", "tns:" + typeName + "." + met.Name + "Input");
225 tw.WriteEndElement ();
227 tw.WriteStartElement ("output", MetaData.WsdlNamespace);
228 tw.WriteAttributeString ("name", met.Name + "Response");
229 tw.WriteAttributeString ("message", "tns:" + typeName + "." + met.Name + "Output");
230 tw.WriteEndElement ();
232 tw.WriteEndElement (); // operation
235 tw.WriteEndElement (); // portType
237 // Binding
239 tw.WriteStartElement ("binding", MetaData.WsdlNamespace);
240 tw.WriteAttributeString ("name", typeName + "Binding");
241 tw.WriteAttributeString ("type", "tns:" + typeName + "PortType");
243 tw.WriteStartElement ("soap", "binding", MetaData.SoapNamespace);
244 tw.WriteAttributeString ("style", "rpc");
245 tw.WriteAttributeString ("transport", "http://schemas.xmlsoap.org/soap/http");
246 tw.WriteEndElement ();
248 WriteTypeSuds (tw, type);
250 SchemaInfo sinfo = (SchemaInfo) dataTypes [GetXmlNamespace (type,null)];
251 if (sinfo != null && !sinfo.SudsGenerated)
253 foreach (Type dt in sinfo.Types)
254 WriteTypeSuds (tw, dt);
255 sinfo.SudsGenerated = true;
258 if (isService)
260 foreach (MethodInfo met in mets)
262 if (met.DeclaringType.Assembly == typeof(object).Assembly) continue;
264 tw.WriteStartElement ("operation", MetaData.WsdlNamespace);
265 tw.WriteAttributeString ("name", met.Name);
267 tw.WriteStartElement ("soap", "operation", MetaData.SoapNamespace);
268 tw.WriteAttributeString ("soapAction", GetSoapAction (met));
269 tw.WriteEndElement ();
271 tw.WriteStartElement ("suds", "method", MetaData.SudsNamespace);
272 tw.WriteAttributeString ("attributes", "public");
273 tw.WriteEndElement ();
275 tw.WriteStartElement ("input", MetaData.WsdlNamespace);
276 tw.WriteAttributeString ("name", met.Name + "Request");
277 WriteMessageBindingBody (tw, type);
278 tw.WriteEndElement ();
280 tw.WriteStartElement ("output", MetaData.WsdlNamespace);
281 tw.WriteAttributeString ("name", met.Name + "Response");
282 WriteMessageBindingBody (tw, type);
283 tw.WriteEndElement ();
285 tw.WriteEndElement (); // operation
288 tw.WriteEndElement (); // binding
291 void WriteTypeSuds (XmlTextWriter tw, Type type)
293 if (type.IsArray || type.IsEnum)
295 return;
297 else if (type.IsInterface)
299 tw.WriteStartElement ("suds", "interface", MetaData.SudsNamespace);
300 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
301 foreach (Type interf in type.GetInterfaces ()) {
302 tw.WriteStartElement ("suds","extends", MetaData.SudsNamespace);
303 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, interf, null));
304 tw.WriteEndElement ();
307 else if (type.IsValueType)
309 tw.WriteStartElement ("suds", "struct", MetaData.SudsNamespace);
310 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
311 if (type.BaseType != typeof(ValueType))
312 tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
314 else
316 tw.WriteStartElement ("suds", "class", MetaData.SudsNamespace);
317 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
319 if (IsService (type))
321 if (type.IsMarshalByRef)
322 tw.WriteAttributeString ("rootType", "MarshalByRefObject");
323 else
324 tw.WriteAttributeString ("rootType", "Delegate");
326 if (type.BaseType != typeof(MarshalByRefObject))
327 tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
329 if (type.IsMarshalByRef) {
330 foreach (Type interf in type.GetInterfaces ()) {
331 tw.WriteStartElement ("suds","implements", MetaData.SudsNamespace);
332 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, interf, null));
333 tw.WriteEndElement ();
337 else if (typeof(ISerializable).IsAssignableFrom (type))
338 tw.WriteAttributeString ("rootType", "ISerializable");
341 tw.WriteEndElement (); // suds
344 void WriteMessageBindingBody (XmlTextWriter tw, Type t)
346 tw.WriteStartElement ("soap", "body", MetaData.SoapNamespace);
347 tw.WriteAttributeString ("use", "encoded");
348 tw.WriteAttributeString ("encodingStyle", MetaData.SoapEncodingNamespace);
349 tw.WriteAttributeString ("namespace", GetXmlNamespace (t, null));
350 tw.WriteEndElement ();
353 void WritePart (XmlTextWriter tw, string name, Type t, Type containerType)
355 tw.WriteStartElement ("part", MetaData.WsdlNamespace);
356 tw.WriteAttributeString ("name", name);
357 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, t, containerType));
358 tw.WriteEndElement ();
361 void WriteDataTypeSchema (XmlTextWriter tw, Type type)
363 if (type.IsArray)
364 WriteArraySchema (tw, type);
365 else if (type.IsEnum)
366 WriteEnumSchema (tw, type);
367 else
368 WriteClassSchema (tw, type);
371 void WriteArraySchema (XmlTextWriter tw, Type type)
373 tw.WriteStartElement ("complexType", MetaData.SchemaNamespace);
374 tw.WriteAttributeString ("name", GetXmlType (type));
375 tw.WriteStartElement ("complexContent", MetaData.SchemaNamespace);
376 tw.WriteStartElement ("restriction", MetaData.SchemaNamespace);
377 tw.WriteAttributeString ("base", GetQualifiedName (tw, MetaData.SoapEncodingNamespace, "Array"));
378 tw.WriteStartElement ("attribute", MetaData.SchemaNamespace);
379 tw.WriteAttributeString ("ref", GetQualifiedName (tw, MetaData.SoapEncodingNamespace, "arrayType"));
381 string arrayType = "";
383 while (type.IsArray)
385 arrayType = arrayType + "[" + new string (',', type.GetArrayRank()-1) + "]";
386 type = type.GetElementType ();
388 arrayType = GetQualifiedXmlType (tw, type, null) + arrayType;
390 tw.WriteAttributeString ("wsdl", "arrayType", MetaData.WsdlNamespace, arrayType);
391 tw.WriteEndElement (); // attribute
392 tw.WriteEndElement (); // restriction
393 tw.WriteEndElement (); // complexContent
394 tw.WriteEndElement (); // complexType
397 void WriteEnumSchema (XmlTextWriter tw, Type type)
399 tw.WriteStartElement ("simpleType", MetaData.SchemaNamespace);
400 tw.WriteAttributeString ("name", GetXmlType (type));
401 tw.WriteAttributeString ("suds", "enumType", MetaData.SudsNamespace, GetQualifiedXmlType (tw, type.UnderlyingSystemType, null));
402 tw.WriteStartElement ("restriction", MetaData.SchemaNamespace);
403 tw.WriteAttributeString ("base", "xsd:string");
405 foreach (string name in Enum.GetNames (type))
407 tw.WriteStartElement ("enumeration", MetaData.SchemaNamespace);
408 tw.WriteAttributeString ("value", name);
409 tw.WriteEndElement ();
411 tw.WriteEndElement (); // restriction
412 tw.WriteEndElement (); // simpleType
415 void WriteClassSchema (XmlTextWriter tw, Type type)
417 tw.WriteStartElement ("element", MetaData.SchemaNamespace);
418 tw.WriteAttributeString ("name", type.Name);
419 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
420 tw.WriteEndElement ();
422 tw.WriteStartElement ("complexType", MetaData.SchemaNamespace);
423 tw.WriteAttributeString ("name", GetXmlType (type));
424 if (type.BaseType != null && type.BaseType != typeof(object) && type.BaseType != typeof(ValueType))
425 tw.WriteAttributeString ("base", GetQualifiedXmlType (tw, type.BaseType, null));
427 FieldInfo[] fields = type.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
429 // Element fields
431 bool elemsStart = false;
432 foreach (FieldInfo fi in fields)
434 SoapFieldAttribute att = (SoapFieldAttribute) InternalRemotingServices.GetCachedSoapAttribute (fi);
435 if (att.UseAttribute) continue;
437 if (!elemsStart) { tw.WriteStartElement ("all", MetaData.SchemaNamespace); elemsStart = true; }
438 tw.WriteStartElement ("element", MetaData.SchemaNamespace);
439 tw.WriteAttributeString ("name", att.XmlElementName);
440 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, fi.FieldType, type));
441 tw.WriteEndElement ();
443 if (elemsStart) tw.WriteEndElement (); // all
445 // Attribute fields
447 foreach (FieldInfo fi in fields)
449 SoapFieldAttribute att = (SoapFieldAttribute) InternalRemotingServices.GetCachedSoapAttribute (fi);
450 if (!att.UseAttribute) continue;
452 tw.WriteStartElement ("attribute", MetaData.SchemaNamespace);
453 tw.WriteAttributeString ("name", att.XmlElementName);
454 tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, fi.FieldType, type));
455 tw.WriteEndElement ();
458 tw.WriteEndElement (); // complexType
462 ArrayList FindServices (ServiceType[] servicetypes)
464 ArrayList list = new ArrayList ();
465 foreach (ServiceType st in servicetypes)
466 if (IsService (st.ObjectType)) list.Add (st);
467 return list;
470 string GetSoapAction (MethodInfo mb)
472 return SoapServices.GetSoapActionFromMethodBase (mb);
475 string GetXmlNamespace (Type t, Type containerType)
477 string name, ns;
479 if (t.IsArray)
481 return GetXmlNamespace (containerType, null);
484 if (SoapServices.GetXmlTypeForInteropType (t, out name, out ns))
485 return ns;
487 SoapTypeAttribute att = (SoapTypeAttribute) InternalRemotingServices.GetCachedSoapAttribute (t);
488 return att.XmlNamespace;
491 string GetQualifiedName (XmlTextWriter tw, string namspace, string localName)
493 return tw.LookupPrefix (namspace) + ":" + localName;
496 string GetQualifiedXmlType (XmlTextWriter tw, Type type, Type containerType)
498 string name, ns;
500 if (type.IsArray)
502 name = GetXmlType (type);
503 ns = GetXmlNamespace (type, containerType);
505 else
507 name = GetXsdType (type);
508 if (name != null) return "xsd:" + name;
510 if (!SoapServices.GetXmlTypeForInteropType (type, out name, out ns))
512 SoapTypeAttribute att = (SoapTypeAttribute) InternalRemotingServices.GetCachedSoapAttribute (type);
513 name = att.XmlTypeName;
514 ns = att.XmlNamespace;
518 return GetQualifiedName (tw, ns, name);
521 string GetXmlType (Type type)
523 if (type.IsArray)
525 string itemType = GetXmlType (type.GetElementType ());
526 itemType = "ArrayOf" + char.ToUpper (itemType[0]) + itemType.Substring (1);
527 if (type.GetArrayRank () > 1) itemType += type.GetArrayRank ();
528 return itemType;
530 else
532 string name = null, ns;
534 name = GetXsdType (type);
535 if (name != null) return name;
537 if (SoapServices.GetXmlTypeForInteropType (type, out name, out ns))
538 return name;
540 SoapTypeAttribute att = (SoapTypeAttribute) InternalRemotingServices.GetCachedSoapAttribute (type);
541 return att.XmlTypeName;
545 string GetServiceName (Type t)
547 return t.Name + "Service";
550 string GetPortName (Type t)
552 return t.Name + "Port";
555 string GetBindingName (Type t)
557 return t.Name + "Binding";
560 void FindTypes (ServiceType[] servicetypes, Hashtable dataTypes, ArrayList services)
562 Hashtable types = new Hashtable ();
563 ArrayList mbrTypes = new ArrayList();
565 foreach (ServiceType st in servicetypes)
566 FindDataTypes (st.ObjectType, null, dataTypes, mbrTypes);
568 foreach (Type mbrType in mbrTypes)
570 ServiceType stFound = null;
571 foreach (ServiceType st in servicetypes)
572 if (mbrType == st.ObjectType) stFound = st;
574 if (stFound != null) services.Add (stFound);
575 else services.Add (new ServiceType (mbrType));
579 void FindDataTypes (Type t, Type containerType, Hashtable types, ArrayList services)
581 if (IsSystemType (t))
583 string ns = GetXmlNamespace (t, null);
584 types [ns] = null;
585 return;
588 if (!IsService (t))
590 if (!t.IsSerializable) return;
592 string ns = GetXmlNamespace (t, containerType);
593 SchemaInfo sinfo = (SchemaInfo) types [ns];
594 if (sinfo == null)
596 sinfo = new SchemaInfo ();
597 types [ns] = sinfo;
600 if (sinfo.Types.Contains (t)) return;
602 sinfo.Types.Add (t);
603 if (t.IsArray) return;
605 FieldInfo[] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
606 foreach (FieldInfo fi in fields)
608 string fns = GetXmlNamespace (fi.FieldType, t);
609 if (!sinfo.Imports.Contains (fns)) sinfo.Imports.Add (fns);
610 FindDataTypes (fi.FieldType, t, types, services);
613 else
615 if (services.Contains (t)) return;
616 services.Add (t);
618 foreach (MethodInfo met in t.GetMethods (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
620 ParameterInfo[] pars = met.GetParameters ();
621 foreach (ParameterInfo par in pars)
622 FindDataTypes (par.ParameterType, t, types, services);
624 FindDataTypes (met.ReturnType, t, types, services);
629 bool IsService (Type t)
631 return t.IsMarshalByRef || t.IsInterface || typeof(Delegate).IsAssignableFrom (t);
634 bool IsSystemType (Type t)
636 return t.FullName.StartsWith ("System.") && !t.IsArray;
639 static string GetXsdType (Type type)
641 if (type.IsEnum) return null;
643 switch (Type.GetTypeCode (type))
645 case TypeCode.Boolean: return "boolean";
646 case TypeCode.Byte: return "unsignedByte";
647 case TypeCode.Char: return "char";
648 case TypeCode.DateTime: return "dateTime";
649 case TypeCode.Decimal: return "decimal";
650 case TypeCode.Double: return "double";
651 case TypeCode.Int16: return "short";
652 case TypeCode.Int32: return "int";
653 case TypeCode.Int64: return "long";
654 case TypeCode.SByte: return "byte";
655 case TypeCode.Single: return "float";
656 case TypeCode.UInt16: return "unsignedShort";
657 case TypeCode.UInt32: return "unsignedInt";
658 case TypeCode.UInt64: return "unsignedLong";
659 case TypeCode.String: return "string";
662 if (type == typeof (TimeSpan))
663 return "duration";
664 if (type == typeof (object))
665 return "anyType";
667 return null;
671 class SchemaInfo
673 public ArrayList Types = new ArrayList ();
674 public ArrayList Imports = new ArrayList ();
675 public bool SudsGenerated;