Index: t3lib/class.t3lib_tceforms.php
===================================================================
--- t3lib/class.t3lib_tceforms.php	(Revision 6276)
+++ t3lib/class.t3lib_tceforms.php	(Arbeitskopie)
@@ -894,7 +894,15 @@
 					$PA['fieldChangeFunc']['alert']=$alertMsgOnChange;
 						// if this is the child of an inline type and it is the field creating the label
 					if ($this->inline->isInlineChildAndLabelField($table, $field)) {
-						$PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('".$PA['itemFormElName']."','".$this->inline->inlineNames['object']."[$table][".$row['uid']."]');";
+						$inlineObjectId = implode(
+							t3lib_TCEforms_inline::Structure_Separator,
+							array(
+								$this->inline->inlineNames['object'],
+								$table,
+								$row['uid']
+							)
+						);
+						$PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('" . $PA['itemFormElName'] . "','" . $inlineObjectId . "');";
 					}
 
 						// Based on the type of the item, call a render function:
Index: t3lib/jsfunc.inline.js
===================================================================
--- t3lib/jsfunc.inline.js	(Revision 6276)
+++ t3lib/jsfunc.inline.js	(Arbeitskopie)
@@ -30,6 +30,7 @@
 ***************************************************************/
 
 var inline = {
+	structureSeparator: '-',
 	prependFormFieldNames: 'data',
 	noTitleString: '[No title]',
 	lockedAjaxMethod: {},
@@ -45,8 +46,8 @@
 	setNoTitleString: function(value) { this.noTitleString = value; },
 
 	expandCollapseRecord: function(objectId, expandSingle) {
-		var currentUid = this.parseFormElementName('none', objectId, 1);
-		var objectPrefix = this.parseFormElementName('full', objectId, 0, 1);
+		var currentUid = this.parseObjectId('none', objectId, 1);
+		var objectPrefix = this.parseObjectId('full', objectId, 0, 1);
 
 		var currentState = '';
 		var collapse = new Array();
@@ -74,7 +75,7 @@
 
 	collapseAllRecords: function(objectId, objectPrefix, callingUid) {
 			// get the form field, where all records are stored
-		var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 2);
+		var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 2, true);
 		var formObj = document.getElementsByName(objectName);
 		var collapse = [];
 
@@ -84,7 +85,7 @@
 
 			var records = formObj[0].value.split(',');
 			for (var i=0; i<records.length; i++) {
-				recObjectId = objectPrefix+'['+records[i]+']';
+				recObjectId = objectPrefix + this.structureSeparator + records[i];
 				if (records[i] != callingUid && Element.visible(recObjectId+'_fields')) {
 					Element.hide(recObjectId+'_fields');
 					if (this.isNewRecord(recObjectId)) this.updateExpandedCollapsedStateLocally(recObjectId, 0);
@@ -97,7 +98,7 @@
 	},
 
 	updateExpandedCollapsedStateLocally: function(objectId, value) {
-		var ucName = 'uc[inlineView]'+this.parseFormElementName('parts', objectId, 3, 2);
+		var ucName = 'uc[inlineView]'+this.parseObjectId('parts', objectId, 3, 2, true);
 		var ucFormObj = document.getElementsByName(ucName);
 		if (ucFormObj.length) {
 			ucFormObj[0].value = value;
@@ -107,7 +108,7 @@
 	createNewRecord: function(objectId, recordUid) {
 		if (this.isBelowMax(objectId)) {
 			if (recordUid) {
-				objectId += '['+recordUid+']';
+				objectId += this.structureSeparator + recordUid;
 			}
 			this.makeAjaxCall('createNewRecord', [this.getNumberOfRTE(), objectId], true);
 		} else {
@@ -307,8 +308,7 @@
 			if (unique.type == 'select') {
 					// remove used items from each select-field of the child records
 				if (!(unique.selector && unique.max == -1)) {
-					var elName = this.parseFormElementName('full', objectId, 1)+'['+recordUid+']['+unique.field+']';
-					var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 1);
+					var formName = this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 1, true);
 
 					var fieldObj = document.getElementsByName(elName);
 					var values = $H(unique.used).values();
@@ -404,13 +404,13 @@
 	},
 
 	changeSorting: function(objectId, direction) {
-		var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 2);
-		var objectPrefix = this.parseFormElementName('full', objectId, 0, 1);
+		var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 2, true);
+		var objectPrefix = this.parseObjectId('full', objectId, 0, 1);
 		var formObj = document.getElementsByName(objectName);
 
 		if (formObj.length) {
 				// the uid of the calling object (last part in objectId)
-			var callingUid = this.parseFormElementName('none', objectId, 1);
+			var callingUid = this.parseObjectId('none', objectId, 1);
 			var records = formObj[0].value.split(',');
 			var current = records.indexOf(callingUid);
 			var changed = false;
@@ -432,8 +432,8 @@
 				formObj[0].value = records.join(',');
 				var cAdj = direction > 0 ? 1 : 0; // adjustment
 				$(objectId+'_div').parentNode.insertBefore(
-					$(objectPrefix+'['+records[current-cAdj]+']_div'),
-					$(objectPrefix+'['+records[current+1-cAdj]+']_div')
+					$(objectPrefix + this.structureSeparator + records[current-cAdj] + '_div'),
+					$(objectPrefix + this.structureSeparator + records[current+1-cAdj] + '_div')
 				);
 				this.redrawSortingButtons(objectPrefix, records);
 			}
@@ -444,7 +444,7 @@
 
 	dragAndDropSorting: function(element) {
 		var objectId = element.getAttribute('id').replace(/_records$/, '');
-		var objectName = inline.prependFormFieldNames+inline.parseFormElementName('parts', objectId, 3);
+		var objectName = inline.prependFormFieldNames+inline.parseObjectId('parts', objectId, 3, 0, true);
 		var formObj = document.getElementsByName(objectName);
 
 		if (formObj.length) {
@@ -464,7 +464,7 @@
 
 			if (inline.data.config && inline.data.config[objectId]) {
 				var table = inline.data.config[objectId].table;
-				inline.redrawSortingButtons(objectId+'['+table+']', checked);
+				inline.redrawSortingButtons(objectId + inline.structureSeparator + table, checked);
 			}
 		}
 	},
@@ -474,7 +474,7 @@
 		Sortable.create(
 			objectId,
 			{
-				format: /^[^_\-](?:[A-Za-z0-9\[\]\-\_]*)\[(.*)\]_div$/,
+				format: /^[^_\-](?:[A-Za-z0-9\-\_]*)-(.*)_div$/,
 				onUpdate: inline.dragAndDropSorting,
 				tag: 'div',
 				handle: 'sortableHandle',
@@ -496,7 +496,7 @@
 			// if no records were passed, fetch them from form field
 		if (typeof records == 'undefined') {
 			records = new Array();
-			var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
+			var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectPrefix, 3, 1, true);
 			var formObj = document.getElementsByName(objectName);
 			if (formObj.length) records = formObj[0].value.split(',');
 		}
@@ -504,7 +504,7 @@
 		for (i=0; i<records.length; i++) {
 			if (!records[i].length) continue;
 
-			headerObj = $(objectPrefix+'['+records[i]+']_header');
+			headerObj = $(objectPrefix + this.structureSeparator + records[i] + '_header');
 			sortingObj[0] = Element.select(headerObj, '.sortingUp');
 			sortingObj[1] = Element.select(headerObj, '.sortingDown');
 
@@ -519,7 +519,7 @@
 
 	memorizeAddRecord: function(objectPrefix, newUid, afterUid, selectedValue) {
 		if (this.isBelowMax(objectPrefix)) {
-			var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
+			var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectPrefix, 3, 1, true);
 			var formObj = document.getElementsByName(objectName);
 
 			if (formObj.length) {
@@ -549,7 +549,7 @@
 
 			// if we reached the maximum off possible records after this action, hide the new buttons
 		if (!this.isBelowMax(objectPrefix)) {
-			var objectParent = this.parseFormElementName('full', objectPrefix, 0 , 1);
+			var objectParent = this.parseObjectId('full', objectPrefix, 0 , 1);
 			var md5 = this.getObjectMD5(objectParent);
 			this.hideElementsWithClassName('.inlineNewButton'+(md5 ? '.'+md5 : ''), objectParent);
 		}
@@ -618,7 +618,7 @@
 					}
 
 					if (!(unique.selector && unique.max == -1)) {
-						var formName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
+						var formName = this.prependFormFieldNames+this.parseObjectId('parts', objectPrefix, 3, 1, true);
 						var formObj = document.getElementsByName(formName);
 						if (formObj.length) {
 							var records = formObj[0].value.split(',');
@@ -639,7 +639,7 @@
 	},
 
 	enableDisableRecord: function(objectId) {
-		var elName = this.parseFormElementName('full', objectId, 2);
+		var elName = this.parseObjectId('full', objectId, 2, 0, true);
 		var imageObj = $(objectId+'_disabled');
 		var valueObj = document.getElementsByName(elName+'[hidden]');
 		var formObj = document.getElementsByName(elName+'[hidden]_0');
@@ -656,10 +656,10 @@
 
 	deleteRecord: function(objectId, options) {
 		var i, j, inlineRecords, records, childObjectId, childTable;
-		var objectPrefix = this.parseFormElementName('full', objectId, 0 , 1);
-		var elName = this.parseFormElementName('full', objectId, 2);
-		var shortName = this.parseFormElementName('parts', objectId, 2);
-		var recordUid = this.parseFormElementName('none', objectId, 1);
+		var objectPrefix = this.parseObjectId('full', objectId, 0 , 1);
+		var elName = this.parseObjectId('full', objectId, 2, 0, true);
+		var shortName = this.parseObjectId('parts', objectId, 2, 0, true);
+		var recordUid = this.parseObjectId('none', objectId, 1);
 		var beforeDeleteIsBelowMax = this.isBelowMax(objectPrefix);
 
 			// revert the unique settings if available
@@ -694,18 +694,18 @@
 		}
 
 		var recordCount = this.memorizeRemoveRecord(
-			this.prependFormFieldNames+this.parseFormElementName('parts', objectId, 3, 2),
+			this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 2, true),
 			recordUid
 		);
 
 		if (recordCount <= 1) {
-			this.destroyDragAndDropSorting(this.parseFormElementName('full', objectId, 0 , 2)+'_records');
+			this.destroyDragAndDropSorting(this.parseObjectId('full', objectId, 0 , 2)+'_records');
 		}
 		this.redrawSortingButtons(objectPrefix);
 
 			// if the NEW-button was hidden and now we can add again new children, show the button
 		if (!beforeDeleteIsBelowMax && this.isBelowMax(objectPrefix)) {
-			var objectParent = this.parseFormElementName('full', objectPrefix, 0 , 1);
+			var objectParent = this.parseObjectId('full', objectPrefix, 0 , 1);
 			var md5 = this.getObjectMD5(objectParent);
 			this.showElementsWithClassName('.inlineNewButton'+(md5 ? '.'+md5 : ''), objectParent);
 		}
@@ -726,16 +726,13 @@
 		return path;
 	},
 
-	parseFormElementName: function(wrap, objectId, rightCount, skipRight) {
-			// remove left and right side "data[...|...]" -> '...|...'
-		objectId = objectId.substr(0, objectId.lastIndexOf(']')).substr(objectId.indexOf('[')+1);
+	parseFormElementName: function(wrap, formElementName, rightCount, skipRight) {
+		var idParts = this.splitFormElementName(formElementName);
 
 		if (!wrap) wrap = 'full';
 		if (!skipRight) skipRight = 0;
 
-		var elReturn;
 		var elParts = new Array();
-		var idParts = objectId.split('][');
 		for (var i=0; i<skipRight; i++) idParts.pop();
 
 		if (rightCount > 0) {
@@ -745,17 +742,79 @@
 			elParts = idParts;
 		}
 
+		var elReturn = this.constructFormElementName(wrap, elParts);
+
+		return elReturn;
+	},
+
+	splitFormElementName: function(formElementName) {
+		// remove left and right side "data[...|...]" -> '...|...'
+		formElementName = formElementName.substr(0, formElementName.lastIndexOf(']')).substr(formElementName.indexOf('[')+1);
+		var parts = objectId.split('][');
+
+		return parts;
+	},
+
+	splitObjectId: function(objectId) {
+		objectId = objectId.substr(objectId.indexOf(this.structureSeparator)+1);
+		var parts = objectId.split(this.structureSeparator);
+
+		return parts;
+	},
+
+	constructFormElementName: function(wrap, parts) {
+		var elReturn;
+
 		if (wrap == 'full') {
-			elReturn = this.prependFormFieldNames+'['+elParts.join('][')+']';
+			elReturn = this.prependFormFieldNames+'['+parts.join('][')+']';
 		} else if (wrap == 'parts') {
-			elReturn = '['+elParts.join('][')+']';
+			elReturn = '['+parts.join('][')+']';
 		} else if (wrap == 'none') {
-			elReturn = elParts.length > 1 ? elParts : elParts.join('');
+			elReturn = parts.length > 1 ? parts : parts.join('');
 		}
 
 		return elReturn;
 	},
 
+	constructObjectId: function(wrap, parts) {
+		var elReturn;
+
+		if (wrap == 'full') {
+			elReturn = this.prependFormFieldNames+this.structureSeparator+parts.join(this.structureSeparator);
+		} else if (wrap == 'parts') {
+			elReturn = this.structureSeparator+parts.join(this.structureSeparator);
+		} else if (wrap == 'none') {
+			elReturn = parts.length > 1 ? parts : parts.join('');
+		}
+
+		return elReturn;
+	},
+
+	parseObjectId: function(wrap, objectId, rightCount, skipRight, returnAsFormElementName) {
+		var idParts = this.splitObjectId(objectId);
+
+		if (!wrap) wrap = 'full';
+		if (!skipRight) skipRight = 0;
+
+		var elParts = new Array();
+		for (var i=0; i<skipRight; i++) idParts.pop();
+
+		if (rightCount > 0) {
+			for (var i=0; i<rightCount; i++) elParts.unshift(idParts.pop());
+		} else {
+			for (var i=0; i<-rightCount; i++) idParts.shift();
+			elParts = idParts;
+		}
+
+		if (returnAsFormElementName) {
+			var elReturn = this.constructFormElementName(wrap, elParts);
+		} else {
+			var elReturn = this.constructObjectId(wrap, elParts);
+		}
+
+		return elReturn;
+	},
+
 	handleChangedField: function(formField, objectId) {
 		var formObj;
 		if (typeof formField == 'object') {
@@ -786,7 +845,7 @@
 
 	isBelowMax: function(objectPrefix) {
 		var isBelowMax = true;
-		var objectName = this.prependFormFieldNames+this.parseFormElementName('parts', objectPrefix, 3, 1);
+		var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectPrefix, 3, 1, true);
 		var formObj = document.getElementsByName(objectName);
 
 		if (this.data.config && this.data.config[objectPrefix] && formObj.length) {
Index: t3lib/class.t3lib_tceforms_inline.php
===================================================================
--- t3lib/class.t3lib_tceforms_inline.php	(Revision 6276)
+++ t3lib/class.t3lib_tceforms_inline.php	(Arbeitskopie)
@@ -90,6 +90,9 @@
 
 
 class t3lib_TCEforms_inline {
+	const Structure_Separator = '-';
+	const Disposal_AttributeName = 'Disposal_AttributeName';
+	const Disposal_AttributeId = 'Disposal_AttributeId';
 
 	/**
 	 * Reference to the calling TCEforms instance
@@ -214,9 +217,9 @@
 		}
 			// add the current inline job to the structure stack
 		$this->pushStructure($table, $row['uid'], $field, $config);
-			// e.g. inline[<table>][<uid>][<field>]
+			// e.g. data[<table>][<uid>][<field>]
 		$nameForm = $this->inlineNames['form'];
-			// e.g. inline[<pid>][<table1>][<uid1>][<field1>][<table2>][<uid2>][<field2>]
+			// e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2>
 		$nameObject = $this->inlineNames['object'];
 			// get the records related to this inline record
 		$relatedRecords = $this->getRelatedRecords($table,$field,$row,$PA,$config);
@@ -231,7 +234,7 @@
 			'table' => $foreign_table,
 			'md5' => md5($nameObject),
 		);
-		$this->inlineData['config'][$nameObject.'['.$foreign_table.']'] = array(
+		$this->inlineData['config'][$nameObject. self::Structure_Separator . $foreign_table] = array(
 			'min' => $minitems,
 			'max' => $maxitems,
 			'sortable' => $config['appearance']['useSortable'],
@@ -251,7 +254,7 @@
 			$uniqueIds = $this->getUniqueIds($relatedRecords['records'], $config, $selConfig['type']=='groupdb');
 			$possibleRecords = $this->getPossibleRecords($table,$field,$row,$config,'foreign_unique');
 			$uniqueMax = $config['appearance']['useCombination'] || $possibleRecords === false ? -1	: count($possibleRecords);
-			$this->inlineData['unique'][$nameObject.'['.$foreign_table.']'] = array(
+			$this->inlineData['unique'][$nameObject. self::Structure_Separator . $foreign_table] = array(
 				'max' => $uniqueMax,
 				'used' => $uniqueIds,
 				'type' => $selConfig['type'],
@@ -284,15 +287,15 @@
 
 			// Render the level links (create new record, localize all, synchronize):
 		if ($config['appearance']['levelLinksPosition']!='none') {
-			$levelLinks = $this->getLevelInteractionLink('newRecord', $nameObject.'['.$foreign_table.']', $config);
+			$levelLinks = $this->getLevelInteractionLink('newRecord', $nameObject . self::Structure_Separator . $foreign_table, $config);
 			if ($language>0) {
 					// Add the "Localize all records" link before all child records:
 				if (isset($config['appearance']['showAllLocalizationLink']) && $config['appearance']['showAllLocalizationLink']) {
-					$levelLinks.= $this->getLevelInteractionLink('localize', $nameObject.'['.$foreign_table.']', $config);
+					$levelLinks.= $this->getLevelInteractionLink('localize', $nameObject . self::Structure_Separator . $foreign_table, $config);
 				}
 					// Add the "Synchronize with default language" link before all child records:
 				if (isset($config['appearance']['showSynchronizationLink']) && $config['appearance']['showSynchronizationLink']) {
-					$levelLinks.= $this->getLevelInteractionLink('synchronize', $nameObject.'['.$foreign_table.']', $config);
+					$levelLinks.= $this->getLevelInteractionLink('synchronize', $nameObject . self::Structure_Separator . $foreign_table, $config);
 				}
 			}
 		}
@@ -364,7 +367,7 @@
 			$this->fObj->registerDefaultLanguageData($foreign_table, $rec);
 		}
 			// Send a mapping information to the browser via JSON:
-			// e.g. data[<curTable>][<curId>][<curField>] => data[<pid>][<parentTable>][<parentId>][<parentField>][<curTable>][<curId>][<curField>]
+			// e.g. data[<curTable>][<curId>][<curField>] => data-<pid>-<parentTable>-<parentId>-<parentField>-<curTable>-<curId>-<curField>
 		$this->inlineData['map'][$this->inlineNames['form']] = $this->inlineNames['object'];
 
 			// Set this variable if we handle a brand new unsaved record:
@@ -383,9 +386,9 @@
 			// Get the current naming scheme for DOM name/id attributes:
 		$nameObject = $this->inlineNames['object'];
 		$appendFormFieldNames = '['.$foreign_table.']['.$rec['uid'].']';
-		$formFieldNames = $nameObject.$appendFormFieldNames;
+		$objectId = $nameObject . self::Structure_Separator . $foreign_table . self::Structure_Separator . $rec['uid'];
 			// Put the current level also to the dynNestedStack of TCEforms:
-		$this->fObj->pushToDynNestedStack('inline', $this->inlineNames['object'].$appendFormFieldNames);
+		$this->fObj->pushToDynNestedStack('inline', $objectId);
 
 		$header = $this->renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord);
 		if (!$isVirtualRecord) {
@@ -418,11 +421,11 @@
 		}
 
 			// set the record container with data for output
-		$out = '<div id="'.$formFieldNames.'_header">'.$header.'</div>';
-		$out .= '<div id="'.$formFieldNames.'_fields"'.$appearanceStyleFields.'>'.$fields.$combination.'</div>';
+		$out = '<div id="' . $objectId . '_header">' . $header . '</div>';
+		$out .= '<div id="' . $objectId . '_fields"' . $appearanceStyleFields . '>' . $fields.$combination . '</div>';
 			// wrap the header, fields and combination part of a child record with a div container
-		$class = 'inlineDiv'.($this->fObj->clientInfo['BROWSER']=='msie' ? 'MSIE' : '').($isNewRecord ? ' inlineIsNewRecord' : '');
-		$out = '<div id="'.$formFieldNames.'_div" class="'.$class.'">' . $out . '</div>';
+		$class = 'inlineDiv'.($this->fObj->clientInfo['BROWSER']=='msie' ? 'MSIE' : '') . ($isNewRecord ? ' inlineIsNewRecord' : '');
+		$out = '<div id="' . $objectId . '_div" class="'.$class.'">' . $out . '</div>';
 
 			// Remove the current level also from the dynNestedStack of TCEforms:
 		$this->fObj->popFromDynNestedStack();
@@ -468,9 +471,9 @@
 	 */
 	function renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord=false) {
 			// Init:
-		$formFieldNames = $this->inlineNames['object'].'['.$foreign_table.']['.$rec['uid'].']';
+		$objectId = $this->inlineNames['object'] . self::Structure_Separator . $foreign_table . self::Structure_Separator . $rec['uid'];
 		$expandSingle = $config['appearance']['expandSingle'] ? 1 : 0;
-		$onClick = "return inline.expandCollapseRecord('".htmlspecialchars($formFieldNames)."', $expandSingle)";
+		$onClick = "return inline.expandCollapseRecord('" . htmlspecialchars($objectId) . "', $expandSingle)";
 
 			// Pre-Processing:
 		$isOnSymmetricSide = t3lib_loadDBGroup::isOnSymmetricSide($parentUid, $config, $rec);
@@ -518,7 +521,7 @@
 
 		$altText = t3lib_BEfunc::getRecordIconAltText($rec, $foreign_table);
 		$iconImg = t3lib_iconWorks::getIconImage($foreign_table, $rec, $this->backPath, 'title="'.htmlspecialchars($altText).'" class="absmiddle"');
-		$label = '<span id="'.$formFieldNames.'_label">'.$recTitle.'</span>';
+		$label = '<span id="' . $objectId . '_label">' . $recTitle . '</span>';
 		if (!$isVirtualRecord) {
 			$iconImg = $this->wrapWithAnchor($iconImg, '#', array('onclick' => $onClick));
 			$label = $this->wrapWithAnchor($label, '#', array('onclick' => $onClick, 'style' => 'display: block;'));
@@ -560,8 +563,8 @@
 		$enableManualSorting = $tcaTableCtrl['sortby'] || $config['MM'] || (!$isOnSymmetricSide && $config['foreign_sortby']) || ($isOnSymmetricSide && $config['symmetric_sortby']) ? true : false;
 
 		$nameObject = $this->inlineNames['object'];
-		$nameObjectFt = $nameObject.'['.$foreign_table.']';
-		$nameObjectFtId = $nameObjectFt.'['.$rec['uid'].']';
+		$nameObjectFt = $nameObject . self::Structure_Separator . $foreign_table;
+		$nameObjectFtId = $nameObjectFt . self::Structure_Separator . $rec['uid'];
 
 		$calcPerms = $GLOBALS['BE_USER']->calcPerms(
 			t3lib_BEfunc::readPageAccess($rec['pid'], $GLOBALS['BE_USER']->getPagePermsClause(1))
@@ -809,9 +812,9 @@
 			$selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->fObj->defaultMultipleSelectorStyle.'"';
 			$size = intval($conf['size']);
 			$size = $conf['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$conf['autoSizeMax']) : $size;
-			$onChange = "return inline.importNewRecord('".$this->inlineNames['object']."[".$conf['foreign_table']."]')";
+			$onChange = "return inline.importNewRecord('" . $this->inlineNames['object']. self::Structure_Separator . $conf['foreign_table'] . "')";
 			$item = '
-				<select id="'.$this->inlineNames['object'].'['.$conf['foreign_table'].']_selector"'.
+				<select id="'.$this->inlineNames['object'] . self::Structure_Separator . $conf['foreign_table'] . '_selector"'.
 							$this->fObj->insertDefStyle('select').
 							($size ? ' size="'.$size.'"' : '').
 							' onchange="'.htmlspecialchars($onChange).'"'.
@@ -852,7 +855,7 @@
 
 		$config = $PA['fieldConf']['config'];
 		$allowed = $config['allowed'];
-		$objectPrefix = $this->inlineNames['object'].'['.$foreign_table.']';
+		$objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $foreign_table;
 
 		$createNewRelationText = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.createNewRelation',1);
 		$onClick = "setFormValueOpenBrowser('db','".('|||'.$allowed.'|'.$objectPrefix.'|inline.checkUniqueElement||inline.importElement')."'); return false;";
@@ -870,7 +873,7 @@
 	 * The possible keys for the parameter $type are 'newRecord', 'localize' and 'synchronize'.
 	 *
 	 * @param	string		$type: The link type, values are 'newRecord', 'localize' and 'synchronize'.
-	 * @param	string		$objectPrefix: The "path" to the child record to create (e.g. 'data[parten_table][parent_uid][parent_field][child_table]')
+	 * @param	string		$objectPrefix: The "path" to the child record to create (e.g. 'data-parentPageId-partenTable-parentUid-parentField-childTable]')
 	 * @param	array		$conf: TCA configuration of the parent(!) field
 	 * @return	string		The HTML code of the new link, wrapped in a div
 	 */
@@ -916,7 +919,7 @@
 	/**
 	 * Creates a link/button to create new records
 	 *
-	 * @param	string		$objectPrefix: The "path" to the child record to create (e.g. '[parten_table][parent_uid][parent_field][child_table]')
+	 * @param	string		$objectPrefix: The "path" to the child record to create (e.g. 'data-parentPageId-partenTable-parentUid-parentField-childTable')
 	 * @param	array		$conf: TCA configuration of the parent(!) field
 	 * @return	string		The HTML code for the new record link
 	 * @deprecated	since TYPO3 4.2.0-beta1
@@ -1149,8 +1152,8 @@
 		}
 
 			// the HTML-object-id's prefix of the dynamically created record
-		$objectPrefix = $this->inlineNames['object'].'['.$current['table'].']';
-		$objectId = $objectPrefix.'['.$record['uid'].']';
+		$objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $current['table'];
+		$objectId = $objectPrefix . self::Structure_Separator . $record['uid'];
 
 			// render the foreign record that should passed back to browser
 		$item = $this->renderForeignRecord($parent['uid'], $record, $config);
@@ -1247,7 +1250,7 @@
 		$jsonArrayScriptCall =& $jsonArray['scriptCall'];
 
 		$nameObject = $this->inlineNames['object'];
-		$nameObjectForeignTable = $nameObject.'['.$current['table'].']';
+		$nameObjectForeignTable = $nameObject . self::Structure_Separator . $current['table'];
 			// Get the name of the field pointing to the original record:
 		$transOrigPointerField = $GLOBALS['TCA'][$current['table']]['ctrl']['transOrigPointerField'];
 			// Get the name of the field used as foreign selector (if any):
@@ -1260,7 +1263,7 @@
 		$localizedItems = array_diff($newItems, $oldItems);
 			// Set the items that should be removed in the forms view:
 		foreach ($removedItems as $item) {
-			$jsonArrayScriptCall[] = "inline.deleteRecord('".$nameObjectForeignTable.'['.$item.']'."', {forceDirectRemoval: true});";
+			$jsonArrayScriptCall[] = "inline.deleteRecord('".$nameObjectForeignTable . self::Structure_Separator . $item . "', {forceDirectRemoval: true});";
 		}
 			// Set the items that should be added in the forms view:
 		foreach ($localizedItems as $item) {
@@ -1270,7 +1273,7 @@
 			$jsonArrayScriptCall[] = "inline.memorizeAddRecord('$nameObjectForeignTable', '".$item."', null, $selectedValue);";
 				// Remove possible virtual records in the form which showed that a child records could be localized:
 			if (isset($row[$transOrigPointerField]) && $row[$transOrigPointerField]) {
-				$jsonArrayScriptCall[] = "inline.fadeAndRemove('".$nameObjectForeignTable.'['.$row[$transOrigPointerField].']_div'."');";
+				$jsonArrayScriptCall[] = "inline.fadeAndRemove('" . $nameObjectForeignTable . self::Structure_Separator . $row[$transOrigPointerField] . '_div' . "');";
 			}
 		}
 		if ($data) {
@@ -1685,10 +1688,9 @@
 		$current = $this->getStructureLevel(-1);
 			// if there are still more inline levels available
 		if ($current !== false) {
-			$lastItemName = $this->getStructureItemName($current);
 			$this->inlineNames = array(
-				'form' => $this->prependFormFieldNames.$lastItemName,
-				'object' => $this->prependNaming.'['.$this->inlineFirstPid.']'.$this->getStructurePath(),
+				'form' => $this->prependFormFieldNames . $this->getStructureItemName($current, self::Disposal_AttributeName),
+				'object' => $this->prependNaming . self::Structure_Separator . $this->inlineFirstPid . self::Structure_Separator . $this->getStructurePath(),
 			);
 			// if there are no more inline levels available
 		} else {
@@ -1698,16 +1700,25 @@
 
 
 	/**
-	 * Create a name/id for usage in HTML output of a level of the structure stack.
+	 * Create a name/id for usage in HTML output of a level of the structure stack to be used in form names.
 	 *
 	 * @param	array		$levelData: Array of a level of the structure stack (containing the keys table, uid and field)
 	 * @return	string		The name/id of that level, to be used for HTML output
 	 */
-	function getStructureItemName($levelData) {
+	function getStructureItemName($levelData, $disposal = self::Disposal_AttributeId) {
 		if (is_array($levelData)) {
-			$name =	'['.$levelData['table'].']' .
-					'['.$levelData['uid'].']' .
-					(isset($levelData['field']) ? '['.$levelData['field'].']' : '');
+			$parts = array($levelData['table'], $levelData['uid']);
+			if (isset($levelData['field'])) {
+				$parts[] = $levelData['field'];
+			}
+
+				// Use in name attributes:
+			if ($disposal === self::Disposal_AttributeName) {
+				$name = '[' . implode('][', $parts) . ']';
+				// Use in id attributes:
+			} else {
+				$name = implode(self::Structure_Separator, $parts);
+			}
 		}
 		return $name;
 	}
@@ -1733,7 +1744,7 @@
 
 	/**
 	 * Get the identifiers of a given depth of level, from the top of the stack to the bottom.
-	 * An identifier consists looks like [<table>][<uid>][<field>].
+	 * An identifier looks like "<table>-<uid>-<field>".
 	 *
 	 * @param	integer		$structureDepth: How much levels to output, beginning from the top of the stack
 	 * @return	string		The path of identifiers
@@ -1744,7 +1755,7 @@
 
 		for ($i = 1; $i <= $structureDepth; $i++) {
 			$current = $this->getStructureLevel(-$i);
-			$string = $this->getStructureItemName($current).$string;
+			$string = $this->getStructureItemName($current, self::Disposal_AttributeId) . $string;
 		}
 
 		return $string;
@@ -1753,7 +1764,7 @@
 
 	/**
 	 * Convert the DOM object-id of an inline container to an array.
-	 * The object-id could look like 'data[inline][tx_mmftest_company][1][employees]'.
+	 * The object-id could look like 'data-parentPageId-tx_mmftest_company-1-employees'.
 	 * The result is written to $this->inlineStructure.
 	 * There are two keys:
 	 *  - 'stable': Containing full qualified identifiers (table, uid and field)
@@ -1766,10 +1777,10 @@
 	function parseStructureString($string, $loadConfig=true) {
 		$unstable = array();
 		$vector = array('table', 'uid', 'field');
-		$pattern = '/^'.$this->prependNaming.'\[(.+?)\]\[(.+)\]$/';
+		$pattern = '/^' . $this->prependNaming . self::Structure_Separator . '(.+?)' . self::Structure_Separator . '(.+)$/';
 		if (preg_match($pattern, $string, $match)) {
 			$this->inlineFirstPid = $match[1];
-			$parts = explode('][', $match[2]);
+			$parts = explode(self::Structure_Separator, $match[2]);
 			$partsCnt = count($parts);
 			for ($i = 0; $i < $partsCnt; $i++) {
 				if ($i > 0 && $i % 3 == 0) {
Index: typo3/jsfunc.tbe_editor.js
===================================================================
--- typo3/jsfunc.tbe_editor.js	(Revision 6276)
+++ typo3/jsfunc.tbe_editor.js	(Arbeitskopie)
@@ -36,7 +36,7 @@
 var TBE_EDITOR = {
 	/* Example:
 		elements: {
-			'data[table][uid]': {
+			'data-parentPid-table-uid': {
 				'field': {
 					'range':		[0, 100],
 					'rangeImg':		'',
