protected void DocumentAfterPublish(Document sender, PublishEventArgs e)
		{
			// when thinking about adding something here, consider ContentOnAfterUpdateDocumentCache!

			if (sender.Level > 2)
			{
				if (sender.ContentType.Alias == Order.NodeAlias || sender.Parent != null && (OrderedProduct.IsAlias(sender.ContentType.Alias) || sender.Parent.Parent != null && OrderedProductVariant.IsAlias(sender.ContentType.Alias)))
				{
					var orderDoc = sender.ContentType.Alias == Order.NodeAlias ? sender : (OrderedProduct.IsAlias(sender.ContentType.Alias) && !OrderedProductVariant.IsAlias(sender.ContentType.Alias) ? new Document(sender.Parent.Id) : new Document(sender.Parent.Parent.Id));

					if (orderDoc.ContentType.Alias != Order.NodeAlias)
						throw new Exception("There was an error in the structure of the order documents");

					// load existing orderInfo (why..? => possibly to preserve information not represented in the umbraco documents)

					if (string.IsNullOrEmpty(orderDoc.getProperty("orderGuid").Value.ToString()))
					{
						Store store = null;
						var storeDoc = sender.GetAncestorDocuments().FirstOrDefault(x => x.ContentType.Alias == OrderStoreFolder.NodeAlias);

						if (storeDoc != null)
						{
							store = StoreHelper.GetAllStores().FirstOrDefault(x => x.Name == storeDoc.Text);
						}

						if (store == null)
						{
							store = StoreHelper.GetAllStores().FirstOrDefault();
						}

						var orderInfo = OrderHelper.CreateOrder(store);
						IO.Container.Resolve<IOrderNumberService>().GenerateAndPersistOrderNumber(orderInfo);
						orderInfo.Status = OrderStatus.Confirmed;
						orderInfo.Save();

						sender.SetProperty("orderGuid", orderInfo.UniqueOrderId.ToString());
						sender.Save();
					}
					else
					{
						var orderGuid = Guid.Parse(orderDoc.getProperty("orderGuid").Value.ToString());

						var orderInfo = OrderHelper.GetOrderInfo(orderGuid);

						var order = new Order(orderDoc.Id);
						orderInfo.CustomerEmail = order.CustomerEmail;
						orderInfo.CustomerFirstName = order.CustomerFirstName;
						orderInfo.CustomerLastName = order.CustomerLastName;

						var dictionaryCustomer = orderDoc.GenericProperties.Where(x => x.PropertyType.Alias.StartsWith("customer")).ToDictionary(customerProperty => customerProperty.PropertyType.Alias, customerProperty => customerProperty.Value.ToString());
						orderInfo.AddCustomerFields(dictionaryCustomer, CustomerDatatypes.Customer);

						var dictionaryShipping = orderDoc.GenericProperties.Where(x => x.PropertyType.Alias.StartsWith("shipping")).ToDictionary(property => property.PropertyType.Alias, property => property.Value.ToString());
						orderInfo.AddCustomerFields(dictionaryShipping, CustomerDatatypes.Shipping);

						var dictionarExtra = orderDoc.GenericProperties.Where(x => x.PropertyType.Alias.StartsWith("extra")).ToDictionary(property => property.PropertyType.Alias, property => property.Value.ToString());
						orderInfo.AddCustomerFields(dictionarExtra, CustomerDatatypes.Extra);

						//orderInfo.SetVATNumber(order.CustomerVATNumber); happens in AddCustomerFields
						var orderPaidProperty = order.Document.getProperty("orderPaid");
						if (orderPaidProperty != null && orderPaidProperty.Value != null)
							orderInfo.Paid = orderPaidProperty.Value == "1";

						// load data recursively from umbraco documents into order tree
						orderInfo.OrderLines = orderDoc.Children.Select(d =>
							{
								var fields = d.GenericProperties.Where(x => !OrderedProduct.DefaultProperties.Contains(x.PropertyType.Alias)).ToDictionary(s => s.PropertyType.Alias, s => d.GetProperty<string>(s.PropertyType.Alias));

								var xDoc = new XDocument(new XElement("Fields"));

								OrderUpdatingService.AddFieldsToXDocumentBasedOnCMSDocumentType(xDoc, fields, d.ContentType.Alias);

								var orderedProduct = new OrderedProduct(d.Id);

								var productInfo = new ProductInfo(orderedProduct, orderInfo);
								productInfo.ProductVariants = d.Children.Select(cd => new ProductVariantInfo(new OrderedProductVariant(cd.Id), productInfo, productInfo.Vat)).ToList();
								return new OrderLine(productInfo, orderInfo) {_customData = xDoc};
							}).ToList();

						// store order
						IO.Container.Resolve<IOrderRepository>().SaveOrderInfo(orderInfo);
					}
					// cancel does give a warning message balloon in Umbraco.
					//e.Cancel = true;

					//if (sender.ContentType.Alias != Order.NodeAlias)
					//{
					//	orderDoc.Publish(new User(0));
					//}

					//if (orderDoc.ParentId != 0)
					//{
					BasePage.Current.ClientTools.SyncTree(sender.Parent.Path, false);
					BasePage.Current.ClientTools.ChangeContentFrameUrl(string.Concat("editContent.aspx?id=", sender.Id));
					//}
					//orderDoc.delete();
					BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.success, "Order Updated!", "This order has been updated!");
				}
			}
		}