diff --git a/NzbDrone.App.Test/ContainerFixture.cs b/NzbDrone.App.Test/ContainerFixture.cs
index 59098aa77..6b9e28fed 100644
--- a/NzbDrone.App.Test/ContainerFixture.cs
+++ b/NzbDrone.App.Test/ContainerFixture.cs
@@ -1,13 +1,14 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using NUnit.Framework;
 using NzbDrone.Common;
 using NzbDrone.Common.Messaging;
 using NzbDrone.Core.Download;
 using NzbDrone.Core.Indexers;
+using NzbDrone.Core.Jobs;
+using NzbDrone.Core.Lifecycle;
 using NzbDrone.Test.Common;
 using FluentAssertions;
-using TinyIoC;
+using System.Linq;
 
 namespace NzbDrone.App.Test
 {
@@ -17,9 +18,12 @@ namespace NzbDrone.App.Test
         [Test]
         public void should_be_able_to_resolve_event_handlers()
         {
-            MainAppContainerBuilder.BuildContainer().Resolve<IEnumerable<IProcessMessage>>().Should().NotBeEmpty();
+            MainAppContainerBuilder.BuildContainer().ResolveAll<IEnumerable<IProcessMessage>>().Should().NotBeEmpty();
         }
 
+
+
+
         [Test]
         public void should_be_able_to_resolve_indexers()
         {
@@ -50,5 +54,17 @@ namespace NzbDrone.App.Test
             executor.Should().NotBeNull();
             executor.Should().BeAssignableTo<IExecute<RssSyncCommand>>();
         }
+
+        [Test]
+        [Ignore("need to fix this at some point")]
+        public void should_return_same_instance_of_singletons()
+        {
+            var container = MainAppContainerBuilder.BuildContainer();
+
+            var first = container.ResolveAll<IHandle<ApplicationShutdownRequested>>().OfType<Scheduler>().Single();
+            var second = container.ResolveAll<IHandle<ApplicationShutdownRequested>>().OfType<Scheduler>().Single();
+
+            first.Should().BeSameAs(second);
+        }
     }
 }
\ No newline at end of file
diff --git a/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj b/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
index b52010006..aaaacf101 100644
--- a/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
+++ b/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
@@ -89,6 +89,7 @@
     <Compile Include="DiskProviderFixture.cs" />
     <Compile Include="EnviromentProviderTest.cs" />
     <Compile Include="ProcessProviderTests.cs" />
+    <Compile Include="ServiceFactoryFixture.cs" />
     <Compile Include="ServiceProviderTests.cs" />
     <Compile Include="WebClientTests.cs" />
   </ItemGroup>
@@ -103,6 +104,10 @@
       <Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
       <Name>NzbDrone.Common</Name>
     </ProjectReference>
+    <ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
+      <Project>{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}</Project>
+      <Name>NzbDrone.Core</Name>
+    </ProjectReference>
     <ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
       <Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
       <Name>NzbDrone.Test.Common</Name>
@@ -111,6 +116,10 @@
       <Project>{FAFB5948-A222-4CF6-AD14-026BE7564802}</Project>
       <Name>NzbDrone.Test.Dummy</Name>
     </ProjectReference>
