diff --git a/Mongo.Migration/ApplicationLogging.cs b/Mongo.Migration/ApplicationLogging.cs
new file mode 100644
index 0000000..2fbbdba
--- /dev/null
+++ b/Mongo.Migration/ApplicationLogging.cs
@@ -0,0 +1,33 @@
+using Microsoft.Extensions.Logging;
+
+public class ApplicationLogging
+{
+	private static ILoggerFactory _factory = null;
+
+	public static void ConfigureLogger(ILoggerFactory factory)
+	{
+		factory.AddFile("logs/migration/log-migration.log");
+	}
+
+	/// 
+	/// Log Factory instance
+	/// 
+	public static ILoggerFactory LoggerFactory
+	{
+		get
+		{
+			if (_factory == null)
+			{
+				_factory = new LoggerFactory();
+				ConfigureLogger(_factory);
+			}
+			return _factory;
+		}
+	}
+
+	/// 
+	/// Get a ILogger instance to be used in migrations 
+	/// 
+	/// ILogger instance
+	public static ILogger CreateLogger() => LoggerFactory.CreateLogger("logger");
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Extensions/EnumerableExtensions.cs b/Mongo.Migration/Extensions/EnumerableExtensions.cs
index bae1372..7c70996 100644
--- a/Mongo.Migration/Extensions/EnumerableExtensions.cs
+++ b/Mongo.Migration/Extensions/EnumerableExtensions.cs
@@ -48,5 +48,41 @@ internal static IDictionary> ToMigrationDi
 
             return dictonary;
         }
