diff --git a/docs/ase-file-specs.md b/docs/ase-file-specs.md
index eefcbe0c5..1e2fab9c3 100644
--- a/docs/ase-file-specs.md
+++ b/docs/ase-file-specs.md
@@ -171,6 +171,9 @@ Ignore this chunk if you find the new palette chunk (0x2019)
                   Saturation     = 13
                   Color          = 14
                   Luminosity     = 15
+                  Addition       = 16
+                  Subtract       = 17
+                  Divide         = 18
   BYTE          Opacity
                   Note: valid only if file header flags field has bit 1 set
   BYTE[3]       For future (set to zero)
diff --git a/src/app/commands/cmd_keyboard_shortcuts.cpp b/src/app/commands/cmd_keyboard_shortcuts.cpp
index b3fdf63a5..a1513b31f 100644
--- a/src/app/commands/cmd_keyboard_shortcuts.cpp
+++ b/src/app/commands/cmd_keyboard_shortcuts.cpp
@@ -21,6 +21,7 @@
 #include "app/ui/keyboard_shortcuts.h"
 #include "app/ui/search_entry.h"
 #include "app/ui/select_accelerator.h"
+#include "app/ui/separator_in_view.h"
 #include "app/ui/skin/skin_theme.h"
 #include "base/bind.h"
 #include "base/fs.h"