+    <ProjectReference Include="..\NzbDrone\NzbDrone.csproj">
+      <Project>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</Project>
+      <Name>NzbDrone</Name>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Properties\" />
diff --git a/NzbDrone.Common.Test/ServiceFactoryFixture.cs b/NzbDrone.Common.Test/ServiceFactoryFixture.cs
new file mode 100644
index 000000000..9241c3fe1
--- /dev/null
+++ b/NzbDrone.Common.Test/ServiceFactoryFixture.cs
@@ -0,0 +1,29 @@
+using System.Linq;
+using FluentAssertions;
+using NUnit.Framework;
+using NzbDrone.Common.Messaging;
+using NzbDrone.Core.Lifecycle;
+using NzbDrone.Test.Common;
+
+namespace NzbDrone.Common.Test
+{
+    [TestFixture]
+    public class ServiceFactoryFixture : TestBase<ServiceFactory>
+    {
+        [SetUp]
+        public void setup()
+        {
+            Mocker.SetConstant(MainAppContainerBuilder.BuildContainer());
+        }
+
+
+        [Test]
+        public void event_handlers_should_be_unique()
+        {
+            var handlers = Subject.BuildAll<IHandle<ApplicationShutdownRequested>>()
+                                  .Select(c => c.GetType().FullName);
+
+            handlers.Should().OnlyHaveUniqueItems();
+        }
+    }
+}
\ No newline at end of file
diff --git a/NzbDrone.Common/Composition/Class1.cs b/NzbDrone.Common/Composition/Class1.cs
new file mode 100644
index 000000000..bf9272525
--- /dev/null
+++ b/NzbDrone.Common/Composition/Class1.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace NzbDrone.Common.Composition
+{
+    public class SingletonAttribute : Attribute
+    {
+    }
+}
\ No newline at end of file
diff --git a/NzbDrone.Common/ContainerBuilderBase.cs b/NzbDrone.Common/ContainerBuilderBase.cs
index ccde67f0b..a648c6a36 100644
--- a/NzbDrone.Common/ContainerBuilderBase.cs
+++ b/NzbDrone.Common/ContainerBuilderBase.cs
@@ -2,8 +2,10 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
+using NzbDrone.Common.Composition;
 using NzbDrone.Common.Messaging;
 using TinyIoC;
+using NzbDrone.Common.Reflection;
 
 namespace NzbDrone.Common
 {
@@ -58,7 +60,15 @@ namespace NzbDrone.Common
             }
             if (implementations.Count == 1)
             {
-                Container.Register(contractType, implementations.Single()).AsMultiInstance();
+                if (implementations.Single().HasAttribute<SingletonAttribute>())
+                {
+                    Container.Register(contractType, implementations.Single()).AsSingleton();
+                }
+                else
+                {
+                    Container.Register(contractType, implementations.Single()).AsMultiInstance();
+                }
+
                 Container.RegisterMultiple(contractType, implementations).AsMultiInstance();
             }
             else
diff --git a/NzbDrone.Common/Messaging/MessageExtensions.cs b/NzbDrone.Common/Messaging/MessageExtensions.cs
index e5f9ec2fe..302aad869 100644
--- a/NzbDrone.Common/Messaging/MessageExtensions.cs
+++ b/NzbDrone.Common/Messaging/MessageExtensions.cs
@@ -8,7 +8,7 @@ namespace NzbDrone.Common.Messaging
         {
             if (!typeof(ICommand).IsAssignableFrom(commandType))
             {
-                throw new ArgumentException("commandType must implement IExecute");
+                throw new ArgumentException("commandType must implement ICommand");
             }
 
             return string.Format("I{0}Executor", commandType.Name);
diff --git a/NzbDrone.Common/NzbDrone.Common.csproj b/NzbDrone.Common/NzbDrone.Common.csproj
index f31a6a3a7..c69f2f66c 100644
--- a/NzbDrone.Common/NzbDrone.Common.csproj
+++ b/NzbDrone.Common/NzbDrone.Common.csproj
@@ -79,6 +79,7 @@
     <Compile Include="Cache\Cached.cs" />
     <Compile Include="Cache\CacheManger.cs" />
     <Compile Include="Cache\ICached.cs" />
+    <Compile Include="Composition\Class1.cs" />
     <Compile Include="ContainerBuilderBase.cs" />
     <Compile Include="EnsureThat\Ensure.cs" />
     <Compile Include="EnsureThat\EnsureBoolExtensions.cs" />
diff --git a/NzbDrone.Common/Reflection/ReflectionExtensions.cs b/NzbDrone.Common/Reflection/ReflectionExtensions.cs
index d772f5765..a19408662 100644
--- a/NzbDrone.Common/Reflection/ReflectionExtensions.cs
+++ b/NzbDrone.Common/Reflection/ReflectionExtensions.cs
@@ -56,5 +56,10 @@ namespace NzbDrone.Common.Reflection
 
             return (T)attribute;
         }
+
+        public static bool HasAttribute<TAttribute>(this Type type)
+        {
+            return type.GetCustomAttributes(typeof(TAttribute), true).Any();
+        }
     }
 }
