             @createAdminRole()
 
         .then =>
-            @fetchAll()
+            @fetch()
 
         .then (tokenStrs) =>
 
+            if not @validTokenStrs(tokenStrs)
+                throw @invalidTokenError(tokenStrs)
+
             ____("tokens: #{tokenStrs.join(',')}")
 
-            Promise.all(
-                for tokenStr in tokenStrs
-                    token = new AdminToken(tokenStr)
-                    @setNew(token)
-            )
+            @updateTokens(tokenStrs)
+
+
+
+    ###*
+    Refresh admin tokens.
+
+    @public
+    @method refreshTokens
+    @return {Promise}
+    ###
+    refreshTokens: ->
+
+        @fetch().then (tokenStrs) =>
+
+            if not @validTokenStrs(tokenStrs)
+
+                console.error("""
+                    AdminTokenManager: Fetched tokens are not valid!
+
+                    Results: #{tokenStrs}
+
+                    """)
+                return Promise.resolve(false)
+
+            @updateTokens(tokenStrs)
+
+
+    ###*
+    Save new tokens and destroy old tokens.
+    @private
+    ###
+    updateTokens: (tokenStrs) ->
+
+        tokens = tokenStrs.map (tokenStr) -> new AdminToken(tokenStr)
+
+        Promise.all(tokens.map (token) => @setNew token).then =>
+
+            promises = []
+
+            for tokenStr of @tokensById when tokenStr not in tokenStrs
+                promises.push @destroy(tokenStr)
+
+            Promise.all promises
+
+
+    ###*
+    set new token
+    @private
+    ###
+    setNew: (token) ->
+
+        { AccessToken } = @models
+
+        @findById(token.id).then (foundToken) =>
+
+            if foundToken?
+                ____("token: #{token.id} already exists.")
+
+                if foundToken.userId isnt ADMIN_USER
+                    console.error """
+                        AdminTokenManager: The token `#{token.id}` is already exist for non-admin user. Skip creating.
+                    """
+                    console.error()
+
+                return false
+
+            ____("saving token: #{token.id}")
+            promisify (cb) =>
+                AccessToken.create token, cb
+
+            .then => true
+
+        .then (tokenIsSavedNow) =>
+            @tokensById[token.id] = token
+
+
+
+    ###*
+    Destroy the token
+    @private
+    ###
+    destroy: (tokenStr) ->
+
+        @findById(tokenStr).then (foundToken) =>
+            # check if the token to be deleted is admin token
+            if foundToken.userId isnt ADMIN_USER.id
+                console.error """
+                    AdminTokenManager: The token `#{token.id}` is not the admin token. Skip destroying.
+                """
+                return false
+
+            { AccessToken } = @models
+
+            promisify (cb) =>
+                AccessToken.destroyById tokenStr, cb
+
             .then =>
-                ____("tokens are created.")
-                ____(@tokens.map((t) -> t.id).join(','))
-                return @tokens.slice()
-
-
+                delete @tokensById[tokenStr]
+
+
+    ###*
+    Find AccessToken model by tokenStr
+    @private
+    ###
+    findById: (tokenStr) ->
+
+        { AccessToken } = @models
+
+        promisify (cb) =>
+            AccessToken.findById tokenStr, cb
+
+
+
+    ###*
+    Create admin user, called once in 'init' function.
+    @private
+    ###
     createAdminUser: ->
         ____("creating admin user. id: #{ADMIN_USER.id}")
         { User } = @models

            User.create ADMIN_USER, cb


    createAdminRole: ->

        ____("creating admin role.")

        fn(cb)


###*
Admin token manager

@class AdminTokenManager
###
class AdminTokenManager

    ###*
    @param {Function|Array(String)} [options.fetch] function to return admin tokens (or promise of it). When string[] is given, these value are used for the admin access token.
    @param {Number} [options.intervalHours] Interval hours to fetch new admin token.
    ###
    constructor: (options = {}) ->

        { fetch, @intervalHours } = options

        @fetch = @constructor.createFetchFunction(fetch)

        @tokensById = {}



    ###*
    Set fetched tokens as admin tokens.

    @public
    @method init
    @param {Object} models app.models in LoopBack
    @return {Promise}
    ###
    init: (@models) ->

        @createAdminUser()
