I'm kind of in the same situation, except that I've abandoned desktop mail clients since moving away from OS X. Mail.app had its problems, and seemed to be getting worse, but it's the only local mail client I've been able to tolerate for some time.

Now I just forward my IMAP accounts to gmail. This is horrible for many reasons (don't lecture me, I know), but I haven't been able to find a good solution and messing about with email is time-consuming.

I may just consolidate on Fastmail when my current IMAP provider subscription needs renewing. From a brief test a while back their web client seems to be on a par with gmail.

If you're looking to consolidate your email the best way is imapfilter https://github.com/lefcha/imapfilter I use this LUA script (this is the Jinja2 template so obviously you'll need to substitute the portions in {{ }} with your real values. It runs on an hourly cronjob on my server and sucks down all the mail from Gmail and another account and then puts it in my main inbox via IMAP (not forwarding) so you don't have to worry about opportunistic transport encryption. It also does not mess with the headers which forwarding emails invariably does.

  -- crontab -e
  -- 0 * * * * /usr/local/bin/imapfilter

  function main ()

      -- See 'man imapfilter_config' for an explanation of
      -- imapfilter options and functions.

      -- Some config examples:
      -- https://github.com/lefcha/imapfilter/blob/master/samples/config.lua
      -- https://gist.github.com/dylanwh/408810
      -- http://www.npcglib.org/~stathis/blog/2012/07/09/linux-task-sorting-mail-with-imapfilter/

      -- General Options
      options.timeout = 120
      options.subscribe = true

      -- Accounts
      {%- for v in ACCOUNTS | from_json %}
      local {{ v.serverName }} = IMAP {
          server = '{{ v.server }}',
          username = '{{ v.username }}',
          password = '{{ v.password }}',
          ssl = '{{ v.ssl }}'
      }

      {%- endfor %}

      -- GMAIL
      -- Gmail behaves differently to normal imap. With a normal imap acccount
      -- you can simply use move_messages(). Google stores both inbox
      -- and sent email in the "[Gmail]/All Mail" folder. An email sent to yourself
      -- from the same email address exists as a single email and is visible in
      -- the Inbox and Sent box. If you delete the inbox mail then the sent mail
      -- is also deleted. Thus it is only safe to delete mail once both the Inbox
      -- and Sent box is copied.

      -- Only go ahead and copy inbox/sent/spam from gmail if I have received
      -- some Inbox email.
      if (gmail['Inbox']:check_status() > 0) then
          inbox_mail = gmail["Inbox"]:select_all()
          inbox_copy_success = inbox_mail:copy_messages({{ PRIMARY }}['Gmail Inbox'])

          sent_mail = gmail['[Gmail]/Sent Mail']:select_all()
          sent_copy_success = sent_mail:copy_messages({{ PRIMARY }}['Gmail Sent'])

          spam_mail = gmail["[Gmail]/Spam"]:select_all()
          spam_mail:move_messages({{ PRIMARY }}['Gmail Spam'])

          -- Only clear the All Mail folder if we were successful in moving
          -- our Inbox and Sent mail. Note: move_messages is supposed to return
          -- booleans for copying the messages and then marking them as deleted.
          -- For some reason the mark for deletion return value is 'nil'.
          -- This may need to be [Gmail]/Bin or [Gmail]/Trash check your account!
          if (inbox_copy_success and sent_copy_success) then
              print('Safe to delete both inbox and sent')
              move_inbox = inbox_mail:move_messages(gmail['[Gmail]/Trash'])
              move_sent = sent_mail:move_messages(gmail['[Gmail]/Trash'])

              if (move_inbox and move_sent) then
                  print('Emptying bin');
                  bin_mail = gmail['[Gmail]/Trash']:select_all()
                  bin_mail:delete_messages()
              end
          end
      end

      {%- if SECONDARY != '' %}
      -- {{ SECONDARY }}
      -- Only go ahead and copy inbox/sent/spam from {{ SECONDARY }} if I have received
      -- some Inbox email.
      if ({{ SECONDARY }}['Inbox']:check_status() > 0) then
          inbox_results = {{ SECONDARY }}['Inbox']:select_all()
          inbox_results:move_messages({{ PRIMARY }}['{{ SECONDARY }} Inbox'])

          sent_results = {{ SECONDARY }}['Sent']:select_all()
          sent_results:move_messages({{ PRIMARY }}['{{ SECONDARY }} Sent'])

          spam_results = {{ SECONDARY }}['Junk']:select_all()
          spam_results:move_messages({{ PRIMARY }}['{{ SECONDARY }} Spam'])
      end
      {%- endif %}
  end

  main()