+
+        internal static IEnumerable CheckForDuplicates(this IEnumerable list)
+        {
+            var uniqueHashes = new HashSet();
+            foreach (var element in list)
+            {
+                var version = element.Version.ToString();
+                var typeName = element.GetType().Name;
+                
+                if (uniqueHashes.Add(typeName+version))
+                    continue;
+
+                throw new DuplicateVersionException(typeName, element.Version);
+            }
+
+            return list;
+        }
+        
+        internal static IDictionary> ToMigrationDictionary(
+            this IEnumerable migrations)
+        {
+            var dictonary = new Dictionary>();
+            var types = from m in migrations select m.Type;
+
+            foreach (var type in types)
+            {
+                if (dictonary.ContainsKey(type))
+                    continue;
+
+                var uniqueMigrations =
+                    migrations.Where(m => m.Type == type).CheckForDuplicates().OrderBy(m => m.Version).ToList();
+                dictonary.Add(type, uniqueMigrations);
+            }
+
+            return dictonary;
+        }
     }
 }
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/AdvancedMigration.cs b/Mongo.Migration/Migrations/AdvancedMigration.cs
new file mode 100644
index 0000000..36064fb
--- /dev/null
+++ b/Mongo.Migration/Migrations/AdvancedMigration.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Migrations
+{
+    public abstract class AdvancedMigration : IAdvancedMigration
+    {
+        protected AdvancedMigration(string version, string collection)
+        {
+            Version = version;
+            CollectionName = collection;
+        }
+
+        public string Version { get; }
+
+        public string CollectionName { get; }
+
+        public Type Type => typeof(AdvancedMigration);
+
+        public virtual void Up(IMongoDatabase db) {
+            var bulk = new List>();
+            var collection = db.GetCollection(CollectionName);
+
+            collection.FindSync(_ => true).ToList().ForEach(document =>
+            {
+               Up(document);
+
+                var update = new ReplaceOneModel(
+                    new BsonDocument {{"_id", document["_id"]}},
+                    document
+                );
+
+                bulk.Add(update);
+            });
+
+            if (bulk.Count > 0)
+            {
+                collection.BulkWrite(bulk);
+            }
+        }
+
+        public virtual void Down(IMongoDatabase db) {
+            var bulk = new List>();
+            var collection = db.GetCollection(CollectionName);
+
+            collection.FindSync(_ => true).ToList().ForEach(document =>
+            {
+               Down(document);
+
+                var update = new ReplaceOneModel(
+                    new BsonDocument {{"_id", document["_id"]}},
+                    document
+                );
+
+                bulk.Add(update);
+            });
+
+            if (bulk.Count > 0)
+            {
+                collection.BulkWrite(bulk);
+            }
+        }
+
+        public abstract void Up(BsonDocument document);
+        
+        public abstract void Down(BsonDocument document);
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/AdvancedMigrationRunner.cs b/Mongo.Migration/Migrations/AdvancedMigrationRunner.cs
new file mode 100644
index 0000000..06cc6eb
--- /dev/null
+++ b/Mongo.Migration/Migrations/AdvancedMigrationRunner.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.Logging;
+using Mongo.Migration.Migrations.Locators;
+using Mongo.Migration.Services;
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Migrations
+{
+    internal class AdvancedMigrationRunner : IAdvancedMigrationRunner
+    {
+        private ILogger _logger;
+        public IAdvancedMigrationLocator _migrationLocator { get; }
+
+        private readonly IVersionService _versionService;
+
+        private IMongoDatabase _db;
+
+        private IMongoCollection _migrationshistory;
+
+        public AdvancedMigrationRunner(IAdvancedMigrationLocator migrationLocator, IVersionService versionService)
+        {
+            _migrationLocator = migrationLocator;
+            _versionService = versionService;
+            _logger = ApplicationLogging.CreateLogger();
+        }
+
+        public void Run(IMongoDatabase db, string runningVersion)
+        {
+            _logger.LogInformation($"Starting the migrations ...");
+
+            _db = db;
+            _migrationshistory = db.GetCollection("_migrationshistory");
+
+            var migrations = _migrationLocator.GetMigrations(typeof(AdvancedMigration)) ?? Enumerable.Empty();
+            var migrationsToDowngrade = new List();
+
+            foreach (var migration in migrations)
+            {
+
+                var migrationsInDb = _migrationshistory.FindSync(CreateQueryForMigration(migration.GetType().ToString())).ToList();
+
+                if (migrationsInDb.Count() > 0)
+                {
+                    foreach (var document in migrationsInDb)
+                    {
+                        if (document["productVersion"].ToString().CompareTo(runningVersion) <= 0)
+                            continue;
+                        else if (document["productVersion"].ToString().CompareTo(runningVersion) > 0)
+                        {
+                            migrationsToDowngrade.Add(migration);
+                        }
+                    }
+                }
+                else
+                {
+                    if (runningVersion.CompareTo(migration.Version) >= 0)
+                    {
+                        try
+                        {
+                            _logger.LogInformation("Starting the migration Up: {0}:{1} ", migration.GetType().ToString(), migration.Version);
+
+                            migration.Up(_db);
+                            _migrationshistory.InsertOne(new BsonDocument { { "migrationId", migration.GetType().ToString() }, { "productVersion", migration.Version } });
+
+                            _logger.LogInformation("Successful migration Up: {0}:{1} ", migration.GetType().ToString(), migration.Version);
+                        }
+                        catch (Exception e)
+                        {
+                            _logger.LogError(e, "Error on migration Up {0}:{1} ", migration.GetType().ToString(), migration.Version);
+                        }
+                    }
+                }
+            }
+
+            migrationsToDowngrade.Reverse();
+            foreach (var migration in migrationsToDowngrade)
+            {
+                try
+                {
+                    _logger.LogInformation("Starting the migration Down: {0}:{1} ", migration.GetType().ToString(), migration.Version);
+
+                    migration.Down(_db);
+                    _migrationshistory.DeleteOne(Builders.Filter.Eq("migrationId", migration.GetType().ToString()));
+
+                    _logger.LogInformation("Successful migration Down: {0}:{1} ", migration.GetType().ToString(), migration.Version);
+                }
+                catch (Exception e)
+                {
+                    _logger.LogError(e, "Error on migration Down {0}:{1} ", migration.GetType().ToString(), migration.Version);
+                }
+            }
+
+            _logger.LogInformation($"Migrations has been done.");
+        }
+
+        private FilterDefinition CreateQueryForMigration(
+            string type)
+        {
+            return Builders.Filter.Eq("migrationId", type);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/CollectionMigrationRunner.cs b/Mongo.Migration/Migrations/CollectionMigrationRunner.cs
index 8c817bc..9c88bdd 100644
--- a/Mongo.Migration/Migrations/CollectionMigrationRunner.cs
+++ b/Mongo.Migration/Migrations/CollectionMigrationRunner.cs
@@ -14,6 +14,8 @@ internal class CollectionMigrationRunner : ICollectionMigrationRunner
     {
         private readonly IMongoClient _client;
 
+        private IMongoDatabase _db;
+
         private readonly ICollectionLocator _collectionLocator;
 
         private readonly string _databaseName;
@@ -74,6 +76,7 @@ private CollectionMigrationRunner(
 
         public void RunAll()
         {
+            _db = _client.GetDatabase(_databaseName);
             var locations = _collectionLocator.GetLocatesOrEmpty();
 
             foreach (var locate in locations)
@@ -83,8 +86,7 @@ public void RunAll()
                 var databaseName = GetDatabaseOrDefault(information);
                 var collectionVersion = _versionService.GetCollectionVersion(type);
 
-                var collection = _client.GetDatabase(databaseName)
-                    .GetCollection(information.Collection);
+                var collection = _db.GetCollection(information.Collection);
 
                 var bulk = new List>();
 
@@ -105,6 +107,7 @@ public void RunAll()
                             );
 
                             bulk.Add(update);
+                            //migrationshistory.InsertOne(new BsonDocument {{"migrationId", nameof(type)}, {"productVersion", _runningVersion}});
                         }
                     }
                 }
diff --git a/Mongo.Migration/Migrations/DatabaseMigrationRunner.cs b/Mongo.Migration/Migrations/DatabaseMigrationRunner.cs
new file mode 100644
index 0000000..ec639cc
--- /dev/null
+++ b/Mongo.Migration/Migrations/DatabaseMigrationRunner.cs
@@ -0,0 +1,48 @@
+using Microsoft.Extensions.Options;
+using Mongo.Migration.Startup;
+using Mongo.Migration.Startup.DotNetCore;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Migrations
+{
+    internal class  DatabaseMigrationRunner : IDatabaseMigrationRunner
+    {
+        private readonly IMongoClient _client;
+
+        private readonly IAdvancedMigrationRunner _migrationRunner;
+
+        private readonly string _databaseName;
+
+        private readonly string _runningVersion;
+
+        private readonly IOptions _options;
+
+        private const int CONNECTION_CHECK_TIMEOUT = 1000;
+        public DatabaseMigrationRunner(
+            IOptions options,
+            IAdvancedMigrationRunner migrationRunner)
+            : this(
+                new MongoClient(options.Value.ConnectionString),
+                migrationRunner,
+                options.Value.RunningVersion)
+        {
+            _options = options;
+            _databaseName = options.Value.Database;
+        }
+
+        public DatabaseMigrationRunner(
+            IMongoClient client,
+            IAdvancedMigrationRunner migrationRunner,
+            string runningVersion)
+        {
+            _runningVersion = runningVersion;
+            _client = client;
+            _migrationRunner = migrationRunner;
+        }
+
+        public void RunAll()
+        {
+            _migrationRunner.Run(_client.GetDatabase(_databaseName), _runningVersion);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/IAdvancedMigration.cs b/Mongo.Migration/Migrations/IAdvancedMigration.cs
new file mode 100644
index 0000000..8ae0a06
--- /dev/null
+++ b/Mongo.Migration/Migrations/IAdvancedMigration.cs
@@ -0,0 +1,23 @@
+using System;
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Migrations
+{
+    public interface IAdvancedMigration
+    {
+        string Version { get; }
+
+        string CollectionName { get; }
+
+        Type Type { get; }
+
+        void Up(IMongoDatabase db);
+
+        void Down(IMongoDatabase db);
+
+        void Up(BsonDocument document);
+
+        void Down(BsonDocument document);
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/IAdvancedMigrationRunner.cs b/Mongo.Migration/Migrations/IAdvancedMigrationRunner.cs
new file mode 100644
index 0000000..6b2a705
--- /dev/null
+++ b/Mongo.Migration/Migrations/IAdvancedMigrationRunner.cs
@@ -0,0 +1,12 @@
+using Mongo.Migration.Migrations.Locators;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Migrations
+{
+    internal interface IAdvancedMigrationRunner
+    {
+        IAdvancedMigrationLocator _migrationLocator { get; }
+
+        void Run(IMongoDatabase db, string runnigVersion);
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/IDatabaseMigrationRunner.cs b/Mongo.Migration/Migrations/IDatabaseMigrationRunner.cs
new file mode 100644
index 0000000..d834c0a
--- /dev/null
+++ b/Mongo.Migration/Migrations/IDatabaseMigrationRunner.cs
@@ -0,0 +1,7 @@
+namespace Mongo.Migration.Migrations
+{
+    internal interface IDatabaseMigrationRunner
+    {
+        void RunAll();
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/IMigrationRunner.cs b/Mongo.Migration/Migrations/IMigrationRunner.cs
index 78f5593..023e3a2 100644
--- a/Mongo.Migration/Migrations/IMigrationRunner.cs
+++ b/Mongo.Migration/Migrations/IMigrationRunner.cs
@@ -1,11 +1,14 @@
 using System;
 using Mongo.Migration.Documents;
+using Mongo.Migration.Migrations.Locators;
 using MongoDB.Bson;
 
 namespace Mongo.Migration.Migrations
 {
     internal interface IMigrationRunner
     {
+        IMigrationLocator _migrationLocator { get; }
+        
         void Run(Type type, BsonDocument document, DocumentVersion to);
         
         void Run(Type type, BsonDocument document);
diff --git a/Mongo.Migration/Migrations/Locators/AdvancedMigrationLocator.cs b/Mongo.Migration/Migrations/Locators/AdvancedMigrationLocator.cs
new file mode 100644
index 0000000..5e7e77a
--- /dev/null
+++ b/Mongo.Migration/Migrations/Locators/AdvancedMigrationLocator.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Mongo.Migration.Documents;
+using Mongo.Migration.Exceptions;
+using Mongo.Migration.Extensions;
+
+namespace Mongo.Migration.Migrations.Locators
+{
+    public abstract class AdvancedMigrationLocator : IAdvancedMigrationLocator
+    {
+        private IEnumerable _assemblies;
+        
+        protected IEnumerable Assemblies => _assemblies ?? (_assemblies = GetAssemblies());
+
+        private IDictionary> _migrations;
+
+        protected IDictionary> Migrations
+        {
+            get
+            {
+                if (_migrations == null)
+                    Locate();
+                
+                if (_migrations.NullOrEmpty())
+                    throw new NoMigrationsFoundException();
+
+                return _migrations;
+            }
+            set { _migrations = value; }
+        }
+
+        public IEnumerable GetMigrations(Type type)
+        {
+            IReadOnlyCollection migrations;
+            Migrations.TryGetValue(type, out migrations);
+
+            return migrations;
+        }
+
+        public IEnumerable GetMigrationsGt(Type type, string version)
+        {
+            var migrations = GetMigrations(type);
+
+            return
+                migrations
+                    .Where(m => m.Version.CompareTo(version) > 0)
+                    .ToList();
+        }
+
+        public IEnumerable GetMigrationsGtEq(Type type, string version)
+        {
+            var migrations = GetMigrations(type);
+
+            return
+                migrations
+                    .Where(m => m.Version.CompareTo(version) >= 0)
+                    .ToList();
+        }
+
+        public DocumentVersion GetLatestVersion(Type type)
+        {         
+            var migrations = GetMigrations(type);
+
+            return migrations.Max(m => m.Version);
+        }
+
+        public abstract void Locate();
+        
+        private static IEnumerable GetAssemblies()
+        {
+            var location = AppDomain.CurrentDomain.BaseDirectory;
+            var path = Path.GetDirectoryName(location);
+
+            if (string.IsNullOrWhiteSpace(path))
+                throw new DirectoryNotFoundException(ErrorTexts.AppDirNotFound);
+
+            var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
+            var migrationAssemblies = Directory.GetFiles(path, "*.MongoMigrations*.dll").Select(Assembly.LoadFile);
+
+            assemblies.AddRange(migrationAssemblies);
+
+            return assemblies;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/Locators/AdvancedTypeMigrationLocator.cs b/Mongo.Migration/Migrations/Locators/AdvancedTypeMigrationLocator.cs
new file mode 100644
index 0000000..57b3081
--- /dev/null
+++ b/Mongo.Migration/Migrations/Locators/AdvancedTypeMigrationLocator.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Linq;
+using Mongo.Migration.Extensions;
+
+namespace Mongo.Migration.Migrations.Locators
+{
+    internal class AdvancedTypeMigrationLocator : AdvancedMigrationLocator
+    {
+        public override void Locate()
+        {
+            var migrationTypes =
+                (from assembly in Assemblies
+                from type in assembly.GetTypes()
+                where typeof(IAdvancedMigration).IsAssignableFrom(type) && !type.IsAbstract
+                select type).Distinct();
+
+            Migrations = migrationTypes.Select(t => (IAdvancedMigration) Activator.CreateInstance(t)).ToMigrationDictionary();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/Locators/IAdvancedMigrationLocator.cs b/Mongo.Migration/Migrations/Locators/IAdvancedMigrationLocator.cs
new file mode 100644
index 0000000..e7ad7cd
--- /dev/null
+++ b/Mongo.Migration/Migrations/Locators/IAdvancedMigrationLocator.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using Mongo.Migration.Documents;
+
+namespace Mongo.Migration.Migrations.Locators
+{
+    public interface IAdvancedMigrationLocator
+    {
+        IEnumerable GetMigrations(Type type);
+
+        IEnumerable GetMigrationsGt(Type type, string version);
+
+        IEnumerable GetMigrationsGtEq(Type type, string version);
+
+        DocumentVersion GetLatestVersion(Type type);
+
+        void Locate();
+    }
+}
\ No newline at end of file
diff --git a/Mongo.Migration/Migrations/MigrationRunner.cs b/Mongo.Migration/Migrations/MigrationRunner.cs
index effd4ca..9431eb2 100644
--- a/Mongo.Migration/Migrations/MigrationRunner.cs
+++ b/Mongo.Migration/Migrations/MigrationRunner.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using Mongo.Migration.Documents;
 using Mongo.Migration.Migrations.Locators;
@@ -10,7 +9,7 @@ namespace Mongo.Migration.Migrations
 {
     internal class MigrationRunner : IMigrationRunner
     {
-        private readonly IMigrationLocator _migrationLocator;
+        public IMigrationLocator _migrationLocator { get; }
 
         private readonly IVersionService _versionService;
 
@@ -19,7 +18,7 @@ public MigrationRunner(IMigrationLocator migrationLocator, IVersionService versi
             _migrationLocator = migrationLocator;
             _versionService = versionService;
         }
-        
+
         public void Run(Type type, BsonDocument document)
         {
             var documentVersion = _versionService.GetVersionOrDefault(document);
@@ -30,7 +29,7 @@ public void Run(Type type, BsonDocument document)
 
             MigrateUpOrDown(type, document, documentVersion, currentOrLatest);
         }
-        
+
         public void Run(Type type, BsonDocument document, DocumentVersion to)
         {
             var documentVersion = _versionService.GetVersionOrDefault(document);
diff --git a/Mongo.Migration/Mongo.Migration.csproj b/Mongo.Migration/Mongo.Migration.csproj
index 596c899..4fb9c37 100644
--- a/Mongo.Migration/Mongo.Migration.csproj
+++ b/Mongo.Migration/Mongo.Migration.csproj
@@ -11,8 +11,13 @@
     
     
     
+    
+    
     
     
+    
+    
+    
     
   
 
\ No newline at end of file
diff --git a/Mongo.Migration/MongoMigration.cs b/Mongo.Migration/MongoMigration.cs
index cd32032..df7814b 100644
--- a/Mongo.Migration/MongoMigration.cs
+++ b/Mongo.Migration/MongoMigration.cs
@@ -28,7 +28,6 @@ public void Run()
             _runtimeVersionLocator.Locate();
             _collectionLocator.Locate();
             _startUpVersionLocator.Locate();
-
             _migrationService.Migrate();
         }
     }
diff --git a/Mongo.Migration/Services/MigrationService.cs b/Mongo.Migration/Services/MigrationService.cs
index 292517b..9fcaa6f 100644
--- a/Mongo.Migration/Services/MigrationService.cs
+++ b/Mongo.Migration/Services/MigrationService.cs
@@ -12,14 +12,16 @@ internal class MigrationService : IMigrationService
     {
         private readonly ILogger _logger;
         private readonly ICollectionMigrationRunner _migrationRunner;
+        private readonly IDatabaseMigrationRunner _dbMigrationRunner;
         private readonly MigrationInterceptorProvider _provider;
         private readonly DocumentVersionSerializer _serializer;
 
         public MigrationService(DocumentVersionSerializer serializer, MigrationInterceptorProvider provider,
-            ICollectionMigrationRunner migrationRunner)
+            ICollectionMigrationRunner migrationRunner, IDatabaseMigrationRunner dbMigrationRunner)
             : this(serializer, provider, NullLoggerFactory.Instance)
         {
             _migrationRunner = migrationRunner;
+            _dbMigrationRunner = dbMigrationRunner;
         }
 
         private MigrationService(
@@ -43,6 +45,7 @@ public void Migrate()
         private void OnStartup()
         {
             _migrationRunner.RunAll();
+            _dbMigrationRunner.RunAll();
         }
 
         private void RegisterSerializer()
diff --git a/Mongo.Migration/Startup/DotNetCore/MongoMigrationExtensions.cs b/Mongo.Migration/Startup/DotNetCore/MongoMigrationExtensions.cs
index 463d774..b3307ee 100644
--- a/Mongo.Migration/Startup/DotNetCore/MongoMigrationExtensions.cs
+++ b/Mongo.Migration/Startup/DotNetCore/MongoMigrationExtensions.cs
@@ -24,9 +24,11 @@ public static void AddMigration(
         private static void RegisterDefaults(IServiceCollection services, IMongoMigrationSettings settings)
         {
             services.AddSingleton(settings);
-            
+
             services.AddSingleton();
             services.AddSingleton();
+            services.AddSingleton();
+            services.AddSingleton();
             services.AddSingleton();
             services.AddSingleton();
             services.AddSingleton();
@@ -36,7 +38,9 @@ private static void RegisterDefaults(IServiceCollection services, IMongoMigratio
             services.AddTransient();
 
             services.AddTransient();
+            services.AddTransient();
             services.AddTransient();
+            services.AddTransient();
             services.AddTransient();
 
             services.AddTransient();
diff --git a/Mongo.Migration/Startup/DotNetCore/MongoMigrationStartupFilter.cs b/Mongo.Migration/Startup/DotNetCore/MongoMigrationStartupFilter.cs
index 9fbd2af..22414b4 100644
--- a/Mongo.Migration/Startup/DotNetCore/MongoMigrationStartupFilter.cs
+++ b/Mongo.Migration/Startup/DotNetCore/MongoMigrationStartupFilter.cs
@@ -28,7 +28,11 @@ public Action Configure(Action next)
         {
             try
             {
+                _logger.LogInformation("Running migration. Please wait....");
+
                 _migration.Run();
+
+                _logger.LogInformation("Migration has been done");
             }
             catch (Exception ex)
             {
diff --git a/Mongo.Migration/Startup/MongoMigrationSettings.cs b/Mongo.Migration/Startup/MongoMigrationSettings.cs
index 8a96f03..8a92529 100644
--- a/Mongo.Migration/Startup/MongoMigrationSettings.cs
+++ b/Mongo.Migration/Startup/MongoMigrationSettings.cs
@@ -5,11 +5,13 @@ namespace Mongo.Migration.Startup
     public class MongoMigrationSettings : IMongoMigrationSettings
     {
         public string ConnectionString { get; set; }
-        
+
         public string Database { get; set; }
 
         public string VersionFieldName { get; set; }
-        
+
+        public string RunningVersion { get; set; } = "1.0.0";
+
         public MongoClientSettings ClientSettings { get; set; }
     }
 }
\ No newline at end of file
diff --git a/Mongo.Migration/Startup/Static/ComponentRegistry.cs b/Mongo.Migration/Startup/Static/ComponentRegistry.cs
index e72650f..acbba3b 100644
--- a/Mongo.Migration/Startup/Static/ComponentRegistry.cs
+++ b/Mongo.Migration/Startup/Static/ComponentRegistry.cs
@@ -18,10 +18,10 @@ internal class ComponentRegistry : IComponentRegistry
         public ComponentRegistry(IMongoMigrationSettings settings, IContainerAdapter containerAdapter = null)
         {
             _settings = settings;
-            
+
             if(containerAdapter == null)
                 containerAdapter = new LightInjectAdapter(new ServiceContainer());
-            
+
             _containerAdapter = containerAdapter;
         }
 
@@ -30,7 +30,7 @@ public void RegisterComponents(IMongoClient client)
             RegisterDefaults();
 
             _containerAdapter.RegisterInstance(client);
-            
+
             _containerAdapter.Register();
         }
 
@@ -42,22 +42,23 @@ public TComponent Get() where TComponent : class
         private void RegisterDefaults()
         {
             _containerAdapter.RegisterInstance(_containerAdapter);
-            
-            _containerAdapter.RegisterSingleton();
-            
             _containerAdapter.RegisterInstance(_settings);
-            
+
+            _containerAdapter.RegisterSingleton();
             _containerAdapter.RegisterSingleton();
             _containerAdapter.RegisterSingleton();
             _containerAdapter.RegisterSingleton();
 
+            _containerAdapter.Register();
+            _containerAdapter.Register();
             _containerAdapter.Register();
             _containerAdapter.Register();
             _containerAdapter.Register();
-
             _containerAdapter.Register();
             _containerAdapter.Register();
             _containerAdapter.Register();
+            _containerAdapter.Register();
+            _containerAdapter.Register();
 
             _containerAdapter.Register();
         }
diff --git a/Mongo.Migration/Utils/MigrationUtils.cs b/Mongo.Migration/Utils/MigrationUtils.cs
new file mode 100644
index 0000000..418cc8a
--- /dev/null
+++ b/Mongo.Migration/Utils/MigrationUtils.cs
@@ -0,0 +1,145 @@
+using System;
+using Microsoft.Extensions.Logging;
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+namespace Mongo.Migration.Utils
+{
+    public class MigrationUtils
+    {
+        private readonly ILogger logger;
+
+        public MigrationUtils()
+        {
+            this.logger = ApplicationLogging.CreateLogger();
+        }
+
+        public long UpdateInnerDocuments(
+            IMongoDatabase db,
+            BsonDocument documentToUpdate,
+            string collection,
+            string documentField) => this.UpdateInnerDocuments(db, documentToUpdate, collection, documentField, "_id");
+
+        public long UpdateInnerDocuments(
+            IMongoDatabase db,
+            BsonDocument documentToUpdate,
+            string collection,
+            string documentField,
+            string fieldToFilter)
+        {
+            logger.LogInformation($"Updating inner documents: {collection}.{documentField} ({fieldToFilter})...");
+
+            var fieldToFilterValue = documentToUpdate.GetValue(fieldToFilter);
+
+            var filter = Builders.Filter.Eq($"{documentField}.{fieldToFilter}", fieldToFilterValue);
+            var update = Builders.Update.Set(documentField, documentToUpdate);
+            var result = db.GetCollection(collection).UpdateMany(filter, update);
+
+            logger.LogInformation($"Has been modified {result.ModifiedCount} register " +
+                $"da collection {collection}, {documentField}.{fieldToFilter}={fieldToFilterValue}.");
+
+            return result.ModifiedCount;
+        }
+
+        public static BsonValue TryGetValue(BsonDocument document, string attr, ILogger logger)
+        {
+            try
+            {
+                return document[attr];
+            }
+            catch (Exception)
+            {
+                logger.LogWarning($"The attribute {attr} not found in document, returning value null");
+                return BsonNull.Value;
+            }
+        }
+
+        public static void UpdateUniqueIndex(IMongoDatabase db, string collectionName, string field, string indexName, ILogger logger)
+        {
+            try
+            {
+                logger.LogInformation($"Update index {collectionName}.{field}");
+
+                var collection = db.GetCollection(collectionName);
+                collection.Indexes.DropOne(indexName);
+
+                var collation = new Collation("en", strength: new Optional(CollationStrength.Secondary));
+
+                var indexModel = new CreateIndexModel(Builders.IndexKeys.Ascending(field), new CreateIndexOptions
+                {
+                    Unique = true,
+                    Collation = collation,
+                    Name = indexName
+                });
+
+                collection.Indexes.CreateOne(indexModel);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, $"Error creating unique index for field  {collectionName}.{field}");
+            }
+        }
+        public static void CreateAscendingIndex(IMongoDatabase db, string collectionName, string field, string indexName, ILogger logger)
+        {
+            try
+            {
+                logger.LogInformation($"Creatinf ascending index: {collectionName}.{field}");
+
+                var collection = db.GetCollection(collectionName);
+
+                var indexModel = new CreateIndexModel(Builders.IndexKeys.Ascending(field), new CreateIndexOptions
+                {
+                    Name = indexName
+                });
+
+                collection.Indexes.CreateOne(indexModel);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, $"Error creating ascending index for field {collectionName}.{field}");
+            }
+        }
+
+        public static void CreateDescendingIndex(IMongoDatabase db, string collectionName, string field, string indexName, ILogger logger)
+        {
+            try
+            {
+                logger.LogInformation($"Creating descending index: {collectionName}.{field}");
+
+                var collection = db.GetCollection(collectionName);
+
+                var indexModel = new CreateIndexModel(Builders.IndexKeys.Descending(field), new CreateIndexOptions
+                {
+                    Name = indexName
+                });
+
+                collection.Indexes.CreateOne(indexModel);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, $"Error creating descending index for field {collectionName}.{field}");
+            }
+        }
+
+        public static void CreateTextIndex(IMongoDatabase db, string collectionName, string field, string indexName, ILogger logger)
+        {
+            try
+            {
+                logger.LogInformation($"Creating text index: {collectionName}.{field}");
+
+                var collection = db.GetCollection(collectionName);
+
+                var indexModel = new CreateIndexModel(Builders.IndexKeys.Text(field), new CreateIndexOptions
+                {
+                    Name = indexName
+                });
+
+                collection.Indexes.CreateOne(indexModel);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, $"Error creating text index for field {collectionName}.{field}");
+            }
+        }
+    }
+}
\ No newline at end of file