function getRecordAsEditTableCells( IdStack $idPath, Editor $editor, Structure $visibleStructure, Record $record, &$startColumn = 0 ) {
	$result = '';
	$childEditorMap = $editor->getAttributeEditorMap();
	
	foreach ( $visibleStructure->getAttributes() as $visibleAttribute ) {
		$childEditor = $childEditorMap->getEditorForAttribute( $visibleAttribute );
		
		if ( $childEditor != null ) {
			$attribute = $childEditor->getAttribute();
			$type = $attribute->type;
			$value = $record->getAttributeValue( $attribute );
			$idPath->pushAttribute( $attribute );
				
			if ( $childEditor instanceof RecordTableCellEditor ) {
				$result .= getRecordAsEditTableCells( $idPath, $childEditor, $visibleAttribute->type, $value, $startColumn );
			} else {
				if ( $childEditor->showEditField( $idPath ) ) {
					$displayValue = $childEditor->edit( $idPath, $value );
				} else {
					$displayValue = "";
				}
				$result .= '<td class="' . getHTMLClassForType( $type, $attribute ) . ' column-' . parityClass( $startColumn ) . '">' . $displayValue . '</td>';
					
				$startColumn++;
			}
			
			$idPath->popAttribute();
		}
		else {
			$result .= "<td/>";
		}
	}
	return $result;
}
	protected function getIdStack( $definedMeaningId ) {

		$o = OmegaWikiAttributes::getInstance();
		global $wgDefinedMeaning ;

		$definedMeaningIdStructure = new Structure( $o->definedMeaningId );
		$definedMeaningIdRecord = new ArrayRecord( $definedMeaningIdStructure, $definedMeaningIdStructure );
		$definedMeaningIdRecord->definedMeaningId = $definedMeaningId;
		
		$idStack = new IdStack( $wgDefinedMeaning );
		$idStack->pushKey( $definedMeaningIdRecord );
		
		return $idStack;
	}
	public function check( IdStack $idPath ) {
		$classAttributes = $idPath->getClassAttributes()->filterClassAttributesOnLevelAndType( $this->levelDefinedMeaningName, $this->annotationType );
		$classAttributes = $this->attributeIDFilter->filter( $classAttributes );
		
		return count( $classAttributes ) > 0;
	}
function rollBackTransactions( $recordSet ) {

	$o = OmegaWikiAttributes::getInstance();
	global
		$wgRequest, $wgUser;
		
	$summary = $wgRequest->getText( 'summary' );
	startNewTransaction( $wgUser->getID(), wfGetIP(), $summary );
		
	$idStack = new IdStack( 'transaction' );
	$transactionKeyStructure = $recordSet->getKey();
	
	for ( $i = 0; $i < $recordSet->getRecordCount(); $i++ ) {
		$transactionRecord = $recordSet->getRecord( $i );

		$transactionId = $transactionRecord->transactionId;
		$idStack->pushKey( simpleRecord( $transactionKeyStructure, array( $transactionId ) ) );

		$updatesInTransaction = $transactionRecord->updatesInTransaction;
		$idStack->pushAttribute( $o->updatesInTransaction );

		$updatedDefinitions = $updatesInTransaction->updatedDefinition;
		$idStack->pushAttribute( $o->updatedDefinition );
		rollBackDefinitions( $idStack, $updatedDefinitions );
		$idStack->popAttribute();

		$updatedRelations = $updatesInTransaction->updatedRelations;
		$idStack->pushAttribute( $o->updatedRelations );
		rollBackRelations( $idStack, $updatedRelations );
		$idStack->popAttribute();
		
		$updatedClassMemberships = $updatesInTransaction->updatedClassMembership;
		$idStack->pushAttribute( $o->updatedClassMembership );
		rollBackClassMemberships( $idStack, $updatedClassMemberships );
		$idStack->popAttribute();
		
		$updatedClassAttributes = $updatesInTransaction->updatedClassAttributes;
		$idStack->pushAttribute( $o->updatedClassAttributes );
		rollBackClassAttributes( $idStack, $updatedClassAttributes );
		$idStack->popAttribute();
		
		$updatedTranslatedTexts = $updatesInTransaction->updatedTranslatedText;
		$idStack->pushAttribute( $o->updatedTranslatedText );
		rollBackTranslatedTexts( $idStack, $updatedTranslatedTexts );
		$idStack->popAttribute();

		$updatedTranslatedTextProperties = $updatesInTransaction->updatedTranslatedTextProperty;
		$idStack->pushAttribute( $o->updatedTranslatedTextProperty );
		rollBackTranslatedTextProperties( $idStack, $updatedTranslatedTextProperties );
		$idStack->popAttribute();

		$o->updatedLinks = $updatesInTransaction->updatedLink;
		$idStack->pushAttribute( $o->updatedLink );
		rollBackLinkAttributes( $idStack, $o->updatedLinks );
		$idStack->popAttribute();

		$o->updatedTexts = $updatesInTransaction->updatedText;
		$idStack->pushAttribute( $o->updatedText );
		rollBackTextAttributes( $idStack, $o->updatedTexts );
		$idStack->popAttribute();

		$updatedSyntranses = $updatesInTransaction->updatedSyntranses;
		$idStack->pushAttribute( $o->updatedSyntranses );
		rollBackSyntranses( $idStack, $updatedSyntranses );
		$idStack->popAttribute();

		$updatedAlternativeDefinitionTexts = $updatesInTransaction->updatedAlternativeDefinitionText;
		$idStack->pushAttribute( $o->updatedAlternativeDefinitionText );
		rollBackAlternativeDefinitionTexts( $idStack, $updatedAlternativeDefinitionTexts );
		$idStack->popAttribute();

		$updatedAlternativeDefinitions = $updatesInTransaction->updatedAlternativeDefinitions;
		$idStack->pushAttribute( $o->updatedAlternativeDefinitions );
		rollBackAlternativeDefinitions( $idStack, $updatedAlternativeDefinitions );
		$idStack->popAttribute();

		$updatedCollectionMemberships = $updatesInTransaction->updatedCollectionMembership;
		$idStack->pushAttribute( $o->updatedCollectionMembership );
		rollBackCollectionMemberships( $idStack, $updatedCollectionMemberships );
		$idStack->popAttribute();

		$idStack->popAttribute();
		$idStack->popKey();
	}
}
	public function add( IdStack $idPath, $record ) {
		$attributeId = $idPath->getKeyStack()->peek( 0 )->classAttributeId;
		$optionMeaningId = $record->optionAttributeOption;
		$languageId = $record->language;
		if ( $languageId == NULL ) {
			$languageId = 0 ;
		}
		if ( $optionMeaningId ) {
			addOptionAttributeOption( $attributeId, $optionMeaningId, $languageId );
		}
	}
	public function save( IdStack $idPath, $value ) {
		$definedMeaningId = (int) $value->definedMeaningId;
		
		$idPath->pushDefinedMeaningId( $definedMeaningId );
		$idPath->pushClassAttributes( new ClassAttributes( $definedMeaningId ) );

		$this->wrappedEditor->save( $idPath, $value );

		$idPath->popClassAttributes();
		$idPath->popDefinedMeaningId();
	}