@@ -502,10 +503,8 @@ private:
             continue;
 
           if (!group) {
-            group = new Separator(
+            group = new SeparatorInView(
               section()->children()[sectionIdx]->text(), HORIZONTAL);
-            group->setStyle(SkinTheme::instance()->styles.separatorInView());
-
             searchList()->addChild(group);
           }
 
diff --git a/src/app/commands/cmd_layer_properties.cpp b/src/app/commands/cmd_layer_properties.cpp
index d39e65c59..1f1461ab7 100644
--- a/src/app/commands/cmd_layer_properties.cpp
+++ b/src/app/commands/cmd_layer_properties.cpp
@@ -18,6 +18,7 @@
 #include "app/context_access.h"
 #include "app/modules/gui.h"
 #include "app/transaction.h"
+#include "app/ui/separator_in_view.h"
 #include "app/ui/timeline/timeline.h"
 #include "app/ui/user_data_popup.h"
 #include "app/ui_context.h"
@@ -54,6 +55,18 @@ class LayerPropertiesWindow : public app::gen::LayerProperties
                             , public doc::ContextObserver
                             , public doc::DocumentObserver {
 public:
+  class BlendModeItem : public ListItem {
+  public:
+    BlendModeItem(const std::string& name,
+                  const doc::BlendMode mode)
+      : ListItem(name)
+      , m_mode(mode) {
+    }
+    doc::BlendMode mode() const { return m_mode; }
+  private:
+    doc::BlendMode m_mode;
+  };
+
   LayerPropertiesWindow()
     : m_timer(250, this)
     , m_document(nullptr)
@@ -62,22 +75,30 @@ public:
     name()->setMinSize(gfx::Size(128, 0));
     name()->setExpansive(true);
 
-    mode()->addItem("Normal");
-    mode()->addItem("Multiply");
-    mode()->addItem("Screen");
-    mode()->addItem("Overlay");
-    mode()->addItem("Darken");
-    mode()->addItem("Lighten");
-    mode()->addItem("Color Dodge");
-    mode()->addItem("Color Burn");
-    mode()->addItem("Hard Light");
-    mode()->addItem("Soft Light");
-    mode()->addItem("Difference");
-    mode()->addItem("Exclusion");
-    mode()->addItem("Hue");
-    mode()->addItem("Saturation");
-    mode()->addItem("Color");
-    mode()->addItem("Luminosity");
+    mode()->addItem(new BlendModeItem("Normal", doc::BlendMode::NORMAL));
+    mode()->addItem(new SeparatorInView);
+    mode()->addItem(new BlendModeItem("Darken", doc::BlendMode::DARKEN));
+    mode()->addItem(new BlendModeItem("Multiply", doc::BlendMode::MULTIPLY));
+    mode()->addItem(new BlendModeItem("Color Burn", doc::BlendMode::COLOR_BURN));
+    mode()->addItem(new SeparatorInView);
+    mode()->addItem(new BlendModeItem("Lighten", doc::BlendMode::LIGHTEN));
+    mode()->addItem(new BlendModeItem("Screen", doc::BlendMode::SCREEN));
+    mode()->addItem(new BlendModeItem("Color Dodge", doc::BlendMode::COLOR_DODGE));
+    mode()->addItem(new BlendModeItem("Addition", doc::BlendMode::ADDITION));
+    mode()->addItem(new SeparatorInView);
+    mode()->addItem(new BlendModeItem("Overlay", doc::BlendMode::OVERLAY));
+    mode()->addItem(new BlendModeItem("Soft Light", doc::BlendMode::SOFT_LIGHT));
+    mode()->addItem(new BlendModeItem("Hard Light", doc::BlendMode::HARD_LIGHT));
+    mode()->addItem(new SeparatorInView);
+    mode()->addItem(new BlendModeItem("Difference", doc::BlendMode::DIFFERENCE));
+    mode()->addItem(new BlendModeItem("Exclusion", doc::BlendMode::EXCLUSION));
+    mode()->addItem(new BlendModeItem("Subtract", doc::BlendMode::SUBTRACT));
+    mode()->addItem(new BlendModeItem("Divide", doc::BlendMode::DIVIDE));
+    mode()->addItem(new SeparatorInView);
+    mode()->addItem(new BlendModeItem("Hue", doc::BlendMode::HSL_HUE));
+    mode()->addItem(new BlendModeItem("Saturation", doc::BlendMode::HSL_SATURATION));
+    mode()->addItem(new BlendModeItem("Color", doc::BlendMode::HSL_COLOR));
+    mode()->addItem(new BlendModeItem("Luminosity", doc::BlendMode::HSL_LUMINOSITY));
 
     name()->Change.connect(base::Bind<void>(&LayerPropertiesWindow::onStartTimer, this));
     mode()->Change.connect(base::Bind<void>(&LayerPropertiesWindow::onStartTimer, this));
@@ -120,7 +141,11 @@ private:
   }
 
   BlendMode blendModeValue() const {
-    return (BlendMode)mode()->getSelectedItemIndex();
+    BlendModeItem* item = dynamic_cast<BlendModeItem*>(mode()->getSelectedItem());
+    if (item)
+      return item->mode();
+    else
+      return doc::BlendMode::NORMAL;
   }
 
   int opacityValue() const {
@@ -290,7 +315,15 @@ private:
       name()->setEnabled(true);
 
       if (m_layer->isImage()) {
-        mode()->setSelectedItemIndex((int)static_cast<LayerImage*>(m_layer)->blendMode());
+        mode()->setSelectedItem(nullptr);
+        for (auto item : *mode()) {
+          if (auto blendModeItem = dynamic_cast<BlendModeItem*>(item)) {
+            if (blendModeItem->mode() == static_cast<LayerImage*>(m_layer)->blendMode()) {
+              mode()->setSelectedItem(item);
+              break;
+            }
+          }
+        }
         mode()->setEnabled(!m_layer->isBackground());
         opacity()->setValue(static_cast<LayerImage*>(m_layer)->opacity());
         opacity()->setEnabled(!m_layer->isBackground());
diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp
index 2737381ea..c73ad9763 100644
--- a/src/app/commands/cmd_options.cpp
+++ b/src/app/commands/cmd_options.cpp
@@ -20,6 +20,7 @@
 #include "app/resource_finder.h"
 #include "app/send_crash.h"
 #include "app/ui/color_button.h"
+#include "app/ui/separator_in_view.h"
 #include "app/ui/skin/skin_theme.h"
 #include "base/bind.h"
 #include "base/convert_to.h"
@@ -623,9 +624,8 @@ private:
 
         if (first) {
           first = false;
-          auto sep = new Separator(base::normalize_path(path), HORIZONTAL);
-          sep->setStyle(theme->styles.separatorInView());
-          themeList()->addChild(sep);
+          themeList()->addChild(
+            new SeparatorInView(base::normalize_path(path), HORIZONTAL));
         }
 
         ThemeItem* item = new ThemeItem(fullPath, fn);
@@ -648,9 +648,8 @@ private:
 
       if (first) {
         first = false;
-        auto sep = new Separator("Extension Themes", HORIZONTAL);
-        sep->setStyle(theme->styles.separatorInView());
-        themeList()->addChild(sep);
+        themeList()->addChild(
+          new Separator("Extension Themes", HORIZONTAL));
       }
 
       for (auto it : ext->themes()) {
diff --git a/src/app/ui/browser_view.cpp b/src/app/ui/browser_view.cpp
index 23c6a608d..00e6325e8 100644
--- a/src/app/ui/browser_view.cpp
+++ b/src/app/ui/browser_view.cpp
@@ -13,6 +13,7 @@
 #include "app/resource_finder.h"
 #include "app/ui/browser_view.h"
 #include "app/ui/main_window.h"
+#include "app/ui/separator_in_view.h"
 #include "app/ui/skin/skin_theme.h"
 #include "app/ui/workspace.h"
 #include "base/file_handle.h"
@@ -427,8 +428,7 @@ private:
   }
 
   void addSeparator() {
-    auto sep = new Separator("", HORIZONTAL);
-    sep->setStyle(SkinTheme::instance()->styles.separatorInView());
+    auto sep = new SeparatorInView(std::string(), HORIZONTAL);
     sep->setBorder(gfx::Border(0, font()->height(), 0, font()->height()));
     sep->setExpansive(true);
     addChild(sep);
diff --git a/src/app/ui/data_recovery_view.cpp b/src/app/ui/data_recovery_view.cpp
index 7f74fc664..04e6c8ac2 100644
--- a/src/app/ui/data_recovery_view.cpp
+++ b/src/app/ui/data_recovery_view.cpp
@@ -15,6 +15,7 @@
 #include "app/crash/session.h"
 #include "app/modules/gui.h"
 #include "app/ui/drop_down_button.h"
+#include "app/ui/separator_in_view.h"
 #include "app/ui/skin/skin_theme.h"
 #include "app/ui/workspace.h"
 #include "base/bind.h"
@@ -114,8 +115,7 @@ void DataRecoveryView::fillList()
     if (session->isEmpty())
       continue;
 
-    auto sep = new Separator(session->name(), HORIZONTAL);
-    sep->setStyle(SkinTheme::instance()->styles.separatorInView());
+    auto sep = new SeparatorInView(session->name(), HORIZONTAL);
     sep->setBorder(sep->border() + gfx::Border(0, 8, 0, 8)*guiscale());
     m_listBox.addChild(sep);
 
diff --git a/src/app/ui/file_selector.cpp b/src/app/ui/file_selector.cpp
index 63570a6d2..539889641 100644
--- a/src/app/ui/file_selector.cpp
+++ b/src/app/ui/file_selector.cpp
@@ -263,11 +263,12 @@ public:
   std::string extrasLabel() const {
     std::string label = "Resize: " + m_extras->resize()->getSelectedItem()->text();
 
-    auto layerItem = m_extras->layers()->getSelectedItem();
-    if (layerItem && !layerItem->getValue().empty())
+    auto layerItem = dynamic_cast<ListItem*>(m_extras->layers()->getSelectedItem());
+    if (layerItem &&
+        !layerItem->getValue().empty())
       label += ", " + layerItem->text();
 
-    auto frameItem = m_extras->frames()->getSelectedItem();
+    auto frameItem = dynamic_cast<ListItem*>(m_extras->frames()->getSelectedItem());
     if (frameItem && !frameItem->getValue().empty())
       label += ", " + frameItem->text();
 
@@ -871,7 +872,8 @@ void FileSelector::onFileTypeChange()
 
     if (m_type == FileSelectorType::Open ||
         m_type == FileSelectorType::OpenMultiple) {
-      std::string origShowExtensions = fileType()->getItem(0)->getValue();
+      std::string origShowExtensions =
+        dynamic_cast<ListItem*>(fileType()->getItem(0))->getValue();
       preferred_open_extensions[origShowExtensions] = fileType()->getValue();
     }
   }
diff --git a/src/app/ui/layer_frame_comboboxes.cpp b/src/app/ui/layer_frame_comboboxes.cpp
index dd5c93e65..e89949f9c 100644
--- a/src/app/ui/layer_frame_comboboxes.cpp
+++ b/src/app/ui/layer_frame_comboboxes.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2016  David Capello
+// Copyright (C) 2016-2017  David Capello
 //
 // This program is distributed under the terms of
 // the End-User License Agreement for Aseprite.
@@ -58,10 +58,10 @@ FrameListItem::FrameListItem(doc::FrameTag* tag)
 void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const std::string& defLayer)
 {
   int i = layers->addItem("Visible layers");
-  layers->getItem(i)->setValue(kAllLayers);
+  dynamic_cast<LayerListItem*>(layers->getItem(i))->setValue(kAllLayers);
 
   i = layers->addItem("Selected layers");
-  layers->getItem(i)->setValue(kSelectedLayers);
+  dynamic_cast<LayerListItem*>(layers->getItem(i))->setValue(kSelectedLayers);
   if (defLayer == kSelectedLayers)
     layers->setSelectedItemIndex(i);
 
@@ -77,10 +77,10 @@ void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const
 void fill_frames_combobox(const doc::Sprite* sprite, ui::ComboBox* frames, const std::string& defFrame)
 {
   int i = frames->addItem("All frames");
-  frames->getItem(i)->setValue(kAllFrames);
+  dynamic_cast<FrameListItem*>(frames->getItem(i))->setValue(kAllFrames);
 
   i = frames->addItem("Selected frames");
-  frames->getItem(i)->setValue(kSelectedFrames);
+  dynamic_cast<FrameListItem*>(frames->getItem(i))->setValue(kSelectedFrames);
   if (defFrame == kSelectedFrames)
     frames->setSelectedItemIndex(i);
 
diff --git a/src/app/ui/separator_in_view.h b/src/app/ui/separator_in_view.h
new file mode 100644
index 000000000..2b85e1759
--- /dev/null
+++ b/src/app/ui/separator_in_view.h
@@ -0,0 +1,29 @@
+// Aseprite
+// Copyright (C) 2017  David Capello
+//
+// This program is distributed under the terms of
+// the End-User License Agreement for Aseprite.
+
+#ifndef APP_UI_SEPARATOR_IN_VIEW_H_INCLUDED
+#define APP_UI_SEPARATOR_IN_VIEW_H_INCLUDED
+#pragma once
+
+#include "app/ui/skin/skin_theme.h"
+#include "ui/separator.h"
+
+namespace app {
+
+class SeparatorInView : public ui::Separator {
+public:
+  SeparatorInView(const std::string& text = std::string(),
+                  int align = ui::HORIZONTAL)
+    : Separator(text, align) {
+    setStyle(skin::SkinTheme::instance()->styles.separatorInView());
+    if (text.empty())
+      setBorder(border() + gfx::Border(0, 2, 0, 2)*ui::guiscale());
+  }
+};
+
+} // namespace app
+
+#endif
diff --git a/src/doc/blend_funcs.cpp b/src/doc/blend_funcs.cpp
index 91f5376b0..3dfdaa9d9 100644
--- a/src/doc/blend_funcs.cpp
+++ b/src/doc/blend_funcs.cpp
@@ -37,6 +37,16 @@ namespace  {
 #define blend_difference(b, s)    (ABS((b) - (s)))
 #define blend_exclusion(b, s, t)  ((t) = MUL_UN8((b), (s), (t)), ((b) + (s) - 2*(t)))
 
+inline uint32_t blend_divide(uint32_t b, uint32_t s)
+{
+  if (b == 0)
+    return 0;
+  else if (b >= s)
+    return 255;
+  else
+    return DIV_UN8(b, s); // return b / s
+}
+
 inline uint32_t blend_color_dodge(uint32_t b, uint32_t s)
 {
   if (b == 0)
@@ -432,6 +442,33 @@ color_t rgba_blender_hsl_luminosity(color_t backdrop, color_t src, int opacity)
   return rgba_blender_normal(backdrop, src, opacity);
 }
 
+color_t rgba_blender_addition(color_t backdrop, color_t src, int opacity)
+{
+  int r = rgba_getr(backdrop) + rgba_getr(src);
+  int g = rgba_getg(backdrop) + rgba_getg(src);
+  int b = rgba_getb(backdrop) + rgba_getb(src);
+  src = rgba(MIN(r, 255), MIN(g, 255), MIN(b, 255), 0) | (src & rgba_a_mask);
+  return rgba_blender_normal(backdrop, src, opacity);
+}
+
+color_t rgba_blender_subtract(color_t backdrop, color_t src, int opacity)
+{
+  int r = rgba_getr(backdrop) - rgba_getr(src);
+  int g = rgba_getg(backdrop) - rgba_getg(src);
+  int b = rgba_getb(backdrop) - rgba_getb(src);
+  src = rgba(MAX(r, 0), MAX(g, 0), MAX(b, 0), 0) | (src & rgba_a_mask);
+  return rgba_blender_normal(backdrop, src, opacity);
+}
+
+color_t rgba_blender_divide(color_t backdrop, color_t src, int opacity)
+{
+  int r = blend_divide(rgba_getr(backdrop), rgba_getr(src));
+  int g = blend_divide(rgba_getg(backdrop), rgba_getg(src));
+  int b = blend_divide(rgba_getb(backdrop), rgba_getb(src));
+  src = rgba(r, g, b, 0) | (src & rgba_a_mask);
+  return rgba_blender_normal(backdrop, src, opacity);
+}
+
 //////////////////////////////////////////////////////////////////////
 // GRAY blenders
 
@@ -591,6 +628,27 @@ color_t graya_blender_exclusion(color_t backdrop, color_t src, int opacity)
   return graya_blender_normal(backdrop, src, opacity);
 }
 
+color_t graya_blender_addition(color_t backdrop, color_t src, int opacity)
+{
+  int v = graya_getv(backdrop) + graya_getv(src);
+  src = graya(MIN(v, 255), 0) | (src & graya_a_mask);
+  return graya_blender_normal(backdrop, src, opacity);
+}
+
+color_t graya_blender_subtract(color_t backdrop, color_t src, int opacity)
+{
+  int v = graya_getv(backdrop) - graya_getv(src);
+  src = graya(MAX(v, 0), 0) | (src & graya_a_mask);
+  return graya_blender_normal(backdrop, src, opacity);
+}
+
+color_t graya_blender_divide(color_t backdrop, color_t src, int opacity)
+{
+  int v = blend_divide(graya_getv(backdrop), graya_getv(src));
+  src = graya(v, 0) | (src & graya_a_mask);
+  return graya_blender_normal(backdrop, src, opacity);
+}
+
 //////////////////////////////////////////////////////////////////////
 // indexed
 
@@ -627,6 +685,9 @@ BlendFunc get_rgba_blender(BlendMode blendmode)
     case BlendMode::HSL_SATURATION: return rgba_blender_hsl_saturation;
     case BlendMode::HSL_COLOR:      return rgba_blender_hsl_color;
     case BlendMode::HSL_LUMINOSITY: return rgba_blender_hsl_luminosity;
+    case BlendMode::ADDITION:       return rgba_blender_addition;
+    case BlendMode::SUBTRACT:       return rgba_blender_subtract;
+    case BlendMode::DIVIDE:         return rgba_blender_divide;
   }
   ASSERT(false);
   return rgba_blender_src;
@@ -657,6 +718,9 @@ BlendFunc get_graya_blender(BlendMode blendmode)
     case BlendMode::HSL_SATURATION: return graya_blender_normal;
     case BlendMode::HSL_COLOR:      return graya_blender_normal;
     case BlendMode::HSL_LUMINOSITY: return graya_blender_normal;
+    case BlendMode::ADDITION:       return graya_blender_addition;
+    case BlendMode::SUBTRACT:       return graya_blender_subtract;
+    case BlendMode::DIVIDE:         return graya_blender_divide;
   }
   ASSERT(false);
   return graya_blender_src;
diff --git a/src/doc/blend_funcs.h b/src/doc/blend_funcs.h
index 595bb3b30..d4b91beee 100644
--- a/src/doc/blend_funcs.h
+++ b/src/doc/blend_funcs.h
@@ -36,6 +36,9 @@ namespace doc {
   color_t rgba_blender_hsl_saturation(color_t backdrop, color_t src, int opacity);
   color_t rgba_blender_hsl_color(color_t backdrop, color_t src, int opacity);
   color_t rgba_blender_hsl_luminosity(color_t backdrop, color_t src, int opacity);
+  color_t rgba_blender_addition(color_t backdrop, color_t src, int opacity);
+  color_t rgba_blender_subtract(color_t backdrop, color_t src, int opacity);
+  color_t rgba_blender_divide(color_t backdrop, color_t src, int opacity);
 
   color_t graya_blender_src(color_t backdrop, color_t src, int opacity);
   color_t graya_blender_merge(color_t backdrop, color_t src, int opacity);
diff --git a/src/doc/blend_mode.h b/src/doc/blend_mode.h
index f26e04c56..f62e49d9e 100644
--- a/src/doc/blend_mode.h
+++ b/src/doc/blend_mode.h
@@ -1,5 +1,5 @@
 // Aseprite Document Library
-// Copyright (c) 2001-2015 David Capello
+// Copyright (c) 2001-2017 David Capello
 //
 // This file is released under the terms of the MIT license.
 // Read LICENSE.txt for more information.
@@ -37,7 +37,10 @@ namespace doc {
     HSL_HUE         = 12,
     HSL_SATURATION  = 13,
     HSL_COLOR       = 14,
-    HSL_LUMINOSITY  = 15
+    HSL_LUMINOSITY  = 15,
+    ADDITION        = 16,
+    SUBTRACT        = 17,
+    DIVIDE          = 18
   };
 
   std::string blend_mode_to_string(BlendMode blendMode);
diff --git a/src/ui/combobox.cpp b/src/ui/combobox.cpp
index 27b9faca4..98741d9f0 100644
--- a/src/ui/combobox.cpp
+++ b/src/ui/combobox.cpp
@@ -146,7 +146,7 @@ void ComboBox::setUseCustomWidget(bool state)
   m_useCustomWidget = state;
 }
 
-int ComboBox::addItem(ListItem* item)
+int ComboBox::addItem(Widget* item)
 {
   bool sel_first = m_items.empty();
 
@@ -163,7 +163,7 @@ int ComboBox::addItem(const std::string& text)
   return addItem(new ListItem(text));
 }
 
-void ComboBox::insertItem(int itemIndex, ListItem* item)
+void ComboBox::insertItem(int itemIndex, Widget* item)
 {
   bool sel_first = m_items.empty();
 
@@ -178,12 +178,10 @@ void ComboBox::insertItem(int itemIndex, const std::string& text)
   insertItem(itemIndex, new ListItem(text));
 }
 
-void ComboBox::removeItem(ListItem* item)
+void ComboBox::removeItem(Widget* item)
 {
-  ListItems::iterator it = std::find(m_items.begin(), m_items.end(), item);
-
+  auto it = std::find(m_items.begin(), m_items.end(), item);
   ASSERT(it != m_items.end());
-
   if (it != m_items.end())
     m_items.erase(it);
 
@@ -194,7 +192,7 @@ void ComboBox::removeItem(int itemIndex)
 {
   ASSERT(itemIndex >= 0 && (std::size_t)itemIndex < m_items.size());
 
-  ListItem* item = m_items[itemIndex];
+  Widget* item = m_items[itemIndex];
 
   m_items.erase(m_items.begin() + itemIndex);
   delete item;
@@ -202,9 +200,8 @@ void ComboBox::removeItem(int itemIndex)
 
 void ComboBox::removeAllItems()
 {
-  ListItems::iterator it, end = m_items.end();
-  for (it = m_items.begin(); it != end; ++it)
-    delete *it;
+  for (Widget* item : m_items)
+    delete item;                // widget
 
   m_items.clear();
   m_selected = -1;
@@ -215,7 +212,7 @@ int ComboBox::getItemCount() const
   return m_items.size();
 }
 
-ListItem* ComboBox::getItem(int itemIndex)
+Widget* ComboBox::getItem(int itemIndex)
 {
   if (itemIndex >= 0 && (std::size_t)itemIndex < m_items.size()) {
     return m_items[itemIndex];
@@ -227,7 +224,7 @@ ListItem* ComboBox::getItem(int itemIndex)
 const std::string& ComboBox::getItemText(int itemIndex) const
 {
   if (itemIndex >= 0 && (std::size_t)itemIndex < m_items.size()) {
-    ListItem* item = m_items[itemIndex];
+    Widget* item = m_items[itemIndex];
     return item->text();
   }
   else {
@@ -241,14 +238,14 @@ void ComboBox::setItemText(int itemIndex, const std::string& text)
 {
   ASSERT(itemIndex >= 0 && (std::size_t)itemIndex < m_items.size());
 
-  ListItem* item = m_items[itemIndex];
+  Widget* item = m_items[itemIndex];
   item->setText(text);
 }
 
 int ComboBox::findItemIndex(const std::string& text) const
 {
   int i = 0;
-  for (const ListItem* item : m_items) {
+  for (const Widget* item : m_items) {
     if ((m_casesensitive && item->text() == text) ||
         (!m_casesensitive && item->text() == text)) {
       return i;
@@ -261,27 +258,30 @@ int ComboBox::findItemIndex(const std::string& text) const
 int ComboBox::findItemIndexByValue(const std::string& value) const
 {
   int i = 0;
-  for (const ListItem* item : m_items) {
-    if (item->getValue() == value)
-      return i;
-    i++;
+  for (const Widget* item : m_items) {
+    if (auto listItem = dynamic_cast<const ListItem*>(item)) {
+      if (listItem->getValue() == value)
+        return i;
+    }
+    ++i;
   }
   return -1;
 }
 
-ListItem* ComboBox::getSelectedItem() const
+Widget* ComboBox::getSelectedItem() const
 {
   return (!m_items.empty() ? m_items[m_selected]: NULL);
 }
 
-void ComboBox::setSelectedItem(ListItem* item)
+void ComboBox::setSelectedItem(Widget* item)
 {
-  ListItems::iterator it = std::find(m_items.begin(), m_items.end(), item);
-
-  ASSERT(it != m_items.end());
-
+  auto it = std::find(m_items.begin(), m_items.end(), item);
   if (it != m_items.end())
     setSelectedItemIndex(std::distance(m_items.begin(), it));
+  else if (m_selected >= 0) {
+    m_selected = -1;
+    onChange();
+  }
 }
 
 int ComboBox::getSelectedItemIndex() const
@@ -296,8 +296,8 @@ void ComboBox::setSelectedItemIndex(int itemIndex)
       m_selected != itemIndex) {
     m_selected = itemIndex;
 
-    ListItems::iterator it = m_items.begin() + itemIndex;
-    ListItem* item = *it;
+    auto it = m_items.begin() + itemIndex;
+    Widget* item = *it;
     m_entry->setText(item->text());
     if (isEditable())
       m_entry->setCaretToEnd();
@@ -310,13 +310,12 @@ std::string ComboBox::getValue() const
 {
   if (isEditable())
     return m_entry->text();
-  else {
-    int index = getSelectedItemIndex();
-    if (index >= 0)
-      return m_items[index]->getValue();
-    else
-      return std::string();
+  int index = getSelectedItemIndex();
+  if (index >= 0) {
+    if (auto listItem = dynamic_cast<ListItem*>(m_items[index]))
+      return listItem->getValue();
   }
+  return std::string();
 }
 
 void ComboBox::setValue(const std::string& value)
@@ -419,8 +418,8 @@ void ComboBox::onSizeHint(SizeHintEvent& ev)
   Size reqSize = entrySize;
 
   // Get the text-length of every item
-  ListItems::iterator it, end = m_items.end();
-  for (it = m_items.begin(); it != end; ++it) {
+  auto end = m_items.end();
+  for (auto it = m_items.begin(); it != end; ++it) {
     int item_w =
       2*guiscale()+
       font()->textLength((*it)->text().c_str())+
@@ -603,7 +602,7 @@ void ComboBox::openListBox()
     gfx::Size size;
     size.w = m_button->bounds().x2() - entryBounds.x - view->border().width();
     size.h = viewport->border().height();
-    for (ListItem* item : m_items)
+    for (Widget* item : m_items)
       size.h += item->sizeHint().h;
 
     int max = MAX(entryBounds.y, ui::display_h() - entryBounds.y2()) - 8*guiscale();
@@ -710,7 +709,7 @@ void ComboBox::putSelectedItemAsCustomWidget()
   if (!useCustomWidget())
     return;
 
-  ListItem* item = getSelectedItem();
+  Widget* item = getSelectedItem();
   if (item && item->parent() == nullptr) {
     if (!m_listbox) {
       item->setBounds(m_entry->childrenBounds());
diff --git a/src/ui/combobox.h b/src/ui/combobox.h
index b01f8f089..9a3a0785a 100644
--- a/src/ui/combobox.h
+++ b/src/ui/combobox.h
@@ -20,7 +20,6 @@ namespace ui {
   class Entry;
   class Event;
   class ListBox;
-  class ListItem;
   class Window;
 
   class ComboBoxEntry;
@@ -31,13 +30,13 @@ namespace ui {
     friend class ComboBoxListBox;
 
   public:
-    typedef std::vector<ListItem*> ListItems;
+    typedef std::vector<Widget*> Items;
 
     ComboBox();
     ~ComboBox();
 
-    ListItems::iterator begin() { return m_items.begin(); }
-    ListItems::iterator end() { return m_items.end(); }
+    Items::iterator begin() { return m_items.begin(); }
+    Items::iterator end() { return m_items.end(); }
 
     void setEditable(bool state);
     void setClickOpen(bool state);
@@ -49,13 +48,13 @@ namespace ui {
     bool isCaseSensitive() const { return m_casesensitive; }
     bool useCustomWidget() const { return m_useCustomWidget; }
 
-    int addItem(ListItem* item);
+    int addItem(Widget* item);
     int addItem(const std::string& text);
-    void insertItem(int itemIndex, ListItem* item);
+    void insertItem(int itemIndex, Widget* item);
     void insertItem(int itemIndex, const std::string& text);
 
     // Removes the given item (you must delete it).
-    void removeItem(ListItem* item);
+    void removeItem(Widget* item);
 
     // Removes and deletes the given item.
     void removeItem(int itemIndex);
@@ -64,14 +63,14 @@ namespace ui {
 
     int getItemCount() const;
 
-    ListItem* getItem(int itemIndex);
+    Widget* getItem(int itemIndex);
     const std::string& getItemText(int itemIndex) const;
     void setItemText(int itemIndex, const std::string& text);
     int findItemIndex(const std::string& text) const;
     int findItemIndexByValue(const std::string& value) const;
 
-    ListItem* getSelectedItem() const;
-    void setSelectedItem(ListItem* item);
+    Widget* getSelectedItem() const;
+    void setSelectedItem(Widget* item);
 
     int getSelectedItemIndex() const;
     void setSelectedItemIndex(int itemIndex);
@@ -110,7 +109,7 @@ namespace ui {
     Button* m_button;
     Window* m_window;
     ComboBoxListBox* m_listbox;
-    ListItems m_items;
+    Items m_items;
     int m_selected;
     bool m_editable;
     bool m_clickopen;
diff --git a/src/ui/listbox.cpp b/src/ui/listbox.cpp
index ff669b487..655e72025 100644
--- a/src/ui/listbox.cpp
+++ b/src/ui/listbox.cpp
@@ -13,8 +13,9 @@
 #include "base/fs.h"
 #include "ui/listitem.h"
 #include "ui/message.h"
-#include "ui/size_hint_event.h"
 #include "ui/resize_event.h"
+#include "ui/separator.h"
+#include "ui/size_hint_event.h"
 #include "ui/system.h"
 #include "ui/theme.h"
 #include "ui/view.h"
@@ -437,7 +438,11 @@ int ListBox::advanceIndexThroughVisibleItems(
     }
     else {
       Widget* item = getChildByIndex(index);
-      if (item && !item->hasFlags(HIDDEN)) {
+      if (item &&
+          !item->hasFlags(HIDDEN) &&
+          // We can completelly ignore separators from navigation
+          // keys.
+          !dynamic_cast<Separator*>(item)) {
         lastVisibleIndex = index;
         delta -= sgn;
       }