public override void Emit(IEmitContext context, IProjectItem projectItem)
        {
            var unicornFile = projectItem as UnicornFile;
            Assert.Cast(unicornFile, nameof(unicornFile));

            var snapshot = unicornFile.Snapshots.First();

            // todo: use real Unicorn configuration instead of hacking it
            var log = new TraceLogger(context.Trace);
            var logger = new DefaultDeserializerLogger(log);
            var fieldFilter = new AllFieldFilter();
            var defaultDeserializer = new DefaultDeserializer(logger, fieldFilter);

            // todo: file has already been read and parsed - do not read it again
            var formatter = new YamlSerializationFormatter(null, null);
            using (var stream = new FileStream(snapshot.SourceFile.AbsoluteFileName, FileMode.Open))
            {
                var serializedItem = formatter.ReadSerializedItem(stream, unicornFile.ShortName);

                if (string.IsNullOrEmpty(serializedItem.DatabaseName))
                {
                    serializedItem.DatabaseName = unicornFile.DatabaseName;
                }

                try
                {
                    defaultDeserializer.Deserialize(serializedItem);
                }
                catch (Exception ex)
                {
                    throw new RetryableEmitException(Texts.Failed_to_deserialize_item, unicornFile.Snapshots.First(), ex.Message);
                }
            }
        }
        protected virtual void CompileUnicornFile([NotNull] ICompileContext context, [NotNull] ISnapshot snapshot, [NotNull] UnicornFile unicornFile)
        {
            // todo: use real Unicorn configuration instead of hacking it
            var formatter = new YamlSerializationFormatter(null, new AllFieldFilter());
            using (var stream = new FileStream(snapshot.SourceFile.AbsoluteFileName, FileMode.Open))
            {
                var serializedItem = formatter.ReadSerializedItem(stream, unicornFile.ShortName);

                var guid = serializedItem.Id;
                var databaseName = serializedItem.DatabaseName ?? unicornFile.DatabaseName;
                var itemIdOrPath = serializedItem.Path;
                var itemName = serializedItem.Name;
                var templateIdOrPath = serializedItem.TemplateId.Format();

                var item = context.Factory.Item(unicornFile.Project, snapshot, guid, databaseName, itemName, itemIdOrPath, templateIdOrPath);
                item.ItemNameProperty.AddSourceTextNode(snapshot);
                item.IsEmittable = false;
                item.IsImport = false;

                item.References.AddRange(context.ReferenceParser.ParseReferences(item, item.TemplateIdOrPathProperty));

                foreach (var sharedField in serializedItem.SharedFields)
                {
                    var field = context.Factory.Field(item);

                    if (!string.IsNullOrEmpty(sharedField.NameHint))
                    {
                        field.FieldName = sharedField.NameHint;
                    }

                    field.FieldId = sharedField.FieldId;
                    field.Value = sharedField.Value;

                    context.ReferenceParser.ParseReferences(item, field.ValueProperty);
                }

                foreach (var version in serializedItem.Versions)
                {
                    foreach (var versionedField in version.Fields)
                    {
                        var field = context.Factory.Field(item);

                        if (!string.IsNullOrEmpty(versionedField.NameHint))
                        {
                            field.FieldName = versionedField.NameHint;
                        }

                        field.FieldId = versionedField.FieldId;
                        field.Value = versionedField.Value;
                        field.Language = version.Language.ToString();
                        field.Version = version.VersionNumber;

                        context.ReferenceParser.ParseReferences(item, field.ValueProperty);
                    }
                }

                unicornFile.Project.AddOrMerge(item);
            }
        }
        public static IItemData GetRemoteItemData(RemoteContentPullArgs args, string itemId)
        {
            try
            {
                WebClient wc = new WebClient { Encoding = Encoding.UTF8 };
                string yamlList = wc.UploadString($"{args.server}/scs/cmcontenttreegetitem.scsvc", "POST",
                    args.GetSerializedData(itemId, false));
                string yaml = JsonConvert.DeserializeObject<List<string>>(yamlList).FirstOrDefault();
                var formatter = new YamlSerializationFormatter(null, null);
                if (yaml != null)
                {
                    using (var ms = new MemoryStream())
                    {
                        IItemData itemData = null;
                        try
                        {
                            var bytes = Encoding.UTF8.GetBytes(yaml);
                            ms.Write(bytes, 0, bytes.Length);

                            ms.Seek(0, SeekOrigin.Begin);
                            itemData = formatter.ReadSerializedItem(ms, itemId);
                            itemData.DatabaseName = args.database;
                        }
                        catch (Exception e)
                        {
                            Log.Error("Problem reading yaml from remote server", e, args);
                        }
                        if (itemData != null)
                        {
                            return itemData;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error("Error getting remote item data for " + itemId, e, args);
            }
            return null;
        }
        private IEnumerable<IItemData> GetRemoteItemData(RemoteContentPullArgs args)
        {
            List<IItemData> ret = new List<IItemData>();
            bool children = args.children;
            args.children = false;
            Queue<string> pullableItems = new Queue<string>();
            WebClient wc = new WebClient { Encoding = Encoding.UTF8 };
            pullableItems.Enqueue(args.id);
            while (pullableItems.Any())
            {
                string cur = pullableItems.Dequeue();
                args.id = cur;
                string yamlList = null;
                try
                {
                    yamlList = wc.UploadString($"{args.server}/scs/cmcontenttreegetitem.scsvc", "POST",
                        args.GetSerializedData());
                }
                catch (Exception e)
                {
                    Log.Error("Problem reading remote server item data", e, this);
                }
                if (string.IsNullOrWhiteSpace(yamlList))
                {
                    yield return new ErrorItemData() {Id = Guid.Parse(args.id), Path = "Problem reading remote server item data" };
                    continue;
                }
                List<string> remoteItems = JsonConvert.DeserializeObject<List<string>>(yamlList);
                var formatter = new YamlSerializationFormatter(null, null);
                foreach (string yaml in remoteItems)
                {
                    using (var ms = new MemoryStream())
                    {
                        IItemData itemData = null;
                        try
                        {
                            var bytes = Encoding.UTF8.GetBytes(yaml);
                            ms.Write(bytes, 0, bytes.Length);

                            ms.Seek(0, SeekOrigin.Begin);
                            itemData = formatter.ReadSerializedItem(ms, args.id);
                            itemData.DatabaseName = args.database;
                        }
                        catch (Exception e)
                        {
                            Log.Error("Problem reading yaml from remote server", e, this);
                        }
                        if (itemData == null)
                        {
                            yield return new ErrorItemData() { Id = Guid.Parse(args.id), Path = "Problem reading yaml from remote server" };
                            continue;
                        }
                        yield return itemData;
                    }
                }
                if (children)
                {
                    ContentTreeNode node = null;
                    try
                    {
                        node =	JsonConvert.DeserializeObject<ContentTreeNode>(wc.UploadString($"{args.server}/scs/cmcontenttree.scsvc", "POST",
                                $@"{{ ""id"": ""{cur}"", ""database"": ""{args.database}"", ""server"": ""{args.server}"" }}"));
                        foreach (ContentTreeNode child in node.Nodes)
                        {
                            pullableItems.Enqueue(child.Id);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error("Problem getting children of node " + cur, e, this);
                    }
                    if (node == null)
                        yield return new ErrorItemData() {Id = Guid.Parse(cur), Path = "Problem getting children of node" };
                }
            }
        }