diff --git a/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj b/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj
new file mode 100644
index 0000000..9af151f
--- /dev/null
+++ b/app/Umbraco/Archetype.Courier/Archetype.Courier.csproj
@@ -0,0 +1,128 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {FE8BE437-8B11-4E49-9B02-F45994E6D723}
+ Library
+ Properties
+ Archetype.Courier
+ Archetype.Courier
+ v4.5
+ 512
+ ..\
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\businesslogic.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\cms.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\interfaces.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\log4net.dll
+ False
+
+
+ ..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.dll
+ False
+
+
+
+
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Core.dll
+ False
+
+
+ lib\Umbraco.Courier.Core.dll
+ False
+
+
+ lib\Umbraco.Courier.DataResolvers.dll
+ False
+
+
+ lib\Umbraco.Courier.Providers.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.DataLayer.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.providers.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\Umbraco.Web.UI.dll
+ False
+
+
+ ..\packages\UmbracoCms.Core.7.1.2\lib\umbraco.XmlSerializers.dll
+ False
+
+
+
+
+ Properties\VersionInfo.cs
+
+
+
+
+
+
+
+
+
+ {7d185d41-4228-4978-acb8-83f9a48ad94f}
+ Archetype.Umbraco
+ True
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs b/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs
new file mode 100644
index 0000000..e880f85
--- /dev/null
+++ b/app/Umbraco/Archetype.Courier/DataResolvers/ArchetypeDataResolver.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Courier.Core;
+using Umbraco.Courier.Core.Enums;
+using Umbraco.Courier.Core.Helpers;
+using Umbraco.Courier.DataResolvers;
+using Umbraco.Courier.ItemProviders;
+
+namespace Archetype.Courier.DataResolvers
+{
+ public class ArchetypeDataResolver : PropertyDataResolverProvider
+ {
+ private enum Direction
+ {
+ Extracting,
+ Packaging
+ }
+
+ public override string EditorAlias
+ {
+ get
+ {
+ return Archetype.Constants.PropertyEditorAlias;
+ }
+ }
+
+ public override void ExtractingDataType(DataType item)
+ {
+ // No longer need to extract the DataType (int) Ids as they now reference the Guid [LK]
+ }
+
+ public override void ExtractingProperty(Item item, ContentProperty propertyData)
+ {
+ ReplacePropertyDataIds(item, propertyData, Direction.Extracting);
+ }
+
+ public override void PackagingDataType(DataType item)
+ {
+ AddDataTypeDependencies(item);
+ }
+
+ public override void PackagingProperty(Item item, ContentProperty propertyData)
+ {
+ ReplacePropertyDataIds(item, propertyData, Direction.Packaging);
+ }
+
+ private void AddDataTypeDependencies(DataType item)
+ {
+ if (item.Prevalues != null && item.Prevalues.Count > 0)
+ {
+ var prevalue = item.Prevalues[0];
+ if (prevalue.Alias.InvariantEquals(Archetype.Constants.PreValueAlias) && !string.IsNullOrWhiteSpace(prevalue.Value))
+ {
+ var config = JsonConvert.DeserializeObject(prevalue.Value);
+
+ if (config != null && config.Fieldsets != null)
+ {
+ foreach (var property in config.Fieldsets.SelectMany(x => x.Properties))
+ {
+ item.Dependencies.Add(property.DataTypeGuid.ToString(), ProviderIDCollection.dataTypeItemProviderGuid);
+ }
+
+ item.Prevalues[0].Value = JsonConvert.SerializeObject(config, Formatting.None);
+ }
+ }
+ }
+ }
+
+ private void ReplacePropertyDataIds(Item item, ContentProperty propertyData, Direction direction)
+ {
+ if (propertyData != null && propertyData.Value != null)
+ {
+ // just look at the amount of dancing around we have to do in order to fake a `PublishedPropertyType`?!
+ var dataTypeId = PersistenceManager.Default.GetNodeId(propertyData.DataType, NodeObjectTypes.DataType);
+ var fakePropertyType = this.CreateFakePropertyType(dataTypeId, this.EditorAlias);
+
+ var converter = new Archetype.PropertyConverters.ArchetypeValueConverter();
+ var archetype = (Archetype.Models.ArchetypeModel)converter.ConvertDataToSource(fakePropertyType, propertyData.Value, false);
+
+ if (archetype != null)
+ {
+ // create a 'fake' provider, as ultimately only the 'Packaging' enum will be referenced.
+ var fakeItemProvider = new PropertyItemProvider();
+
+ foreach (var property in archetype.Fieldsets.SelectMany(x => x.Properties))
+ {
+ if (property == null || string.IsNullOrWhiteSpace(property.PropertyEditorAlias))
+ continue;
+
+ // create a 'fake' item for Courier to process
+ var fakeItem = new ContentPropertyData()
+ {
+ ItemId = item.ItemId,
+ Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, this.EditorAlias, property.PropertyEditorAlias, property.Alias }),
+ Data = new List
+ {
+ new ContentProperty
+ {
+ Alias = property.Alias,
+ DataType = PersistenceManager.Default.GetUniqueId(property.DataTypeId, NodeObjectTypes.DataType),
+ PropertyEditorAlias = property.PropertyEditorAlias,
+ Value = property.Value
+ }
+ }
+ };
+
+ if (direction == Direction.Packaging)
+ {
+ try
+ {
+ // run the 'fake' item through Courier's data resolvers
+ ResolutionManager.Instance.PackagingItem(fakeItem, fakeItemProvider);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error(string.Concat("Error resolving data value: ", fakeItem.Name), ex);
+ }
+
+ // pass up the dependencies and resources
+ item.Dependencies.AddRange(fakeItem.Dependencies);
+ item.Resources.AddRange(fakeItem.Resources);
+
+ if (fakeItem.Data != null && fakeItem.Data.Any())
+ {
+ var firstDataType = fakeItem.Data.FirstOrDefault();
+ if (firstDataType != null)
+ {
+ // add a dependency for the property's data-type
+ property.DataTypeGuid = firstDataType.ToString();
+ item.Dependencies.Add(property.DataTypeGuid, ProviderIDCollection.dataTypeItemProviderGuid);
+ }
+ }
+ }
+ else if (direction == Direction.Extracting)
+ {
+ // run the 'fake' item through Courier's data resolvers
+ ResolutionManager.Instance.ExtractingItem(fakeItem, fakeItemProvider);
+
+ // resolve the property's data-type Id
+ int identifier;
+ if (int.TryParse(Dependencies.ConvertIdentifier(property.DataTypeGuid, IdentifierReplaceDirection.FromGuidToNodeId), out identifier))
+ property.DataTypeId = dataTypeId;
+ }
+
+ if (fakeItem.Data != null && fakeItem.Data.Any())
+ {
+ var firstDataType = fakeItem.Data.FirstOrDefault();
+ if (firstDataType != null)
+ {
+ // set the resolved property data value
+ property.Value = firstDataType.Value;
+ }
+ }
+ }
+
+ if (item.Name.Contains(string.Concat(this.EditorAlias, ": Nested")))
+ {
+ // if the Archetype is nested, then we only want to return the object itself - not a serialized string
+ propertyData.Value = archetype;
+ }
+ else
+ {
+ // if the Archetype is the root/container, then we can serialize it to a string
+ propertyData.Value = JsonConvert.SerializeObject(archetype, Formatting.None);
+ }
+ }
+ }
+ }
+
+ private PublishedPropertyType CreateFakePropertyType(int dataTypeId, string propertyEditorAlias)
+ {
+ return new PublishedPropertyType(null, new PropertyType(new DataTypeDefinition(-1, propertyEditorAlias) { Id = dataTypeId }));
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs b/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..00fbf9d
--- /dev/null
+++ b/app/Umbraco/Archetype.Courier/Properties/AssemblyInfo.cs
@@ -0,0 +1,14 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Archetype.Courier")]
+[assembly: AssemblyDescription("A set of tools to support Archetype with Umbraco Courier")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Umbrella Inc Ltd")]
+[assembly: AssemblyProduct("Archetype.Courier")]
+[assembly: AssemblyCopyright("Copyright \xa9 Lee Kelleher, Umbrella Inc Ltd 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("6F05C431-ABBF-4D77-9D3D-5AF6C8E318AF")]
diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll
new file mode 100644
index 0000000..b690a35
Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Core.dll differ
diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll
new file mode 100644
index 0000000..88534f5
Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.DataResolvers.dll differ
diff --git a/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll
new file mode 100644
index 0000000..07910fc
Binary files /dev/null and b/app/Umbraco/Archetype.Courier/lib/Umbraco.Courier.Providers.dll differ
diff --git a/app/Umbraco/Archetype.Courier/packages.config b/app/Umbraco/Archetype.Courier/packages.config
new file mode 100644
index 0000000..ee6c9d2
--- /dev/null
+++ b/app/Umbraco/Archetype.Courier/packages.config
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Umbraco/Umbraco.Archetype.sln b/app/Umbraco/Umbraco.Archetype.sln
index bb5fa55..342d893 100644
--- a/app/Umbraco/Umbraco.Archetype.sln
+++ b/app/Umbraco/Umbraco.Archetype.sln
@@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Tests", "Archetyp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseSizer", "DatabaseSizer\DatabaseSizer.csproj", "{0114C963-C514-49C1-B7AB-DCB1825F498C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archetype.Courier", "Archetype.Courier\Archetype.Courier.csproj", "{FE8BE437-8B11-4E49-9B02-F45994E6D723}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -32,6 +34,10 @@ Global
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0114C963-C514-49C1-B7AB-DCB1825F498C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE8BE437-8B11-4E49-9B02-F45994E6D723}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE