diff --git a/api/album_list_test.go b/api/album_list_test.go
index 380e0e3cc..e60cbfa28 100644
--- a/api/album_list_test.go
+++ b/api/album_list_test.go
@@ -5,8 +5,8 @@ import (
 
 	"github.com/deluan/gosonic/api/responses"
 	"github.com/deluan/gosonic/domain"
+	"github.com/deluan/gosonic/persistence"
 	. "github.com/deluan/gosonic/tests"
-	"github.com/deluan/gosonic/tests/mocks"
 	"github.com/deluan/gosonic/utils"
 	. "github.com/smartystreets/goconvey/convey"
 )
@@ -14,7 +14,7 @@ import (
 func TestGetAlbumList(t *testing.T) {
 	Init(t, false)
 
-	mockAlbumRepo := mocks.CreateMockAlbumRepo()
+	mockAlbumRepo := persistence.CreateMockAlbumRepo()
 	utils.DefineSingleton(new(domain.AlbumRepository), func() domain.AlbumRepository {
 		return mockAlbumRepo
 	})
diff --git a/api/base_api_controller.go b/api/base_api_controller.go
index f7a79e59a..09b2a3cbf 100644
--- a/api/base_api_controller.go
+++ b/api/base_api_controller.go
@@ -46,6 +46,9 @@ func (c *BaseAPIController) ParamInt(param string, def int) int {
 
 func (c *BaseAPIController) ParamBool(param string, def bool) bool {
 	value := def
+	if c.Input().Get(param) == "" {
+		return def
+	}
 	c.Ctx.Input.Bind(&value, param)
 	return value
 }
diff --git a/api/browsing_test.go b/api/browsing_test.go
index e719462a4..2cb50bc58 100644
--- a/api/browsing_test.go
+++ b/api/browsing_test.go
@@ -7,8 +7,8 @@ import (
 	"github.com/deluan/gosonic/consts"
 	"github.com/deluan/gosonic/domain"
 	"github.com/deluan/gosonic/engine"
+	"github.com/deluan/gosonic/persistence"
 	. "github.com/deluan/gosonic/tests"
-	"github.com/deluan/gosonic/tests/mocks"
 	"github.com/deluan/gosonic/utils"
 	. "github.com/smartystreets/goconvey/convey"
 )
@@ -35,11 +35,11 @@ const (
 func TestGetIndexes(t *testing.T) {
 	Init(t, false)
 
-	mockRepo := mocks.CreateMockArtistIndexRepo()
+	mockRepo := persistence.CreateMockArtistIndexRepo()
 	utils.DefineSingleton(new(domain.ArtistIndexRepository), func() domain.ArtistIndexRepository {
 		return mockRepo
 	})
-	propRepo := mocks.CreateMockPropertyRepo()
+	propRepo := engine.CreateMockPropertyRepo()
 	utils.DefineSingleton(new(engine.PropertyRepository), func() engine.PropertyRepository {
 		return propRepo
 	})
@@ -116,15 +116,15 @@ func TestGetIndexes(t *testing.T) {
 func TestGetMusicDirectory(t *testing.T) {
 	Init(t, false)
 
-	mockArtistRepo := mocks.CreateMockArtistRepo()
+	mockArtistRepo := persistence.CreateMockArtistRepo()
 	utils.DefineSingleton(new(domain.ArtistRepository), func() domain.ArtistRepository {
 		return mockArtistRepo
 	})
-	mockAlbumRepo := mocks.CreateMockAlbumRepo()
+	mockAlbumRepo := persistence.CreateMockAlbumRepo()
 	utils.DefineSingleton(new(domain.AlbumRepository), func() domain.AlbumRepository {
 		return mockAlbumRepo
 	})
-	mockMediaFileRepo := mocks.CreateMockMediaFileRepo()
+	mockMediaFileRepo := persistence.CreateMockMediaFileRepo()
 	utils.DefineSingleton(new(domain.MediaFileRepository), func() domain.MediaFileRepository {
 		return mockMediaFileRepo
 	})
diff --git a/api/get_cover_art_test.go b/api/get_cover_art_test.go
index 32016dad4..f582bd3d0 100644
--- a/api/get_cover_art_test.go
+++ b/api/get_cover_art_test.go
@@ -10,8 +10,8 @@ import (
 	"github.com/astaxie/beego"
 	"github.com/deluan/gosonic/api/responses"
 	"github.com/deluan/gosonic/domain"
+	"github.com/deluan/gosonic/persistence"
 	. "github.com/deluan/gosonic/tests"
-	"github.com/deluan/gosonic/tests/mocks"
 	"github.com/deluan/gosonic/utils"
 	. "github.com/smartystreets/goconvey/convey"
 )
@@ -28,7 +28,7 @@ func getCoverArt(params ...string) (*http.Request, *httptest.ResponseRecorder) {
 func TestGetCoverArt(t *testing.T) {
 	Init(t, false)
 
-	mockMediaFileRepo := mocks.CreateMockMediaFileRepo()
+	mockMediaFileRepo := persistence.CreateMockMediaFileRepo()
 	utils.DefineSingleton(new(domain.MediaFileRepository), func() domain.MediaFileRepository {
 		return mockMediaFileRepo
 	})
diff --git a/api/media_annotation.go b/api/media_annotation.go
index 01a0067e0..901e763fa 100644
--- a/api/media_annotation.go
+++ b/api/media_annotation.go
@@ -6,38 +6,31 @@ import (
 
 	"github.com/astaxie/beego"
 	"github.com/deluan/gosonic/api/responses"
-	"github.com/deluan/gosonic/domain"
-	"github.com/deluan/gosonic/itunesbridge"
+	"github.com/deluan/gosonic/engine"
 	"github.com/deluan/gosonic/utils"
 )
 
 type MediaAnnotationController struct {
 	BaseAPIController
-	itunes itunesbridge.ItunesControl
-	mfRepo domain.MediaFileRepository
+	scrobbler engine.Scrobbler
 }
 
 func (c *MediaAnnotationController) Prepare() {
-	utils.ResolveDependencies(&c.itunes, &c.mfRepo)
+	utils.ResolveDependencies(&c.scrobbler)
 }
 
 func (c *MediaAnnotationController) Scrobble() {
 	id := c.RequiredParamString("id", "Required id parameter is missing")
 	time := c.ParamTime("time", time.Now())
-	submission := c.ParamBool("submission", true)
-
+	submission := c.ParamBool("submission", false)
+	println(submission)
 	if submission {
-		mf, err := c.mfRepo.Get(id)
-		if err != nil || mf == nil {
-			beego.Error("Id", id, "not found!")
-			c.SendError(responses.ERROR_DATA_NOT_FOUND, "Id not found")
-		}
-
-		beego.Info(fmt.Sprintf(`Scrobbling (%s) "%s" at %v`, id, mf.Title, time))
-		if err := c.itunes.Scrobble(id, time); err != nil {
+		mf, err := c.scrobbler.Register(id, time, true)
+		if err != nil {
 			beego.Error("Error scrobbling:", err)
 			c.SendError(responses.ERROR_GENERIC, "Internal error")
 		}
+		beego.Info(fmt.Sprintf(`Scrobbled (%s) "%s" at %v`, id, mf.Title, time))
 	}
 
 	response := c.NewEmpty()
diff --git a/api/stream_test.go b/api/stream_test.go
index c704fbccb..1f9d7b2a9 100644
--- a/api/stream_test.go
+++ b/api/stream_test.go
@@ -3,16 +3,17 @@ package api_test
 import (
 	"testing"
 
-	"github.com/deluan/gosonic/api/responses"
-	"github.com/deluan/gosonic/domain"
-	. "github.com/deluan/gosonic/tests"
-	"github.com/deluan/gosonic/tests/mocks"
-	"github.com/deluan/gosonic/utils"
-	. "github.com/smartystreets/goconvey/convey"
+	"fmt"
 	"net/http"
 	"net/http/httptest"
+
 	"github.com/astaxie/beego"
-	"fmt"
+	"github.com/deluan/gosonic/api/responses"
+	"github.com/deluan/gosonic/domain"
+	"github.com/deluan/gosonic/persistence"
+	. "github.com/deluan/gosonic/tests"
+	"github.com/deluan/gosonic/utils"
+	. "github.com/smartystreets/goconvey/convey"
 )
 
 func stream(params ...string) (*http.Request, *httptest.ResponseRecorder) {
@@ -27,7 +28,7 @@ func stream(params ...string) (*http.Request, *httptest.ResponseRecorder) {
 func TestStream(t *testing.T) {
 	Init(t, false)
 
-	mockMediaFileRepo := mocks.CreateMockMediaFileRepo()
+	mockMediaFileRepo := persistence.CreateMockMediaFileRepo()
 	utils.DefineSingleton(new(domain.MediaFileRepository), func() domain.MediaFileRepository {
 		return mockMediaFileRepo
 	})
diff --git a/conf/inject_definitions.go b/conf/inject_definitions.go
index 0ccd7eed9..c38718a6e 100644
--- a/conf/inject_definitions.go
+++ b/conf/inject_definitions.go
@@ -27,6 +27,7 @@ func init() {
 	utils.DefineSingleton(new(engine.Cover), engine.NewCover)
 	utils.DefineSingleton(new(engine.Playlists), engine.NewPlaylists)
 	utils.DefineSingleton(new(engine.Search), engine.NewSearch)
+	utils.DefineSingleton(new(engine.Scrobbler), engine.NewScrobbler)
 
 	utils.DefineSingleton(new(scanner.CheckSumRepository), persistence.NewCheckSumRepository)
 	utils.DefineSingleton(new(scanner.Scanner), scanner.NewItunesScanner)
diff --git a/engine/cover_test.go b/engine/cover_test.go
index 3d9dfdf25..073be3f02 100644
--- a/engine/cover_test.go
+++ b/engine/cover_test.go
@@ -7,15 +7,15 @@ import (
 	"image"
 
 	"github.com/deluan/gosonic/engine"
+	"github.com/deluan/gosonic/persistence"
 	. "github.com/deluan/gosonic/tests"
-	"github.com/deluan/gosonic/tests/mocks"
 	. "github.com/smartystreets/goconvey/convey"
 )
 
 func TestCover(t *testing.T) {
 	Init(t, false)
 
-	mockMediaFileRepo := mocks.CreateMockMediaFileRepo()
+	mockMediaFileRepo := persistence.CreateMockMediaFileRepo()
 
 	cover := engine.NewCover(mockMediaFileRepo)
 	out := new(bytes.Buffer)
diff --git a/tests/mocks/mock_property_repo.go b/engine/mock_property_repo.go
similarity index 89%
rename from tests/mocks/mock_property_repo.go
rename to engine/mock_property_repo.go
index 9ba5c6869..f35f92b64 100644
--- a/tests/mocks/mock_property_repo.go
+++ b/engine/mock_property_repo.go
@@ -1,9 +1,7 @@
-package mocks
+package engine
 
 import (
 	"errors"
-
-	"github.com/deluan/gosonic/engine"
 )
 
 func CreateMockPropertyRepo() *MockProperty {
@@ -11,7 +9,7 @@ func CreateMockPropertyRepo() *MockProperty {
 }
 
 type MockProperty struct {
-	engine.PropertyRepository
+	PropertyRepository
 	data map[string]string
 	err  bool
 }
diff --git a/engine/scrobbler.go b/engine/scrobbler.go
new file mode 100644
index 000000000..3347fcac9
--- /dev/null
+++ b/engine/scrobbler.go
@@ -0,0 +1,41 @@
+package engine
+
+import (
+	"errors"
+	"fmt"
+	"time"
+
+	"github.com/deluan/gosonic/domain"
+	"github.com/deluan/gosonic/itunesbridge"
+)
+
+type Scrobbler interface {
+	Register(id string, playDate time.Time, submit bool) (*domain.MediaFile, error)
+}
+
+func NewScrobbler(itunes itunesbridge.ItunesControl, mr domain.MediaFileRepository) Scrobbler {
+	return scrobbler{itunes, mr}
+}
+
+type scrobbler struct {
+	itunes itunesbridge.ItunesControl
+	mfRepo domain.MediaFileRepository
+}
+
+func (s scrobbler) Register(id string, playDate time.Time, submit bool) (*domain.MediaFile, error) {
+	mf, err := s.mfRepo.Get(id)
+	if err != nil {
+		return nil, err
+	}
+
+	if mf == nil {
+		return nil, errors.New(fmt.Sprintf(`Id "%s" not found`, id))
+	}
+
+	if submit {
+		if err := s.itunes.MarkAsPlayed(id, playDate); err != nil {
+			return nil, err
+		}
+	}
+	return mf, nil
+}
diff --git a/engine/scrobbler_test.go b/engine/scrobbler_test.go
new file mode 100644
index 000000000..d7bea3358
--- /dev/null
+++ b/engine/scrobbler_test.go
@@ -0,0 +1,74 @@
+package engine_test
+
+import (
+	"testing"
+	"time"
+
+	"github.com/deluan/gosonic/engine"
+	"github.com/deluan/gosonic/itunesbridge"
+	"github.com/deluan/gosonic/persistence"
+	. "github.com/deluan/gosonic/tests"
+	. "github.com/smartystreets/goconvey/convey"
+	"github.com/syndtr/goleveldb/leveldb/errors"
+)
+
+func TestScrobbler(t *testing.T) {
+
+	Init(t, false)
+
+	mfRepo := persistence.CreateMockMediaFileRepo()
+	itCtrl := &mockItunesControl{}
+
+	scrobbler := engine.NewScrobbler(itCtrl, mfRepo)
+
+	Convey("Given a DB with one song", t, func() {
+		mfRepo.SetData(`[{"Id":"2","Title":"Hands Of Time"}]`, 1)
+
+		Convey("When I scrobble an existing song", func() {
+			now := time.Now()
+			mf, err := scrobbler.Register("2", now, true)
+
+			Convey("Then I get the scrobbled song back", func() {
+				So(err, ShouldBeNil)
+				So(mf.Title, ShouldEqual, "Hands Of Time")
+			})
+
+			Convey("And iTunes is notified", func() {
+				So(itCtrl.played, ShouldContainKey, "2")
+				So(itCtrl.played["2"].Equal(now), ShouldBeTrue)
+			})
+
+		})
+
+		Convey("When the ID is not in the DB", func() {
+			_, err := scrobbler.Register("3", time.Now(), true)
+
+			Convey("Then I receive an error", func() {
+				So(err, ShouldNotBeNil)
+			})
+
+			Convey("And iTunes is not notified", func() {
+				So(itCtrl.played, ShouldNotContainKey, "3")
+			})
+		})
+
+	})
+
+}
+
+type mockItunesControl struct {
+	itunesbridge.ItunesControl
+	played map[string]time.Time
+	error  bool
+}
+
+func (m *mockItunesControl) MarkAsPlayed(id string, playDate time.Time) error {
+	if m.error {
+		return errors.New("ID not found")
+	}
+	if m.played == nil {
+		m.played = make(map[string]time.Time)
+	}
+	m.played[id] = playDate
+	return nil
+}
diff --git a/itunesbridge/itunes.go b/itunesbridge/itunes.go
index 29e528942..57b26b51d 100644
--- a/itunesbridge/itunes.go
+++ b/itunesbridge/itunes.go
@@ -6,16 +6,16 @@ import (
 )
 
 type ItunesControl interface {
-	Scrobble(id string, playDate time.Time) error
+	MarkAsPlayed(id string, playDate time.Time) error
 }
 
 func NewItunesControl() ItunesControl {
-	return itunesControl{}
+	return &itunesControl{}
 }
 
 type itunesControl struct{}
 
-func (c itunesControl) Scrobble(id string, playDate time.Time) error {
+func (c *itunesControl) MarkAsPlayed(id string, playDate time.Time) error {
 	script := Script{fmt.Sprintf(
 		`set theTrack to the first item of (every track whose database ID is equal to "%s")`, id),
 		`set c to (get played count of theTrack)`,
@@ -26,6 +26,6 @@ func (c itunesControl) Scrobble(id string, playDate time.Time) error {
 	return script.Run()
 }
 
-func (c itunesControl) formatDateTime(d time.Time) string {
+func (c *itunesControl) formatDateTime(d time.Time) string {
 	return d.Format("Jan _2, 2006 3:04PM")
 }
diff --git a/tests/mocks/mock_album_repo.go b/persistence/mock_album_repo.go
similarity index 98%
rename from tests/mocks/mock_album_repo.go
rename to persistence/mock_album_repo.go
index 87ef40d80..c85d2c6a9 100644
--- a/tests/mocks/mock_album_repo.go
+++ b/persistence/mock_album_repo.go
@@ -1,4 +1,4 @@
-package mocks
+package persistence
 
 import (
 	"encoding/json"
diff --git a/tests/mocks/mock_artist_repo.go b/persistence/mock_artist_repo.go
similarity index 97%
rename from tests/mocks/mock_artist_repo.go
rename to persistence/mock_artist_repo.go
index 2d97fd71d..5a45abe3f 100644
--- a/tests/mocks/mock_artist_repo.go
+++ b/persistence/mock_artist_repo.go
@@ -1,4 +1,4 @@
-package mocks
+package persistence
 
 import (
 	"encoding/json"
diff --git a/tests/mocks/mock_index_repo.go b/persistence/mock_index_repo.go
similarity index 97%
rename from tests/mocks/mock_index_repo.go
rename to persistence/mock_index_repo.go
index b6f7debc8..36ef87242 100644
--- a/tests/mocks/mock_index_repo.go
+++ b/persistence/mock_index_repo.go
@@ -1,4 +1,4 @@
-package mocks
+package persistence
 
 import (
 	"encoding/json"
diff --git a/tests/mocks/mock_mediafile_repo.go b/persistence/mock_mediafile_repo.go
similarity index 98%
rename from tests/mocks/mock_mediafile_repo.go
rename to persistence/mock_mediafile_repo.go
index 559318a2d..28f57b14c 100644
--- a/tests/mocks/mock_mediafile_repo.go
+++ b/persistence/mock_mediafile_repo.go
@@ -1,4 +1,4 @@
-package mocks
+package persistence
 
 import (
 	"encoding/json"