\ No newline at end of file
diff --git a/NzbDrone.Common/ServiceFactory.cs b/NzbDrone.Common/ServiceFactory.cs
index 0a47da334..29e79912a 100644
--- a/NzbDrone.Common/ServiceFactory.cs
+++ b/NzbDrone.Common/ServiceFactory.cs
@@ -28,7 +28,7 @@ namespace NzbDrone.Common
 
         public IEnumerable<T> BuildAll<T>() where T : class
         {
-            return _container.ResolveAll<T>();
+            return _container.ResolveAll<T>().GroupBy(c => c.GetType().FullName).Select(g => g.First());
         }
 
         public object Build(Type contract)
diff --git a/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs b/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs
index 27d0813c1..e0045bd7d 100644
--- a/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs
+++ b/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs
@@ -12,15 +12,15 @@ namespace NzbDrone.Core.Test.Datastore
 
     [TestFixture]
     public class
-        BasicRepositoryFixture : DbTest<BasicRepository<JobDefinition>, JobDefinition>
+        BasicRepositoryFixture : DbTest<BasicRepository<ScheduledTask>, ScheduledTask>
     {
-        private JobDefinition _basicType;
+        private ScheduledTask _basicType;
 
 
         [SetUp]
         public void Setup()
         {
-            _basicType = Builder<JobDefinition>
+            _basicType = Builder<ScheduledTask>
                     .CreateNew()
                     .With(c => c.Id = 0)
                     .Build();
@@ -33,6 +33,18 @@ namespace NzbDrone.Core.Test.Datastore
             Subject.All().Should().HaveCount(1);
         }
 
+        [Test]
+        public void purge_should_delete_all()
+        {
+            Subject.InsertMany(Builder<ScheduledTask>.CreateListOfSize(10).BuildListOfNew());
+
+            AllStoredModels.Should().HaveCount(10);
+
+            Subject.Purge();
+
+            AllStoredModels.Should().BeEmpty();
+
+        }
 
 
         [Test]
@@ -62,6 +74,12 @@ namespace NzbDrone.Core.Test.Datastore
             Subject.SingleOrDefault().Should().NotBeNull();
         }
 
