protected SPFile GetFile(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            if (folderHost.CurrentWebFolder != null)
                return folderHost.CurrentWebFolder.ParentWeb.GetFile(GetSafeFileUrl(folderHost.CurrentWebFolder, moduleFile));

            if (folderHost.CurrentContentType != null)
                return folderHost.CurrentContentTypeFolder.ParentWeb.GetFile(GetSafeFileUrl(folderHost.CurrentContentTypeFolder, moduleFile));

            if (folderHost.CurrentLibraryFolder != null)
                return folderHost.CurrentLibraryFolder.ParentWeb.GetFile(GetSafeFileUrl(folderHost.CurrentLibraryFolder, moduleFile));

            throw new ArgumentException("CurrentWebFolder/CurrentContentType/CurrentLibraryFolder should not be null");

        }
        public override ModelNode ReverseSingleHost(object reverseHost, ReverseOptions options)
        {
            var item = (reverseHost as ModuleFileReverseHost).HostFile;
            var context = (reverseHost as ModuleFileReverseHost).HostClientContext;

            var def = new ModuleFileDefinition();

            def.FileName = item.Name;

            using (var stream = File.OpenBinaryDirect(
                context,
                item.ServerRelativeUrl).Stream)
            {
                def.Content = ModuleFileUtils.ReadFully(stream);
            }

            return new ModuleFileModelNode
            {
                Options = { RequireSelfProcessing = true },
                Value = def
            };
        }
        private void ProcessFile(
            object modelHost,
            SPFolder folder,
            ModuleFileDefinition moduleFile)
        {
            DeployModuleFile(
                folder,
                GetSafeFileUrl(folder, moduleFile),
                moduleFile.FileName,
                moduleFile.Content,
                moduleFile.Overwrite,
                before =>
                {
                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model = null,
                        EventType = ModelEventType.OnProvisioning,
                        Object = before.Exists ? before : null,
                        ObjectType = typeof(SPFile),
                        ObjectDefinition = moduleFile,
                        ModelHost = modelHost
                    });

                },
                after =>
                {
                    var shouldUpdateItem = false;

                    if (!string.IsNullOrEmpty(moduleFile.Title))
                    {
                        after.ListItemAllFields["Title"] = moduleFile.Title;
                        shouldUpdateItem = true;
                    }

                    if (!string.IsNullOrEmpty(moduleFile.ContentTypeId) ||
                        !string.IsNullOrEmpty(moduleFile.ContentTypeName))
                    {
                        var list = folder.ParentWeb.Lists[folder.ParentListId];

                        if (!string.IsNullOrEmpty(moduleFile.ContentTypeId))
                            after.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupListContentTypeById(list, moduleFile.ContentTypeId);

                        if (!string.IsNullOrEmpty(moduleFile.ContentTypeName))
                            after.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupContentTypeByName(list, moduleFile.ContentTypeName);

                        shouldUpdateItem = true;
                    }

                    if (moduleFile.DefaultValues.Count > 0)
                    {
                        FieldLookupService.EnsureDefaultValues(after.ListItemAllFields, moduleFile.DefaultValues);
                        shouldUpdateItem = true;
                    }

                    FieldLookupService.EnsureValues(after.ListItemAllFields, moduleFile.Values, true);

                    if (shouldUpdateItem)
                    {
                        after.ListItemAllFields.Update();
                    }

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model = null,
                        EventType = ModelEventType.OnProvisioned,
                        Object = after,
                        ObjectType = typeof(SPFile),
                        ObjectDefinition = moduleFile,
                        ModelHost = modelHost
                    });
                });
        }
        private File ProcessFile(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var context = folderHost.CurrentListFolder.Context;

            var web = folderHost.CurrentWeb;
            var list = folderHost.CurrentList;
            var folder = folderHost.CurrentListFolder;

            context.Load(folder, f => f.ServerRelativeUrl);
            context.Load(folder, f => f.Properties);

            context.ExecuteQueryWithTrace();

            var stringCustomContentType = ResolveContentTypeId(folderHost, moduleFile);

            if (list != null)
            {
                context.Load(list, l => l.EnableMinorVersions);
                context.Load(list, l => l.EnableVersioning);
                context.Load(list, l => l.EnableModeration);

                context.ExecuteQueryWithTrace();
            }

            var file = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(file, f => f.Exists);
            context.ExecuteQueryWithTrace();

            InvokeOnModelEvent<ModuleFileDefinition, File>(file, ModelEventType.OnUpdating);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = file.Exists ? file : null,
                ObjectType = typeof(File),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });

            var doesFileHasListItem =
                //Forms folders
             !(folder != null
              &&
              (folder.Properties.FieldValues.ContainsKey("vti_winfileattribs")
               && folder.Properties.FieldValues["vti_winfileattribs"].ToString() == "00000012"));

            WithSafeFileOperation(list, file, f =>
            {
                var fileName = moduleFile.FileName;
                var fileContent = moduleFile.Content;

                var fileCreatingInfo = new FileCreationInformation
                {
                    Url = fileName,
                    Overwrite = file.Exists
                };

                if (fileContent.Length < ContentStreamFileSize)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.Content for small file less than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.Content = fileContent;
                }
                else
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.ContentStream for big file more than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.ContentStream = new System.IO.MemoryStream(fileContent);
                }

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Overwriting file");
                var updatedFile = folder.Files.Add(fileCreatingInfo);

                if (!string.IsNullOrEmpty(stringCustomContentType))
                    updatedFile.ListItemAllFields[BuiltInInternalFieldNames.ContentTypeId] = stringCustomContentType;

                if (moduleFile.DefaultValues.Count > 0)
                    EnsureDefaultValues(updatedFile.ListItemAllFields, moduleFile);

                if (!string.IsNullOrEmpty(stringCustomContentType) || moduleFile.DefaultValues.Count > 0)
                    updatedFile.ListItemAllFields.Update();

                return updatedFile;
            }, doesFileHasListItem);

            var resultFile = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(resultFile, f => f.Exists);
            context.ExecuteQueryWithTrace();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = resultFile,
                ObjectType = typeof(File),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });

            InvokeOnModelEvent<ModuleFileDefinition, File>(resultFile, ModelEventType.OnUpdated);

            return resultFile;
        }
        private void ProcessWebFolder(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var web = folderHost.HostWeb;
            var folder = folderHost.CurrentWebFolder;

            var context = web.Context;

            if (!folder.IsPropertyAvailable("ServerRelativeUrl"))
            {
                context.Load(folder, f => f.ServerRelativeUrl);
                context.ExecuteQueryWithTrace();
            }

            var currentFile = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(currentFile, f => f.Exists);
            context.ExecuteQueryWithTrace();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = currentFile.Exists ? currentFile : null,
                ObjectType = typeof(File),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });

            if (moduleFile.Overwrite)
            {
                var fileCreatingInfo = new FileCreationInformation
                {
                    Url = moduleFile.FileName,
                    Overwrite = true
                };

                if (moduleFile.Content.Length < ContentStreamFileSize)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.Content for small file less than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.Content = moduleFile.Content;
                }
                else
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.ContentStream for big file more than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.ContentStream = new System.IO.MemoryStream(moduleFile.Content);
                }

                var file = folder.Files.Add(fileCreatingInfo);

                folder.Context.ExecuteQueryWithTrace();

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = file,
                    ObjectType = typeof(File),
                    ObjectDefinition = moduleFile,
                    ModelHost = folderHost
                });
            }
            else
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = currentFile.Exists ? currentFile : null,
                    ObjectType = typeof(File),
                    ObjectDefinition = moduleFile,
                    ModelHost = folderHost
                });
            }

            folder.Update();
            folder.Context.ExecuteQueryWithTrace();
        }
 private string GetSafeFileUrl(SPFolder folder, ModuleFileDefinition moduleFile)
 {
     return folder.ServerRelativeUrl + "/" + moduleFile.FileName;
 }
 public static ModelNode AddHostModuleFile(this ModelNode model, ModuleFileDefinition definition, Action<ModelNode> action)
 {
     return model.AddDefinitionNodeWithOptions(definition, action, ModelNodeOptions.New().NoSelfProcessing());
 }
        protected File GetFile(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            Folder folder = null;

            if (folderHost.CurrentList != null)
                folder = folderHost.CurrentListFolder;
            else if (folderHost.CurrentContentType != null)
                folder = folderHost.CurrentContentTypeFolder;
            else if (folderHost.CurrentWebFolder != null)
                folder = folderHost.CurrentWebFolder;

            var web = folderHost.HostWeb;
            var context = web.Context;

            var file = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(file, f => f.Exists);
            context.ExecuteQueryWithTrace();

            return file;
        }
        protected string ResolveContentTypeId(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var context = folderHost.CurrentListFolder.Context;
            var list = folderHost.CurrentList;
            var stringCustomContentType = string.Empty;

            if (!string.IsNullOrEmpty(moduleFile.ContentTypeId))
            {
                stringCustomContentType = moduleFile.ContentTypeId;
            }
            else if (!string.IsNullOrEmpty(moduleFile.ContentTypeName))
            {
                // preload custom content type

                var listContentTypes = list.ContentTypes;
                context.Load(listContentTypes);
                context.ExecuteQueryWithTrace();

                var listContentType = listContentTypes.ToList()
                                                      .FirstOrDefault(c => c.Name.ToUpper() == moduleFile.ContentTypeName.ToUpper());

                if (listContentType == null)
                {
                    throw new ArgumentNullException(
                        string.Format("Cannot find content type with Name:[{0}] in List:[{1}]",
                            new string[]
                                    {
                                        moduleFile.ContentTypeName,
                                        list.Title
                                    }));
                }

                stringCustomContentType = listContentType.Id.ToString();
            }

            return stringCustomContentType;
        }
        protected string ResolveContentTypeId(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var context = folderHost.CurrentListFolder.Context;
            var list = folderHost.CurrentList;
            var stringCustomContentType = string.Empty;

            if (!string.IsNullOrEmpty(moduleFile.ContentTypeId))
            {
                stringCustomContentType = moduleFile.ContentTypeId;
            }
            else if (!string.IsNullOrEmpty(moduleFile.ContentTypeName))
            {
                stringCustomContentType = ContentTypeLookupService.LookupContentTypeByName(list, moduleFile.ContentTypeName).Id.ToString();
            }

            return stringCustomContentType;
        }
        private File ProcessFile(FolderModelHost folderHost, ModuleFileDefinition definition)
        {
            var context = folderHost.CurrentListFolder.Context;

            var web = folderHost.CurrentWeb;
            var list = folderHost.CurrentList;
            var folder = folderHost.CurrentListFolder;

            context.Load(folder, f => f.ServerRelativeUrl);

            #if !NET35
            context.Load(folder, f => f.Properties);
            #endif

            context.ExecuteQueryWithTrace();

            var stringCustomContentType = ResolveContentTypeId(folderHost, definition);

            if (list != null)
            {
                context.Load(list, l => l.EnableMinorVersions);
                context.Load(list, l => l.EnableVersioning);
                context.Load(list, l => l.EnableModeration);

                context.ExecuteQueryWithTrace();
            }

            var file = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, definition));

            context.Load(file, f => f.Exists);
            context.ExecuteQueryWithTrace();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = file.Exists ? file : null,
                ObjectType = typeof(File),
                ObjectDefinition = definition,
                ModelHost = folderHost
            });

            #if !NET35
            var doesFileHasListItem =
                //Forms folders
             !(folder != null
              &&
              (folder.Properties.FieldValues.ContainsKey("vti_winfileattribs")
               && folder.Properties.FieldValues["vti_winfileattribs"].ToString() == "00000012"));

            #endif

            #if NET35
            var doesFileHasListItem = true;
            #endif

            WithSafeFileOperation(list, file, f =>
            {
                var fileName = definition.FileName;
                var fileContent = definition.Content;

                var fileCreatingInfo = new FileCreationInformation
                {
                    Url = fileName,
                    Overwrite = file.Exists
                };

                if (fileContent.Length < ContentStreamFileSize)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.Content for small file less than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.Content = fileContent;
                }
                else
                {
            #if NET35
                    throw new SPMeta2Exception(string.Format("SP2010 CSOM implementation does no support file more than {0}. Checkout FileCreationInformation and avialabe Content size.", ContentStreamFileSize));
            #endif

            #if !NET35
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Using fileCreatingInfo.ContentStream for big file more than: [{0}]", ContentStreamFileSize);
                    fileCreatingInfo.ContentStream = new System.IO.MemoryStream(fileContent);
            #endif
                }

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Overwriting file");
                var updatedFile = folder.Files.Add(fileCreatingInfo);

                FieldLookupService.EnsureDefaultValues(updatedFile.ListItemAllFields, definition.DefaultValues);

                if (!string.IsNullOrEmpty(stringCustomContentType))
                    updatedFile.ListItemAllFields[BuiltInInternalFieldNames.ContentTypeId] = stringCustomContentType;

                if (!string.IsNullOrEmpty(definition.Title))
                    updatedFile.ListItemAllFields[BuiltInInternalFieldNames.Title] = definition.Title;

                FieldLookupService.EnsureValues(updatedFile.ListItemAllFields, definition.Values, true);

                if (!string.IsNullOrEmpty(stringCustomContentType)
                    || definition.DefaultValues.Count > 0
                    || definition.Values.Count > 0
                    || !string.IsNullOrEmpty(definition.Title))
                {
                    updatedFile.ListItemAllFields.Update();
                }

                return updatedFile;
            }, doesFileHasListItem);

            var resultFile = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, definition));

            context.Load(resultFile, f => f.Exists);
            context.ExecuteQueryWithTrace();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = resultFile,
                ObjectType = typeof(File),
                ObjectDefinition = definition,
                ModelHost = folderHost
            });

            return resultFile;
        }
        public void Deploy_ModuleFiles()
        {
            // Step 1, define security groups
            var helloModuleFile = new ModuleFileDefinition
            {
                FileName = "hello-module.txt",
                Content = Encoding.UTF8.GetBytes("A hello world module file provision.")
            };

            var angularFile = new ModuleFileDefinition
            {
                FileName = "angular.min.js",
                Content = Encoding.UTF8.GetBytes(ResourceReader.ReadFromResourceName("Modules.js.angular.min.js"))
            };

            var jQueryFile = new ModuleFileDefinition
            {
                FileName = "jquery-1.11.1.min.js",
                Content = Encoding.UTF8.GetBytes(ResourceReader.ReadFromResourceName("Modules.js.jquery-1.11.1.min.js"))
            };

            var jsFolder = new FolderDefinition { Name = "spmeta2-custom-js" };

            // deploy web model - list and add content type links to list
            var webModel = SPMeta2Model
                             .NewWebModel(web =>
                             {
                                 web
                                     .AddList(BuiltInListDefinitions.StyleLibrary, list =>
                                     {
                                         list
                                             .AddModuleFile(helloModuleFile)
                                             .AddFolder(jsFolder, folder =>
                                             {
                                                 folder
                                                     .AddModuleFile(angularFile)
                                                     .AddModuleFile(jQueryFile);
                                             });
                                     });
                             });

            DeployWebModel(webModel);
        }
 public static ModelNode AddModuleFile(this ModelNode model, ModuleFileDefinition definition, Action<ModelNode> action)
 {
     return model.AddDefinitionNode(definition, action);
 }
 public static ModelNode AddModuleFile(this ModelNode model, ModuleFileDefinition definition)
 {
     return AddModuleFile(model, definition, null);
 }
 private void EnsureDefaultValues(SPListItem newFileItem, ModuleFileDefinition definition)
 {
     foreach (var defaultValue in definition.DefaultValues)
     {
         if (!string.IsNullOrEmpty(defaultValue.FieldName))
         {
             if (newFileItem.Fields.ContainsFieldWithStaticName(defaultValue.FieldName))
             {
                 if (newFileItem[defaultValue.FieldName] == null)
                     newFileItem[defaultValue.FieldName] = defaultValue.Value;
             }
         }
         else if (defaultValue.FieldId.HasValue && defaultValue.FieldId != default(Guid))
         {
             if (newFileItem.Fields.OfType<SPField>().Any(f => f.Id == defaultValue.FieldId.Value))
             {
                 if (newFileItem[defaultValue.FieldId.Value] == null)
                     newFileItem[defaultValue.FieldId.Value] = defaultValue.Value;
             }
         }
     }
 }
 private static void EnsureDefaultValues(ListItem newFileItem, ModuleFileDefinition publishingPageModel)
 {
     foreach (var defaultValue in publishingPageModel.DefaultValues)
     {
         if (!string.IsNullOrEmpty(defaultValue.FieldName))
         {
             if (newFileItem.FieldValues.ContainsKey(defaultValue.FieldName))
             {
                 if (newFileItem[defaultValue.FieldName] == null)
                     newFileItem[defaultValue.FieldName] = defaultValue.Value;
             }
             else
             {
                 newFileItem[defaultValue.FieldName] = defaultValue.Value;
             }
         }
         else if (defaultValue.FieldId.HasValue && defaultValue.FieldId != default(Guid))
         {
             // unsupported by CSOM API yet
         }
     }
 }
        private void ProcessContentTypeModuleFile(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var folder = folderHost.CurrentContentTypeFolder;

            var currentFile = folder.ParentWeb.GetFile(GetSafeFileUrl(folder, moduleFile));

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = currentFile.Exists ? currentFile : null,
                ObjectType = typeof(SPFile),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });

            if (moduleFile.Overwrite)
            {
                var file = folder.Files.Add(moduleFile.FileName, moduleFile.Content, moduleFile.Overwrite);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = file,
                    ObjectType = typeof(SPFile),
                    ObjectDefinition = moduleFile,
                    ModelHost = folderHost
                });
            }
            else
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = currentFile.Exists ? currentFile : null,
                    ObjectType = typeof(SPFile),
                    ObjectDefinition = moduleFile,
                    ModelHost = folderHost
                });
            }

            folder.Update();
        }
 private string GetSafeFileUrl(Folder folder, ModuleFileDefinition moduleFile)
 {
     return UrlUtility.CombineUrl(folder.ServerRelativeUrl, moduleFile.FileName);
 }
        private void ProcessFile(
            object modelHost,
            SPFolder folder, ModuleFileDefinition moduleFile)
        {
            var web = folder.ParentWeb;
            var list = folder.DocumentLibrary;

            var file = web.GetFile(GetSafeFileUrl(folder, moduleFile));

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = file.Exists ? file : null,
                ObjectType = typeof(SPFile),
                ObjectDefinition = moduleFile,
                ModelHost = modelHost
            });

            var fileName = moduleFile.FileName;
            var fileContent = moduleFile.Content;

            // for file deployment to the folder, root web folder or under _cts or other spccial folders
            // list == null

            // big todo with correct update and punblishing
            // get prev SPMeta2 impl for publishing pages
            if (list != null && (file.Exists && file.CheckOutType != SPFile.SPCheckOutType.None))
                file.UndoCheckOut();

            if (list != null && (list.EnableMinorVersions && file.Exists && file.Level == SPFileLevel.Published))
                file.UnPublish("Provision");

            if (list != null && (file.Exists && file.CheckOutType == SPFile.SPCheckOutType.None))
                file.CheckOut();

            var spFile = folder.Files.Add(fileName, fileContent, file.Exists);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = spFile,
                ObjectType = typeof(SPFile),
                ObjectDefinition = moduleFile,
                ModelHost = modelHost
            });

            spFile.Update();

            if (list != null && (file.Exists && file.CheckOutType != SPFile.SPCheckOutType.None))
                spFile.CheckIn("Provision");

            if (list != null && (list.EnableMinorVersions || list.EnableVersioning))
                spFile.Publish("Provision");

            if (list != null && list.EnableModeration)
                spFile.Approve("Provision");
        }
        private File ProcessFile(FolderModelHost folderHost, ModuleFileDefinition moduleFile)
        {
            var context = folderHost.CurrentLibraryFolder.Context;

            var web = folderHost.CurrentWeb;
            var list = folderHost.CurrentList;
            var folder = folderHost.CurrentLibraryFolder;

            context.Load(folder, f => f.ServerRelativeUrl);
            context.ExecuteQuery();

            if (list != null)
            {
                context.Load(list, l => l.EnableMinorVersions);
                context.Load(list, l => l.EnableVersioning);
                context.Load(list, l => l.EnableModeration);

                context.ExecuteQuery();
            }

            var file = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(file, f => f.Exists);
            context.ExecuteQuery();

            InvokeOnModelEvent<ModuleFileDefinition, File>(file, ModelEventType.OnUpdating);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = file.Exists ? file : null,
                ObjectType = typeof(File),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });

            WithSafeFileOperation(list, file, f =>
            {
                var fileName = moduleFile.FileName;
                var fileContent = moduleFile.Content;

                var fileCreatingInfo = new FileCreationInformation
                {
                    Url = fileName,
                    Content = fileContent,
                    Overwrite = file.Exists
                };

                return folder.Files.Add(fileCreatingInfo);

            });

            var resultFile = web.GetFileByServerRelativeUrl(GetSafeFileUrl(folder, moduleFile));

            context.Load(resultFile, f => f.Exists);
            context.ExecuteQuery();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioned,
                Object = resultFile,
                ObjectType = typeof(File),
                ObjectDefinition = moduleFile,
                ModelHost = folderHost
            });
            InvokeOnModelEvent<ModuleFileDefinition, File>(resultFile, ModelEventType.OnUpdated);

            return resultFile;
        }