   # return: promise
   # ------------------------------------------------------------
   load_remote_notes: =>
-    # fetch remote notes
     # TODO handle failure
-    return apiClient.notes.all()
-      .$promise.then (data) =>
-        @_merge_remote_notes(data['notes'])
-        # FIXME need to use promise
-        return @get_all_notes()
+    return apiClient.notes.all().$promise.then (data) =>
+      @_merge_remote_notes(data['notes']).then(
+        () =>
+          console.log('finish merging remote notes')
+          return @get_all_notes()
+        (error) =>
+          # TODO pass error on
+          alert('_merge_remote_notes() failed!')
+      )
 
   # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Merge/Sync Operations >
 

  # ------------------------------------------------------------------------------------------------------------------
  # Operations for notes
  # ------------------------------------------------------------------------------------------------------------------
  # TODO prevent multipal duplicated requests
  vm.refresh_all_notes = ->
    # TODO handle failure
    noteManager.load_remote_notes().then (notes) ->
        vm.all_notes = notes

  vm.load_note = (guid) ->

        title = note_meta['title']
        console.log('Merging note [' + guid + ']')

        find_p = @find_note_by_guid(guid).then (note) =>
          _find_p_must_finish_promise_list = []
          if note == null
            console.log('About to add note ' + guid)
            p = @add_note_meta({
              guid: guid
              title: title
            }).then () => console.log('note ' + guid + ' metadata added!')
            _find_p_must_finish_promise_list.push(p)
            console.log('pushed to _find_p_must_finish_promise_list. TAG: A')

          else
            console.log('local note ' + guid + ' exists, updating from remote.')
            switch note.status
              when @NOTE_STATUS.NEW
                console.log('[IMPOSSIBLE] remote note\'s local cache is in status NEW')

              when @NOTE_STATUS.SYNCED_META
                # update note title
                p = @update_note({
                  guid: guid
                  title: title
                })
                _find_p_must_finish_promise_list.push(p)
                console.log('pushed to _find_p_must_finish_promise_list. TAG: B')

              when @NOTE_STATUS.SYNCED_ALL
                # fetch the whole note from server and update local
                console.log('local note ' + guid + ' is SYNCED_ALL, about to fetch from remote for updating')
                @fetch_remote_note(guid).then(
                  (data) =>
                    note =
                      guid: data.note.guid
                      title: data.note.title
                      md: data.note.md
                    p = @update_note(note)
                    # maybe FIXME did not add to promise waiting list
                    #_find_p_must_finish_promise_list.push(p)
                    #console.log('pushed to _find_p_must_finish_promise_list. TAG: C')
                  (error) =>
                    alert('fetch note ' + guid + ' failed during _merge_remote_notes():' + JSON.stringify(error))
                )

              when @NOTE_STATUS.MODIFIED
                # do nothing
                console.log('do nothing')

              else
                alert('IMPOSSIBLE: no correct note status')
          return Promise.all(_find_p_must_finish_promise_list)
        must_finish_promise_list.push(find_p)
        console.log('pushed to must_finish_promise_list. TAG: D')

    # Phase two: deleted local notes not needed
    # Notes that should be deleted:
    # not in remote and status is not new/modified
    p = @get_all_notes().then (notes) =>
      for n in notes
        if (n.guid not in remote_note_guid_list) && n.status != @NOTE_STATUS.NEW && n.status != @NOTE_STATUS.MODIFIED
          _p = @delete_note(n.guid)
          must_finish_promise_list.push(_p)
          console.log('pushed to must_finish_promise_list. TAG: E')
    must_finish_promise_list.push(p)
    console.log('pushed to must_finish_promise_list. TAG: F')

    console.log('about to return from _merge_remote_notes(). promise list: ' + JSON.stringify(must_finish_promise_list))
    console.log('check if promises in promise list is actually Promises:')
    for p in must_finish_promise_list
      if p instanceof Promise
        console.log('is Promise!')
      else
        console.log('is NOT Promise!!')
    return Promise.all(must_finish_promise_list)

  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| DB Operations >

  get_all_notes: () =>
    console.log('get_all_notes() invoked')
    return new Promise (resolve, reject) =>
      resolve(@db_server.notes.query().all().execute())

  delete_note: (guid) =>
    console.log('delete_note(' + guid + ') invoked')
    return @find_note_by_guid(guid).then(
      (note) =>
        alert('!!')
        if note is null
