{
	title: 'Testing new EntityGrid',
	closable: true,
	onInitialize: function (i_self) {

		console.clear();

		(function () {

			var o_dmd = {
				"__cid__": "dmd",
				"entities": {
					"WSHCURET00": {
						"cid": "A",
						"title": {
							"da": "Transportører",
							"en": "Couriers"
						},
						"idColumn": "CURNAME",
						"columns": {
							"CURCURTKN": {
								"__dbType__": "primaryKey",
								"title": {
									"da": "ID",
									"en": "ID"
								}
							},
							"CURNAME": {
								"__dbType__": "text",
								"title": {
									"da": "Navn",
									"en": "Name"
								},
								"isTitle": true
							},
							"CURDESC": {
								"__dbType__": "longtext",
								"title": {
									"da": "Beskrivelse",
									"en": "Description"
								}
							},
							"CURTEST": {
								"title": {
									"da": "Beskrivelse",
									"en": "Description"
								},
								"type": "varchar(200)"
							},
							"CURPROP": {
								"__dbType__": "xpd",
								"title": {
									"da": "Transportør",
									"en": "Courier"
								},
								"xpd": "courier"
							}
						},
						"view": {
							"base_grid": {
								"title": "base grid view",
								"ui": {
									"uiType": "entitygrid",
									"title": "base grid ui",
									"items": [
										{
											"name": "CURCURTKN",
											"width": 50
										},
										{
											"name": "CURNAME"
										},
										{
											"name": "CURDESC"
										},
										{
											"name": "CURPROP_TITLE"
										}
									]
								}
							},
							"base_form": {
								"title": "base form view",
								"ui": {
									"uiType": "entityform",
									"items": [
										{
											"uiType": "tabpanel",
											"items": [
												{
													"uiType": "panel",
													"title": "Main Panel",
													"items": [
														{
															"name": "CURCURTKN" 
														},
														{
															"name": "CURNAME" 
														},
														{
															"name": "CURDESC" 
														}
													]
												}
											]
										}
									]
								}
							}
						},
						"ui": {
							"grids": {
								"portfolio": {
									"columns": [
										{
											"name": "CURCURTKN"
										}
									]
								}
							},
							"forms": {

							}
						}
					}
				}
			};

			var XPD = {};
			XPD.fn = {};
			window.XPD = XPD;

			XPD.rules = {
				"idProperty": "__cid__",
				"propertyRulesPath": null,
				"propertyRulesFn": "window.XPD.fn.rules",
				"properties": {
					"type": {
						"type": "string",
						"uiType": "varchar"
					},
					"required": {
						"type": "boolean",
						"value": false,
						"uiType": "boolean"
					},
					"export": {
						"type": "boolean",
						"value": true,
						"uiType": "enumboolean"
					},
					"alias": {
						"type": "array",
						"value": [],
						"uiType": "picker",
						"multiselect": true,
						"allowCreate": true,
						"preBurn": "alias.preBurn",
						"afterBurn": "alias.afterBurn"
					},
					"enumeration": {
						"type": "string",
						"alias": ["enum"],
						"uiType": "varchar"
					},
					"uiType": {
						"type": "string",
						"value": "varchar",
						"uiType": "varchar"
					},
					"preBurn": {
						"type": "function",
						"value": "",
						"uiType": "aceeditor",
						"export": false
					},
					"afterBurn": {
						"type": "function",
						"value": "",
						"uiType": "aceeditor",
						"export": false
					},
					"values": {
						"type": "array",
						"value": [],
						"uiType": "picker",
						"export": false
					},
					"allowedTypes": {
						"type": "array",
						"value": [],
						"uiType": "picker",
						"export": false,
						"multiselect": true,
						"allowCreate": true
					},
					"defaultType": {
						"type": "string",
						"export": false
					},
					"preBurnIndex": {
						"type": "number",
						"value": -1
					}
				},
				"collections": {
					"varchar": {
						"id": -1,
						"name": "varchar",
						"apply": "string"
					},
					"integer": {
						"id": -2,
						"name": "integer",
						"apply": "number"
					},
					"string": {
						"id": 1,
						"name": "string",
						"properties": {
							"type": {
								"value": "string"
							},
							"value": {
								"type": "string",
								"value": ""
							}
						}
					},
					"number": {
						"id": 2,
						"name": "number",
						"properties": {
							"type": {
								"value": "number"
							},
							"value": {
								"type": "number",
								"value": 0
							},
							"uiType": {
								"value": "number"
							}
						}
					},
					"array": {
						"id": 3,
						"name": "array",
						"properties": {
							"type": {
								"value": "array"
							},
							"value": {
								"type": "array",
								"value": []
							},
							"uiType": {
								"value": "json"
							}
						}
					},
					"object": {
						"id": 4,
						"name": "object",
						"properties": {
							"type": {
								"value": "object"
							},
							"value": {
								"type": "object",
								"value": {}
							},
							"uiType": {
								"value": "json"
							}
						}
					},
					"boolean": {
						"id": 5,
						"name": "boolean",
						"properties": {
							"type": {
								"value": "boolean"
							},
							"value": {
								"type": "boolean",
								"value": false
							},
							"uiType": {
								"value": "boolean"
							}
						}
					},
					"i18n": {
						"id": 6,
						"name": "i18n",
						"properties": {
							"type": {
								"value": "i18n"
							},
							"value": {
								"type": "string",
								"value": false
							},
							"uiType": {
								"value": "i18n"
							}
						}
					},
					"function": {
						"id": 7,
						"name": "function",
						"properties": {
							"type": {
								"value": "function"
							},
							"value": {
								"type": "string",
								"value": false
							},
							"uiType": {
								"value": "aceeditor"
							}
						}
					}
				}
			};
			XPD.fn.rules = {
				alias: {
					preBurn: function (value, o_value, s_property) {
						// Only look for and use alias values if the value object
						// does not have the property defined already
						if ( o_value[s_property] == null ) {
							ip2.each(value, function (s_alias) {
								// Keep checking if value object now has the property defined
								if ( o_value[s_alias] != null && o_value[s_property] == null ) {
									o_value[s_property] = o_value[s_alias];
									delete o_value[s_alias];
								}
							});
						}
					}
				}
			};

			XPD.db2types = {
				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.db2types",
				"idProperty": "__dbType__",
				"properties": {
					"__dbType__": {
						"type": "string",
						"value": "generic",
						"export": false
					},
					"type": {
						"type": "string",
						"value": "varchar",
						"required": true,
						"export": "type",
						"preBurn": "type.preBurn"
					},
					"uiType": {
						"type": "string",
						"value": "varchar",
						"required": true,
						"alias": ["uitype"],
						"export": false
					},
					"length": {
						"type": "number",
						"value": 128,
						"required": true,
						"export": false
					},
					"isTitle": {
						"type": "boolean",
						"value": false,
						"export": false
					}
				},
				"collections": {
					"varchar": {
						"id": -1,
						"apply": "text"
					},
					"generic": {
						"id": 1
					},
					"primaryKey": {
						"id": 2,
						"properties": {
							"type": {
								"value": "int"
							},
							"uiType": {
								"value": "number"
							},
							"length": {
								"value": 11
							},
							"autoIncrement": {
								"type": "boolean",
								"value": true,
								"export": "auto_increment",
								"alias": ["auto_increment"]
							},
							"primary": {
								"type": "boolean",
								"value": true
							},
							"readonly": {
								"type": "boolean",
								"value": true,
								"alias": ["readOnly"]
							}
						}
					},
					"text": {
						"id": 1,
						"collections": {
							"longtext": {
								"id": 2,
								"properties": {
									"uiType": {
										"value": "textarea"
									},
									"length": {
										"value": 16384
									}
								},
								"collections": {
									"html": {
										"id": 3,
										"properties": {
											"uiType": {
												"value": "html"
											}
										}
									},
									"markdown": {
										"id": 4,
										"properties": {
											"uiType": {
												"value": "markdown"
											}
										}
									},
									"jsontext": {
										"id": 5,
										"properties": {
											"uiType": {
												"value": "jsontext"
											}
										}
									}
								}
							}
						}
					},
					"number": {
						"id": 6,
						"properties": {
							"uiType": {
								"value": "number"
							},
							"type": {
								"value": "int"
							},
							"length": {
								"value": 5
							}
						}
					},
					"xpd": {
						"id": 7,
						"properties": {
							"uiType": {
								"value": "xpd"
							},
							"type": {
								"value": "varchar"
							},
							"length": {
								"value": 32768
							},
							"file": {
								"type": "string",
								"value": "",
								"alias": ["xpd"]
							}
						}
					}
				}
			};
			XPD.fn.db2types = {
				type: {
					preBurn: function (value, o_value, s_property) {
						
						var a_split = value.split('(');
						var s_type = a_split[0];
						o_value.type = s_type;

						if ( a_split.length > 1 ) {
							a_split = a_split[1].split(')');
							var n_length = +(a_split[0]);
							o_value.length = n_length;
						}
					},
					afterBurn: function (value, o_value, s_property) {

						// Change
						// type: varchar
						// length: 11
						// into varchar(11) etc..

						// TODO: RegEx magic - this crappy quick example
						var a_match = value.match(/\(/g) || [];
						if ( !a_match.length ) {
							o_value[s_property] = value+'('+o_value.length+')';
						}
					}
				}
			};

			XPD.ext407uiFull = {

				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.ext407",

				"idProperty": "uiType",

				"properties": {
					"uiType": {
						"type": "string",
						"value": "panel",
						"alias": [
							"uitype"
						]
					},
					"className": {
						"type": "string",
						"export": "$className"
					},
					"uiName": {
						"type": "string",
						"export": "xtype"
					},
					"childProperties": {
						"type": "array",
						"preBurn": "childProperties.preBurn",
						"preBurnIndex": 99999999
					},
					"title": {
						"type": "i18n",
						"value": ""
					}
				},

				"collections": {

					"container": {
						"id": 1,
						"properties": {
							"items": {
								"type": "array",
								"allowedTypes": [
									"container",
									"panel"
								],
								"defaultType": "container"
							},
							"childProperties": {
								"value": ["items"]
							}
						},
						"collection": {
							"viewport": {
								"id": 2
							},
							"fieldcontainer": {
								"id": 3,
								"collection": {
									"checkboxgroup": {
										"id": 4,
										"collection": {
											"radiogroup": {
												"id": 5
											}
										}				
									}
								}
							},
							"fieldset": {
								"id": 6
							},
							"headercontainer": {
								"id": 7,
								"collection": {
									"gridcolumn": {
										"id": 8,
										"collection": {
											"rownumberer": {
												"id": 9
											},
											"actioncolumn": {
												"id": 10
											},
											"booleancolumn": {
												"id": 11
											},
											"datecolumn": {
												"id": 12
											},
											"numbercolumn": {
												"id": 13
											},
											"templatecolumn": {
												"id": 14
											},
											"checkcolumn": {
												"id": 15
											}
										}
									}
								}
							},
							"propertyheadercontainer": {
								"id": 16
							},
							"panel": {
								"id": 17,
								"collection": {
									"buttongroup": {
										"id": 18
									},
									"form": {
										"id": 19
									},
									"menu": {
										"id": 20,
										"collection": {
											"colormenu": {
												"id": 21
											},
											"datemenu": {
												"id": 22
											},
											"listmenu": {
												"id": 23
											},
											"rangemenu": {
												"id": 24
											}
										}
									},
									"tablepanel": {
										"id": 25,
										"collection": {
											"gridpanel": {
												"id": 26,
												"collection": {
													"propertygrid": {
														"id": 27
													},
													"livesearchgridpanel": {
														"id": 28
													},
													"transformgrid": {
														"id": 29
													}

												}
											},
											"treepanel": {
												"id": 30
											},
											"tabpanel": {
												"id": 31
											},
											"tip": {
												"id": 32,
												"collection": {
													"slidertip": {
														"id": 33
													},
													"tooltip": {
														"id": 34,
														"collection": {
															"quicktip": {
																"id": 35
															}
														}
													}
												}
											},
											"gmappanel": {
												"id": 36
											}
										}
									}
								}
							},
							"header": {
								"id": 37,
								"collection": {
									"tabbar": {
										"id": 38
									}
								}
							},
							"toolbar": {
								"id": 39,
								"collection": {
									"pagingtoolbar": {
										"id": 40
									},
									"statusbar": {
										"id": 41
									}
								}
							},
							"grouptabpanel": {
								"id": 42
							}
						}
					},
					"image": {
						"id": 43
					},
					"loadmask": {
						"id": 44
					},
					"progressbar": {
						"id": 45
					},
					"button": {
						"id": 45,
						"collection": {
							"splitbutton": {
								"id": 46,
								"collection": {
									"cycle": {
										"id": 47
									}
								}
							},
							"tab": {
								"id": 48
							}
						}
					},
					"draw": {
						"id": 49,
						"collection": {
							"chart": {
								"id": 50
							}
						}
					},
					"flash": {
						"id": 51
					},
					"label": {
						"id": 52
					},
					"field": {
						"id": 53,
						"collection": {
							"checkbox": {
								"id": 54,
								"collection": {
									"radio": {
										"id": 55
									}
								}
							},
							"displayfield": {
								"id": 56
							},
							"hiddenfield": {
								"id": 57
							},
							"textfield": {
								"id": 58,
								"collection": {
									"fileuploadfield": {
										"id": 59
									},
									"textareafield": {
										"id": 60
									},
									"triggerfield": {
										"id": 61,
										"collection": {
											"pickerfield": {
												"id": 62,
												"collection": {
													"combobox": {
														"id": 63
													},
													"datefield": {
														"id": 64
													},
													"timefield": {
														"id": 65
													}
												}
											},
											"spinnerfield": {
												"id": 66,
												"collection": {
													"numberfield": {
														"id": 67
													}
												}
											}
										}
									}
								}
							},
							"multislider": {
								"id": 68,
								"collection": {
									"sliderfield": {
										"id": 69
									}
								}
							},
							"multiselectfield": {
								"id": 70,
								"collection": {
									"itemselector": {
										"id": 71
									}
								}
							}
						}
					},
					"htmleditor": {
						"id": 72
					},
					"gridscroller": {
						"id": 73,
						"collection": {
							"paginggridscroller": {
								"id": 74
							}
						}
					},

					"menuitem": {
						"id": 75,
						"collection": {
							"menucheckitem": {
								"id": 76
							},
							"menuseparator": {
								"id": 77
							}
						}
					},
					"tool": {
						"id": 78
					},
					"colorpicker": {
						"id": 79
					},
					"datepicker": {
						"id": 80
					}
				}
			};

			XPD.ext407ui = {
				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.ext407ui",
				"idProperty": "uiType",
				"properties": {
					"title": {
						"type": "i18n",
						"value": ""
					},
					"uiType": {
						"type": "string",
						"value": "panel",
						"alias": [
							"uitype"
						]
					},
					"className": {
						"type": "string",
						"export": "$className"
					},
					"uiName": {
						"type": "string",
						"export": "xtype"
					},
					"childProperties": {
						"type": "array",
						"preBurn": "childProperties.preBurn",
						"preBurnIndex": 99999999
					}
				},
				"collections": {
					"entitygrid": {
						"id": 1,
						"properties": {
							"columns": {
								"type": "array",
								"alias": [
									"items"
								],
								"preBurn": "entityColumns.preBurn",
								"preBurnIndex": 1,
								"allowedTypes": [
									"column",
									"numbercolumn"
								],
								"defaultType": "column"
							},
							"className": {
								"value": "Ext.ux.entity.Grid"
							},
							"uiName": {
								"value": "entitygrid"
							},
							"tbar": {
								"type": "array",
								"allowedTypes": [
									"button",
									"splitbutton"
								],
								"defaultType": "button"
							},
							"childProperties": {
								"value": ["columns", "tbar"]
							}
						}
					},
					"column": {
						"id": 2,
						"properties": {
							"header": {
								"type": "string",
								"alias": [
									"title"
								]
							},
							"width": {
								"type": "number"
							},
							"dataIndex": {
								"type": "string",
								"alias": [
									"name"
								]
							},
							"editor": {
								"type": "object"
							},
							"className": {
								"value": "Ext.grid.column.Column"
							},
							"uiName": {
								"value": "column"
							}
						},
						"collections": {
							"numbercolumn": {
								"id": 6,
								"properties": {
									"className": {
										"value": "Ext.grid.column.NumberColumn"
									},
									"uiName": {
										"value": "numbercolumn"
									}
								}
							}
						}
					},
					"entityform": {
						"id": 3,
						"properties": {
							"items": {
								"type": "array",
								"defaultType": "panel"
							},
							"childProperties": {
								"value": ["items", "tbar"]
							},
							"tbar": {
								"type": "array",
								"allowedTypes": [
									"button",
									"splitbutton"
								],
								"defaultType": "button"
							},
							"className": {
								"value": "Ext.ux.entity.Form"
							},
							"uiName": {
								"value": "entityform"
							}
						}
					},
					"tabpanel": {
						"id": 4,
						"properties": {
							"items": {
								"type": "array",
								"defaultType": "panel"
							},
							"childProperties": {
								"value": ["items"]
							},
							"className": {
								"value": "Ext.tab.Panel"
							},
							"uiName": {
								"value": "tabpanel"
							}
						}
					},
					"panel": {
						"id": 5,
						"properties": {
							"items": {
								"type": "array",
								"defaultType": "panel"
							},
							"dockedItems": {
								"type": "array",
								"defaultType": "panel"
							},
							"childProperties": {
								"value": ["items", "dockedItems"]
							},
							"className": {
								"value": "Ext.panel.Panel"
							},
							"uiName": {
								"value": "panel"
							}
						}
					},
					"display": {
						"id": 7,
						"properties": {
							"context": {
								"type": "object",
								"value": {
									"form": "display",
									"grid": "column"
								}
							},
							"className": {
								"value": "Ext.form.field.Display"
							},
							"uiName": {
								"value": "display"
							}
						}
					},
					"varchar": {
						"id": 8,
						"properties": {
							"context": {
								"type": "object",
								"value": {
									"form": "varchar",
									"grid": "column"
								}
							},
							"className": {
								"value": "Ext.form.field.Text"
							},
							"uiName": {
								"value": "textfield"
							},
							"fieldLabel": {
								"type": "string",
								"alias": ["title"]
							}
						}
					},
					"textarea": {
						"id": 9,
						"properties": {
							"context": {
								"type": "object",
								"value": {
									"form": "textarea",
									"grid": "column"
								}
							},
							"className": {
								"value": "Ext.form.field.Textarea"
							},
							"uiName": {
								"value": "textarea"
							},
							"fieldLabel": {
								"type": "string",
								"alias": ["title"]
							}
						}
					},
					"number": {
						"id": 10,
						"properties": {
							"context": {
								"type": "object",
								"value": {
									"form": "number",
									"grid": "numbercolumn"
								}
							},
							"className": {
								"value": "Ext.form.field.Number"
							},
							"uiName": {
								"value": "numberfield"
							},
							"fieldLabel": {
								"type": "string",
								"alias": ["title"]
							}
						}
					}
				}
			};
			XPD.fn.ext407ui = {
				entityColumns: {
					preBurn: function (value, o_value, s_property) {

						var o_compiler = this;
						var s_idProperty = o_compiler.idProperty;

						ip2.each(value, function (o_column, n_index, a_context) {
							
							// Translate the idPropertyType to grid context (total hack)
							var s_key = o_column[s_idProperty];

							// Only process if there is a key handy at this time
							// Since we are mapping from possible extension from a field
							if ( s_key ) {

								var o_collection = o_compiler.collections[s_key];
								var o_map = o_collection.properties.context || {};
								var s_map = o_map.value && o_map.value.grid;

								if ( s_map ) {
									o_column[s_idProperty] = s_map;
								}
							}
						});
					}
				},
				childProperties: {
					preBurn: function (value, o_value, s_property) {

						// value = ["columns", "tbar"]
						// o_value = {uiType: 'entitygrid', columns: [...],..}
						// s_property = childProperties

						var o_compiler = this;
						var s_idProperty = o_compiler.idProperty;
						var s_type = o_value[s_idProperty];

						// Find the collection in the compiler that matches this o_value
						var o_collection = o_compiler.collections[s_type];
						var o_properties = o_collection.properties;

						// Iterate the childProperties array ["items", "dockedItems"]
						ip2.each(value, function (s_key) {

							// Find the definition in the values
							ip2.each(o_value[s_key], function (o_definition, index, o_context) {

								// o_definition = {name: "CURCURTKN", uiType: "column", ...}
								
								// Get defaultType for this child if none is supplied
								if ( o_definition[s_idProperty] == null ) {
									o_definition[s_idProperty] = o_properties[s_key].defaultType;
								}

								o_context[index] = xpd.compile(o_definition, o_compiler);
							});
						});
					}
				}
			}

			XPD.db2dmd = {
				"idProperty": "__cid__",
				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.db2dmd",
				"properties": {},
				"collections": {
					"dmd": {
						"id": 1,
						"properties": {
							"API": {
								"type": "object",
								"value": {
									"proxy": "ip2dmdproxy.aspx"
								}
							},
							"entity": {
								"type": "object",
								"alias": ["entities"],
								"preBurn": "entity.preBurn"
							},
							"relation": {
								"type": "object",
								"alias": ["relations"]
							}
						}
					},
					"entity": {
						"id": 2,
						"properties": {
							"cid": {
								"type": "string"
							},
							"title": {
								"type": "i18n"
							},
							"fieldRulePath": {
								"type": "string",
								"value": "window.XPD.db2types"
							},
							"uiRulePath": {
								"type": "string",
								"value": "window.XPD.ext407ui",
								"export": false
							},
							"field": {
								"type": "object",
								"alias": ["columns", "columns"],
								"export": "columns",
								"preBurn": "field.preBurn",
								"preBurnIndex": 2
							},
							"view": {
								"type": "object",
								"alias": ["views"],
								"preBurn": "view.preBurn",
								"preBurnIndex": 3
							},
							"idColumn": {
								"type": "string",
								"preBurn": "idColumn.preBurn",
								"export": false,
								"preBurnIndex": 1
							}
						}
					},
					"view": {
						"id": 3,
						"properties": {
							"title": {
								"type": "i18n"
							},
							"items": {
								"type": "array"
							},
							"uiRulePath": {
								"type": "string",
								"value": "window.XPD.ext407ui"
							},
							"__cid__": {
								"type": "string",
								"value": "entitygrid",
								"uiType": "picker",
								"values": ["entitygrid", "entityform"]
							}
						}
					}
				}
			};
			XPD.fn.db2dmd = {
				entity: {
					preBurn: function (value, o_value, s_property) {

						var o_compiler = this;
						
						ip2.each(value, function (o_entity, s_entity, o_context) {
							
							var s_idProperty = o_compiler.idProperty;
							// We apply the correct collection ID manually here (if not supplied)
							o_entity[s_idProperty] || (o_entity[s_idProperty]='entity');
							
							// Compile the entity
							o_entity = o_context[s_entity] = xpd.compile(o_entity, o_compiler);
						});
					}
				},
				field: {
					preBurn: function (value, o_value, s_property) {

						var o_compiler = this;
						var o_rules = xpd.getXpdRules(o_value.fieldRulePath);
						
						ip2.each(value, function (o_field, s_field, o_context) {
							
							var s_idProperty = o_rules.idProperty;
							// We apply the correct collection ID manually here (if not supplied)
							o_field[s_idProperty] || (o_field[s_idProperty]='generic');
							
							// Compile the fields against rules
							o_context[s_field] = xpd.compile(o_field, o_rules);
						});
					}
				},
				view: {
					preBurn: function (value, o_value, s_property) {

						var o_compiler = this;
						
						ip2.each(value, function (o_view, s_view, o_context) {

							// Now compile the views
							// Iterate all objects and arrays to extend
							// from fields where name is applicable
							var o_match = o_value.field;
							o_view = o_context[s_view] = xpd.deepInherit(o_view, o_match, 'name');
							
							// We provide a idProperty if none exists
							var s_idProperty = o_compiler.idProperty;
							o_view[s_idProperty] || (o_view[s_idProperty]='view');
							
							// Compile the view against rules
							o_view = o_context[s_view] = xpd.compile(o_view, o_compiler);

							// Compile the view against the supplied uiRules
							var o_uiRules = xpd.getXpdRules(o_view.uiRulePath);
							o_view = o_context[s_view] = xpd.compile(o_view, o_uiRules);
						});
					}
				},
				ui: {
					preBurn: function (value, o_value, s_property) {
					}
				},
				idColumn: {
					preBurn: function (value, o_value, s_property) {

						var o_compiler = this;

						ip2.each(o_value.field, function (o_field, s_field, o_context) {
							if ( s_field == value ) {
								o_context[s_field].primary = true;
							}
						});
					}
				},
			};

			XPD.dmd = {
				"idProperty": "__cid__",
				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.dmd",
				"properties": {
					"API": {
						"type": "string",
						"value": "ip2dmdproxy.aspx"
					},
					"entity": {
						"type": "object",
						"alias": ["entities"]
					},
					"relation": {
						"type": "object"
					}
				}
			};

			XPD.entity = {
				"idProperty": "__cid__",
				"propertyRulesPath": "",
				"propertyRulesFn": "window.XPD.fn.entity",
				"properties": {
					"cid": {
						"type": "string"
					},
					"title": {
						"type": "i18n"
					},
					"propertyRulesPath": {
						"type": "string",
						"value": "window.XPD.db2types"
					},
					"uiRulePath": {
						"type": "string",
						"value": "window.XPD.ext407ui",
						"export": false
					},
					"field": {
						"type": "object",
						"alias": ["columns", "columns"],
						"export": "columns",
						"preBurn": "field.preBurn",
						"preBurnIndex": 2
					},
					"view": {
						"type": "object",
						"alias": ["views"],
						"preBurn": "view.preBurn",
						"preBurnIndex": 3
					},
					"idColumn": {
						"type": "string",
						"preBurn": "idColumn.preBurn",
						"export": false,
						"preBurnIndex": 1
					}
				}
			};

			XPD.view = {
				"idProperty": "__cid__",
				"propertyRulesPath": "window.XPD.rules",
				"propertyRulesFn": "window.XPD.fn.view",
				"properties": {
					"uiType": {
						"type": "string",
						"uiType": "picker",
						"value": "entitygrid",
						"values": ["entitygrid", "entityform"]
					},
					"title": {
						"type": "i18n"
					},
					"items": {
						"type": "array"
					},
					"uiRulePath": {
						"type": "string",
						"value": "window.XPD.ext407ui"
					}
				}
			};

			var deepInherit = function (child, o_match, s_against) {
				
				ip2.each(child.items, function (value, key, context) {
					if ( value.name && o_match[value.name] ) {
						var o_parent = o_match[value.name];
						ip2.defaults(value, o_parent);
					}

					if ( value.items ) {
						context[key] = deepInherit(value, o_match, s_against);
					}
				});

				return child;
			};

			var inherit = function (o_xpd) {

				// Make sure we have properties and collections
				o_xpd.properties || (o_xpd.properties={});
				o_xpd.collections || (o_xpd.collections={});

				// Go through each collection and inherit properties from parent properties
				ip2.each(o_xpd.collections, function (o_collection, s_key) {

					// Get "name" property from s_key if not present in o_collection
					if ( o_collection.name == null ) {
						o_collection.name = s_key;
					}

					// Make sure we have properties and collections
					o_collection.properties || (o_collection.properties={});
					o_collection.collections || (o_collection.collections={});

					ip2.each(o_xpd.properties, function (o_parentProp, s_parentPropName) {
						// Collection does not have this parent property
						if ( !o_collection.properties[s_parentPropName] ) {
							o_collection.properties[s_parentPropName] = o_parentProp;
						}
						// Parent does have this parent property - defaults it
						else {
							ip2.defaults(o_collection.properties[s_parentPropName], o_parentProp);
						}
					});
				});

				// Go through collections in collections
				ip2.each(o_xpd.collections, function (o_collection) {
					inherit(o_collection);
				});

				return o_xpd;
			};
			var flatten = function (o_original, s_against) {

				if ( o_original.__flat__ ) return o_original;

				s_against || (s_against='name');

				var o_xpd = ip2.extend({}, o_original);

				inherit(o_xpd);

				o_xpd = ip2.xpd.flatten(o_xpd, s_against);

				// Apply rule property values
				var o_rules = getXpdRules(o_xpd.propertyRulesPath, o_xpd);

				applyRules(o_xpd, o_rules);
				o_xpd.__rules__ = o_rules;
				o_xpd.__flat__ = true;

				return o_xpd;
			};

			var getXpdRules = function (path, o_xpd) {

				if ( path && path.__flat__ ) return path;

				var o_rules;
				var o_fn;

				// Check if propertyRulesPath property is null (means its a core ruleset)
				if ( path === null ) {
					o_rules = ip2.extend({}, o_xpd);
					o_fn = ip2.getProperty(o_rules.propertyRulesFn);
				}

				// Rules could be a string to a property?
				if ( ip2.getProperty(path) ) {
					var o_path = ip2.getProperty(path);
					o_fn = ip2.getProperty(o_path.propertyRulesFn);
					o_rules = flatten(o_path);
				}

				if ( !o_rules ) {
					console.log('no rules could be gotten for these rules');
					debugger;
				}

				// Get rule pre and afterburn functions by propertyRulesFn
				// TODO: Make a method that takes anything as argument
				o_rules.__fn__ = o_fn || {};

				return o_rules;
			};
			var applyRules = function (o_xpd, o_rules) {

				ip2.each(o_xpd.collections, function (o_collection) {
				
					ip2.each(o_collection.properties, function (o_property) {

						// Get rule values for each property and extend upon
						var s_type = o_property.type;
						var o_parentRule = o_rules.collections[s_type];

						ip2.each(o_parentRule.properties, function (o_parentProp, s_key) {
							// This property does not exist - so we add its value from rules
							if ( o_property[s_key] == null && o_parentProp.value ) {
								o_property[s_key] = o_parentProp.value;
							}
						});
					});
				});
			};

			var preBurn = function (o_settings) {

				var o_context = o_settings.context;
				var o_rule = o_settings.rule;
				var o_fn = o_settings.fn;
				var o_prop = o_settings.property;
				var o_value = o_settings.value;
				var s_prop = o_settings.propertyName;

				var a_preBurn = [];
				var n_preBurnDefaultIndex = 0;
				
				ip2.each(o_prop, function (value, key) {

					var o_ruleProp = o_rule.properties[key] || {};
					var s_preBurn = o_ruleProp.preBurn;
					var f_preBurn = s_preBurn ? ip2.getProperty(s_preBurn, o_fn) : null;

					if ( f_preBurn ) {
						var n_preBurn = ( o_ruleProp.preBurnIndex > 0 ) ? o_ruleProp.preBurnIndex : n_preBurnDefaultIndex--;
						a_preBurn.push({
							index: n_preBurn,
							fn: f_preBurn,
							context: o_context,
							args: [value, o_value, s_prop || key]
						});
					}
				});

				// Now sort the preBurn array
				a_preBurn.sort(function (a, b) {
					return a.index - b.index;
				});
				// Run through preBurn array and preBurn
				ip2.each(a_preBurn, function (o_preBurn) {
					o_preBurn.fn.apply(o_preBurn.context, o_preBurn.args);
				});
			};

			var compile = function (o_original, o_compiler) {

				var o_value = ip2.extend({}, o_original);

				// Process compiler
				o_compiler = getXpdRules(o_compiler);
				var o_compilerRules = o_compiler.__rules__;
				var o_compilerRulesFn = o_compilerRules.__fn__;
				var o_compilerFn = o_compiler.__fn__;

				var s_idKey = o_value[o_compiler.idProperty];
				var o_collection = o_compiler.collections[s_idKey];

				// Apply the preBurn of the rules of rules (yeah.... I know)
				ip2.each(o_collection.properties, function (o_prop, s_propName) {

					var s_type = o_prop.type;
					var o_compilerRule = o_compilerRules.collections[s_type];

					preBurn({
						context: o_compiler,
						rule: o_compilerRule,
						fn: o_compilerRulesFn,
						property: o_prop,
						propertyName: s_propName,
						value: o_value
					});

					// Apply defaults from compiler properties
					if ( o_value[s_propName] == null && o_prop.value ) {
						o_value[s_propName] = o_prop.value;
					}
				});

				// preBurn values against XPD compiler
				preBurn({
					context: o_compiler,
					rule: o_collection,
					fn: o_compilerFn,
					property: o_value,
					value: o_value
				});

				return o_value;
			};

			var xpd = {
				applyRules: applyRules,
				compile: compile,
				deepInherit: deepInherit,
				flatten: flatten,
				getXpdRules: getXpdRules,
				inherit: inherit,
				preBurn: preBurn
			};

			XPD.xpd = xpd;
		})();


		// Need to be able to load files and return as JSON
		var loader = function (s_path) {
			return ip2.sajax.request({
				url: s_path,
				method: 'GET',
				asJson: true
			});
		};

		var compileXpd = function (xpd) {

			if ( xpd.__compiled__ ) return xpd;

			var o_xpd;
			var s_rulesPath = o_xpd.rulesPath;


		};

		// Compile = explode the given value against a XPD and apply all inherited values
		// and apply preBurns.
		// alias property will overload property keys etc..)
		var compile = function (value, xpd) {

			// If value is a string then it is a path to be loaded
			var o_value = ip2.isString(value) ? loader(value) : value; 
			
			// Clone the value object
			o_value = ip2.extend({}, value);
			
			// If xpd value is a string then it is a path to be loaded
			var o_xpd = ip2.isString(xpd) ? loader(xpd) : xpd; 

			// Compile the XPD (will compile it against its own ruleset)
			o_xpd = compileXpd(o_xpd);

			// preBurn the value properties against XPD
			preBurn(o_value, o_xpd);

			return o_value;
		};

		var o_dmd = loader('wsh-base/dmd/webshop.dmd');
		var o_compiled = compile('wsh-base/dmd/webshop.dmd', 'wsh-base/xpdrules/dmd/dmd.xpd');


	}
}