UT_Error OXML_Element_Table::serialize(IE_Exp_OpenXML* exporter)
{
	UT_Error err = UT_OK;

	err = exporter->startTable();
	if(err != UT_OK)
		return err;

	err = this->serializeProperties(exporter);
	if(err != UT_OK)
		return err;

	//set the row numbers
	std::vector<OXML_Element*>::size_type i;
	OXML_ElementVector children = getChildren();
	for (i = 0; i < children.size(); i++)
	{
		OXML_Element_Row* r = static_cast<OXML_Element_Row*>(get_pointer(children[i]));
		r->setRowNumber(i);
	}

	err = this->serializeChildren(exporter);
	if(err != UT_OK)
		return err;

	return exporter->finishTable();
}
bool OXML_Element_Table::incrementBottomVerticalMergeStart(OXML_Element_Cell* cell)
{
	std::vector<OXML_Element_Row*>::reverse_iterator rit;
	for( rit=m_rows.rbegin(); rit < m_rows.rend(); ++rit )
	{
		OXML_Element_Row* pRow = *rit;
		if(pRow->incrementBottomVerticalMergeStart(cell))
			return true;
	}
	return false;	
}
bool OXML_Element_Table::incrementRightHorizontalMergeStart(OXML_Element_Cell* cell)
{
	std::vector<OXML_Element_Row*>::reverse_iterator rit;
	for( rit=m_rows.rbegin(); rit < m_rows.rend(); ++rit )
	{
		OXML_Element_Row* pRow = *rit;
		if(pRow->incrementRightHorizontalMergeStart(cell))
			return true;
		cell->setTop(cell->getTop()-1); //decrement top if we can't find the starting cell in this row
	}
	return false;	
}
void OXML_Element_Table::addMissingCell(int rowNumber, OXML_Element_Cell* cell)
{
	std::vector<OXML_Element*>::size_type i;
	OXML_ElementVector children = getChildren();
	for (i = 0; i < children.size(); i++)
	{
		OXML_Element_Row* r = static_cast<OXML_Element_Row*>(get_pointer(children[i]));
		if(i == rowNumber)
		{
			r->addMissingCell(cell);
			return;
		}
	}
}
bool IE_Exp_OpenXML_Listener::populateStrux(pf_Frag_Strux* sdh, const PX_ChangeRecord* pcr , fl_ContainerLayout** /* psfh */)
{
	if(pcr->getType() != PX_ChangeRecord::PXT_InsertStrux)
		return false;

	const PX_ChangeRecord_Strux* pcrx = static_cast<const PX_ChangeRecord_Strux *> (pcr);

	PT_AttrPropIndex api = pcr->getIndexAP();			
	const PP_AttrProp* pAP = NULL;
	bool bHaveProp = pdoc->getAttrProp(api,&pAP);

	switch (pcrx->getStruxType())
	{
		case PTX_Section:
		{
			section = new OXML_Section();
			section->setTarget(TARGET_DOCUMENT);
			OXML_SharedSection shared_section(section);

			//add section properties 
			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Section Property: %s=%s\n", szName, szValue));	
						if(section->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Section Attribute: %s=%s\n", szName, szValue));	
						if(section->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}

			return document->appendSection(shared_section) == UT_OK;
		}
		case PTX_Block:
		{
			paragraph = new OXML_Element_Paragraph(getNextId());
			OXML_SharedElement shared_paragraph(static_cast<OXML_Element*>(paragraph));

			//add paragraph properties 
			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						if(paragraph->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						if(paragraph->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}
			
			if(!m_cellStack.empty())
			{
				OXML_Element_Cell* cell = m_cellStack.top();
				return cell->appendElement(shared_paragraph) == UT_OK;
			}
			else if(bInTextbox)
				return textbox->appendElement(shared_paragraph) == UT_OK;

			return section->appendElement(shared_paragraph) == UT_OK;
		}
		case PTX_SectionHdrFtr:
        {
			section = new OXML_Section(getNextId());
			OXML_SharedSection shared_section(static_cast<OXML_Section*>(section));

			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Header/Footer Property: %s=%s\n", szName, szValue));	
						if(section->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Header/Footer Attribute: %s=%s\n", szName, szValue));	
						if(section->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}

				if(pAP->getAttribute("type", szValue))
				{
					if(strstr(szValue, "header"))
					{
						section->setTarget(TARGET_HEADER);
						return document->addHeader(shared_section) == UT_OK;
					}
					else if(strstr(szValue, "footer"))
					{
						section->setTarget(TARGET_FOOTER);
						return document->addFooter(shared_section) == UT_OK;
					}
				}				
			}
			return true;			
		}
		case PTX_SectionEndnote:
        {
			savedSection = section; //save the current section
			savedParagraph = paragraph; //save the current paragraph

			section = new OXML_Section(getNextId());
			OXML_SharedSection shared_section(static_cast<OXML_Section*>(section));

			section->setTarget(TARGET_ENDNOTE);

			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Endnote Property: %s=%s\n", szName, szValue));	
						if(section->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Endnote Attribute: %s=%s\n", szName, szValue));	
						if(section->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}

			return document->addEndnote(shared_section) == UT_OK;
		}
		case PTX_SectionTable:
		{	
			OXML_Element_Table* table = new OXML_Element_Table(getNextId());
			OXML_SharedElement shared_table(static_cast<OXML_Element*>(table));

			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Table Property: %s=%s\n", szName, szValue));	
						if(table->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Table Attribute: %s=%s\n", szName, szValue));	
						if(table->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}
			tableHelper.OpenTable(sdh, pcr->getIndexAP());

			bool tableInTable = !m_tableStack.empty();
			m_tableStack.push(table);

			if(tableInTable)
			{
				//this is a table inside another table
				OXML_Element_Cell* cell = m_cellStack.top();
				return cell->appendElement(shared_table) == UT_OK;
			}

			return section->appendElement(shared_table) == UT_OK;
		}
		case PTX_SectionCell:
		{
			OXML_Element_Table* table = NULL;
			if(!m_tableStack.empty())
				table = m_tableStack.top();

			if(!table)
			{
				UT_DEBUGMSG(("FRT: OpenXML exporter corrupted table layout. Invalid Cell Open."));
				return false;
			}

			OXML_Element_Row* row = NULL;
			if(!m_rowStack.empty())
				row = m_rowStack.top();

			tableHelper.OpenCell(api);
			UT_sint32 left = tableHelper.getLeft();
			UT_sint32 right = tableHelper.getRight();
			UT_sint32 top = tableHelper.getTop();
			UT_sint32 bottom = tableHelper.getBot();

			if(!row || tableHelper.isNewRow())
			{
				row = new OXML_Element_Row(getNextId(), table);
				m_rowStack.push(row);
				row->setNumCols(tableHelper.getNumCols());
				OXML_SharedElement shared_row(static_cast<OXML_Element*>(row));
				if(table->appendElement(shared_row) != UT_OK)
					return false;
			}

			OXML_Element_Cell* cell = new OXML_Element_Cell(getNextId(), table, row, left, right, top, bottom);
			m_cellStack.push(cell);
			OXML_SharedElement shared_cell(static_cast<OXML_Element*>(cell));

			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Cell Property: %s=%s\n", szName, szValue));	
						if(cell->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Cell Attribute: %s=%s\n", szName, szValue));	
						if(cell->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}
					
			return row->appendElement(shared_cell) == UT_OK;
		}
		case PTX_SectionFootnote:
        {
			savedSection = section; //save the current section
			savedParagraph = paragraph; //save the current paragraph

			section = new OXML_Section(getNextId());
			OXML_SharedSection shared_section(static_cast<OXML_Section*>(section));

			section->setTarget(TARGET_FOOTNOTE);
			
			if(bHaveProp && pAP)
			{
				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Footnote Property: %s=%s\n", szName, szValue));	
						if(section->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("Footnote Attribute: %s=%s\n", szName, szValue));	
						if(section->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}
			}

			return document->addFootnote(shared_section) == UT_OK;
		}
		case PTX_SectionFrame:
        {
			const gchar* frameType = NULL;

			if(!(bHaveProp && pAP))
				return true;

			if(!(pAP->getProperty("frame-type",frameType) && frameType && *frameType))
				return true;

			if(!strcmp(frameType,"textbox"))
			{
				bInTextbox = true;
			}
			else if(!strcmp(frameType,"image"))
			{
				// TODO: handle positioned images
			}

			if(bInTextbox)
			{
				textbox = new OXML_Element_TextBox(getNextId());
				OXML_SharedElement shared_textbox(static_cast<OXML_Element*>(textbox));

				OXML_Element_Run* element_run = new OXML_Element_Run(getNextId());
				OXML_SharedElement shared_element_run(static_cast<OXML_Element*>(element_run));

				if(element_run->appendElement(shared_textbox) != UT_OK)
					return false;

				const gchar* szValue;
				const gchar* szName;
				size_t propCount = pAP->getPropertyCount();

				size_t i;
				for(i=0; i<propCount; i++)
				{
					if(pAP->getNthProperty(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("TextBox Property: %s=%s\n", szName, szValue));	
						if(textbox->setProperty(szName, szValue) != UT_OK)
							return false;		
					}
				}

				size_t attrCount = pAP->getAttributeCount();

				for(i=0; i<attrCount; i++)
				{
					if(pAP->getNthAttribute(i, szName, szValue))
					{
						//TODO: Take the debug message out when we are done
						UT_DEBUGMSG(("TextBox Attribute: %s=%s\n", szName, szValue));	
						if(textbox->setAttribute(szName, szValue) != UT_OK)
							return false;		
					}
				}

				return paragraph->appendElement(shared_element_run) == UT_OK;
			}
			return true;
		}
		case PTX_EndCell:
		{
			tableHelper.CloseCell();
			if(m_cellStack.empty())
				return false;

			m_cellStack.pop();
			return true;
		}
		case PTX_EndTable:
		{
			tableHelper.CloseTable();
			if(m_tableStack.empty())
				return false;

			//pop the rows that belong to this table
			int nRows = m_tableStack.top()->getNumberOfRows();
			for(int i=0; i<nRows; i++)
			{
				if(m_rowStack.empty())
					return false;
			
				m_rowStack.pop();
			}

			//pop the table
			m_tableStack.pop();
			return true;
		}
		case PTX_EndFootnote:
		{
			section = savedSection; //recover the last section
			paragraph = savedParagraph; //recover the last paragraph
			return true;
		}
		case PTX_EndEndnote:
		{
			section = savedSection; //recover the last section
			paragraph = savedParagraph; //recover the last paragraph
			return true;
		}
		case PTX_EndFrame:
		{
			if(bInTextbox)
				bInTextbox = false;
			return true;
		}
		case PTX_SectionMarginnote:
		case PTX_SectionAnnotation:
		case PTX_SectionTOC:
		case PTX_EndMarginnote:
		case PTX_EndAnnotation:
		case PTX_EndTOC:	
		default:
			return true;
	}

	return true;
}
void OXMLi_ListenerState_Table::startElement (OXMLi_StartElementRequest * rqst)
{
	if (nameMatches(rqst->pName, NS_W_KEY, "tbl"))
	{
		OXML_Element_Table* pTable = new OXML_Element_Table("");
		m_tableStack.push(pTable);
		OXML_SharedElement table(pTable);
		rqst->stck->push(table);
		rqst->handled = true;
		pTable->setCurrentRowNumber(-1);
		pTable->setCurrentColNumber(-1);
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tr"))
	{
		if(m_tableStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();
		OXML_Element_Row* pRow = new OXML_Element_Row("", table);
		m_rowStack.push(pRow);
		OXML_SharedElement row(pRow);
		rqst->stck->push(row);
		rqst->handled = true;
		table->incrementCurrentRowNumber();
		table->setCurrentColNumber(0);
		pRow->setRowNumber(table->getCurrentRowNumber());
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tc"))
	{
		if(m_tableStack.empty() || m_rowStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();				
		OXML_Element_Row* row = m_rowStack.top();				
		OXML_Element_Cell* pCell = new OXML_Element_Cell("", table, row, 
								table->getCurrentColNumber(), table->getCurrentColNumber()+1, //left right
								table->getCurrentRowNumber(), table->getCurrentRowNumber()+1); //top,bottom
		m_cellStack.push(pCell);
		OXML_SharedElement cell(pCell);
		rqst->stck->push(cell);
		rqst->handled = true;
		table->incrementCurrentColNumber();
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "gridSpan"))
	{
		if(m_tableStack.empty() || m_cellStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();				
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
		if(val)
		{
			int span = atoi(val);
			int left = table->getCurrentColNumber()-1;
			int right = left + span;
			//change current cell's right index
			OXML_Element_Cell* cell = m_cellStack.top();
			cell->setRight(right);
			//update column index of current table			
			table->setCurrentColNumber(right);
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "vMerge"))
	{
		if(m_cellStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Cell* cell = m_cellStack.top();				
		cell->setVerticalMergeStart(false); //default to continue if the attribute is missing
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
		if(val && !strcmp(val, "restart")) 
		{
			cell->setVerticalMergeStart(true);
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "hMerge"))
	{
		if(m_cellStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Cell* cell = m_cellStack.top();				
		cell->setHorizontalMergeStart(false); //default to continue if the attribute is missing
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
		if(val && !strcmp(val, "restart")) 
		{
			cell->setHorizontalMergeStart(true);
		}
		rqst->handled = true;
	}

	//Table Properties
	else if(nameMatches(rqst->pName, NS_W_KEY, "gridCol") && 
			contextMatches(rqst->context->back(), NS_W_KEY, "tblGrid"))
	{
		if(m_tableStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();				
		const gchar* w = attrMatches(NS_W_KEY, "w", rqst->ppAtts);
		if(w) 
		{
			//append this width to table-column-props property
			const gchar* tableColumnProps = NULL;
			UT_Error ret = table->getProperty("table-column-props", tableColumnProps);
			if((ret != UT_OK) || !tableColumnProps)
				tableColumnProps = "";				
			std::string cols(tableColumnProps);
			cols += _TwipsToPoints(w);
			cols += "pt/";
			ret = table->setProperty("table-column-props", cols);
			if(ret != UT_OK)
			{	
				UT_DEBUGMSG(("FRT:OpenXML importer can't set table-column-props:%s\n", cols.c_str()));
			}
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "trHeight") && 
			contextMatches(rqst->context->back(), NS_W_KEY, "trPr"))
	{
		if(m_tableStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();				
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
		if(val) 
		{
			const gchar* tableRowHeights = NULL;
			UT_Error ret = table->getProperty("table-row-heights", tableRowHeights);
			if((ret != UT_OK) || !tableRowHeights)
				tableRowHeights = "";				
			std::string rowHeights(tableRowHeights);
			rowHeights += _TwipsToPoints(val);
			rowHeights += "pt/";
			ret = table->setProperty("table-row-heights", rowHeights);
			if(ret != UT_OK)
			{
				UT_DEBUGMSG(("FRT:OpenXML importer can't set table-row-heights:%s\n", rowHeights.c_str()));
			}
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "left") ||
			nameMatches(rqst->pName, NS_W_KEY, "right") ||
			nameMatches(rqst->pName, NS_W_KEY, "top") ||
			nameMatches(rqst->pName, NS_W_KEY, "bottom"))
	{
		rqst->handled = true;
		const gchar* color = attrMatches(NS_W_KEY, "color", rqst->ppAtts);
		const gchar* sz = attrMatches(NS_W_KEY, "sz", rqst->ppAtts);
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);

		UT_Error ret = UT_OK;

		std::string borderName(rqst->pName);
		borderName = borderName.substr(strlen(NS_W_KEY)+1);
		if(!borderName.compare("bottom"))
			borderName = "bot";

		std::string borderStyle = borderName + "-style";
		std::string borderColor = borderName + "-color";
		std::string borderThickness = borderName + "-thickness";

		OXML_Element* element = NULL;

		if(rqst->context->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		if(contextMatches(rqst->context->back(), NS_W_KEY, "tcBorders"))
			element = m_cellStack.empty() ? NULL : m_cellStack.top();
		else if(contextMatches(rqst->context->back(), NS_W_KEY, "tblBorders"))
			element = m_tableStack.empty() ? NULL : m_tableStack.top();

		if(!element)
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		if(color && strcmp(color, "auto")) 
		{
			ret = element->setProperty(borderColor, color);
			if(ret != UT_OK)
			{
				UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:%s\n", borderColor.c_str(), color));
			}
		}
		if(sz) 
		{
			std::string szVal(_EighthPointsToPoints(sz));
			szVal += "pt";
			ret = element->setProperty(borderThickness, szVal);
			if(ret != UT_OK)
			{
				UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:%s\n", borderThickness.c_str(), color));
			}
		}

		std::string styleValue = "1"; //single line border by default
		if(val)
		{
			if(!strcmp(val, "dashed"))
				styleValue = "0"; 
		}

		ret = element->setProperty(borderStyle, styleValue);
		if(ret != UT_OK)
		{
			UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:0\n", borderStyle.c_str()));
		}
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "shd"))
	{
		const gchar* fill = attrMatches(NS_W_KEY, "fill", rqst->ppAtts);

		UT_Error ret = UT_OK;
		OXML_Element* element = NULL;

		if(rqst->context->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		if(contextMatches(rqst->context->back(), NS_W_KEY, "tcPr"))
			element = m_cellStack.empty() ? NULL : m_cellStack.top();
		else if(contextMatches(rqst->context->back(), NS_W_KEY, "tblPr"))
			element = m_tableStack.empty() ? NULL : m_tableStack.top();

		if(!element)
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		if(fill && strcmp(fill, "auto")) 
		{
			ret = element->setProperty("background-color", fill);
			if(ret != UT_OK)
			{
				UT_DEBUGMSG(("FRT:OpenXML importer can't set background-color:%s\n", fill));	
			}
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tblStyle"))
	{
		if(m_tableStack.empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_Element_Table* table = m_tableStack.top();				
		const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
		if(val && table) 
		{
			std::string styleName(val);
			OXML_Document* doc = OXML_Document::getInstance();
			if(doc)
				table->applyStyle(doc->getStyleById(styleName));
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tblPr"))
	{
		if(m_tableStack.empty())
		{
			//we must be in tblStyle in styles, so let's push the table instance to m_tableStack
			OXML_Element_Table* tbl = static_cast<OXML_Element_Table*>(get_pointer(rqst->stck->top()));
			m_tableStack.push(tbl);
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "trPr"))
	{
		if(m_rowStack.empty())
		{
			//we must be in styles, so let's push the row instance to m_rowStack
			OXML_Element_Row* row = static_cast<OXML_Element_Row*>(get_pointer(rqst->stck->top()));
			m_rowStack.push(row);
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tcPr"))
	{
		if(m_cellStack.empty())
		{
			//we must be in styles, so let's push the cell instance to m_cellStack
			OXML_Element_Cell* cell = static_cast<OXML_Element_Cell*>(get_pointer(rqst->stck->top()));
			m_cellStack.push(cell);
		}
		rqst->handled = true;
	}
	//TODO: more coming here
}