+        [Test]
+        public void single_or_default_on_empty_table_should_return_null()
+        {
+            Subject.SingleOrDefault().Should().BeNull();
+        }
+
         [Test]
         public void getting_model_with_invalid_id_should_throw()
         {
diff --git a/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs b/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs
index 7be8b7bd2..d12d414bb 100644
--- a/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs
+++ b/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs
@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Data;
 using System.Linq;
 using FizzWare.NBuilder;
 using FluentAssertions;
@@ -12,15 +11,29 @@ using NzbDrone.Core.Tv;
 
 namespace NzbDrone.Core.Test.Datastore
 {
+
+    public class DatabaseFixture : DbTest
+    {
+        [Test]
+        public void SingleOrDefault_should_return_null_on_empty_db()
+        {
+            Mocker.Resolve<IDatabase>()
+                  .DataMapper.Query<Series>()
+                  .SingleOrDefault(c => c.CleanTitle == "SomeTitle")
+                  .Should()
+                  .BeNull();
+        }
+    }
+
     [TestFixture]
-    public class ObjectDatabaseFixture : DbTest<BasicRepository<JobDefinition>, JobDefinition>
+    public class ObjectDatabaseFixture : DbTest<BasicRepository<ScheduledTask>, ScheduledTask>
     {
-        private JobDefinition _sampleType;
+        private ScheduledTask _sampleType;
 
         [SetUp]
         public void SetUp()
         {
-            _sampleType = Builder<JobDefinition>
+            _sampleType = Builder<ScheduledTask>
                     .CreateNew()
                     .With(s => s.Id = 0)
                     .Build();
@@ -31,7 +44,7 @@ namespace NzbDrone.Core.Test.Datastore
         public void should_be_able_to_write_to_database()
         {
             Subject.Insert(_sampleType);
-            Db.All<JobDefinition>().Should().HaveCount(1);
+            Db.All<ScheduledTask>().Should().HaveCount(1);
         }
 
         [Test]
@@ -51,7 +64,7 @@ namespace NzbDrone.Core.Test.Datastore
         [Test]
         public void should_be_able_to_store_empty_list()
         {
-            var series = new List<JobDefinition>();
+            var series = new List<ScheduledTask>();
 
             Subject.InsertMany(series);
         }
@@ -70,19 +83,22 @@ namespace NzbDrone.Core.Test.Datastore
             _sampleType.Id = 0;
             Subject.Insert(_sampleType);
 
-            Db.All<JobDefinition>().Should().HaveCount(1);
+            Db.All<ScheduledTask>().Should().HaveCount(1);
             _sampleType.Id.Should().Be(1);
         }
 
 
 
 
+
+
+
         [Test]
         public void should_have_id_when_returned_from_database()
         {
             _sampleType.Id = 0;
             Subject.Insert(_sampleType);
-            var item = Db.All<JobDefinition>();
+            var item = Db.All<ScheduledTask>();
 
             item.Should().HaveCount(1);
             item.First().Id.Should().NotBe(0);
@@ -94,7 +110,7 @@ namespace NzbDrone.Core.Test.Datastore
         public void should_be_able_to_find_object_by_id()
         {
             Subject.Insert(_sampleType);
-            var item = Db.All<JobDefinition>().Single(c => c.Id == _sampleType.Id);
+            var item = Db.All<ScheduledTask>().Single(c => c.Id == _sampleType.Id);
 
             item.Id.Should().NotBe(0);
             item.Id.Should().Be(_sampleType.Id);
@@ -104,7 +120,7 @@ namespace NzbDrone.Core.Test.Datastore
         [Test]
         public void set_fields_should_only_update_selected_filed()
         {
-            var childModel = new JobDefinition
+            var childModel = new ScheduledTask
                 {
                     Name = "Address",
                     Interval = 12
@@ -117,8 +133,8 @@ namespace NzbDrone.Core.Test.Datastore
 
             Subject.SetFields(childModel, t => t.Name);
 
-            Db.All<JobDefinition>().Single().Name.Should().Be("A");
-            Db.All<JobDefinition>().Single().Interval.Should().Be(12);
+            Db.All<ScheduledTask>().Single().Name.Should().Be("A");
+            Db.All<ScheduledTask>().Single().Interval.Should().Be(12);
         }
 
         [Test]
@@ -128,7 +144,7 @@ namespace NzbDrone.Core.Test.Datastore
             var rootFolder = Db.Insert(new RootFolders.RootFolder() { Path = "C:\test" });
 
             var series = Builder<Series>.CreateNew()
-                .With(c=>c.RootFolderId = rootFolder.Id)
+                .With(c => c.RootFolderId = rootFolder.Id)
                 .BuildNew();
 
             Db.Insert(series);
diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs
index 7198d8392..2613b7055 100644
--- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs
+++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs
@@ -16,6 +16,9 @@ namespace NzbDrone.Core.DataAugmentation.Scene
         IHandleAsync<ApplicationStartedEvent>,
         IExecute<UpdateSceneMappingCommand>
     {
+
+        private static readonly object mutex = new object();
+
         private readonly ISceneMappingRepository _repository;
         private readonly ISceneMappingProxy _sceneMappingProxy;
         private readonly Logger _logger;
@@ -62,15 +65,18 @@ namespace NzbDrone.Core.DataAugmentation.Scene
             try
             {
                 var mappings = _sceneMappingProxy.Fetch();
-
-                if (mappings.Any())
-                {
-                    _repository.Purge();
-                    _repository.InsertMany(mappings);
-                }
-                else
+                
+                lock (mutex)
                 {
-                    _logger.Warn("Received empty list of mapping. will not update.");
+                    if (mappings.Any())
+                    {
+                        _repository.Purge();
+                        _repository.InsertMany(mappings);
+                    }
+                    else
+                    {
+                        _logger.Warn("Received empty list of mapping. will not update.");
+                    }
                 }
             }
             catch (Exception ex)
diff --git a/NzbDrone.Core/Datastore/Migration/Migration20130324.cs b/NzbDrone.Core/Datastore/Migration/Migration20130324.cs
index 3feca052d..a581b751a 100644
--- a/NzbDrone.Core/Datastore/Migration/Migration20130324.cs
+++ b/NzbDrone.Core/Datastore/Migration/Migration20130324.cs
@@ -91,11 +91,10 @@ namespace NzbDrone.Core.Datastore.Migration
                   .WithColumn("Type").AsString().Unique()
                   .WithColumn("Name").AsString().Unique();
 
-            Create.TableForModel("JobDefinitions")
+            Create.TableForModel("ScheduledTasks")
                   .WithColumn("Name").AsString().Unique()
                   .WithColumn("Interval").AsInt32()
-                  .WithColumn("LastExecution").AsDateTime()
-                  .WithColumn("Success").AsBoolean();
+                  .WithColumn("LastExecution").AsDateTime();
 
             Create.TableForModel("IndexerDefinitions")
                   .WithColumn("Enable").AsBoolean()
diff --git a/NzbDrone.Core/Datastore/TableMapping.cs b/NzbDrone.Core/Datastore/TableMapping.cs
index b824d74b8..fe6f87ffc 100644
--- a/NzbDrone.Core/Datastore/TableMapping.cs
+++ b/NzbDrone.Core/Datastore/TableMapping.cs
@@ -33,7 +33,7 @@ namespace NzbDrone.Core.Datastore
             Mapper.Entity<RootFolder>().RegisterModel("RootFolders").Ignore(r => r.FreeSpace);
 
             Mapper.Entity<IndexerDefinition>().RegisterModel("IndexerDefinitions");
-            Mapper.Entity<JobDefinition>().RegisterModel("JobDefinitions");
+            Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
             Mapper.Entity<ExternalNotificationDefinition>().RegisterModel("ExternalNotificationDefinitions");
 
             Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
diff --git a/NzbDrone.Core/Jobs/JobRepository.cs b/NzbDrone.Core/Jobs/JobRepository.cs
index cd8299aee..26d468a8b 100644
--- a/NzbDrone.Core/Jobs/JobRepository.cs
+++ b/NzbDrone.Core/Jobs/JobRepository.cs
@@ -1,78 +1,35 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using NLog;
 using NzbDrone.Common.Messaging;
 using NzbDrone.Core.Datastore;
-using NzbDrone.Core.Indexers;
-using NzbDrone.Core.Lifecycle;
-using NzbDrone.Core.Providers;
 
 namespace NzbDrone.Core.Jobs
 {
-    public interface IJobRepository : IBasicRepository<JobDefinition>
+    public interface IScheduledTaskRepository : IBasicRepository<ScheduledTask>
     {
-        IList<JobDefinition> GetPendingJobs();
-        JobDefinition GetDefinition(Type type);
+        IList<ScheduledTask> GetPendingJobs();
+        ScheduledTask GetDefinition(Type type);
     }
 
-    public class JobRepository : BasicRepository<JobDefinition>, IJobRepository, IHandle<ApplicationStartedEvent>
+
+    public class ScheduledTaskRepository : BasicRepository<ScheduledTask>, IScheduledTaskRepository
     {
-        private readonly Logger _logger;
 
-        public JobRepository(IDatabase database, Logger logger, IMessageAggregator messageAggregator)
+        public ScheduledTaskRepository(IDatabase database, IMessageAggregator messageAggregator)
             : base(database, messageAggregator)
         {
-            _logger = logger;
         }
 
-        public JobDefinition GetDefinition(Type type)
+        public ScheduledTask GetDefinition(Type type)
         {
             return Query.Single(c => c.Name == type.FullName);
         }
 
 
-        public IList<JobDefinition> GetPendingJobs()
+        public IList<ScheduledTask> GetPendingJobs()
         {
             return Query.Where(c => c.Interval != 0).ToList().Where(c => c.LastExecution < DateTime.Now.AddMinutes(-c.Interval)).ToList();
         }
-
-        public void Handle(ApplicationStartedEvent message)
-        {
-           /* var currentJobs = All().ToList();
-
-
-            var timers = new[]
-                {
-                    new JobDefinition{ Interval = 25, Name = typeof(RssSyncCommand).FullName},
-                    new JobDefinition{ Interval = 24*60, Name = typeof(UpdateXemMappings).FullName}
-                };
-
-
-            _logger.Debug("Initializing jobs. Available: {0} Existing:{1}", timers.Count(), currentJobs.Count());
-
-            foreach (var job in currentJobs)
-            {
-                if (!timers.Any(c => c.Name == job.Name))
-                {
-                    _logger.Debug("Removing job from database '{0}'", job.Name);
-                    Delete(job.Id);
-                }
-            }
-
-            foreach (var job in timers)
-            {
-                var currentDefinition = currentJobs.SingleOrDefault(c => c.Name == job.GetType().ToString());
-
-                if (currentDefinition == null)
-                {
-                    currentDefinition = job;
-                }
-
-                currentDefinition.Interval = job.Interval;
-
-                Upsert(currentDefinition);
-            }*/
-        }
     }
 }
diff --git a/NzbDrone.Core/Jobs/JobDefinition.cs b/NzbDrone.Core/Jobs/ScheduledTask.cs
similarity index 71%
rename from NzbDrone.Core/Jobs/JobDefinition.cs
rename to NzbDrone.Core/Jobs/ScheduledTask.cs
index 44d81eed4..5e3a4e21d 100644
--- a/NzbDrone.Core/Jobs/JobDefinition.cs
+++ b/NzbDrone.Core/Jobs/ScheduledTask.cs
@@ -3,11 +3,10 @@ using NzbDrone.Core.Datastore;
 
 namespace NzbDrone.Core.Jobs
 {
-    public class JobDefinition : ModelBase
+    public class ScheduledTask : ModelBase
     {
         public String Name { get; set; }
         public Int32 Interval { get; set; }
         public DateTime LastExecution { get; set; }
-        public Boolean Success { get; set; }
     }
 }
\ No newline at end of file
diff --git a/NzbDrone.Core/Jobs/JobTimer.cs b/NzbDrone.Core/Jobs/Scheduler.cs
similarity index 55%
rename from NzbDrone.Core/Jobs/JobTimer.cs
rename to NzbDrone.Core/Jobs/Scheduler.cs
index 19286dfbf..c53bd6380 100644
--- a/NzbDrone.Core/Jobs/JobTimer.cs
+++ b/NzbDrone.Core/Jobs/Scheduler.cs
@@ -1,39 +1,40 @@
 using System;
 using System.Timers;
+using NzbDrone.Common.Composition;
 using NzbDrone.Common.Messaging;
 using NzbDrone.Core.Lifecycle;
 
 namespace NzbDrone.Core.Jobs
 {
-    public class JobTimer :
+    [Singleton]
+    public class Scheduler :
         IHandle<ApplicationStartedEvent>,
         IHandle<ApplicationShutdownRequested>
     {
-        private readonly IJobRepository _jobRepository;
+        private readonly ITaskManager _taskManager;
         private readonly IMessageAggregator _messageAggregator;
-        private readonly Timer _timer;
+        private static readonly Timer Timer = new Timer();
 
-        public JobTimer(IJobRepository jobRepository, IMessageAggregator messageAggregator)
+        public Scheduler(ITaskManager taskManager, IMessageAggregator messageAggregator)
         {
-            _jobRepository = jobRepository;
+            _taskManager = taskManager;
             _messageAggregator = messageAggregator;
-            _timer = new Timer();
         }
 
         public void Handle(ApplicationStartedEvent message)
         {
-            _timer.Interval = 1000 * 30;
-            _timer.Elapsed += (o, args) => ExecuteCommands();
-            //_timer.Start();
+            Timer.Interval = 1000 * 30;
+            Timer.Elapsed += (o, args) => ExecuteCommands();
+            Timer.Start();
         }
 
         private void ExecuteCommands()
         {
-            var jobs = _jobRepository.GetPendingJobs();
+            var tasks = _taskManager.GetPending();
 
-            foreach (var jobDefinition in jobs)
+            foreach (var task in tasks)
             {
-                var commandType = Type.GetType(jobDefinition.Name);
+                var commandType = Type.GetType(task.Name);
                 var command = (ICommand)Activator.CreateInstance(commandType);
 
                 _messageAggregator.PublishCommand(command);
@@ -42,7 +43,9 @@ namespace NzbDrone.Core.Jobs
 
         public void Handle(ApplicationShutdownRequested message)
         {
-            _timer.Stop();
+            Timer.Stop();
         }
     }
+
+
 }
\ No newline at end of file
diff --git a/NzbDrone.Core/Jobs/TaskManager.cs b/NzbDrone.Core/Jobs/TaskManager.cs
new file mode 100644
index 000000000..ab4b33c66
--- /dev/null
+++ b/NzbDrone.Core/Jobs/TaskManager.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.Linq;
+using NLog;
+using NzbDrone.Common.Messaging;
+using NzbDrone.Core.Indexers;
+using NzbDrone.Core.Lifecycle;
+using NzbDrone.Core.Providers;
+
+namespace NzbDrone.Core.Jobs
+{
+    public interface ITaskManager
+    {
+        IList<ScheduledTask> GetPending();
+    }
+
+    public class TaskManager : IHandle<ApplicationStartedEvent>, ITaskManager
+    {
+        private readonly IScheduledTaskRepository _scheduledTaskRepository;
+        private readonly Logger _logger;
+
+        public TaskManager(IScheduledTaskRepository scheduledTaskRepository, Logger logger)
+        {
+            _scheduledTaskRepository = scheduledTaskRepository;
+            _logger = logger;
+        }
+
+
+        public IList<ScheduledTask> GetPending()
+        {
+            return _scheduledTaskRepository.GetPendingJobs();
+        }
+
+        public void Handle(ApplicationStartedEvent message)
+        {
+            var defaultTasks = new[]
+                {
+                    new ScheduledTask{ Interval = 25, Name = typeof(RssSyncCommand).FullName},
+                    new ScheduledTask{ Interval = 24*60, Name = typeof(UpdateXemMappings).FullName}
+                };
+
+            var currentTasks = _scheduledTaskRepository.All();
+
+
+            _logger.Debug("Initializing jobs. Available: {0} Existing:{1}", defaultTasks.Count(), currentTasks.Count());
+
+
+            foreach (var job in currentTasks)
+            {
+                if (!defaultTasks.Any(c => c.Name == job.Name))
+                {
+                    _logger.Debug("Removing job from database '{0}'", job.Name);
+                    _scheduledTaskRepository.Delete(job.Id);
+                }
+            }
+
+            foreach (var defaultTask in defaultTasks)
+            {
+                var currentDefinition = currentTasks.SingleOrDefault(c => c.Name == defaultTask.Name);
+
+                if (currentDefinition == null)
+                {
+                    currentDefinition = defaultTask;
+                    _scheduledTaskRepository.Upsert(currentDefinition);
+                }
+
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index d29e7cd9d..df8204e74 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -244,6 +244,7 @@
     <Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
     <Compile Include="Indexers\IndexerWithSetting.cs" />
     <Compile Include="Indexers\RssSyncCommand.cs" />
+    <Compile Include="Jobs\TaskManager.cs" />
     <Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
     <Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
     <Compile Include="MediaFiles\Events\EpisodeDownloadedEvent.cs" />
@@ -285,10 +286,10 @@
     <Compile Include="Indexers\Wombles\Wombles.cs" />
     <Compile Include="Indexers\Wombles\WomblesParser.cs" />
     <Compile Include="Instrumentation\LogRepository.cs" />
-    <Compile Include="Jobs\JobDefinition.cs" />
+    <Compile Include="Jobs\ScheduledTask.cs" />
     <Compile Include="Jobs\JobQueueItem.cs" />
     <Compile Include="Jobs\JobRepository.cs" />
-    <Compile Include="Jobs\JobTimer.cs" />
+    <Compile Include="Jobs\Scheduler.cs" />
     <Compile Include="Lifecycle\ApplicationStartedEvent.cs" />
     <Compile Include="MediaCover\MediaCover.cs" />
     <Compile Include="MediaFiles\EpisodeFileMovingService.cs" />
diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution
index 6cb47a29a..444b34b1d 100644
--- a/NzbDrone.ncrunchsolution
+++ b/NzbDrone.ncrunchsolution
@@ -2,6 +2,7 @@
   <FileVersion>1</FileVersion>
   <AutoEnableOnStartup>False</AutoEnableOnStartup>
   <AllowParallelTestExecution>true</AllowParallelTestExecution>
+  <AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
   <FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
   <FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio>
   <FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>
diff --git a/NzbDrone/NLog.config b/NzbDrone/NLog.config
index a5d313b44..f74e2d081 100644
--- a/NzbDrone/NLog.config
+++ b/NzbDrone/NLog.config
@@ -27,6 +27,6 @@
   <rules>
     <logger name="*" minlevel="Trace" writeTo="consoleLogger"/>
     <logger name="*" minlevel="Off" writeTo="udpTarget"/>
-    <logger name="*" minlevel="Trace" writeTo="rollingFileLogger"/>
+    <logger name="*" minlevel="Warn" writeTo="rollingFileLogger"/>
   </rules>
 </nlog>
\ No newline at end of file