diff --git a/resources/lib/api.py b/resources/lib/api.py
index d0ad8594..cc639408 100644
--- a/resources/lib/api.py
+++ b/resources/lib/api.py
@@ -37,15 +37,6 @@ class API(object):
         else:
             favorite = userdata['IsFavorite']
             likes = userdata.get('Likes')
-            # Userrating is based on likes and favourite
-            if favorite:
-                user_rating = 5
-            elif likes:
-                user_rating = 3
-            elif likes is False:
-                user_rating = 0
-            else:
-                user_rating = 1
 
             last_played = userdata.get('LastPlayedDate')
             if last_played:
@@ -72,8 +63,7 @@ class API(object):
             'PlayCount': playcount,
             'Played': played,
             'LastPlayedDate': last_played,
-            'Resume': resume,
-            'UserRating': user_rating
+            'Resume': resume
         }
 
     def get_people(self):
diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py
index 4ecaa1f3..90877379 100644
--- a/resources/lib/entrypoint.py
+++ b/resources/lib/entrypoint.py
@@ -548,7 +548,7 @@ def refreshPlaylist():
                 sound=False)
 
     except Exception as e:
-        log.error("Refresh playlists/nodes failed: %s" % e)
+        log.exception("Refresh playlists/nodes failed: %s" % e)
         dialog.notification(
             heading=lang(29999),
             message=lang(33070),
@@ -698,7 +698,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
             playcount = 0
             
         rating = item.get('CommunityRating')
-        if not rating: rating = userdata['UserRating']
+        if not rating: rating = 0
 
         # Populate the extradata list and artwork
         extradata = {
diff --git a/resources/lib/kodidb_functions.py b/resources/lib/kodidb_functions.py
index fe76b5e2..fc6cdb12 100644
--- a/resources/lib/kodidb_functions.py
+++ b/resources/lib/kodidb_functions.py
@@ -25,769 +25,6 @@ class Kodidb_Functions():
         self.cursor = cursor
         
         self.artwork = artwork.Artwork()
-        
-
-    def addPath(self, path):
-
-        query = ' '.join((
-
-            "SELECT idPath",
-            "FROM path",
-            "WHERE strPath = ?"
-        ))
-        self.cursor.execute(query, (path,))
-        try:
-            pathid = self.cursor.fetchone()[0]
-        except TypeError:
-            self.cursor.execute("select coalesce(max(idPath),0) from path")
-            pathid = self.cursor.fetchone()[0] + 1
-            query = (
-                '''
-                INSERT INTO path(
-                    idPath, strPath)
-
-                VALUES (?, ?)
-                '''
-            )
-            self.cursor.execute(query, (pathid, path))
-
-        return pathid
-
-    def getPath(self, path):
-
-        query = ' '.join((
-
-            "SELECT idPath",
-            "FROM path",
-            "WHERE strPath = ?"
-        ))
-        self.cursor.execute(query, (path,))
-        try:
-            pathid = self.cursor.fetchone()[0]
-        except TypeError:
-            pathid = None
-
-        return pathid
-
-    def addFile(self, filename, pathid):
-
-        query = ' '.join((
-
-            "SELECT idFile",
-            "FROM files",
-            "WHERE strFilename = ?",
-            "AND idPath = ?"
-        ))
-        self.cursor.execute(query, (filename, pathid,))
-        try:
-            fileid = self.cursor.fetchone()[0]
-        except TypeError:
-            self.cursor.execute("select coalesce(max(idFile),0) from files")
-            fileid = self.cursor.fetchone()[0] + 1
-            query = (
-                '''
-                INSERT INTO files(
-                    idFile, strFilename)
-
-                VALUES (?, ?)
-                '''
-            )
-            self.cursor.execute(query, (fileid, filename))
-
-        return fileid
-
-    def getFile(self, fileid):
-
-        query = ' '.join((
-
-            "SELECT strFilename",
-            "FROM files",
-            "WHERE idFile = ?"
-        ))
-        self.cursor.execute(query, (fileid,))
-        try:
-            filename = self.cursor.fetchone()[0]
-        except TypeError:
-            filename = ""
-
-        return filename
-
-    def removeFile(self, path, filename):
-        
-        pathid = self.getPath(path)
-
-        if pathid is not None:
-            query = ' '.join((
-
-                "DELETE FROM files",
-                "WHERE idPath = ?",
-                "AND strFilename = ?"
-            ))
-            self.cursor.execute(query, (pathid, filename,))
-
-    def addCountries(self, kodiid, countries, mediatype):
-        
-        if self.kodiversion in (15, 16, 17):
-            # Kodi Isengard, Jarvis, Krypton
-            for country in countries:
-                query = ' '.join((
-
-                    "SELECT country_id",
-                    "FROM country",
-                    "WHERE name = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (country,))
-
-                try:
-                    country_id = self.cursor.fetchone()[0]
-
-                except TypeError:
-                    # Country entry does not exists
-                    self.cursor.execute("select coalesce(max(country_id),0) from country")
-                    country_id = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO country(country_id, name) values(?, ?)"
-                    self.cursor.execute(query, (country_id, country))
-                    log.debug("Add country to media, processing: %s" % country)
-
-                finally: # Assign country to content
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO country_link(
-                            country_id, media_id, media_type)
-                        
-                        VALUES (?, ?, ?)
-                        '''
-                    )
-                    self.cursor.execute(query, (country_id, kodiid, mediatype))
-        else:
-            # Kodi Helix
-            for country in countries:
-                query = ' '.join((
-
-                    "SELECT idCountry",
-                    "FROM country",
-                    "WHERE strCountry = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (country,))
-
-                try:
-                    idCountry = self.cursor.fetchone()[0]
-                
-                except TypeError:
-                    # Country entry does not exists
-                    self.cursor.execute("select coalesce(max(idCountry),0) from country")
-                    idCountry = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO country(idCountry, strCountry) values(?, ?)"
-                    self.cursor.execute(query, (idCountry, country))
-                    log.debug("Add country to media, processing: %s" % country)
-                
-                finally:
-                    # Only movies have a country field
-                    if "movie" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO countrylinkmovie(
-                                idCountry, idMovie)
-
-                            VALUES (?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (idCountry, kodiid))
-
-    def addPeople(self, kodiid, people, mediatype):
-        
-        castorder = 1
-        for person in people:
-
-            name = person['Name']
-            person_type = person['Type']
-            thumb = person['imageurl']
-            
-            # Kodi Isengard, Jarvis, Krypton
-            if self.kodiversion in (15, 16, 17):
-                query = ' '.join((
-
-                    "SELECT actor_id",
-                    "FROM actor",
-                    "WHERE name = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (name,))
-                
-                try:
-                    actorid = self.cursor.fetchone()[0]
-
-                except TypeError:
-                    # Cast entry does not exists
-                    self.cursor.execute("select coalesce(max(actor_id),0) from actor")
-                    actorid = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO actor(actor_id, name) values(?, ?)"
-                    self.cursor.execute(query, (actorid, name))
-                    log.debug("Add people to media, processing: %s" % name)
-
-                finally:
-                    # Link person to content
-                    if "Actor" in person_type:
-                        role = person.get('Role')
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO actor_link(
-                                actor_id, media_id, media_type, role, cast_order)
-
-                            VALUES (?, ?, ?, ?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (actorid, kodiid, mediatype, role, castorder))
-                        castorder += 1
-                    
-                    elif "Director" in person_type:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO director_link(
-                                actor_id, media_id, media_type)
-
-                            VALUES (?, ?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (actorid, kodiid, mediatype))
-                    
-                    elif person_type in ("Writing", "Writer"):
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO writer_link(
-                                actor_id, media_id, media_type)
-
-                            VALUES (?, ?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (actorid, kodiid, mediatype))
-
-                    elif "Artist" in person_type:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO actor_link(
-                                actor_id, media_id, media_type)
-                            
-                            VALUES (?, ?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (actorid, kodiid, mediatype))
-            # Kodi Helix
-            else:
-                query = ' '.join((
-
-                    "SELECT idActor",
-                    "FROM actors",
-                    "WHERE strActor = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (name,))
-                
-                try:
-                    actorid = self.cursor.fetchone()[0]
-
-                except TypeError:
-                    # Cast entry does not exists
-                    self.cursor.execute("select coalesce(max(idActor),0) from actors")
-                    actorid = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO actors(idActor, strActor) values(?, ?)"
-                    self.cursor.execute(query, (actorid, name))
-                    log.debug("Add people to media, processing: %s" % name)
-
-                finally:
-                    # Link person to content
-                    if "Actor" in person_type:
-                        role = person.get('Role')
-
-                        if "movie" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO actorlinkmovie(
-                                    idActor, idMovie, strRole, iOrder)
-
-                                VALUES (?, ?, ?, ?)
-                                '''
-                            )
-                        elif "tvshow" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO actorlinktvshow(
-                                    idActor, idShow, strRole, iOrder)
-
-                                VALUES (?, ?, ?, ?)
-                                '''
-                            )
-                        elif "episode" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO actorlinkepisode(
-                                    idActor, idEpisode, strRole, iOrder)
-
-                                VALUES (?, ?, ?, ?)
-                                '''
-                            )
-                        else: return # Item is invalid
-                            
-                        self.cursor.execute(query, (actorid, kodiid, role, castorder))
-                        castorder += 1
-
-                    elif "Director" in person_type:
-                        if "movie" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO directorlinkmovie(
-                                    idDirector, idMovie)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-                        elif "tvshow" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO directorlinktvshow(
-                                    idDirector, idShow)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-                        elif "musicvideo" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO directorlinkmusicvideo(
-                                    idDirector, idMVideo)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-
-                        elif "episode" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO directorlinkepisode(
-                                    idDirector, idEpisode)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-                        else: return # Item is invalid
-
-                        self.cursor.execute(query, (actorid, kodiid))
-
-                    elif person_type in ("Writing", "Writer"):
-                        if "movie" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO writerlinkmovie(
-                                    idWriter, idMovie)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-                        elif "episode" in mediatype:
-                            query = (
-                                '''
-                                INSERT OR REPLACE INTO writerlinkepisode(
-                                    idWriter, idEpisode)
-
-                                VALUES (?, ?)
-                                '''
-                            )
-                        else: return # Item is invalid
-                            
-                        self.cursor.execute(query, (actorid, kodiid))
-
-                    elif "Artist" in person_type:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO artistlinkmusicvideo(
-                                idArtist, idMVideo)
-                            
-                            VALUES (?, ?)
-                            '''
-                        )
-                        self.cursor.execute(query, (actorid, kodiid))
-
-            # Add person image to art table
-            if thumb:
-                arttype = person_type.lower()
-
-                if "writing" in arttype:
-                    arttype = "writer"
-
-                self.artwork.add_update_art(thumb, actorid, arttype, "thumb", self.cursor)
-
-    def addGenres(self, kodiid, genres, mediatype):
-
-        
-        # Kodi Isengard, Jarvis, Krypton
-        if self.kodiversion in (15, 16, 17):
-            # Delete current genres for clean slate
-            query = ' '.join((
-
-                "DELETE FROM genre_link",
-                "WHERE media_id = ?",
-                "AND media_type = ?"
-            ))
-            self.cursor.execute(query, (kodiid, mediatype,))
-
-            # Add genres
-            for genre in genres:
-                
-                query = ' '.join((
-
-                    "SELECT genre_id",
-                    "FROM genre",
-                    "WHERE name = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (genre,))
-                
-                try:
-                    genre_id = self.cursor.fetchone()[0]
-                
-                except TypeError:
-                    # Create genre in database
-                    self.cursor.execute("select coalesce(max(genre_id),0) from genre")
-                    genre_id = self.cursor.fetchone()[0] + 1
-                    
-                    query = "INSERT INTO genre(genre_id, name) values(?, ?)"
-                    self.cursor.execute(query, (genre_id, genre))
-                    log.debug("Add Genres to media, processing: %s" % genre)
-                
-                finally:
-                    # Assign genre to item
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO genre_link(
-                            genre_id, media_id, media_type)
-
-                        VALUES (?, ?, ?)
-                        '''
-                    )
-                    self.cursor.execute(query, (genre_id, kodiid, mediatype))
-        else:
-            # Kodi Helix
-            # Delete current genres for clean slate
-            if "movie" in mediatype:
-                self.cursor.execute("DELETE FROM genrelinkmovie WHERE idMovie = ?", (kodiid,))
-            elif "tvshow" in mediatype:
-                self.cursor.execute("DELETE FROM genrelinktvshow WHERE idShow = ?", (kodiid,))
-            elif "musicvideo" in mediatype:
-                self.cursor.execute("DELETE FROM genrelinkmusicvideo WHERE idMVideo = ?", (kodiid,))
-
-            # Add genres
-            for genre in genres:
-
-                query = ' '.join((
-
-                    "SELECT idGenre",
-                    "FROM genre",
-                    "WHERE strGenre = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (genre,))
-                
-                try:
-                    idGenre = self.cursor.fetchone()[0]
-                
-                except TypeError:
-                    # Create genre in database
-                    self.cursor.execute("select coalesce(max(idGenre),0) from genre")
-                    idGenre = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
-                    self.cursor.execute(query, (idGenre, genre))
-                    log.debug("Add Genres to media, processing: %s" % genre)
-                
-                finally:
-                    # Assign genre to item
-                    if "movie" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE into genrelinkmovie(
-                                idGenre, idMovie)
-
-                            VALUES (?, ?)
-                            '''
-                        )
-                    elif "tvshow" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE into genrelinktvshow(
-                                idGenre, idShow)
-
-                            VALUES (?, ?)
-                            '''
-                        )
-                    elif "musicvideo" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE into genrelinkmusicvideo(
-                                idGenre, idMVideo)
-
-                            VALUES (?, ?)
-                            '''
-                        )
-                    else: return # Item is invalid
-                        
-                    self.cursor.execute(query, (idGenre, kodiid))
-
-    def addStudios(self, kodiid, studios, mediatype):
-
-        for studio in studios:
-
-            if self.kodiversion in (15, 16, 17):
-                # Kodi Isengard, Jarvis, Krypton
-                query = ' '.join((
-
-                    "SELECT studio_id",
-                    "FROM studio",
-                    "WHERE name = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (studio,))
-                try:
-                    studioid = self.cursor.fetchone()[0]
-                
-                except TypeError:
-                    # Studio does not exists.
-                    self.cursor.execute("select coalesce(max(studio_id),0) from studio")
-                    studioid = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO studio(studio_id, name) values(?, ?)"
-                    self.cursor.execute(query, (studioid, studio))
-                    log.debug("Add Studios to media, processing: %s" % studio)
-
-                finally: # Assign studio to item
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO studio_link(
-                            studio_id, media_id, media_type)
-                        
-                        VALUES (?, ?, ?)
-                        ''')
-                    self.cursor.execute(query, (studioid, kodiid, mediatype))
-            else:
-                # Kodi Helix
-                query = ' '.join((
-
-                    "SELECT idstudio",
-                    "FROM studio",
-                    "WHERE strstudio = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (studio,))
-                try:
-                    studioid = self.cursor.fetchone()[0]
-
-                except TypeError:
-                    # Studio does not exists.
-                    self.cursor.execute("select coalesce(max(idstudio),0) from studio")
-                    studioid = self.cursor.fetchone()[0] + 1
-
-                    query = "INSERT INTO studio(idstudio, strstudio) values(?, ?)"
-                    self.cursor.execute(query, (studioid, studio))
-                    log.debug("Add Studios to media, processing: %s" % studio)
-
-                finally: # Assign studio to item
-                    if "movie" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO studiolinkmovie(idstudio, idMovie) 
-                            VALUES (?, ?)
-                            ''')
-                    elif "musicvideo" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO studiolinkmusicvideo(idstudio, idMVideo) 
-                            VALUES (?, ?)
-                            ''')
-                    elif "tvshow" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO studiolinktvshow(idstudio, idShow) 
-                            VALUES (?, ?)
-                            ''')
-                    elif "episode" in mediatype:
-                        query = (
-                            '''
-                            INSERT OR REPLACE INTO studiolinkepisode(idstudio, idEpisode) 
-                            VALUES (?, ?)
-                            ''')
-                    self.cursor.execute(query, (studioid, kodiid))
-
-    def addStreams(self, fileid, streamdetails, runtime):
-        
-        # First remove any existing entries
-        self.cursor.execute("DELETE FROM streamdetails WHERE idFile = ?", (fileid,))
-        if streamdetails:
-            # Video details
-            for videotrack in streamdetails['video']:
-                query = (
-                    '''
-                    INSERT INTO streamdetails(
-                        idFile, iStreamType, strVideoCodec, fVideoAspect, 
-                        iVideoWidth, iVideoHeight, iVideoDuration ,strStereoMode)
-                    
-                    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (fileid, 0, videotrack['codec'],
-                    videotrack['aspect'], videotrack['width'], videotrack['height'],
-                    runtime ,videotrack['video3DFormat']))
-            
-            # Audio details
-            for audiotrack in streamdetails['audio']:
-                query = (
-                    '''
-                    INSERT INTO streamdetails(
-                        idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage)
-                    
-                    VALUES (?, ?, ?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (fileid, 1, audiotrack['codec'],
-                    audiotrack['channels'], audiotrack['language']))
-
-            # Subtitles details
-            for subtitletrack in streamdetails['subtitle']:
-                query = (
-                    '''
-                    INSERT INTO streamdetails(
-                        idFile, iStreamType, strSubtitleLanguage)
-
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (fileid, 2, subtitletrack))
-
-    def addPlaystate(self, fileid, resume_seconds, total_seconds, playcount, dateplayed):
-        
-        # Delete existing resume point
-        query = ' '.join((
-
-            "DELETE FROM bookmark",
-            "WHERE idFile = ?"
-        ))
-        self.cursor.execute(query, (fileid,))
-        
-        # Set watched count
-        query = ' '.join((
-
-            "UPDATE files",
-            "SET playCount = ?, lastPlayed = ?",
-            "WHERE idFile = ?"
-        ))
-        self.cursor.execute(query, (playcount, dateplayed, fileid))
-        
-        # Set the resume bookmark
-        if resume_seconds:
-            self.cursor.execute("select coalesce(max(idBookmark),0) from bookmark")
-            bookmarkId =  self.cursor.fetchone()[0] + 1
-            query = (
-                '''
-                INSERT INTO bookmark(
-                    idBookmark, idFile, timeInSeconds, totalTimeInSeconds, player, type)
-                
-                VALUES (?, ?, ?, ?, ?, ?)
-                '''
-            )
-            self.cursor.execute(query, (bookmarkId, fileid, resume_seconds, total_seconds,
-                "DVDPlayer", 1))
-
-    def addTags(self, kodiid, tags, mediatype):
-        
-        # First, delete any existing tags associated to the id
-        if self.kodiversion in (15, 16, 17):
-            # Kodi Isengard, Jarvis, Krypton
-            query = ' '.join((
-
-                "DELETE FROM tag_link",
-                "WHERE media_id = ?",
-                "AND media_type = ?"
-            ))
-            self.cursor.execute(query, (kodiid, mediatype))
-        else:
-            # Kodi Helix
-            query = ' '.join((
-
-                "DELETE FROM taglinks",
-                "WHERE idMedia = ?",
-                "AND media_type = ?"
-            ))
-            self.cursor.execute(query, (kodiid, mediatype))
-    
-        # Add tags
-        log.debug("Adding Tags: %s" % tags)
-        for tag in tags:
-            self.addTag(kodiid, tag, mediatype)
-
-    def addTag(self, kodiid, tag, mediatype):
-
-        if self.kodiversion in (15, 16, 17):
-            # Kodi Isengard, Jarvis, Krypton
-            query = ' '.join((
-
-                "SELECT tag_id",
-                "FROM tag",
-                "WHERE name = ?",
-                "COLLATE NOCASE"
-            ))
-            self.cursor.execute(query, (tag,))
-            try:
-                tag_id = self.cursor.fetchone()[0]
-            
-            except TypeError:
-                # Create the tag, because it does not exist
-                tag_id = self.createTag(tag)
-                log.debug("Adding tag: %s" % tag)
-
-            finally:
-                # Assign tag to item
-                query = (
-                    '''
-                    INSERT OR REPLACE INTO tag_link(
-                        tag_id, media_id, media_type)
-                    
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (tag_id, kodiid, mediatype))
-        else:
-            # Kodi Helix
-            query = ' '.join((
-
-                "SELECT idTag",
-                "FROM tag",
-                "WHERE strTag = ?",
-                "COLLATE NOCASE"
-            ))
-            self.cursor.execute(query, (tag,))
-            try:
-                tag_id = self.cursor.fetchone()[0]
-            
-            except TypeError:
-                # Create the tag
-                tag_id = self.createTag(tag)
-                log.debug("Adding tag: %s" % tag)
-            
-            finally:
-                # Assign tag to item
-                query = (
-                    '''
-                    INSERT OR REPLACE INTO taglinks(
-                        idTag, idMedia, media_type)
-                    
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (tag_id, kodiid, mediatype))
 
     def createTag(self, name):
         
@@ -836,7 +73,7 @@ class Kodidb_Functions():
         return tag_id
 
     def updateTag(self, oldtag, newtag, kodiid, mediatype):
-
+        # TODO: Move to video nodes eventually
         log.debug("Updating: %s with %s for %s: %s" % (oldtag, newtag, mediatype, kodiid))
         
         if self.kodiversion in (15, 16, 17):
@@ -885,263 +122,3 @@ class Kodidb_Functions():
                     "AND idTag = ?"
                 ))
                 self.cursor.execute(query, (kodiid, mediatype, oldtag,))
