List<Textbox> _GrowList;	// list of TextBox's that need to be checked for growth

		public TableRow(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_TableCells=null;
			_Height=null;
			_Visibility=null;
			_CanGrow = false;
			_GrowList = null;

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "TableCells":
						_TableCells = new TableCells(r, this, xNodeLoop);
						break;
					case "Height":
						_Height = new RSize(r, xNodeLoop);
						break;
					case "Visibility":
						_Visibility = new Visibility(r, this, xNodeLoop);
						break;
					default:
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown TableRow element '" + xNodeLoop.Name + "' ignored.");
						break;
				}
			}
			if (_TableCells == null)
				OwnerReport.rl.LogError(8, "TableRow requires the TableCells element.");
			if (_Height == null)
				OwnerReport.rl.LogError(8, "TableRow requires the Height element.");
		}
		Visibility _Visibility;	// Indicates if all of the dynamic rows for this grouping
							// should be hidden and replaced with a subtotal row for
							// this grouping scope		

		public DynamicRows(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_Grouping=null;
			_Sorting=null;
			_Subtotal=null;
			_ReportItems=null;
			_Visibility=null;
			// Run thru the attributes
			//			foreach(XmlAttribute xAttr in xNode.Attributes)
			//			{
			//			}

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "Grouping":
						_Grouping = new Grouping(r, this, xNodeLoop);
						break;
					case "Sorting":
						_Sorting = new Sorting(r, this, xNodeLoop);
						break;
					case "Subtotal":
						_Subtotal = new Subtotal(r, this, xNodeLoop);
						break;
					case "ReportItems":
						_ReportItems = new ReportItems(r, this, xNodeLoop);
						break;
					case "Visibility":
						_Visibility = new Visibility(r, this, xNodeLoop);
						break;
					default:	
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown DynamicRow element '" + xNodeLoop.Name + "' ignored.");
						break;
				}
			}
			if (_Grouping == null)
				OwnerReport.rl.LogError(8, "DynamicRows requires the Grouping element.");
			if (_ReportItems == null || _ReportItems.Items.Count != 1)
				OwnerReport.rl.LogError(8, "DynamicRows requires the ReportItems element defined with exactly one report item.");
		}
		Textbox _ToggleTextbox;	//  resolved TextBox for toggling visibility
	
		public TableGroup(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_Grouping=null;
			_Sorting=null;
			_Header=null;
			_Footer=null;
			_Visibility=null;
			_ToggleTextbox=null;

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "Grouping":
						_Grouping = new Grouping(r, this, xNodeLoop);
						break;
					case "Sorting":
						_Sorting = new Sorting(r, this, xNodeLoop);
						break;
					case "Header":
						_Header = new Header(r, this, xNodeLoop);
						break;
					case "Footer":
						_Footer = new Footer(r, this, xNodeLoop);
						break;
					case "Visibility":
						_Visibility = new Visibility(r, this, xNodeLoop);
						break;
					default:	
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown TableGroup element '" + xNodeLoop.Name + "' ignored.");
						break;
				}
			}
			if (_Grouping == null)
				OwnerReport.rl.LogError(8, "TableGroup requires the Grouping element.");
		}
		Textbox _ToggleTextbox;	//  resolved TextBox for toggling visibility
	
		public Details(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_TableRows=null;
			_Grouping=null;
			_Sorting=null;
			_Visibility=null;
			_ToggleTextbox = null;

			// Loop thru all the child nodes
			foreach(XmlNode xNodeLoop in xNode.ChildNodes)
			{
				if (xNodeLoop.NodeType != XmlNodeType.Element)
					continue;
				switch (xNodeLoop.Name)
				{
					case "TableRows":
						_TableRows = new TableRows(r, this, xNodeLoop);
						break;
					case "Grouping":
						_Grouping = new Grouping(r, this, xNodeLoop);
						break;
					case "Sorting":
						_Sorting = new Sorting(r, this, xNodeLoop);
						break;
					case "Visibility":
						_Visibility = new Visibility(r, this, xNodeLoop);
						break;
					default:
						// don't know this element - log it
						OwnerReport.rl.LogError(4, "Unknown Details element " + xNodeLoop.Name + " ignored.");
						break;
				}
			}
			if (_TableRows == null)
				OwnerReport.rl.LogError(8, "Details requires the TableRows element.");
		}
		public bool ReportItemElement(XmlNode xNodeLoop)
		{
			switch (xNodeLoop.Name)
			{
				case "Style":
					_Style = new Style(OwnerReport, this, xNodeLoop);
					break;
				case "Action":
					_Action = new Action(OwnerReport, this, xNodeLoop);
					break;
				case "Top":
					_Top = new RSize(OwnerReport, xNodeLoop);
					break;
				case "Left":
					_Left = new RSize(OwnerReport, xNodeLoop);
					break;
				case "Height":
					_Height = new RSize(OwnerReport, xNodeLoop);
					break;
				case "Width":
					_Width = new RSize(OwnerReport, xNodeLoop);
					break;
				case "ZIndex":
					_ZIndex = XmlUtil.Integer(xNodeLoop.InnerText);
					break;
				case "Visibility":
					_Visibility = new Visibility(OwnerReport, this, xNodeLoop);
					break;
				case "ToolTip":
					_ToolTip = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.String);
					break;
				case "Label":
					_Label = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Variant);
					break;
				case "LinkToChild":
					_LinkToChild = xNodeLoop.InnerText;
					break;
				case "Bookmark":
					_Bookmark = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.String);
					break;
				case "RepeatWith":
					_RepeatWith = xNodeLoop.InnerText;
					break;
				case "Custom":
					_Custom = new Custom(OwnerReport, this, xNodeLoop);
					break;
				case "DataElementName":
					_DataElementName = xNodeLoop.InnerText;
					break;
				case "DataElementOutput":
					_DataElementOutput = Oranikle.Report.Engine.DataElementOutput.GetStyle(xNodeLoop.InnerText, OwnerReport.rl);
					break;
                case "rd:DefaultName":
                    break;      // MS tag: we don't use but don't want to generate a warning
				default:  
					return false;	// Not a report item element
			}
			return true;
		}
		bool _InMatrix;		// true if reportitem is in a matrix
		public ReportItem(ReportDefn r, ReportLink p, XmlNode xNode) : base(r, p)
		{
			_Name=null;
			_Style=null;
			_Action=null;
			_Top=null;
			_Left=null;
			_Height=null;
			_Width=null;
			_ZIndex=0;
			_Visibility=null;
			_ToolTip=null;
			_Label=null;
			_LinkToChild=null;
			_Bookmark=null;
			_RepeatWith=null;
			_Custom=null;
			_DataElementName=null;
			_DataElementOutput=DataElementOutputEnum.Auto;
			// Run thru the attributes
			foreach(XmlAttribute xAttr in xNode.Attributes)
			{
				switch (xAttr.Name)
				{
					case "Name":
						_Name = new Name(xAttr.Value);
						break;
				}
			}
		}
        public bool ReportItemElement(XmlNode xNodeLoop)
        {
            switch (xNodeLoop.Name)
            {
            case "Style":
                _Style = new Style(OwnerReport, this, xNodeLoop);
                break;

            case "Action":
                _Action = new Action(OwnerReport, this, xNodeLoop);
                break;

            case "Top":
                _Top = new RSize(OwnerReport, xNodeLoop);
                break;

            case "Left":
                _Left = new RSize(OwnerReport, xNodeLoop);
                break;

            case "Height":
                _Height = new RSize(OwnerReport, xNodeLoop);
                break;

            case "Width":
                _Width = new RSize(OwnerReport, xNodeLoop);
                break;

            case "ZIndex":
                _ZIndex = XmlUtil.Integer(xNodeLoop.InnerText);
                break;

            case "Visibility":
                _Visibility = new Visibility(OwnerReport, this, xNodeLoop);
                break;

            case "ToolTip":
                _ToolTip = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.String);
                break;

            case "Label":
                _Label = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.Variant);
                break;

            case "LinkToChild":
                _LinkToChild = xNodeLoop.InnerText;
                break;

            case "Bookmark":
                _Bookmark = new Expression(OwnerReport, this, xNodeLoop, ExpressionType.String);
                break;

            case "RepeatWith":
                _RepeatWith = xNodeLoop.InnerText;
                break;

            case "Custom":
                _Custom = new Custom(OwnerReport, this, xNodeLoop);
                break;

            case "DataElementName":
                _DataElementName = xNodeLoop.InnerText;
                break;

            case "DataElementOutput":
                _DataElementOutput = Oranikle.Report.Engine.DataElementOutput.GetStyle(xNodeLoop.InnerText, OwnerReport.rl);
                break;

            case "rd:DefaultName":
                break;          // MS tag: we don't use but don't want to generate a warning

            default:
                return(false);                          // Not a report item element
            }
            return(true);
        }