-
-    def removeTag(self, kodiid, tagname, mediatype):
-
-        if self.kodiversion in (15, 16, 17):
-            # Kodi Isengard, Jarvis, Krypton
-            query = ' '.join((
-
-                "SELECT tag_id",
-                "FROM tag",
-                "WHERE name = ?",
-                "COLLATE NOCASE"
-            ))
-            self.cursor.execute(query, (tagname,))
-            try:
-                tag_id = self.cursor.fetchone()[0]
-            except TypeError:
-                return
-            else:
-                query = ' '.join((
-
-                    "DELETE FROM tag_link",
-                    "WHERE media_id = ?",
-                    "AND media_type = ?",
-                    "AND tag_id = ?"
-                ))
-                self.cursor.execute(query, (kodiid, mediatype, tag_id,))
-        else:
-            # Kodi Helix
-            query = ' '.join((
-
-                "SELECT idTag",
-                "FROM tag",
-                "WHERE strTag = ?",
-                "COLLATE NOCASE"
-            ))
-            self.cursor.execute(query, (tagname,))
-            try:
-                tag_id = self.cursor.fetchone()[0]
-            except TypeError:
-                return
-            else:
-                query = ' '.join((
-
-                    "DELETE FROM taglinks",
-                    "WHERE idMedia = ?",
-                    "AND media_type = ?",
-                    "AND idTag = ?"
-                ))
-                self.cursor.execute(query, (kodiid, mediatype, tag_id,))
-
-    def createBoxset(self, boxsetname):
-
-        log.debug("Adding boxset: %s" % boxsetname)
-        query = ' '.join((
-
-            "SELECT idSet",
-            "FROM sets",
-            "WHERE strSet = ?",
-            "COLLATE NOCASE"
-        ))
-        self.cursor.execute(query, (boxsetname,))
-        try:
-            setid = self.cursor.fetchone()[0]
-
-        except TypeError:
-            self.cursor.execute("select coalesce(max(idSet),0) from sets")
-            setid = self.cursor.fetchone()[0] + 1
-
-            query = "INSERT INTO sets(idSet, strSet) values(?, ?)"
-            self.cursor.execute(query, (setid, boxsetname))
-
-        return setid
-
-    def assignBoxset(self, setid, movieid):
-        
-        query = ' '.join((
-
-            "UPDATE movie",
-            "SET idSet = ?",
-            "WHERE idMovie = ?"
-        ))
-        self.cursor.execute(query, (setid, movieid,))
-
-    def removefromBoxset(self, movieid):
-
-        query = ' '.join((
-
-            "UPDATE movie",
-            "SET idSet = null",
-            "WHERE idMovie = ?"
-        ))
-        self.cursor.execute(query, (movieid,))
-
-    def addSeason(self, showid, seasonnumber, season_name=None):
-
-        query = ' '.join((
-
-            "SELECT idSeason",
-            "FROM seasons",
-            "WHERE idShow = ?",
-            "AND season = ?"
-        ))
-        self.cursor.execute(query, (showid, seasonnumber,))
-        try:
-            seasonid = self.cursor.fetchone()[0]
-        except TypeError:
-            self.cursor.execute("select coalesce(max(idSeason),0) from seasons")
-            seasonid = self.cursor.fetchone()[0] + 1
-            query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)"
-            self.cursor.execute(query, (seasonid, showid, seasonnumber))
-
-        if self.kodiversion in (16,17) and season_name is not None:
-            query = "UPDATE seasons SET name = ? WHERE idSeason = ?"
-            self.cursor.execute(query, (season_name, seasonid))
-
-        return seasonid
-
-    def addArtist(self, name, musicbrainz):
-
-        query = ' '.join((
-
-            "SELECT idArtist, strArtist",
-            "FROM artist",
-            "WHERE strMusicBrainzArtistID = ?"
-        ))
-        self.cursor.execute(query, (musicbrainz,))
-        try:
-            result = self.cursor.fetchone()
-            artistid = result[0]
-            artistname = result[1]
-
-        except TypeError:
-
-            query = ' '.join((
-
-                "SELECT idArtist",
-                "FROM artist",
-                "WHERE strArtist = ?",
-                "COLLATE NOCASE"
-            ))
-            self.cursor.execute(query, (name,))
-            try:
-                artistid = self.cursor.fetchone()[0]
-            except TypeError:
-                self.cursor.execute("select coalesce(max(idArtist),0) from artist")
-                artistid = self.cursor.fetchone()[0] + 1
-                query = (
-                    '''
-                    INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID)
-
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (artistid, name, musicbrainz))
-        else:
-            if artistname != name:
-                query = "UPDATE artist SET strArtist = ? WHERE idArtist = ?"
-                self.cursor.execute(query, (name, artistid,))
-
-        return artistid
-
-    def addAlbum(self, name, musicbrainz):
-
-        query = ' '.join((
-
-            "SELECT idAlbum",
-            "FROM album",
-            "WHERE strMusicBrainzAlbumID = ?"
-        ))
-        self.cursor.execute(query, (musicbrainz,))
-        try:
-            albumid = self.cursor.fetchone()[0]
-        except TypeError:
-            # Create the album
-            self.cursor.execute("select coalesce(max(idAlbum),0) from album")
-            albumid = self.cursor.fetchone()[0] + 1
-            if self.kodiversion in (15, 16, 17):
-                query = (
-                    '''
-                    INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType)
-
-                    VALUES (?, ?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (albumid, name, musicbrainz, "album"))
-            else: # Helix
-                query = (
-                    '''
-                    INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID)
-
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                self.cursor.execute(query, (albumid, name, musicbrainz))
-
-        return albumid
-
-    def addMusicGenres(self, kodiid, genres, mediatype):
-
-        if mediatype == "album":
-
-            # Delete current genres for clean slate
-            query = ' '.join((
-
-                "DELETE FROM album_genre",
-                "WHERE idAlbum = ?"
-            ))
-            self.cursor.execute(query, (kodiid,))
-
-            for genre in genres:
-                query = ' '.join((
-
-                    "SELECT idGenre",
-                    "FROM genre",
-                    "WHERE strGenre = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (genre,))
-                try:
-                    genreid = self.cursor.fetchone()[0]
-                except TypeError:
-                    # Create the genre
-                    self.cursor.execute("select coalesce(max(idGenre),0) from genre")
-                    genreid = self.cursor.fetchone()[0] + 1
-                    query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
-                    self.cursor.execute(query, (genreid, genre))
-
-                query = "INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) values(?, ?)"
-                self.cursor.execute(query, (genreid, kodiid))
-
-        elif mediatype == "song":
-            
-            # Delete current genres for clean slate
-            query = ' '.join((
-
-                "DELETE FROM song_genre",
-                "WHERE idSong = ?"
-            ))
-            self.cursor.execute(query, (kodiid,))
-
-            for genre in genres:
-                query = ' '.join((
-
-                    "SELECT idGenre",
-                    "FROM genre",
-                    "WHERE strGenre = ?",
-                    "COLLATE NOCASE"
-                ))
-                self.cursor.execute(query, (genre,))
-                try:
-                    genreid = self.cursor.fetchone()[0]
-                except TypeError:
-                    # Create the genre
-                    self.cursor.execute("select coalesce(max(idGenre),0) from genre")
-                    genreid = self.cursor.fetchone()[0] + 1
-                    query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
-                    self.cursor.execute(query, (genreid, genre))
-
-                query = "INSERT OR REPLACE INTO song_genre(idGenre, idSong) values(?, ?)"
-                self.cursor.execute(query, (genreid, kodiid))
\ No newline at end of file
diff --git a/resources/lib/objects/common.py b/resources/lib/objects/_common.py
similarity index 99%
rename from resources/lib/objects/common.py
rename to resources/lib/objects/_common.py
index 60070e01..f4b75d14 100644
--- a/resources/lib/objects/common.py
+++ b/resources/lib/objects/_common.py
@@ -27,7 +27,7 @@ class Items(object):
     total = 0
 
 
-    def __init__(self, **kwargs):
+    def __init__(self):
 
         self.artwork = artwork.Artwork()
         self.emby = embyserver.Read_EmbyServer()
diff --git a/resources/lib/objects/_kodi_common.py b/resources/lib/objects/_kodi_common.py
new file mode 100644
index 00000000..028a0a4f
--- /dev/null
+++ b/resources/lib/objects/_kodi_common.py
@@ -0,0 +1,822 @@
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+
+import logging
+
+import xbmc
+
+import api
+import artwork
+
+##################################################################################################
+
+log = logging.getLogger("EMBY."+__name__)
+
+##################################################################################################
+
+
+class KodiItems(object):
+
+
+    def __init__(self):
+
+        self.artwork = artwork.Artwork()
+        self.kodi_version = int(xbmc.getInfoLabel('System.BuildVersion')[:2])
+
+    def create_entry_path(self):
+        self.cursor.execute("select coalesce(max(idPath),0) from path")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_file(self):
+        self.cursor.execute("select coalesce(max(idFile),0) from files")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_person(self):
+        self.cursor.execute("select coalesce(max(actor_id),0) from actor")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_genre(self):
+        self.cursor.execute("select coalesce(max(genre_id),0) from genre")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_studio(self):
+        self.cursor.execute("select coalesce(max(studio_id),0) from studio")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_bookmark(self):
+        self.cursor.execute("select coalesce(max(idBookmark),0) from bookmark")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_tag(self):
+        self.cursor.execute("select coalesce(max(tag_id),0) from tag")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def add_path(self, path):
+
+        path_id = self.get_path(path)
+        if path_id is None:
+            # Create a new entry
+            path_id = self.create_entry_path()
+            query = (
+                '''
+                INSERT INTO path(idPath, strPath)
+
+                VALUES (?, ?)
+                '''
+            )
+            self.cursor.execute(query, (path_id, path))
+
+        return path_id
+
+    def get_path(self, path):
+
+        query = ' '.join((
+
+            "SELECT idPath",
+            "FROM path",
+            "WHERE strPath = ?"
+        ))
+        self.cursor.execute(query, (path,))
+        try:
+            path_id = self.cursor.fetchone()[0]
+        except TypeError:
+            path_id = None
+
+        return path_id
+
+    def update_path(self, path_id, path, media_type, scraper):
+
+        query = ' '.join((
+
+            "UPDATE path",
+            "SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
+            "WHERE idPath = ?"
+        ))
+        self.cursor.execute(query, (path, media_type, scraper, 1, path_id))
+
+    def remove_path(self, path_id):
+        kodicursor.execute("DELETE FROM path WHERE idPath = ?", (path_id,))
+
+    def add_file(self, filename, path_id):
+
+        query = ' '.join((
+
+            "SELECT idFile",
+            "FROM files",
+            "WHERE strFilename = ?",
+            "AND idPath = ?"
+        ))
+        self.cursor.execute(query, (filename, path_id,))
+        try:
+            file_id = self.cursor.fetchone()[0]
+        except TypeError:
+            # Create a new entry
+            file_id = self.create_entry_file()
+            query = (
+                '''
+                INSERT INTO files(idFile, idPath, strFilename)
+
+                VALUES (?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (file_id, path_id, filename))
+
+        return file_id
+
+    def update_file(self, file_id, filename, path_id, date_added):
+
+        query = ' '.join((
+
+            "UPDATE files",
+            "SET idPath = ?, strFilename = ?, dateAdded = ?",
+            "WHERE idFile = ?"
+        ))
+        self.cursor.execute(query, (path_id, filename, date_added, file_id))
+
+    def remove_file(self, path, filename):
+
+        path_id = self.get_path(path)
+        if path_id is not None:
+
+            query = ' '.join((
+
+                "DELETE FROM files",
+                "WHERE idPath = ?",
+                "AND strFilename = ?"
+            ))
+            self.cursor.execute(query, (path_id, filename,))
+
+    def get_filename(self, file_id):
+
+        query = ' '.join((
+
+            "SELECT strFilename",
+            "FROM files",
+            "WHERE idFile = ?"
+        ))
+        self.cursor.execute(query, (file_id,))
+        try:
+            filename = self.cursor.fetchone()[0]
+        except TypeError:
+            filename = ""
+
+        return filename
+
+    def add_people(self, kodi_id, people, media_type):
+
+        def add_thumbnail(person_id, person, type_):
+    
+            thumbnail = person['imageurl']
+            if thumbnail:
+
+                art = type_.lower()
+                if "writing" in art:
+                    art = "writer"
+
+                self.artwork.add_update_art(thumbnail, person_id, art, "thumb", self.cursor)
+
+        def add_link(link_type, person_id, kodi_id, media_type):
+
+            query = (
+                "INSERT OR REPLACE INTO " + link_type + "(actor_id, media_id, media_type)"
+                "VALUES (?, ?, ?)"
+            )
+            self.cursor.execute(query, (person_id, kodi_id, media_type))
+
+        cast_order = 1
+
+        if self.kodi_version > 14:
+
+            for person in people:
+
+                name = person['Name']
+                type_ = person['Type']
+                person_id = self._get_person(name)
+
+                # Link person to content
+                if type_ == "Actor":
+                    role = person.get('Role')
+                    query = (
+                        '''
+                        INSERT OR REPLACE INTO actor_link(
+                            actor_id, media_id, media_type, role, cast_order)
+
+                        VALUES (?, ?, ?, ?, ?)
+                        '''
+                    )
+                    self.cursor.execute(query, (person_id, kodi_id, media_type, role, cast_order))
+                    cast_order += 1
+                
+                elif type_ == "Director":
+                    add_link("director_link", person_id, kodi_id, media_type)
+                
+                elif type_ in ("Writing", "Writer"):
+                    add_link("writer_link", person_id, kodi_id, media_type)
+
+                elif type_ == "Artist":
+                    add_link("actor_link", person_id, kodi_id, media_type)
+
+                add_thumbnail(person_id, person, type_)
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            for person in people:
+                name = person['Name']
+                type_ = person['Type']
+
+                query = ' '.join((
+
+                    "SELECT idActor",
+                    "FROM actors",
+                    "WHERE strActor = ?",
+                    "COLLATE NOCASE"
+                ))
+                self.cursor.execute(query, (name,))
+
+                try:
+                    person_id = self.cursor.fetchone()[0]
+
+                except TypeError:
+                    # Cast entry does not exists
+                    self.cursor.execute("select coalesce(max(idActor),0) from actors")
+                    person_id = self.cursor.fetchone()[0] + 1
+
+                    query = "INSERT INTO actors(idActor, strActor) values(?, ?)"
+                    self.cursor.execute(query, (person_id, name))
+                    log.debug("Add people to media, processing: %s", name)
+
+                finally:
+                    # Link person to content
+                    if type_ == "Actor":
+                        role = person.get('Role')
+
+                        if media_type == "movie":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO actorlinkmovie(
+                                    idActor, idMovie, strRole, iOrder)
+
+                                VALUES (?, ?, ?, ?)
+                                '''
+                            )
+                        elif media_type == "tvshow":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO actorlinktvshow(
+                                    idActor, idShow, strRole, iOrder)
+
+                                VALUES (?, ?, ?, ?)
+                                '''
+                            )
+                        elif media_type == "episode":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO actorlinkepisode(
+                                    idActor, idEpisode, strRole, iOrder)
+
+                                VALUES (?, ?, ?, ?)
+                                '''
+                            )
+                        else: return # Item is invalid
+                            
+                        self.cursor.execute(query, (person_id, kodi_id, role, cast_order))
+                        cast_order += 1
+
+                    elif type_ == "Director":
+                        if media_type == "movie":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO directorlinkmovie(idDirector, idMovie)
+                                VALUES (?, ?)
+                                '''
+                            )
+                        elif media_type == "tvshow":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO directorlinktvshow(idDirector, idShow)
+                                VALUES (?, ?)
+                                '''
+                            )
+                        elif media_type == "musicvideo":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO directorlinkmusicvideo(idDirector, idMVideo)
+                                VALUES (?, ?)
+                                '''
+                            )
+                        elif media_type == "episode":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO directorlinkepisode(idDirector, idEpisode)
+                                VALUES (?, ?)
+                                '''
+                            )
+                        else: return # Item is invalid
+
+                        self.cursor.execute(query, (person_id, kodi_id))
+
+                    elif type_ in ("Writing", "Writer"):
+                        if media_type == "movie":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO writerlinkmovie(
+                                    idWriter, idMovie)
+
+                                VALUES (?, ?)
+                                '''
+                            )
+                        elif media_type == "episode":
+                            query = (
+                                '''
+                                INSERT OR REPLACE INTO writerlinkepisode(
+                                    idWriter, idEpisode)
+
+                                VALUES (?, ?)
+                                '''
+                            )
+                        else: return # Item is invalid
+                            
+                        self.cursor.execute(query, (person_id, kodi_id))
+
+                    elif type_ == "Artist":
+                        query = (
+                            '''
+                            INSERT OR REPLACE INTO artistlinkmusicvideo(
+                                idArtist, idMVideo)
+                            
+                            VALUES (?, ?)
+                            '''
+                        )
+                        self.cursor.execute(query, (person_id, kodi_id))
+
+                    add_thumbnail(person_id, person, type_)
+    
+    def _add_person(self, name):
+
+        person_id = self.create_entry_person()
+        query = "INSERT INTO actor(actor_id, name) values(?, ?)"
+        self.cursor.execute(query, (person_id, name))
+        log.debug("Add people to media, processing: %s", name)
+
+        return person_id
+
+    def _get_person(self, name):
+
+        query = ' '.join((
+
+            "SELECT actor_id",
+            "FROM actor",
+            "WHERE name = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (name,))
+        
+        try:
+            person_id = self.cursor.fetchone()[0]
+        except TypeError:
+            person_id = self._add_person(name)
+
+        return person_id
+
+    def add_genres(self, kodi_id, genres, media_type):
+
+        if self.kodi_version > 14:
+            # Delete current genres for clean slate
+            query = ' '.join((
+
+                "DELETE FROM genre_link",
+                "WHERE media_id = ?",
+                "AND media_type = ?"
+            ))
+            self.cursor.execute(query, (kodi_id, media_type,))
+
+            # Add genres
+            for genre in genres:
+                
+                genre_id = self._get_genre(genre)
+                query = (
+                    '''
+                    INSERT OR REPLACE INTO genre_link(
+                        genre_id, media_id, media_type)
+
+                    VALUES (?, ?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (genre_id, kodi_id, media_type))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            # Delete current genres for clean slate
+            if media_type == "movie":
+                self.cursor.execute("DELETE FROM genrelinkmovie WHERE idMovie = ?", (kodi_id,))
+            elif media_type == "tvshow":
+                self.cursor.execute("DELETE FROM genrelinktvshow WHERE idShow = ?", (kodi_id,))
+            elif media_type == "musicvideo":
+                self.cursor.execute("DELETE FROM genrelinkmusicvideo WHERE idMVideo = ?", (kodi_id,))
+
+            # Add genres
+            for genre in genres:
+
+                query = ' '.join((
+
+                    "SELECT idGenre",
+                    "FROM genre",
+                    "WHERE strGenre = ?",
+                    "COLLATE NOCASE"
+                ))
+                self.cursor.execute(query, (genre,))
+
+                try:
+                    genre_id = self.cursor.fetchone()[0]
+
+                except TypeError:
+                    # Create genre in database
+                    self.cursor.execute("select coalesce(max(idGenre),0) from genre")
+                    genre_id = self.cursor.fetchone()[0] + 1
+
+                    query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
+                    self.cursor.execute(query, (genre_id, genre))
+                    log.debug("Add Genres to media, processing: %s", genre)
+
+                finally:
+                    # Assign genre to item
+                    if media_type == "movie":
+                        query = (
+                            '''
+                            INSERT OR REPLACE into genrelinkmovie(idGenre, idMovie)
+                            VALUES (?, ?)
+                            '''
+                        )
+                    elif media_type == "tvshow":
+                        query = (
+                            '''
+                            INSERT OR REPLACE into genrelinktvshow(idGenre, idShow)
+                            VALUES (?, ?)
+                            '''
+                        )
+                    elif media_type == "musicvideo":
+                        query = (
+                            '''
+                            INSERT OR REPLACE into genrelinkmusicvideo(idGenre, idMVideo)
+                            VALUES (?, ?)
+                            '''
+                        )
+                    else: return # Item is invalid
+                        
+                    self.cursor.execute(query, (genre_id, kodi_id))
+
+    def _add_genre(self, genre):
+
+        genre_id = self.create_entry_genre()
+        query = "INSERT INTO genre(genre_id, name) values(?, ?)"
+        self.cursor.execute(query, (genre_id, genre))
+        log.debug("Add Genres to media, processing: %s", genre)
+
+        return genre_id
+
+    def _get_genre(self, genre):
+
+        query = ' '.join((
+
+            "SELECT genre_id",
+            "FROM genre",
+            "WHERE name = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (genre,))
+
+        try:
+            genre_id = self.cursor.fetchone()[0]
+        except TypeError:
+            genre_id = self._add_genre(genre)
+
+        return genre_id
+
+    def add_studios(self, kodi_id, studios, media_type):
+
+        if self.kodi_version > 14:
+
+            for studio in studios:
+
+                studio_id = self._get_studio(studio)
+                query = (
+                    '''
+                    INSERT OR REPLACE INTO studio_link(
+                        studio_id, media_id, media_type)
+                    
+                    VALUES (?, ?, ?)
+                    ''')
+                self.cursor.execute(query, (studio_id, kodi_id, media_type))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            for studio in studios:
+
+                query = ' '.join((
+
+                    "SELECT idstudio",
+                    "FROM studio",
+                    "WHERE strstudio = ?",
+                    "COLLATE NOCASE"
+                ))
+                self.cursor.execute(query, (studio,))
+                try:
+                    studio_id = self.cursor.fetchone()[0]
+
+                except TypeError:
+                    # Studio does not exists.
+                    self.cursor.execute("select coalesce(max(idstudio),0) from studio")
+                    studio_id = self.cursor.fetchone()[0] + 1
+
+                    query = "INSERT INTO studio(idstudio, strstudio) values(?, ?)"
+                    self.cursor.execute(query, (studio_id, studio))
+                    log.debug("Add Studios to media, processing: %s", studio)
+
+                finally: # Assign studio to item
+                    if media_type == "movie":
+                        query = (
+                            '''
+                            INSERT OR REPLACE INTO studiolinkmovie(idstudio, idMovie) 
+                            VALUES (?, ?)
+                            ''')
+                    elif media_type == "musicvideo":
+                        query = (
+                            '''
+                            INSERT OR REPLACE INTO studiolinkmusicvideo(idstudio, idMVideo) 
+                            VALUES (?, ?)
+                            ''')
+                    elif media_type == "tvshow":
+                        query = (
+                            '''
+                            INSERT OR REPLACE INTO studiolinktvshow(idstudio, idShow) 
+                            VALUES (?, ?)
+                            ''')
+                    elif media_type == "episode":
+                        query = (
+                            '''
+                            INSERT OR REPLACE INTO studiolinkepisode(idstudio, idEpisode) 
+                            VALUES (?, ?)
+                            ''')
+                    self.cursor.execute(query, (studio_id, kodi_id))
+
+    def _add_studio(self, studio):
+
+        studio_id = self.create_entry_studio()
+        query = "INSERT INTO studio(studio_id, name) values(?, ?)"
+        self.cursor.execute(query, (studio_id, studio))
+        log.debug("Add Studios to media, processing: %s", studio)
+
+        return studio_id
+
+    def _get_studio(self, studio):
+
+        query = ' '.join((
+
+            "SELECT studio_id",
+            "FROM studio",
+            "WHERE name = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (studio,))
+        try:
+            studio_id = self.cursor.fetchone()[0]
+        except TypeError:
+            studio_id = self._add_studio(studio)
+
+        return studio_id
+
+    def add_streams(self, file_id, streams, runtime):
+        # First remove any existing entries
+        self.cursor.execute("DELETE FROM streamdetails WHERE idFile = ?", (file_id,))
+        if streams:
+            # Video details
+            for track in streams['video']:
+                query = (
+                    '''
+                    INSERT INTO streamdetails(
+                        idFile, iStreamType, strVideoCodec, fVideoAspect, 
+                        iVideoWidth, iVideoHeight, iVideoDuration ,strStereoMode)
+
+                    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (file_id, 0, track['codec'], track['aspect'],
+                                            track['width'], track['height'], runtime,
+                                            track['video3DFormat']))
+            # Audio details
+            for track in streams['audio']:
+                query = (
+                    '''
+                    INSERT INTO streamdetails(
+                        idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage)
+
+                    VALUES (?, ?, ?, ?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (file_id, 1, track['codec'], track['channels'],
+                                            track['language']))
+            # Subtitles details
+            for track in streams['subtitle']:
+                query = (
+                    '''
+                    INSERT INTO streamdetails(idFile, iStreamType, strSubtitleLanguage)
+                    VALUES (?, ?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (file_id, 2, track))
+
+    def add_playstate(self, file_id, resume, total, playcount, date_played):
+
+        # Delete existing resume point
+        self.cursor.execute("DELETE FROM bookmark WHERE idFile = ?", (file_id,))
+        # Set watched count
+        self.set_playcount(file_id, playcount, date_played)
+
+        if resume:
+            bookmark_id = self.create_entry_bookmark()
+            query = (
+                '''
+                INSERT INTO bookmark(
+                    idBookmark, idFile, timeInSeconds, totalTimeInSeconds, player, type)
+
+                VALUES (?, ?, ?, ?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (bookmark_id, file_id, resume, total, "DVDPlayer", 1))
+
+    def set_playcount(self, file_id, playcount, date_played):
+
+        query = ' '.join((
+
+            "UPDATE files",
+            "SET playCount = ?, lastPlayed = ?",
+            "WHERE idFile = ?"
+        ))
+        self.cursor.execute(query, (playcount, date_played, file_id))
+
+    def add_tags(self, kodi_id, tags, media_type):
+
+        if self.kodi_version > 14:
+            
+            query = ' '.join((
+
+                "DELETE FROM tag_link",
+                "WHERE media_id = ?",
+                "AND media_type = ?"
+            ))
+            self.cursor.execute(query, (kodi_id, media_type))
+
+            # Add tags
+            log.debug("Adding Tags: %s", tags)
+            for tag in tags:
+                tag_id = self.get_tag(kodi_id, tag, media_type)
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            query = ' '.join((
+
+                "DELETE FROM taglinks",
+                "WHERE idMedia = ?",
+                "AND media_type = ?"
+            ))
+            self.cursor.execute(query, (kodi_id, media_type))
+
+            # Add tags
+            log.debug("Adding Tags: %s", tags)
+            for tag in tags:
+                tag_id = self.get_tag_old(kodi_id, tag, media_type)
+
+    def _add_tag(self, tag):
+
+        tag_id = self.create_entry_tag()
+        query = "INSERT INTO tag(tag_id, name) values(?, ?)"
+        self.cursor.execute(query, (tag_id, tag))
+        log.debug("Create tag_id: %s name: %s", tag_id, tag)
+
+        return tag_id
+
+    def get_tag(self, kodi_id, tag, media_type):
+
+        if self.kodi_version > 14:
+
+            query = ' '.join((
+
+                "SELECT tag_id",
+                "FROM tag",
+                "WHERE name = ?",
+                "COLLATE NOCASE"
+            ))
+            self.cursor.execute(query, (tag,))
+            try:
+                tag_id = self.cursor.fetchone()[0]
+            except TypeError:
+                tag_id = self._add_tag(tag)
+
+            query = (
+                '''
+                INSERT OR REPLACE INTO tag_link(tag_id, media_id, media_type)
+                VALUES (?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (tag_id, kodi_id, media_type))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            tag_id = self.get_tag_old(kodi_id, tag, media_type)
+
+        return tag_id
+
+    def get_tag_old(self, kodi_id, tag, media_type):
+        # TODO: Remove Helix code when Krypton is RC
+        query = ' '.join((
+
+            "SELECT idTag",
+            "FROM tag",
+            "WHERE strTag = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (tag,))
+        try:
+            tag_id = self.cursor.fetchone()[0]
+
+        except TypeError:
+            # Create the tag
+            self.cursor.execute("select coalesce(max(idTag),0) from tag")
+            tag_id = self.cursor.fetchone()[0] + 1
+
+            query = "INSERT INTO tag(idTag, strTag) values(?, ?)"
+            self.cursor.execute(query, (tag_id, name))
+            log.debug("Create idTag: %s name: %s", tag_id, name)
+
+        finally:
+            # Assign tag to item
+            query = (
+                '''
+                INSERT OR REPLACE INTO taglinks(
+                    idTag, idMedia, media_type)
+                
+                VALUES (?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (tag_id, kodi_id, media_type))
+
+        return tag_id
+
+    def remove_tag(self, kodi_id, tag, media_type):
+
+        if self.kodi_version > 14:
+
+            query = ' '.join((
+
+                "SELECT tag_id",
+                "FROM tag",
+                "WHERE name = ?",
+                "COLLATE NOCASE"
+            ))
+            self.cursor.execute(query, (tag,))
+            try:
+                tag_id = self.cursor.fetchone()[0]
+            except TypeError:
+                return
+            else:
+                query = ' '.join((
+
+                    "DELETE FROM tag_link",
+                    "WHERE media_id = ?",
+                    "AND media_type = ?",
+                    "AND tag_id = ?"
+                ))
+                self.cursor.execute(query, (kodi_id, media_type, tag_id,))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            query = ' '.join((
+
+                "SELECT idTag",
+                "FROM tag",
+                "WHERE strTag = ?",
+                "COLLATE NOCASE"
+            ))
+            self.cursor.execute(query, (tag,))
+            try:
+                tag_id = self.cursor.fetchone()[0]
+            except TypeError:
+                return
+            else:
+                query = ' '.join((
+
+                    "DELETE FROM taglinks",
+                    "WHERE idMedia = ?",
+                    "AND media_type = ?",
+                    "AND idTag = ?"
+                ))
+                self.cursor.execute(query, (kodi_id, media_type, tag_id,))
diff --git a/resources/lib/objects/_kodi_movies.py b/resources/lib/objects/_kodi_movies.py
new file mode 100644
index 00000000..38b78922
--- /dev/null
+++ b/resources/lib/objects/_kodi_movies.py
@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+
+import logging
+
+from _kodi_common import KodiItems
+
+##################################################################################################
+
+log = logging.getLogger("EMBY."+__name__)
+
+##################################################################################################
+
+
+class KodiMovies(KodiItems):
+
+
+    def __init__(self, cursor):
+        self.cursor = cursor
+
+        KodiItems.__init__(self)
+
+    def create_entry(self):
+        self.cursor.execute("select coalesce(max(idMovie),0) from movie")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_set(self):
+        self.cursor.execute("select coalesce(max(idSet),0) from sets")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_country(self):
+        self.cursor.execute("select coalesce(max(country_id),0) from country")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def get_movie(self, kodi_id):
+
+        query = "SELECT * FROM movie WHERE idMovie = ?"
+        self.cursor.execute(query, (kodi_id,))
+        try:
+            kodi_id = self.cursor.fetchone()[0]
+        except TypeError:
+            kodi_id = None
+
+        return kodi_id
+
+    def add_movie(self, *args):
+
+        query = (
+            '''
+            INSERT INTO movie(
+                idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07,
+                c09, c10, c11, c12, c14, c15, c16, c18, c19, c21)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def add_movie_17(self, *args):
+        # Create the movie entry
+        query = (
+            '''
+            INSERT INTO movie(
+                idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07,
+                c09, c10, c11, c12, c14, c15, c16, c18, c19, c21, premiered)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def update_movie(self, *args):
+        
+        query = ' '.join((
+
+            "UPDATE movie",
+            "SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?,",
+                "c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?,",
+                "c16 = ?, c18 = ?, c19 = ?, c21 = ?",
+            "WHERE idMovie = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_movie_17(self, *args):
+
+        query = ' '.join((
+
+            "UPDATE movie",
+            "SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?,",
+                "c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?,",
+                "c16 = ?, c18 = ?, c19 = ?, c21 = ?, premiered = ?",
+            "WHERE idMovie = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def remove_movie(self, kodi_id, file_id):
+        self.cursor.execute("DELETE FROM movie WHERE idMovie = ?", (kodi_id,))
+        self.cursor.execute("DELETE FROM files WHERE idFile = ?", (file_id,))
+
+    def add_countries(self, kodi_id, countries):
+        
+        if self.kodi_version > 14:
+            
+            for country in countries:
+                country_id = self._get_country(country)
+
+                query = (
+                    '''
+                    INSERT OR REPLACE INTO country_link(country_id, media_id, media_type)
+                    VALUES (?, ?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (country_id, kodi_id, "movie"))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            for country in countries:
+                query = ' '.join((
+
+                    "SELECT idCountry",
+                    "FROM country",
+                    "WHERE strCountry = ?",
+                    "COLLATE NOCASE"
+                ))
+                self.cursor.execute(query, (country,))
+
+                try:
+                    country_id = self.cursor.fetchone()[0]
+                except TypeError:
+                    # Create a new entry
+                    self.cursor.execute("select coalesce(max(idCountry),0) from country")
+                    country_id = self.cursor.fetchone()[0] + 1
+
+                    query = "INSERT INTO country(idCountry, strCountry) values(?, ?)"
+                    self.cursor.execute(query, (country_id, country))
+                    log.debug("Add country to media, processing: %s", country)
+
+                query = (
+                    '''
+                    INSERT OR REPLACE INTO countrylinkmovie(idCountry, idMovie)
+                    VALUES (?, ?)
+                    '''
+                )
+                self.cursor.execute(query, (country_id, kodi_id))
+    
+    def _add_country(self, country):
+
+        country_id = self.create_entry_country()
+        query = "INSERT INTO country(country_id, name) values(?, ?)"
+        self.cursor.execute(query, (country_id, country))
+        log.debug("Add country to media, processing: %s", country)
+
+        return country_id
+
+    def _get_country(self, country):
+
+        query = ' '.join((
+
+            "SELECT country_id",
+            "FROM country",
+            "WHERE name = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (country,))
+        try:
+            country_id = self.cursor.fetchone()[0]
+        except TypeError:
+            country_id = self._add_country(country)
+
+        return country_id
+
+    def add_boxset(self, boxset):
+
+        query = ' '.join((
+
+            "SELECT idSet",
+            "FROM sets",
+            "WHERE strSet = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (boxset,))
+        try:
+            set_id = self.cursor.fetchone()[0]
+        except TypeError:
+            set_id = self._add_boxset(boxset)
+
+        return set_id
+
+    def _add_boxset(self, boxset):
+
+        set_id = self.create_entry_set()
+        query = "INSERT INTO sets(idSet, strSet) values(?, ?)"
+        self.cursor.execute(query, (set_id, boxset))
+        log.debug("Adding boxset: %s", boxset)
+
+        return set_id
+
+    def set_boxset(self, set_id, movie_id):
+
+        query = ' '.join((
+
+            "UPDATE movie",
+            "SET idSet = ?",
+            "WHERE idMovie = ?"
+        ))
+        self.cursor.execute(query, (set_id, movie_id,))
+
+    def remove_from_boxset(self, movie_id):
+
+        query = ' '.join((
+
+            "UPDATE movie",
+            "SET idSet = null",
+            "WHERE idMovie = ?"
+        ))
+        self.cursor.execute(query, (movie_id,))
+
+    def remove_boxset(self, set_id):
+        self.cursor.execute("DELETE FROM sets WHERE idSet = ?", (kodi_id,))
diff --git a/resources/lib/objects/_kodi_music.py b/resources/lib/objects/_kodi_music.py
new file mode 100644
index 00000000..88210355
--- /dev/null
+++ b/resources/lib/objects/_kodi_music.py
@@ -0,0 +1,406 @@
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+
+import logging
+
+from _kodi_common import KodiItems
+
+##################################################################################################
+
+log = logging.getLogger("EMBY."+__name__)
+
+##################################################################################################
+
+
+class KodiMusic(KodiItems):
+
+
+    def __init__(self, cursor):
+        self.cursor = cursor
+
+        KodiItems.__init__(self)
+
+    def create_entry(self):
+        self.cursor.execute("select coalesce(max(idArtist),0) from artist")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_album(self):
+        self.cursor.execute("select coalesce(max(idAlbum),0) from album")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_song(self):
+        self.cursor.execute("select coalesce(max(idSong),0) from song")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_genre(self):
+        self.cursor.execute("select coalesce(max(idGenre),0) from genre")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def update_path(self, path_id, path):
+
+        query = "UPDATE path SET strPath = ? WHERE idPath = ?"
+        self.cursor.execute(query, (path, path_id))
+
+    def add_role(self):
+        query = (
+            '''
+            INSERT OR REPLACE INTO role(idRole, strRole)
+            VALUES (?, ?)
+            '''
+        )
+        self.cursor.execute(query, (1, 'Composer'))
+
+    def get_artist(self, name, musicbrainz):
+
+        query = ' '.join((
+
+            "SELECT idArtist, strArtist",
+            "FROM artist",
+            "WHERE strMusicBrainzArtistID = ?"
+        ))
+        self.cursor.execute(query, (musicbrainz,))
+        try:
+            result = self.cursor.fetchone()
+            artist_id = result[0]
+            artist_name = result[1]
+        except TypeError:
+            artist_id = self._add_artist(name, musicbrainz)
+        else:
+            if artist_name != name:
+                self.update_artist_name(artist_id, name)
+
+        return artist_id
+
+    def _add_artist(self, name, musicbrainz):
+
+        query = ' '.join((
+            # Safety check, when musicbrainz does not exist
+            "SELECT idArtist",
+            "FROM artist",
+            "WHERE strArtist = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (name,))
+        try:
+            artist_id = self.cursor.fetchone()[0]
+        except TypeError:
+            artist_id = self.create_entry()
+            query = (
+                '''
+                INSERT INTO artist(idArtist, strArtist, strMusicBrainzArtistID)
+                VALUES (?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (artist_id, name, musicbrainz))
+
+        return artist_id
+
+    def update_artist_name(self, kodi_id, name):
+
+        query = "UPDATE artist SET strArtist = ? WHERE idArtist = ?"
+        self.cursor.execute(query, (name, kodi_id,))
+
+    def update_artist_16(self, *args):
+        query = ' '.join((
+
+            "UPDATE artist",
+            "SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?,",
+                "lastScraped = ?",
+            "WHERE idArtist = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_artist(self, *args):
+        query = ' '.join((
+
+            "UPDATE artist",
+            "SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?,",
+                "lastScraped = ?, dateAdded = ?",
+            "WHERE idArtist = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def link_artist(self, kodi_id, album_id, name):
+        query = (
+            '''
+            INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist)
+            VALUES (?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (kodi_id, album_id, name))
+
+    def add_discography(self, kodi_id, album, year):
+        query = (
+            '''
+            INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear)
+            VALUES (?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (kodi_id, album, year))
+
+    def get_album(self, name, musicbrainz):
+
+        query = ' '.join((
+
+            "SELECT idAlbum",
+            "FROM album",
+            "WHERE strMusicBrainzAlbumID = ?"
+        ))
+        self.cursor.execute(query, (musicbrainz,))
+        try:
+            album_id = self.cursor.fetchone()[0]
+        except TypeError:
+            album_id = self._add_album(name, musicbrainz)
+
+        return album_id
+
+    def _add_album(self, name, musicbrainz):
+
+        album_id = self.create_entry_album()
+        if self.kodi_version > 14:
+            query = (
+                '''
+                INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID, strReleaseType)
+                VALUES (?, ?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (album_id, name, musicbrainz, "album"))
+        else:
+            # TODO: Remove Helix code when Krypton is RC
+            query = (
+                '''
+                INSERT INTO album(idAlbum, strAlbum, strMusicBrainzAlbumID)
+                VALUES (?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (album_id, name, musicbrainz))
+
+        return album_id
+
+    def update_album(self, *args):
+        query = ' '.join((
+
+            "UPDATE album",
+            "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
+                "iRating = ?, lastScraped = ?, strReleaseType = ?",
+            "WHERE idAlbum = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_album_17(self, *args):
+        query = ' '.join((
+
+            "UPDATE album",
+            "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
+                "iUserrating = ?, lastScraped = ?, strReleaseType = ?",
+            "WHERE idAlbum = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_album_15(self, *args):
+        query = ' '.join((
+
+            "UPDATE album",
+            "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
+                "iRating = ?, lastScraped = ?, dateAdded = ?, strReleaseType = ?",
+            "WHERE idAlbum = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_album_14(self, *args):
+        # TODO: Remove Helix code when Krypton is RC
+        query = ' '.join((
+
+            "UPDATE album",
+            "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
+                "iRating = ?, lastScraped = ?, dateAdded = ?",
+            "WHERE idAlbum = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def get_album_artist(self, album_id, artists):
+
+        query = ' '.join((
+
+            "SELECT strArtists",
+            "FROM album",
+            "WHERE idAlbum = ?"
+        ))
+        self.cursor.execute(query, (album_id,))
+        try:
+            curr_artists = self.cursor.fetchone()[0]
+        except TypeError:
+            return
+
+        if curr_artists != artists:
+            self._update_album_artist(album_id, artists)
+
+    def _update_album_artist(self, album_id, artists):
+
+        query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
+        self.cursor.execute(query, (artists, album_id))
+
+    def add_single(self, *args):
+        query = (
+            '''
+            INSERT INTO album(idAlbum, strGenres, iYear, strReleaseType)
+
+            VALUES (?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def add_single_15(self, *args):
+        query = (
+            '''
+            INSERT INTO album(idAlbum, strGenres, iYear, dateAdded, strReleaseType)
+
+            VALUES (?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (albumid, args))
+
+    def add_single_14(self, *args):
+        # TODO: Remove Helix code when Krypton is RC
+        query = (
+            '''
+            INSERT INTO album(idAlbum, strGenres, iYear, dateAdded)
+
+            VALUES (?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (albumid, genre, year, dateadded))
+
+    def add_song(self, *args):
+        query = (
+            '''
+            INSERT INTO song(
+                idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack,
+                iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed,
+                rating)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def update_song(self, *args):
+        query = ' '.join((
+
+            "UPDATE song",
+            "SET idAlbum = ?, strArtists = ?, strGenres = ?, strTitle = ?, iTrack = ?,",
+                "iDuration = ?, iYear = ?, strFilename = ?, iTimesPlayed = ?, lastplayed = ?,",
+                "rating = ?, comment = ?",
+            "WHERE idSong = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def link_song_artist(self, kodi_id, song_id, index, artist):
+
+        if self.kodi_version > 16:
+            query = (
+                '''
+                INSERT OR REPLACE INTO song_artist(idArtist, idSong, idRole, iOrder, strArtist)
+                VALUES (?, ?, ?, ?, ?)
+                '''
+            )
+            kodicursor.execute(query, (kodi_id, song_id, 1, index, artist))
+        else:
+            query = (
+                '''
+                INSERT OR REPLACE INTO song_artist(idArtist, idSong, iOrder, strArtist)
+                VALUES (?, ?, ?, ?)
+                '''
+            )
+            self.cursor.execute(query, (kodi_id, song_id, index, artist))
+
+    def link_song_album(self, song_id, album_id, track, title, duration):
+        query = (
+            '''
+            INSERT OR REPLACE INTO albuminfosong(
+                idAlbumInfoSong, idAlbumInfo, iTrack, strTitle, iDuration)
+
+            VALUES (?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (song_id, album_id, track, title, duration))
+
+    def rate_song(self, kodi_id, playcount, rating, date_played):
+
+        query = "UPDATE song SET iTimesPlayed = ?, lastplayed = ?, rating = ? WHERE idSong = ?"
+        self.cursor.execute(query, (playcount, date_played, rating, kodi_id))
+
+    def add_genres(self, kodi_id, genres, media_type):
+
+        if media_type == "album":
+            # Delete current genres for clean slate
+            query = ' '.join((
+
+                "DELETE FROM album_genre",
+                "WHERE idAlbum = ?"
+            ))
+            self.cursor.execute(query, (kodi_id,))
+
+            for genre in genres:
+
+                genre_id = self.get_genre(genre)
+                query = "INSERT OR REPLACE INTO album_genre(idGenre, idAlbum) values(?, ?)"
+                self.cursor.execute(query, (genre_id, kodi_id))
+
+        elif media_type == "song":
+            # Delete current genres for clean slate
+            query = ' '.join((
+
+                "DELETE FROM song_genre",
+                "WHERE idSong = ?"
+            ))
+            self.cursor.execute(query, (kodi_id,))
+
+            for genre in genres:
+
+                genre_id = self.get_genre(genre)
+                query = "INSERT OR REPLACE INTO song_genre(idGenre, idSong) values(?, ?)"
+                self.cursor.execute(query, (genre_id, kodi_id))
+
+    def get_genre(self, genre):
+
+        query = ' '.join((
+
+            "SELECT idGenre",
+            "FROM genre",
+            "WHERE strGenre = ?",
+            "COLLATE NOCASE"
+        ))
+        self.cursor.execute(query, (genre,))
+        try:
+            genre_id = self.cursor.fetchone()[0]
+        except TypeError:
+            genre_id = self._add_genre(genre)
+
+        return genre_id
+
+    def _add_genre(self, genre):
+
+        genre_id = self.create_entry_genre()
+        query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)"
+        self.cursor.execute(query, (genre_id, genre))
+
+        return genre_id
+
+    def remove_artist(self, kodi_id):
+        self.cursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodi_id,))
+
+    def remove_album(self, kodi_id):
+        self.cursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodi_id,))
+
+    def remove_song(self, kodi_id):
+        self.cursor.execute("DELETE FROM song WHERE idSong = ?", (kodi_id,))
diff --git a/resources/lib/objects/_kodi_musicvideos.py b/resources/lib/objects/_kodi_musicvideos.py
new file mode 100644
index 00000000..729a27fa
--- /dev/null
+++ b/resources/lib/objects/_kodi_musicvideos.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+
+import logging
+
+from _kodi_common import KodiItems
+
+##################################################################################################
+
+log = logging.getLogger("EMBY."+__name__)
+
+##################################################################################################
+
+
+class KodiMusicVideos(KodiItems):
+
+
+    def __init__(self, cursor):
+        self.cursor = cursor
+
+        KodiItems.__init__(self)
+
+    def create_entry(self):
+        self.cursor.execute("select coalesce(max(idMVideo),0) from musicvideo")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def get_musicvideo(self, kodi_id):
+
+        query = "SELECT * FROM musicvideo WHERE idMVideo = ?"
+        self.cursor.execute(query, (kodi_id,))
+        try:
+            kodi_id = self.cursor.fetchone()[0]
+        except TypeError:
+            kodi_id = None
+
+        return kodi_id
+
+    def add_musicvideo(self, *args):
+
+        query = (
+            '''
+            INSERT INTO musicvideo(
+                idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10, c11, c12)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def update_musicvideo(self, *args):
+        
+        query = ' '.join((
+
+            "UPDATE musicvideo",
+            "SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?,",
+                "c11 = ?, c12 = ?"
+            "WHERE idMVideo = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def remove_musicvideo(self, kodi_id, file_id):
+        self.cursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (kodi_id,))
+        self.cursor.execute("DELETE FROM files WHERE idFile = ?", (file_id,))
diff --git a/resources/lib/objects/_kodi_tvshows.py b/resources/lib/objects/_kodi_tvshows.py
new file mode 100644
index 00000000..8fe7ad53
--- /dev/null
+++ b/resources/lib/objects/_kodi_tvshows.py
@@ -0,0 +1,170 @@
+# -*- coding: utf-8 -*-
+
+##################################################################################################
+
+import logging
+
+from _kodi_common import KodiItems
+
+##################################################################################################
+
+log = logging.getLogger("EMBY."+__name__)
+
+##################################################################################################
+
+
+class KodiTVShows(KodiItems):
+
+
+    def __init__(self, cursor):
+        self.cursor = cursor
+
+        KodiItems.__init__(self)
+
+    def create_entry(self):
+        self.cursor.execute("select coalesce(max(idShow),0) from tvshow")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_season(self):
+        self.cursor.execute("select coalesce(max(idSeason),0) from seasons")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def create_entry_episode(self):
+        self.cursor.execute("select coalesce(max(idEpisode),0) from episode")
+        kodi_id = self.cursor.fetchone()[0] + 1
+
+        return kodi_id
+
+    def get_tvshow(self, kodi_id):
+
+        query = "SELECT * FROM tvshow WHERE idShow = ?"
+        self.cursor.execute(query, (kodi_id,))
+        try:
+            kodi_id = self.cursor.fetchone()[0]
+        except TypeError:
+            kodi_id = None
+
+        return kodi_id
+
+    def get_episode(self, kodi_id):
+
+        query = "SELECT * FROM episode WHERE idEpisode = ?"
+        self.cursor.execute(query, (kodi_id,))
+        try:
+            kodi_id = self.cursor.fetchone()[0]
+        except TypeError:
+            kodi_id = None
+
+        return kodi_id
+
+    def add_tvshow(self, *args):
+
+        query = (
+            '''
+            INSERT INTO tvshow(idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14, c15)
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def update_tvshow(self, *args):
+        
+        query = ' '.join((
+
+            "UPDATE tvshow",
+            "SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?,",
+                "c12 = ?, c13 = ?, c14 = ?, c15 = ?",
+            "WHERE idShow = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def link_tvshow(self, show_id, path_id):
+        query = "INSERT OR REPLACE INTO tvshowlinkpath(idShow, idPath) values(?, ?)"
+        self.cursor.execute(query, (show_id, path_id))
+
+    def get_season(self, show_id, number, name=None):
+
+        query = ' '.join((
+
+            "SELECT idSeason",
+            "FROM seasons",
+            "WHERE idShow = ?",
+            "AND season = ?"
+        ))
+        self.cursor.execute(query, (show_id, number,))
+        try:
+            season_id = self.cursor.fetchone()[0]
+        except TypeError:
+            season_id = self._add_season(show_id, number)
+
+        if self.kodi_version > 15 and name is not None:
+            query = "UPDATE seasons SET name = ? WHERE idSeason = ?"
+            self.cursor.execute(query, (name, season_id))
+
+        return season_id
+
+    def _add_season(self, show_id, number):
+
+        season_id = self.create_entry_season()
+        query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)"
+        self.cursor.execute(query, (season_id, show_id, number))
+
+        return season_id
+
+    def add_episode(self, *args):
+        query = (
+            '''
+            INSERT INTO episode(
+                idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14,
+                idShow, c15, c16)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def add_episode_16(self, *args):
+        query = (
+            '''
+            INSERT INTO episode(
+                idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14,
+                idShow, c15, c16, idSeason)
+
+            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+            '''
+        )
+        self.cursor.execute(query, (args))
+
+    def update_episode(self, *args):
+        query = ' '.join((
+
+            "UPDATE episode",
+            "SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?,",
+                "c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, idShow = ?",
+            "WHERE idEpisode = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def update_episode_16(self, *args):
+        query = ' '.join((
+
+            "UPDATE episode",
+            "SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?,",
+                "c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, idSeason = ?, idShow = ?",
+            "WHERE idEpisode = ?"
+        ))
+        self.cursor.execute(query, (args))
+
+    def remove_tvshow(self, kodi_id):
+        self.cursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodi_id,))
+
+    def remove_season(self, kodi_id):
+        self.cursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodi_id,))
+
+    def remove_episode(self, kodi_id, file_id):
+        self.cursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodi_id,))
+        self.cursor.execute("DELETE FROM files WHERE idFile = ?", (file_id,))
diff --git a/resources/lib/objects/movies.py b/resources/lib/objects/movies.py
index fdc0f9ee..63540000 100644
--- a/resources/lib/objects/movies.py
+++ b/resources/lib/objects/movies.py
@@ -6,9 +6,9 @@ import logging
 import urllib
 
 import api
-import common
 import embydb_functions as embydb
-import kodidb_functions as kodidb
+import _kodi_movies
+from _common import Items
 from utils import window, settings, language as lang, catch_except
 
 ##################################################################################################
@@ -18,7 +18,7 @@ log = logging.getLogger("EMBY."+__name__)
 ##################################################################################################
 
 
-class Movies(common.Items):
+class Movies(Items):
 
 
     def __init__(self, embycursor, kodicursor, pdialog=None):
@@ -26,12 +26,12 @@ class Movies(common.Items):
         self.embycursor = embycursor
         self.emby_db = embydb.Embydb_Functions(self.embycursor)
         self.kodicursor = kodicursor
-        self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
+        self.kodi_db = _kodi_movies.KodiMovies(self.kodicursor)
         self.pdialog = pdialog
 
         self.new_time = int(settings('newvideotime'))*1000
 
-        common.Items.__init__(self)
+        Items.__init__(self)
 
     def _get_func(self, item_type, action):
 
@@ -176,7 +176,6 @@ class Movies(common.Items):
     @catch_except()
     def add_update(self, item, view=None):
         # Process single movie
-        kodicursor = self.kodicursor
         emby_db = self.emby_db
         artwork = self.artwork
         API = api.API(item)
@@ -196,16 +195,10 @@ class Movies(common.Items):
             update_item = False
             log.debug("movieid: %s not found", itemid)
             # movieid
-            kodicursor.execute("select coalesce(max(idMovie),0) from movie")
-            movieid = kodicursor.fetchone()[0] + 1
+            movieid = self.kodi_db.create_entry()
 
         else:
-            # Verification the item is still in Kodi
-            query = "SELECT * FROM movie WHERE idMovie = ?"
-            kodicursor.execute(query, (movieid,))
-            try:
-                kodicursor.fetchone()[0]
-            except TypeError:
+            if self.kodi_db.get_movie(movieid) is None:
                 # item is not found, let's recreate it.
                 update_item = False
                 log.info("movieid: %s missing from Kodi, repairing the entry", movieid)
@@ -312,30 +305,15 @@ class Movies(common.Items):
 
             # Update the movie entry
             if self.kodi_version > 16:
-                query = ' '.join((
-
-                    "UPDATE movie",
-                    "SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?,",
-                        "c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?,",
-                        "c16 = ?, c18 = ?, c19 = ?, c21 = ?, premiered = ?",
-                    "WHERE idMovie = ?"
-                ))
-                kodicursor.execute(query, (title, plot, shortplot, tagline, votecount, rating,
-                                           writer, year, imdb, sorttitle, runtime, mpaa, genre,
-                                           director, title, studio, trailer, country, year,
-                                           movieid))
+                self.kodi_db.update_movie_17(title, plot, shortplot, tagline, votecount, rating,
+                                             writer, year, imdb, sorttitle, runtime, mpaa, genre,
+                                             director, title, studio, trailer, country, year,
+                                             movieid)
             else:
-                query = ' '.join((
+                self.kodi_db.update_movie(title, plot, shortplot, tagline, votecount, rating,
+                                          writer, year, imdb, sorttitle, runtime, mpaa, genre,
+                                          director, title, studio, trailer, country, movieid)
 
-                    "UPDATE movie",
-                    "SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?,",
-                        "c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?,",
-                        "c16 = ?, c18 = ?, c19 = ?, c21 = ?",
-                    "WHERE idMovie = ?"
-                ))
-                kodicursor.execute(query, (title, plot, shortplot, tagline, votecount, rating,
-                                           writer, year, imdb, sorttitle, runtime, mpaa, genre,
-                                           director, title, studio, trailer, country, movieid))
             # Update the checksum in emby table
             emby_db.updateReference(itemid, checksum)
 
@@ -344,87 +322,57 @@ class Movies(common.Items):
             log.info("ADD movie itemid: %s - Title: %s", itemid, title)
 
             # Add path
-            pathid = self.kodi_db.addPath(path)
+            pathid = self.kodi_db.add_path(path)
             # Add the file
-            fileid = self.kodi_db.addFile(filename, pathid)
+            fileid = self.kodi_db.add_file(filename, pathid)
 
             # Create the movie entry
             if self.kodi_version > 16:
-                query = (
-                    '''
-                    INSERT INTO movie(
-                        idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07,
-                        c09, c10, c11, c12, c14, c15, c16, c18, c19, c21, premiered)
-
-                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (movieid, fileid, title, plot, shortplot, tagline,
-                                           votecount, rating, writer, year, imdb, sorttitle,
-                                           runtime, mpaa, genre, director, title, studio, trailer,
-                                           country, year))
+                self.kodi_db.add_movie_17(movieid, fileid, title, plot, shortplot, tagline,
+                                          votecount, rating, writer, year, imdb, sorttitle,
+                                          runtime, mpaa, genre, director, title, studio, trailer,
+                                          country, year)
             else:
-                query = (
-                    '''
-                    INSERT INTO movie(
-                        idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07,
-                        c09, c10, c11, c12, c14, c15, c16, c18, c19, c21)
+                self.kodi_db.add_movie(movieid, fileid, title, plot, shortplot, tagline,
+                                       votecount, rating, writer, year, imdb, sorttitle,
+                                       runtime, mpaa, genre, director, title, studio, trailer,
+                                       country)
 
-                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (movieid, fileid, title, plot, shortplot, tagline,
-                                           votecount, rating, writer, year, imdb, sorttitle,
-                                           runtime, mpaa, genre, director, title, studio, trailer,
-                                           country))
             # Create the reference in emby table
             emby_db.addReference(itemid, movieid, "Movie", "movie", fileid, pathid, None,
                                  checksum, viewid)
 
         # Update the path
-        query = ' '.join((
-
-            "UPDATE path",
-            "SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
-            "WHERE idPath = ?"
-        ))
-        kodicursor.execute(query, (path, "movies", "metadata.local", 1, pathid))
-
+        self.kodi_db.update_path(pathid, path, "movies", "metadata.local")
         # Update the file
-        query = ' '.join((
-
-            "UPDATE files",
-            "SET idPath = ?, strFilename = ?, dateAdded = ?",
-            "WHERE idFile = ?"
-        ))
-        kodicursor.execute(query, (pathid, filename, dateadded, fileid))
+        self.kodi_db.update_file(fileid, filename, pathid, dateadded)
 
         # Process countries
         if 'ProductionLocations' in item:
-            self.kodi_db.addCountries(movieid, item['ProductionLocations'], "movie")
+            self.kodi_db.add_countries(movieid, item['ProductionLocations'])
         # Process cast
         people = artwork.get_people_artwork(item['People'])
-        self.kodi_db.addPeople(movieid, people, "movie")
+        self.kodi_db.add_people(movieid, people, "movie")
         # Process genres
-        self.kodi_db.addGenres(movieid, genres, "movie")
+        self.kodi_db.add_genres(movieid, genres, "movie")
         # Process artwork
-        artwork.add_artwork(artwork.get_all_artwork(item), movieid, "movie", kodicursor)
+        artwork.add_artwork(artwork.get_all_artwork(item), movieid, "movie", self.kodicursor)
         # Process stream details
         streams = API.get_media_streams()
-        self.kodi_db.addStreams(fileid, streams, runtime)
+        self.kodi_db.add_streams(fileid, streams, runtime)
         # Process studios
-        self.kodi_db.addStudios(movieid, studios, "movie")
+        self.kodi_db.add_studios(movieid, studios, "movie")
         # Process tags: view, emby tags
         tags = [viewtag]
         tags.extend(item['Tags'])
         if userdata['Favorite']:
             tags.append("Favorite movies")
         log.info("Applied tags: %s", tags)
-        self.kodi_db.addTags(movieid, tags, "movie")
+        self.kodi_db.add_tags(movieid, tags, "movie")
         # Process playstates
         resume = API.adjust_resume(userdata['Resume'])
         total = round(float(runtime), 6)
-        self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+        self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
 
         return True
 
@@ -442,7 +390,7 @@ class Movies(common.Items):
             setid = emby_dbitem[0]
 
         except TypeError:
-            setid = self.kodi_db.createBoxset(title)
+            setid = self.kodi_db.add_boxset(title)
 
         # Process artwork
         artwork.add_artwork(artwork.get_all_artwork(boxset), setid, "set", self.kodicursor)
@@ -475,7 +423,7 @@ class Movies(common.Items):
                     continue
 
                 log.info("New addition to boxset %s: %s", title, movie['Name'])
-                self.kodi_db.assignBoxset(setid, movieid)
+                self.kodi_db.set_boxset(setid, movieid)
                 # Update emby reference
                 emby_db.updateParentId(itemid, setid)
             else:
@@ -486,7 +434,7 @@ class Movies(common.Items):
         for movie in process:
             movieid = current[movie]
             log.info("Remove from boxset %s: %s", title, movieid)
-            self.kodi_db.removefromBoxset(movieid)
+            self.kodi_db.remove_from_boxset(movieid)
             # Update emby reference
             emby_db.updateParentId(movie, None)
 
@@ -516,9 +464,9 @@ class Movies(common.Items):
 
         # Process favorite tags
         if userdata['Favorite']:
-            self.kodi_db.addTag(movieid, "Favorite movies", "movie")
+            self.kodi_db.get_tag(movieid, "Favorite movies", "movie")
         else:
-            self.kodi_db.removeTag(movieid, "Favorite movies", "movie")
+            self.kodi_db.remove_tag(movieid, "Favorite movies", "movie")
 
         # Process playstates
         playcount = userdata['PlayCount']
@@ -528,13 +476,12 @@ class Movies(common.Items):
 
         log.debug("%s New resume point: %s", itemid, resume)
 
-        self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+        self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
         emby_db.updateReference(itemid, checksum)
 
     def remove(self, itemid):
         # Remove movieid, fileid, emby reference
         emby_db = self.emby_db
-        kodicursor = self.kodicursor
         artwork = self.artwork
 
         emby_dbitem = emby_db.getItem_byId(itemid)
@@ -549,12 +496,10 @@ class Movies(common.Items):
         # Remove the emby reference
         emby_db.removeItem(itemid)
         # Remove artwork
-        artwork.delete_artwork(kodiid, mediatype, kodicursor)
+        artwork.delete_artwork(kodiid, mediatype, self.kodicursor)
 
         if mediatype == "movie":
-            # Delete kodi movie and file
-            kodicursor.execute("DELETE FROM movie WHERE idMovie = ?", (kodiid,))
-            kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
+            self.kodi_db.remove_movie(kodiid, fileid)
 
         elif mediatype == "set":
             # Delete kodi boxset
@@ -562,10 +507,10 @@ class Movies(common.Items):
             for movie in boxset_movies:
                 embyid = movie[0]
                 movieid = movie[1]
-                self.kodi_db.removefromBoxset(movieid)
+                self.kodi_db.remove_from_boxset(movieid)
                 # Update emby reference
                 emby_db.updateParentId(embyid, None)
 
-            kodicursor.execute("DELETE FROM sets WHERE idSet = ?", (kodiid,))
+            self.kodi_db.remove_boxset(kodiid)
 
         log.info("Deleted %s %s from kodi database", mediatype, itemid)
diff --git a/resources/lib/objects/music.py b/resources/lib/objects/music.py
index ee64eca9..ab81d3d8 100644
--- a/resources/lib/objects/music.py
+++ b/resources/lib/objects/music.py
@@ -6,10 +6,10 @@ import logging
 from datetime import datetime
 
 import api
-import common
 import embydb_functions as embydb
-import kodidb_functions as kodidb
 import musicutils
+import _kodi_music
+from _common import Items
 from utils import window, settings, language as lang, catch_except
 
 ##################################################################################################
@@ -19,7 +19,7 @@ log = logging.getLogger("EMBY."+__name__)
 ##################################################################################################
 
 
-class Music(common.Items):
+class Music(Items):
 
 
     def __init__(self, embycursor, kodicursor, pdialog=None):
@@ -27,7 +27,7 @@ class Music(common.Items):
         self.embycursor = embycursor
         self.emby_db = embydb.Embydb_Functions(self.embycursor)
         self.kodicursor = kodicursor
-        self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
+        self.kodi_db = _kodi_music.KodiMusic(self.kodicursor)
         self.pdialog = pdialog
 
         self.new_time = int(settings('newmusictime'))*1000
@@ -38,7 +38,7 @@ class Music(common.Items):
         self.userid = window('emby_currUser')
         self.server = window('emby_server%s' % self.userid)
 
-        common.Items.__init__(self)
+        Items.__init__(self)
 
     def _get_func(self, item_type, action):
 
@@ -218,6 +218,8 @@ class Music(common.Items):
         except TypeError:
             update_item = False
             log.debug("artistid: %s not found", itemid)
+        else:
+            pass
 
         ##### The artist details #####
         lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
@@ -253,30 +255,15 @@ class Music(common.Items):
             log.info("ADD artist itemid: %s - Name: %s", itemid, name)
             # safety checks: It looks like Emby supports the same artist multiple times.
             # Kodi doesn't allow that. In case that happens we just merge the artist entries.
-            artistid = self.kodi_db.addArtist(name, musicBrainzId)
+            artistid = self.kodi_db.get_artist(name, musicBrainzId)
             # Create the reference in emby table
             emby_db.addReference(itemid, artistid, artisttype, "artist", checksum=checksum)
 
         # Process the artist
-        if self.kodi_version in (16, 17):
-            query = ' '.join((
-
-                "UPDATE artist",
-                "SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?,",
-                    "lastScraped = ?",
-                "WHERE idArtist = ?"
-            ))
-            kodicursor.execute(query, (genres, bio, thumb, fanart, lastScraped, artistid))
+        if self.kodi_version > 15:
+            self.kodi_db.update_artist_16(genres, bio, thumb, fanart, lastScraped, artistid)
         else:
-            query = ' '.join((
-
-                "UPDATE artist",
-                "SET strGenres = ?, strBiography = ?, strImage = ?, strFanart = ?,",
-                    "lastScraped = ?, dateAdded = ?",
-                "WHERE idArtist = ?"
-            ))
-            kodicursor.execute(query, (genres, bio, thumb, fanart, lastScraped,
-                                       dateadded, artistid))
+            self.kodi_db.update_artist(genres, bio, thumb, fanart, lastScraped, dateadded, artistid)
 
         # Update artwork
         artwork.add_artwork(artworks, artistid, "artist", kodicursor)
@@ -313,7 +300,7 @@ class Music(common.Items):
         genres = item.get('Genres')
         genre = " / ".join(genres)
         bio = API.get_overview()
-        rating = userdata['UserRating']
+        rating = 0
         artists = item['AlbumArtists']
         artistname = []
         for artist in artists:
@@ -337,56 +324,27 @@ class Music(common.Items):
             log.info("ADD album itemid: %s - Name: %s", itemid, name)
             # safety checks: It looks like Emby supports the same artist multiple times.
             # Kodi doesn't allow that. In case that happens we just merge the artist entries.
-            albumid = self.kodi_db.addAlbum(name, musicBrainzId)
+            albumid = self.kodi_db.get_album(name, musicBrainzId)
             # Create the reference in emby table
             emby_db.addReference(itemid, albumid, "MusicAlbum", "album", checksum=checksum)
 
-
         # Process the album info
         if self.kodi_version == 17:
             # Kodi Krypton
-            query = ' '.join((
-
-                "UPDATE album",
-                "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
-                    "iUserrating = ?, lastScraped = ?, strReleaseType = ?",
-                "WHERE idAlbum = ?"
-            ))
-            kodicursor.execute(query, (artistname, year, genre, bio, thumb, rating, lastScraped,
-                                       "album", albumid))
+            self.kodi_db.update_album_17(artistname, year, genre, bio, thumb, rating, lastScraped,
+                                         "album", albumid)
         elif self.kodi_version == 16:
             # Kodi Jarvis
-            query = ' '.join((
-
-                "UPDATE album",
-                "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
-                    "iRating = ?, lastScraped = ?, strReleaseType = ?",
-                "WHERE idAlbum = ?"
-            ))
-            kodicursor.execute(query, (artistname, year, genre, bio, thumb, rating, lastScraped,
-                                       "album", albumid))
+            self.kodi_db.update_album(artistname, year, genre, bio, thumb, rating, lastScraped,
+                                      "album", albumid)
         elif self.kodi_version == 15:
             # Kodi Isengard
-            query = ' '.join((
-
-                "UPDATE album",
-                "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
-                    "iRating = ?, lastScraped = ?, dateAdded = ?, strReleaseType = ?",
-                "WHERE idAlbum = ?"
-            ))
-            kodicursor.execute(query, (artistname, year, genre, bio, thumb, rating, lastScraped,
-                                       dateadded, "album", albumid))
+            self.kodi_db.update_album_15(artistname, year, genre, bio, thumb, rating, lastScraped,
+                                         dateadded, "album", albumid)
         else:
-            # Kodi Helix
-            query = ' '.join((
-
-                "UPDATE album",
-                "SET strArtists = ?, iYear = ?, strGenres = ?, strReview = ?, strImage = ?,",
-                    "iRating = ?, lastScraped = ?, dateAdded = ?",
-                "WHERE idAlbum = ?"
-            ))
-            kodicursor.execute(query, (artistname, year, genre, bio, thumb, rating, lastScraped,
-                                       dateadded, albumid))
+            # TODO: Remove Helix code when Krypton is RC
+            self.kodi_db.update_album_14(artistname, year, genre, bio, thumb, rating, lastScraped,
+                                         dateadded, albumid)
 
         # Assign main artists to album
         for artist in item['AlbumArtists']:
@@ -403,18 +361,10 @@ class Music(common.Items):
                 artistid = emby_dbartist[0]
             else:
                 # Best take this name over anything else.
-                query = "UPDATE artist SET strArtist = ? WHERE idArtist = ?"
-                kodicursor.execute(query, (artistname, artistid,))
+                self.kodi_db.update_artist_name(artistid, artistname)
 
             # Add artist to album
-            query = (
-                '''
-                INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist)
-
-                VALUES (?, ?, ?)
-                '''
-            )
-            kodicursor.execute(query, (artistid, albumid, artistname))
+            self.kodi_db.link_artist(artistid, albumid, artistname)
             # Update emby reference with parentid
             emby_db.updateParentId(artistId, albumid)
 
@@ -427,17 +377,10 @@ class Music(common.Items):
                 pass
             else:
                 # Update discography
-                query = (
-                    '''
-                    INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear)
-
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (artistid, name, year))
+                self.kodi_db.add_discography(artistid, name, year)
 
         # Add genres
-        self.kodi_db.addMusicGenres(albumid, genres, "album")
+        self.kodi_db.add_genres(albumid, genres, "album")
         # Update artwork
         artwork.add_artwork(artworks, albumid, "album", kodicursor)
 
@@ -462,6 +405,7 @@ class Music(common.Items):
         except TypeError:
             update_item = False
             log.debug("songid: %s not found", itemid)
+            songid = self.kodi_db.create_entry_song()
 
         ##### The song details #####
         checksum = API.get_checksum()
@@ -484,7 +428,7 @@ class Music(common.Items):
             track = disc*2**16 + tracknumber
         year = item.get('ProductionYear')
         duration = API.get_runtime()
-        rating = userdata['UserRating']
+        rating = 0
 
         #if enabled, try to get the rating from file and/or emby
         if not self.directstream:
@@ -524,20 +468,11 @@ class Music(common.Items):
             log.info("UPDATE song itemid: %s - Title: %s", itemid, title)
 
             # Update path
-            query = "UPDATE path SET strPath = ? WHERE idPath = ?"
-            kodicursor.execute(query, (path, pathid))
+            self.kodi_db.update_path(pathid, path)
 
             # Update the song entry
-            query = ' '.join((
-
-                "UPDATE song",
-                "SET idAlbum = ?, strArtists = ?, strGenres = ?, strTitle = ?, iTrack = ?,",
-                    "iDuration = ?, iYear = ?, strFilename = ?, iTimesPlayed = ?, lastplayed = ?,",
-                    "rating = ?, comment = ?",
-                "WHERE idSong = ?"
-            ))
-            kodicursor.execute(query, (albumid, artists, genre, title, track, duration, year,
-                                       filename, playcount, dateplayed, rating, comment, songid))
+            self.kodi_db.update_song(albumid, artists, genre, title, track, duration, year,
+                                     filename, playcount, dateplayed, rating, comment, songid)
 
             # Update the checksum in emby table
             emby_db.updateReference(itemid, checksum)
@@ -547,7 +482,7 @@ class Music(common.Items):
             log.info("ADD song itemid: %s - Title: %s", itemid, title)
 
             # Add path
-            pathid = self.kodi_db.addPath(path)
+            pathid = self.kodi_db.add_path(path)
 
             try:
                 # Get the album
@@ -558,7 +493,7 @@ class Music(common.Items):
                 album_name = item.get('Album')
                 if album_name:
                     log.info("Creating virtual music album for song: %s", itemid)
-                    albumid = self.kodi_db.addAlbum(album_name, API.get_provider('MusicBrainzAlbum'))
+                    albumid = self.kodi_db.get_album(album_name, API.get_provider('MusicBrainzAlbum'))
                     emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album")
                 else:
                     # No album Id associated to the song.
@@ -578,70 +513,30 @@ class Music(common.Items):
                 except TypeError:
                     # No album found, create a single's album
                     log.info("Failed to add album. Creating singles.")
-                    kodicursor.execute("select coalesce(max(idAlbum),0) from album")
-                    albumid = kodicursor.fetchone()[0] + 1
+                    album_id = self.kodi_db.create_entry_album()
                     if self.kodi_version == 16:
-                        # Kodi Jarvis
-                        query = (
-                            '''
-                            INSERT INTO album(idAlbum, strGenres, iYear, strReleaseType)
+                        self.kodi_db.add_single(albumid, genre, year, "single")
 
-                            VALUES (?, ?, ?, ?)
-                            '''
-                        )
-                        kodicursor.execute(query, (albumid, genre, year, "single"))
                     elif self.kodi_version == 15:
-                        # Kodi Isengard
-                        query = (
-                            '''
-                            INSERT INTO album(idAlbum, strGenres, iYear, dateAdded, strReleaseType)
+                        self.kodi_db.add_single_15(albumid, genre, year, dateadded, "single")
 
-                            VALUES (?, ?, ?, ?, ?)
-                            '''
-                        )
-                        kodicursor.execute(query, (albumid, genre, year, dateadded, "single"))
                     else:
-                        # Kodi Helix
-                        query = (
-                            '''
-                            INSERT INTO album(idAlbum, strGenres, iYear, dateAdded)
-
-                            VALUES (?, ?, ?, ?)
-                            '''
-                        )
-                        kodicursor.execute(query, (albumid, genre, year, dateadded))
+                        # TODO: Remove Helix code when Krypton is RC
+                        self.kodi_db.add_single_14(albumid, genre, year, dateadded)
 
             # Create the song entry
-            kodicursor.execute("select coalesce(max(idSong),0) from song")
-            songid = kodicursor.fetchone()[0] + 1
-            query = (
-                '''
-                INSERT INTO song(
-                    idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack,
-                    iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed,
-                    rating)
-
-                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                '''
-            )
-            kodicursor.execute(query, (songid, albumid, pathid, artists, genre, title, track,
-                                       duration, year, filename, musicBrainzId, playcount,
-                                       dateplayed, rating))
+            self.kodi_db.add_song(songid, albumid, pathid, artists, genre, title, track, duration,
+                                  year, filename, musicBrainzId, playcount, dateplayed, rating)
 
             # Create the reference in emby table
             emby_db.addReference(itemid, songid, "Audio", "song", pathid=pathid, parentid=albumid,
                                  checksum=checksum)
 
         # Link song to album
-        query = (
-            '''
-            INSERT OR REPLACE INTO albuminfosong(
-                idAlbumInfoSong, idAlbumInfo, iTrack, strTitle, iDuration)
-
-            VALUES (?, ?, ?, ?, ?)
-            '''
-        )
-        kodicursor.execute(query, (songid, albumid, track, title, duration))
+        self.kodi_db.link_song_album(songid, albumid, track, title, duration)
+        # Create default role
+        if self.kodi_version > 16:
+            self.kodi_db.add_role()
 
         # Link song to artists
         for index, artist in enumerate(item['ArtistItems']):
@@ -658,35 +553,8 @@ class Music(common.Items):
                 artist_edb = emby_db.getItem_byId(artist_eid)
                 artistid = artist_edb[0]
             finally:
-                if self.kodi_version >= 17:
-                    # Kodi Krypton
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO song_artist(idArtist, idSong, idRole, iOrder, strArtist)
-
-                        VALUES (?, ?, ?, ?, ?)
-                        '''
-                    )
-                    kodicursor.execute(query, (artistid, songid, 1, index, artist_name))
-
-                    # May want to look into only doing this once?
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO role(idRole, strRole)
-
-                        VALUES (?, ?)
-                        '''
-                    )
-                    kodicursor.execute(query, (1, 'Composer'))
-                else:
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO song_artist(idArtist, idSong, iOrder, strArtist)
-
-                        VALUES (?, ?, ?, ?)
-                        '''
-                    )
-                    kodicursor.execute(query, (artistid, songid, index, artist_name))
+                # Link song to artist
+                self.kodi_db.link_song_artist(artistid, songid, index, artist_name)
 
         # Verify if album artist exists
         album_artists = []
@@ -705,51 +573,18 @@ class Music(common.Items):
                 artist_edb = emby_db.getItem_byId(artist_eid)
                 artistid = artist_edb[0]
             finally:
-                query = (
-                    '''
-                    INSERT OR REPLACE INTO album_artist(idArtist, idAlbum, strArtist)
-
-                    VALUES (?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (artistid, albumid, artist_name))
+                # Link artist to album
+                self.kodi_db.link_artist(artistid, albumid, artist_name)
                 # Update discography
                 if item.get('Album'):
-                    query = (
-                        '''
-                        INSERT OR REPLACE INTO discography(idArtist, strAlbum, strYear)
-
-                        VALUES (?, ?, ?)
-                        '''
-                    )
-                    kodicursor.execute(query, (artistid, item['Album'], 0))
+                    self.kodi_db.add_discography(artistid, item['Album'], 0)
 
+        # Artist names
         album_artists = " / ".join(album_artists)
-        query = ' '.join((
-
-            "SELECT strArtists",
-            "FROM album",
-            "WHERE idAlbum = ?"
-        ))
-        kodicursor.execute(query, (albumid,))
-        result = kodicursor.fetchone()
-        if result and result[0] != album_artists:
-            # Field is empty
-            if self.kodi_version in (16, 17):
-                # Kodi Jarvis, Krypton
-                query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
-                kodicursor.execute(query, (album_artists, albumid))
-            elif self.kodi_version == 15:
-                # Kodi Isengard
-                query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
-                kodicursor.execute(query, (album_artists, albumid))
-            else:
-                # Kodi Helix
-                query = "UPDATE album SET strArtists = ? WHERE idAlbum = ?"
-                kodicursor.execute(query, (album_artists, albumid))
+        self.kodi_db.get_album_artist(albumid, album_artists)
 
         # Add genres
-        self.kodi_db.addMusicGenres(songid, genres, "song")
+        self.kodi_db.add_genres(songid, genres, "song")
 
         # Update artwork
         allart = artwork.get_all_artwork(item, parent_info=True)
@@ -774,7 +609,7 @@ class Music(common.Items):
         itemid = item['Id']
         checksum = API.get_checksum()
         userdata = API.get_userdata()
-        rating = userdata['UserRating']
+        rating = 0
 
         # Get Kodi information
         emby_dbitem = emby_db.getItem_byId(itemid)
@@ -799,17 +634,7 @@ class Music(common.Items):
 
             #process item ratings
             rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating)
-
-            query = "UPDATE song SET iTimesPlayed = ?, lastplayed = ?, rating = ? WHERE idSong = ?"
-            kodicursor.execute(query, (playcount, dateplayed, rating, kodiid))
-
-        elif mediatype == "album":
-            # Process playstates
-            if self.kodi_version >= 17:
-                query = "UPDATE album SET fRating = ? WHERE idAlbum = ?"
-            else:
-                query = "UPDATE album SET iRating = ? WHERE idAlbum = ?"
-            kodicursor.execute(query, (rating, kodiid))
+            self.kodi_db.rate_song(playcount, dateplayed, rating, kodiid)
 
         emby_db.updateReference(itemid, checksum)
 
@@ -889,21 +714,19 @@ class Music(common.Items):
             # Remove artist
             self.removeArtist(kodiid)
 
-        log.info("Deleted %s: %s from kodi database" % (mediatype, itemid))
+        log.info("Deleted %s: %s from kodi database", mediatype, itemid)
 
-    def removeSong(self, kodiId):
+    def removeSong(self, kodi_id):
 
-        kodicursor = self.kodicursor
+        self.artwork.delete_artwork(kodi_id, "song", self.kodicursor)
+        self.kodi_db.remove_song(kodi_id)
 
-        self.artwork.delete_artwork(kodiId, "song", self.kodicursor)
-        self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiId,))
+    def removeAlbum(self, kodi_id):
 
-    def removeAlbum(self, kodiId):
+        self.artwork.delete_artwork(kodi_id, "album", self.kodicursor)
+        self.kodi_db.remove_album(kodi_id)
 
-        self.artwork.delete_artwork(kodiId, "album", self.kodicursor)
-        self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiId,))
+    def removeArtist(self, kodi_id):
 
-    def removeArtist(self, kodiId):
-
-        self.artwork.delete_artwork(kodiId, "artist", self.kodicursor)
-        self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiId,))
+        self.artwork.delete_artwork(kodi_id, "artist", self.kodicursor)
+        self.kodi_db.remove_artist(kodi_id)
diff --git a/resources/lib/objects/musicvideos.py b/resources/lib/objects/musicvideos.py
index 16db704a..118c36ee 100644
--- a/resources/lib/objects/musicvideos.py
+++ b/resources/lib/objects/musicvideos.py
@@ -6,9 +6,9 @@ import logging
 import urllib
 
 import api
-import common
 import embydb_functions as embydb
-import kodidb_functions as kodidb
+import _kodi_musicvideos
+from _common import Items
 from utils import window, language as lang, catch_except
 
 ##################################################################################################
@@ -18,7 +18,7 @@ log = logging.getLogger("EMBY."+__name__)
 ##################################################################################################
 
 
-class MusicVideos(common.Items):
+class MusicVideos(Items):
 
 
     def __init__(self, embycursor, kodicursor, pdialog=None):
@@ -26,10 +26,10 @@ class MusicVideos(common.Items):
         self.embycursor = embycursor
         self.emby_db = embydb.Embydb_Functions(self.embycursor)
         self.kodicursor = kodicursor
-        self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
+        self.kodi_db = _kodi_musicvideos.KodiMusicVideos(self.kodicursor)
         self.pdialog = pdialog
 
-        common.Items.__init__(self)
+        Items.__init__(self)
 
     def _get_func(self, item_type, action):
 
@@ -119,7 +119,7 @@ class MusicVideos(common.Items):
 
 
     def added(self, items, total=None, view=None):
-        for item in super(MusicVideos, self).added(items, total, True):
+        for item in super(MusicVideos, self).added(items, total):
             if self.add_update(item, view):
                 self.content_pop(item.get('Name', "unknown"))
 
@@ -146,16 +146,10 @@ class MusicVideos(common.Items):
             update_item = False
             log.debug("mvideoid: %s not found", itemid)
             # mvideoid
-            kodicursor.execute("select coalesce(max(idMVideo),0) from musicvideo")
-            mvideoid = kodicursor.fetchone()[0] + 1
+            mvideoid = self.kodi_db.create_entry()
 
         else:
-            # Verification the item is still in Kodi
-            query = "SELECT * FROM musicvideo WHERE idMVideo = ?"
-            kodicursor.execute(query, (mvideoid,))
-            try:
-                kodicursor.fetchone()[0]
-            except TypeError:
+            if self.kodi_db.get_musicvideo(mvideoid) is None:
                 # item is not found, let's recreate it.
                 update_item = False
                 log.info("mvideoid: %s missing from Kodi, repairing the entry.", mvideoid)
@@ -224,24 +218,10 @@ class MusicVideos(common.Items):
         if update_item:
             log.info("UPDATE mvideo itemid: %s - Title: %s", itemid, title)
 
-            # Update path
-            query = "UPDATE path SET strPath = ? WHERE idPath = ?"
-            kodicursor.execute(query, (path, pathid))
-
-            # Update the filename
-            query = "UPDATE files SET strFilename = ?, dateAdded = ? WHERE idFile = ?"
-            kodicursor.execute(query, (filename, dateadded, fileid))
-
             # Update the music video entry
-            query = ' '.join((
+            self.kodi_db.update_musicvideo(title, runtime, director, studio, year, plot, album,
+                                           artist, genre, track, mvideoid)
 
-                "UPDATE musicvideo",
-                "SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?,",
-                    "c11 = ?, c12 = ?"
-                "WHERE idMVideo = ?"
-            ))
-            kodicursor.execute(query, (title, runtime, director, studio, year, plot, album,
-                                       artist, genre, track, mvideoid))
             # Update the checksum in emby table
             emby_db.updateReference(itemid, checksum)
 
@@ -250,57 +230,23 @@ class MusicVideos(common.Items):
             log.info("ADD mvideo itemid: %s - Title: %s", itemid, title)
 
             # Add path
-            query = ' '.join((
-
-                "SELECT idPath",
-                "FROM path",
-                "WHERE strPath = ?"
-            ))
-            kodicursor.execute(query, (path,))
-            try:
-                pathid = kodicursor.fetchone()[0]
-            except TypeError:
-                kodicursor.execute("select coalesce(max(idPath),0) from path")
-                pathid = kodicursor.fetchone()[0] + 1
-                query = (
-                    '''
-                    INSERT OR REPLACE INTO path(
-                        idPath, strPath, strContent, strScraper, noUpdate)
-
-                    VALUES (?, ?, ?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (pathid, path, "musicvideos", "metadata.local", 1))
-
+            pathid = self.kodi_db.add_path(path)
             # Add the file
-            kodicursor.execute("select coalesce(max(idFile),0) from files")
-            fileid = kodicursor.fetchone()[0] + 1
-            query = (
-                '''
-                INSERT INTO files(
-                    idFile, idPath, strFilename, dateAdded)
-
-                VALUES (?, ?, ?, ?)
-                '''
-            )
-            kodicursor.execute(query, (fileid, pathid, filename, dateadded))
+            fileid = self.kodi_db.add_file(filename, pathid)
 
             # Create the musicvideo entry
-            query = (
-                '''
-                INSERT INTO musicvideo(
-                    idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10, c11, c12)
-
-                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                '''
-            )
-            kodicursor.execute(query, (mvideoid, fileid, title, runtime, director, studio,
-                                       year, plot, album, artist, genre, track))
+            self.kodi_db.add_musicvideo(mvideoid, fileid, title, runtime, director, studio,
+                                        year, plot, album, artist, genre, track)
 
             # Create the reference in emby table
             emby_db.addReference(itemid, mvideoid, "MusicVideo", "musicvideo", fileid, pathid,
                                  checksum=checksum, mediafolderid=viewid)
 
+        # Update the path
+        self.kodi_db.update_path(pathid, path, "musicvideos", "metadata.local")
+        # Update the file
+        self.kodi_db.update_file(fileid, filename, pathid, dateadded)
+
         # Process cast
         people = item['People']
         artists = item['ArtistItems']
@@ -308,26 +254,26 @@ class MusicVideos(common.Items):
             artist['Type'] = "Artist"
         people.extend(artists)
         people = artwork.get_people_artwork(people)
-        self.kodi_db.addPeople(mvideoid, people, "musicvideo")
+        self.kodi_db.add_people(mvideoid, people, "musicvideo")
         # Process genres
-        self.kodi_db.addGenres(mvideoid, genres, "musicvideo")
+        self.kodi_db.add_genres(mvideoid, genres, "musicvideo")
         # Process artwork
         artwork.add_artwork(artwork.get_all_artwork(item), mvideoid, "musicvideo", kodicursor)
         # Process stream details
         streams = API.get_media_streams()
-        self.kodi_db.addStreams(fileid, streams, runtime)
+        self.kodi_db.add_streams(fileid, streams, runtime)
         # Process studios
-        self.kodi_db.addStudios(mvideoid, studios, "musicvideo")
+        self.kodi_db.add_studios(mvideoid, studios, "musicvideo")
         # Process tags: view, emby tags
         tags = [viewtag]
         tags.extend(item['Tags'])
         if userdata['Favorite']:
             tags.append("Favorite musicvideos")
-        self.kodi_db.addTags(mvideoid, tags, "musicvideo")
+        self.kodi_db.add_tags(mvideoid, tags, "musicvideo")
         # Process playstates
         resume = API.adjust_resume(userdata['Resume'])
         total = round(float(runtime), 6)
-        self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+        self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
 
         return True
 
@@ -354,9 +300,9 @@ class MusicVideos(common.Items):
 
         # Process favorite tags
         if userdata['Favorite']:
-            self.kodi_db.addTag(mvideoid, "Favorite musicvideos", "musicvideo")
+            self.kodi_db.get_tag(mvideoid, "Favorite musicvideos", "musicvideo")
         else:
-            self.kodi_db.removeTag(mvideoid, "Favorite musicvideos", "musicvideo")
+            self.kodi_db.remove_tag(mvideoid, "Favorite musicvideos", "musicvideo")
 
         # Process playstates
         playcount = userdata['PlayCount']
@@ -364,7 +310,7 @@ class MusicVideos(common.Items):
         resume = API.adjust_resume(userdata['Resume'])
         total = round(float(runtime), 6)
 
-        self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+        self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
         emby_db.updateReference(itemid, checksum)
 
     def remove(self, itemid):
@@ -382,26 +328,13 @@ class MusicVideos(common.Items):
         except TypeError:
             return
 
+        # Remove the emby reference
+        emby_db.removeItem(itemid)
         # Remove artwork
-        query = ' '.join((
+        artwork.delete_artwork(mvideoid, "musicvideo", self.kodicursor)
 
-            "SELECT url, type",
-            "FROM art",
-            "WHERE media_id = ?",
-            "AND media_type = 'musicvideo'"
-        ))
-        kodicursor.execute(query, (mvideoid,))
-        for row in kodicursor.fetchall():
-
-            url = row[0]
-            imagetype = row[1]
-            if imagetype in ("poster", "fanart"):
-                artwork.delete_cached_artwork(url)
-
-        kodicursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (mvideoid,))
-        kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
+        self.kodi_db.remove_musicvideo(mvideoid, fileid)
         if self.direct_path:
-            kodicursor.execute("DELETE FROM path WHERE idPath = ?", (pathid,))
-        self.embycursor.execute("DELETE FROM emby WHERE emby_id = ?", (itemid,))
+            self.kodi_db.remove_path(pathid)
 
         log.info("Deleted musicvideo %s from kodi database", itemid)
diff --git a/resources/lib/objects/tvshows.py b/resources/lib/objects/tvshows.py
index c44ca75b..afb96312 100644
--- a/resources/lib/objects/tvshows.py
+++ b/resources/lib/objects/tvshows.py
@@ -7,9 +7,10 @@ import urllib
 from ntpath import dirname
 
 import api
-import common
 import embydb_functions as embydb
 import kodidb_functions as kodidb
+import _kodi_tvshows
+from _common import Items
 from utils import window, settings, language as lang, catch_except
 
 ##################################################################################################
@@ -19,7 +20,7 @@ log = logging.getLogger("EMBY."+__name__)
 ##################################################################################################
 
 
-class TVShows(common.Items):
+class TVShows(Items):
 
 
     def __init__(self, embycursor, kodicursor, pdialog=None):
@@ -27,12 +28,12 @@ class TVShows(common.Items):
         self.embycursor = embycursor
         self.emby_db = embydb.Embydb_Functions(self.embycursor)
         self.kodicursor = kodicursor
-        self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
+        self.kodi_db = _kodi_tvshows.KodiTVShows(self.kodicursor)
         self.pdialog = pdialog
 
         self.new_time = int(settings('newvideotime'))*1000
 
-        common.Items.__init__(self)
+        Items.__init__(self)
 
     def _get_func(self, item_type, action):
 
@@ -252,16 +253,11 @@ class TVShows(common.Items):
         except TypeError:
             update_item = False
             log.debug("showid: %s not found", itemid)
-            kodicursor.execute("select coalesce(max(idShow),0) from tvshow")
-            showid = kodicursor.fetchone()[0] + 1
+            showid = self.kodi_db.create_entry()
 
         else:
             # Verification the item is still in Kodi
-            query = "SELECT * FROM tvshow WHERE idShow = ?"
-            kodicursor.execute(query, (showid,))
-            try:
-                kodicursor.fetchone()[0]
-            except TypeError:
+            if self.kodi_db.get_tvshow(showid) is None:
                 # item is not found, let's recreate it.
                 update_item = False
                 log.info("showid: %s missing from Kodi, repairing the entry", showid)
@@ -345,15 +341,8 @@ class TVShows(common.Items):
             log.info("UPDATE tvshow itemid: %s - Title: %s", itemid, title)
 
             # Update the tvshow entry
-            query = ' '.join((
-
-                "UPDATE tvshow",
-                "SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?,",
-                    "c12 = ?, c13 = ?, c14 = ?, c15 = ?",
-                "WHERE idShow = ?"
-            ))
-            kodicursor.execute(query, (title, plot, rating, premieredate, genre, title,
-                                       tvdb, mpaa, studio, sorttitle, showid))
+            self.kodi_db.update_tvshow(title, plot, rating, premieredate, genre, title,
+                                       tvdb, mpaa, studio, sorttitle, showid)
 
             # Update the checksum in emby table
             emby_db.updateReference(itemid, checksum)
@@ -363,68 +352,49 @@ class TVShows(common.Items):
             log.info("ADD tvshow itemid: %s - Title: %s", itemid, title)
 
             # Add top path
-            toppathid = self.kodi_db.addPath(toplevelpath)
-            query = ' '.join((
-
-                "UPDATE path",
-                "SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
-                "WHERE idPath = ?"
-            ))
-            kodicursor.execute(query, (toplevelpath, "tvshows", "metadata.local", 1, toppathid))
+            toppathid = self.kodi_db.add_path(toplevelpath)
+            self.kodi_db.update_path(toppathid, toplevelpath, "tvshows", "metadata.local")
 
             # Add path
-            pathid = self.kodi_db.addPath(path)
+            pathid = self.kodi_db.add_path(path)
 
             # Create the tvshow entry
-            query = (
-                '''
-                INSERT INTO tvshow(idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14, c15)
-
-                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                '''
-            )
-            kodicursor.execute(query, (showid, title, plot, rating, premieredate, genre,
-                                       title, tvdb, mpaa, studio, sorttitle))
-
-            # Link the path
-            query = "INSERT INTO tvshowlinkpath(idShow, idPath) values(?, ?)"
-            kodicursor.execute(query, (showid, pathid))
+            self.kodi_db.add_tvshow(showid, title, plot, rating, premieredate, genre,
+                                    title, tvdb, mpaa, studio, sorttitle)
 
             # Create the reference in emby table
             emby_db.addReference(itemid, showid, "Series", "tvshow", pathid=pathid,
                                  checksum=checksum, mediafolderid=viewid)
 
-        # Update the path
-        query = ' '.join((
 
-            "UPDATE path",
-            "SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
-            "WHERE idPath = ?"
-        ))
-        kodicursor.execute(query, (path, None, None, 1, pathid))
+        # Link the path
+        self.kodi_db.link_tvshow(showid, pathid)
+
+        # Update the path
+        self.kodi_db.update_path(pathid, path, None, None)
 
         # Process cast
         people = artwork.get_people_artwork(item['People'])
-        self.kodi_db.addPeople(showid, people, "tvshow")
+        self.kodi_db.add_people(showid, people, "tvshow")
         # Process genres
-        self.kodi_db.addGenres(showid, genres, "tvshow")
+        self.kodi_db.add_genres(showid, genres, "tvshow")
         # Process artwork
         artwork.add_artwork(artwork.get_all_artwork(item), showid, "tvshow", kodicursor)
         # Process studios
-        self.kodi_db.addStudios(showid, studios, "tvshow")
+        self.kodi_db.add_studios(showid, studios, "tvshow")
         # Process tags: view, emby tags
         tags = [viewtag]
         tags.extend(item['Tags'])
         if userdata['Favorite']:
             tags.append("Favorite tvshows")
-        self.kodi_db.addTags(showid, tags, "tvshow")
+        self.kodi_db.add_tags(showid, tags, "tvshow")
         # Process seasons
         all_seasons = emby.getSeasons(itemid)
         for season in all_seasons['Items']:
             self.add_updateSeason(season, showid=showid)
         else:
             # Finally, refresh the all season entry
-            seasonid = self.kodi_db.addSeason(showid, -1)
+            seasonid = self.kodi_db.get_season(showid, -1)
             # Process artwork
             artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor)
 
@@ -456,7 +426,7 @@ class TVShows(common.Items):
                 self.add_update(show)
                 return
 
-        seasonid = self.kodi_db.addSeason(showid, seasonnum, item['Name'])
+        seasonid = self.kodi_db.get_season(showid, seasonnum, item['Name'])
 
         if item['LocationType'] != "Virtual":
             # Create the reference in emby table
@@ -494,16 +464,11 @@ class TVShows(common.Items):
             update_item = False
             log.debug("episodeid: %s not found", itemid)
             # episodeid
-            kodicursor.execute("select coalesce(max(idEpisode),0) from episode")
-            episodeid = kodicursor.fetchone()[0] + 1
+            episodeid = self.kodi_db.create_entry_episode()
 
         else:
             # Verification the item is still in Kodi
-            query = "SELECT * FROM episode WHERE idEpisode = ?"
-            kodicursor.execute(query, (episodeid,))
-            try:
-                kodicursor.fetchone()[0]
-            except TypeError:
+            if self.kodi_db.get_episode(episodeid) is None:
                 # item is not found, let's recreate it.
                 update_item = False
                 log.info("episodeid: %s missing from Kodi, repairing the entry", episodeid)
@@ -571,7 +536,7 @@ class TVShows(common.Items):
                 log.error("Skipping: %s. Unable to add series: %s", itemid, seriesId)
                 return False
 
-        seasonid = self.kodi_db.addSeason(showid, season)
+        seasonid = self.kodi_db.get_season(showid, season)
 
 
         ##### GET THE FILE AND PATH #####
@@ -610,27 +575,14 @@ class TVShows(common.Items):
             # Update the movie entry
             if self.kodi_version in (16, 17):
                 # Kodi Jarvis, Krypton
-                query = ' '.join((
-
-                    "UPDATE episode",
-                    "SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?,",
-                        "c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, idSeason = ?, idShow = ?",
-                    "WHERE idEpisode = ?"
-                ))
-                kodicursor.execute(query, (title, plot, rating, writer, premieredate, runtime,
-                                           director, season, episode, title, airsBeforeSeason,
-                                           airsBeforeEpisode, seasonid, showid, episodeid))
+                self.kodi_db.update_episode_16(title, plot, rating, writer, premieredate, runtime,
+                                               director, season, episode, title, airsBeforeSeason,
+                                               airsBeforeEpisode, seasonid, showid, episodeid)
             else:
-                query = ' '.join((
+                self.kodi_db.update_episode(title, plot, rating, writer, premieredate, runtime,
+                                            director, season, episode, title, airsBeforeSeason,
+                                            airsBeforeEpisode, showid, episodeid)
 
-                    "UPDATE episode",
-                    "SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?,",
-                        "c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ?, idShow = ?",
-                    "WHERE idEpisode = ?"
-                ))
-                kodicursor.execute(query, (title, plot, rating, writer, premieredate, runtime,
-                                           director, season, episode, title, airsBeforeSeason,
-                                           airsBeforeEpisode, showid, episodeid))
             # Update the checksum in emby table
             emby_db.updateReference(itemid, checksum)
             # Update parentid reference
@@ -641,86 +593,49 @@ class TVShows(common.Items):
             log.info("ADD episode itemid: %s - Title: %s", itemid, title)
 
             # Add path
-            pathid = self.kodi_db.addPath(path)
+            pathid = self.kodi_db.add_path(path)
             # Add the file
-            fileid = self.kodi_db.addFile(filename, pathid)
+            fileid = self.kodi_db.add_file(filename, pathid)
 
             # Create the episode entry
             if self.kodi_version in (16, 17):
                 # Kodi Jarvis, Krypton
-                query = (
-                    '''
-                    INSERT INTO episode(
-                        idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14,
-                        idShow, c15, c16, idSeason)
-
-                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (episodeid, fileid, title, plot, rating, writer,
-                                           premieredate, runtime, director, season, episode, title,
-                                           showid, airsBeforeSeason, airsBeforeEpisode, seasonid))
+                self.kodi_db.add_episode_16(episodeid, fileid, title, plot, rating, writer,
+                                            premieredate, runtime, director, season, episode, title,
+                                            showid, airsBeforeSeason, airsBeforeEpisode, seasonid)
             else:
-                query = (
-                    '''
-                    INSERT INTO episode(
-                        idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14,
-                        idShow, c15, c16)
-
-                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-                    '''
-                )
-                kodicursor.execute(query, (episodeid, fileid, title, plot, rating, writer,
-                                           premieredate, runtime, director, season, episode, title,
-                                           showid, airsBeforeSeason, airsBeforeEpisode))
+                self.kodi_db.add_episode(episodeid, fileid, title, plot, rating, writer,
+                                         premieredate, runtime, director, season, episode, title,
+                                         showid, airsBeforeSeason, airsBeforeEpisode)
 
             # Create the reference in emby table
             emby_db.addReference(itemid, episodeid, "Episode", "episode", fileid, pathid,
                                  seasonid, checksum)
 
         # Update the path
-        query = ' '.join((
-
-            "UPDATE path",
-            "SET strPath = ?, strContent = ?, strScraper = ?, noUpdate = ?",
-            "WHERE idPath = ?"
-        ))
-        kodicursor.execute(query, (path, None, None, 1, pathid))
-
+        self.kodi_db.update_path(pathid, path, None, None)
         # Update the file
-        query = ' '.join((
-
-            "UPDATE files",
-            "SET idPath = ?, strFilename = ?, dateAdded = ?",
-            "WHERE idFile = ?"
-        ))
-        kodicursor.execute(query, (pathid, filename, dateadded, fileid))
+        self.kodi_db.update_file(fileid, filename, pathid, dateadded)
 
         # Process cast
         people = artwork.get_people_artwork(item['People'])
-        self.kodi_db.addPeople(episodeid, people, "episode")
+        self.kodi_db.add_people(episodeid, people, "episode")
         # Process artwork
         artworks = artwork.get_all_artwork(item)
         artwork.add_update_art(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
         # Process stream details
         streams = API.get_media_streams()
-        self.kodi_db.addStreams(fileid, streams, runtime)
+        self.kodi_db.add_streams(fileid, streams, runtime)
         # Process playstates
         resume = API.adjust_resume(userdata['Resume'])
         total = round(float(runtime), 6)
-        self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+        self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
         if not self.direct_path and resume:
             # Create additional entry for widgets. This is only required for plugin/episode.
-            temppathid = self.kodi_db.getPath("plugin://plugin.video.emby.tvshows/")
-            tempfileid = self.kodi_db.addFile(filename, temppathid)
-            query = ' '.join((
-
-                "UPDATE files",
-                "SET idPath = ?, strFilename = ?, dateAdded = ?",
-                "WHERE idFile = ?"
-            ))
-            kodicursor.execute(query, (temppathid, filename, dateadded, tempfileid))
-            self.kodi_db.addPlaystate(tempfileid, resume, total, playcount, dateplayed)
+            temppathid = self.kodi_db.get_path("plugin://plugin.video.emby.tvshows/")
+            tempfileid = self.kodi_db.add_file(filename, temppathid)
+            self.kodi_db.update_file(tempfileid, filename, temppathid, dateadded)
+            self.kodi_db.add_playstate(tempfileid, resume, total, playcount, dateplayed)
 
         return True
 
@@ -750,9 +665,9 @@ class TVShows(common.Items):
         # Process favorite tags
         if mediatype == "tvshow":
             if userdata['Favorite']:
-                self.kodi_db.addTag(kodiid, "Favorite tvshows", "tvshow")
+                self.kodi_db.get_tag(kodiid, "Favorite tvshows", "tvshow")
             else:
-                self.kodi_db.removeTag(kodiid, "Favorite tvshows", "tvshow")
+                self.kodi_db.remove_tag(kodiid, "Favorite tvshows", "tvshow")
         elif mediatype == "episode":
             # Process playstates
             playcount = userdata['PlayCount']
@@ -762,25 +677,19 @@ class TVShows(common.Items):
 
             log.debug("%s New resume point: %s", itemid, resume)
 
-            self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
+            self.kodi_db.add_playstate(fileid, resume, total, playcount, dateplayed)
             if not self.direct_path and not resume:
                 # Make sure there's no other bookmarks created by widget.
-                filename = self.kodi_db.getFile(fileid)
-                self.kodi_db.removeFile("plugin://plugin.video.emby.tvshows/", filename)
+                filename = self.kodi_db.get_filename(fileid)
+                self.kodi_db.remove_file("plugin://plugin.video.emby.tvshows/", filename)
 
             if not self.direct_path and resume:
                 # Create additional entry for widgets. This is only required for plugin/episode.
-                filename = self.kodi_db.getFile(fileid)
-                temppathid = self.kodi_db.getPath("plugin://plugin.video.emby.tvshows/")
-                tempfileid = self.kodi_db.addFile(filename, temppathid)
-                query = ' '.join((
-
-                    "UPDATE files",
-                    "SET idPath = ?, strFilename = ?, dateAdded = ?",
-                    "WHERE idFile = ?"
-                ))
-                self.kodicursor.execute(query, (temppathid, filename, dateadded, tempfileid))
-                self.kodi_db.addPlaystate(tempfileid, resume, total, playcount, dateplayed)
+                filename = self.kodi_db.get_filename(fileid)
+                temppathid = self.kodi_db.get_path("plugin://plugin.video.emby.tvshows/")
+                tempfileid = self.kodi_db.add_file(filename, temppathid)
+                self.kodi_db.update_file(tempfileid, filename, temppathid, dateadded)
+                self.kodi_db.add_playstate(tempfileid, resume, total, playcount, dateplayed)
 
         emby_db.updateReference(itemid, checksum)
 
@@ -890,7 +799,7 @@ class TVShows(common.Items):
         
         kodicursor = self.kodicursor
         self.artwork.delete_artwork(kodiid, "tvshow", kodicursor)
-        kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,))
+        self.kodi_db.remove_tvshow(kodiid)
         log.debug("Removed tvshow: %s", kodiid)
 
     def removeSeason(self, kodiid):
@@ -898,7 +807,7 @@ class TVShows(common.Items):
         kodicursor = self.kodicursor
 
         self.artwork.delete_artwork(kodiid, "season", kodicursor)
-        kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
+        self.kodi_db.remove_season(kodiid)
         log.debug("Removed season: %s", kodiid)
 
     def removeEpisode(self, kodiid, fileid):
@@ -906,6 +815,5 @@ class TVShows(common.Items):
         kodicursor = self.kodicursor
 
         self.artwork.delete_artwork(kodiid, "episode", kodicursor)
-        kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,))
-        kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
+        self.kodi_db.remove_episode(kodiid, fileid)
         log.debug("Removed episode: %s", kodiid)
diff --git a/resources/lib/videonodes.py b/resources/lib/videonodes.py
index f8475d79..5a140e88 100644
--- a/resources/lib/videonodes.py
+++ b/resources/lib/videonodes.py
@@ -67,18 +67,17 @@ class VideoNodes(object):
                 dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
             xbmcvfs.exists(path)
 
+        if delete:
+            dirs, files = xbmcvfs.listdir(nodepath)
+            for file in files:
+                xbmcvfs.delete(nodepath + file)
+
+            log.info("Sucessfully removed videonode: %s." % tagname)
+            return
         # Create the node directory
         if not xbmcvfs.exists(nodepath) and not mediatype == "photos":
             # We need to copy over the default items
             xbmcvfs.mkdirs(nodepath)
-        else:
-            if delete:
-                dirs, files = xbmcvfs.listdir(nodepath)
-                for file in files:
-                    xbmcvfs.delete(nodepath + file)
-
-                log.info("Sucessfully removed videonode: %s." % tagname)
-                return
 
         # Create index entry
         nodeXML = "%sindex.xml" % nodepath