diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt
index bf4dc0cc0bcc8b7c788d35985966abbab0d33a65..600c78c7c2731c65d5ab4177324aefdb2cc72e52 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt
@@ -30,11 +30,14 @@ class BufferListAdapter(
   liveData: LiveData<List<BufferProps>?>,
   runInBackground: (() -> Unit) -> Any,
   runOnUiThread: (Runnable) -> Any,
-  private val clickListener: ((BufferId) -> Unit)? = null
+  private val clickListener: ((BufferId) -> Unit)? = null,
+  private val longClickListener: ((BufferId) -> Unit)? = null
 ) : RecyclerView.Adapter<BufferListAdapter.BufferViewHolder>() {
   var data = mutableListOf<BufferListItem>()
 
-  var collapsedNetworks = MutableLiveData<Set<NetworkId>>()
+  private val collapsedNetworks = MutableLiveData<Set<NetworkId>>()
+
+  val selectedBuffers = MutableLiveData<Set<BufferId>>()
 
   fun expandListener(networkId: NetworkId) {
     if (collapsedNetworks.value.orEmpty().contains(networkId))
@@ -43,14 +46,29 @@ class BufferListAdapter(
       collapsedNetworks.postValue(collapsedNetworks.value.orEmpty() + networkId)
   }
 
+  fun toggleSelection(buffer: BufferId) {
+    val value = selectedBuffers.value.orEmpty()
+    if (value.contains(buffer)) {
+      selectedBuffers.value = value - buffer
+    } else {
+      selectedBuffers.value = value + buffer
+    }
+  }
+
+  fun unselectAll() {
+    selectedBuffers.value = emptySet()
+  }
+
   init {
     collapsedNetworks.value = emptySet()
+    selectedBuffers.value = emptySet()
 
-    liveData.zip(collapsedNetworks).observe(
-      lifecycleOwner, Observer { it: Pair<List<BufferProps>?, Set<NetworkId>>? ->
+    liveData.zip(collapsedNetworks, selectedBuffers).observe(
+      lifecycleOwner, Observer { it: Triple<List<BufferProps>?, Set<NetworkId>, Set<BufferId>>? ->
       runInBackground {
         val list = it?.first ?: emptyList()
         val collapsedNetworks = it?.second ?: emptySet()
+        val selected = it?.third ?: emptySet()
 
         val old: List<BufferListItem> = data
         val new: List<BufferListItem> = list.sortedBy { props ->
@@ -61,7 +79,8 @@ class BufferListAdapter(
             BufferListItem(
               props,
               BufferState(
-                networkExpanded = !collapsedNetworks.contains(props.network.networkId)
+                networkExpanded = !collapsedNetworks.contains(props.network.networkId),
+                selected = selected.contains(props.info.bufferId)
               )
             )
         }.filter { (props, state) ->
@@ -97,25 +116,29 @@ class BufferListAdapter(
       LayoutInflater.from(parent.context).inflate(
         R.layout.widget_buffer, parent, false
       ),
-      clickListener = clickListener
+      clickListener = clickListener,
+      longClickListener = longClickListener
     )
     BufferInfo.Type.QueryBuffer.toInt()   -> BufferViewHolder.QueryBuffer(
       LayoutInflater.from(parent.context).inflate(
         R.layout.widget_buffer, parent, false
       ),
-      clickListener = clickListener
+      clickListener = clickListener,
+      longClickListener = longClickListener
     )
     BufferInfo.Type.GroupBuffer.toInt()   -> BufferViewHolder.GroupBuffer(
       LayoutInflater.from(parent.context).inflate(
         R.layout.widget_buffer, parent, false
       ),
-      clickListener = clickListener
+      clickListener = clickListener,
+      longClickListener = longClickListener
     )
     BufferInfo.Type.StatusBuffer.toInt()  -> BufferViewHolder.StatusBuffer(
       LayoutInflater.from(parent.context).inflate(
         R.layout.widget_network, parent, false
       ),
       clickListener = clickListener,
+      longClickListener = longClickListener,
       expansionListener = ::expandListener
     )
     else                                  -> throw IllegalArgumentException(
@@ -146,7 +169,8 @@ class BufferListAdapter(
   )
 
   data class BufferState(
-    val networkExpanded: Boolean
+    val networkExpanded: Boolean,
+    val selected: Boolean
   )
 
   abstract class BufferViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@@ -155,6 +179,7 @@ class BufferListAdapter(
     class StatusBuffer(
       itemView: View,
       private val clickListener: ((BufferId) -> Unit)? = null,
+      private val longClickListener: ((BufferId) -> Unit)? = null,
       private val expansionListener: ((NetworkId) -> Unit)? = null
     ) : BufferViewHolder(itemView) {
       @BindView(R.id.status)
@@ -179,6 +204,16 @@ class BufferListAdapter(
             clickListener?.invoke(buffer)
         }
 
+        itemView.setOnLongClickListener {
+          val buffer = bufferId
+          if (buffer != null) {
+            longClickListener?.invoke(buffer)
+            true
+          } else {
+            false
+          }
+        }
+
         status.setOnClickListener {
           val network = networkId
           if (network != null)
@@ -210,6 +245,8 @@ class BufferListAdapter(
           }
         )
 
+        itemView.isSelected = state.selected
+
         if (state.networkExpanded) {
           status.setImageDrawable(itemView.context.getCompatDrawable(R.drawable.ic_chevron_up))
         } else {
@@ -220,7 +257,8 @@ class BufferListAdapter(
 
     class GroupBuffer(
       itemView: View,
-      private val clickListener: ((BufferId) -> Unit)? = null
+      private val clickListener: ((BufferId) -> Unit)? = null,
+      private val longClickListener: ((BufferId) -> Unit)? = null
     ) : BufferViewHolder(itemView) {
       @BindView(R.id.status)
       lateinit var status: ImageView
@@ -249,6 +287,16 @@ class BufferListAdapter(
             clickListener?.invoke(buffer)
         }
 
+        itemView.setOnLongClickListener {
+          val buffer = bufferId
+          if (buffer != null) {
+            longClickListener?.invoke(buffer)
+            true
+          } else {
+            false
+          }
+        }
+
         online = itemView.context.getCompatDrawable(R.drawable.ic_status).mutate()
         offline = itemView.context.getCompatDrawable(R.drawable.ic_status_offline).mutate()
 
@@ -282,6 +330,8 @@ class BufferListAdapter(
           }
         )
 
+        itemView.isSelected = state.selected
+
         description.visibleIf(props.description.isNotBlank())
 
         status.setImageDrawable(
@@ -295,7 +345,8 @@ class BufferListAdapter(
 
     class ChannelBuffer(
       itemView: View,
-      private val clickListener: ((BufferId) -> Unit)? = null
+      private val clickListener: ((BufferId) -> Unit)? = null,
+      private val longClickListener: ((BufferId) -> Unit)? = null
     ) : BufferViewHolder(itemView) {
       @BindView(R.id.status)
       lateinit var status: ImageView
@@ -324,6 +375,16 @@ class BufferListAdapter(
             clickListener?.invoke(buffer)
         }
 
+        itemView.setOnLongClickListener {
+          val buffer = bufferId
+          if (buffer != null) {
+            longClickListener?.invoke(buffer)
+            true
+          } else {
+            false
+          }
+        }
+
         online = itemView.context.getCompatDrawable(R.drawable.ic_status_channel).mutate()
         offline = itemView.context.getCompatDrawable(R.drawable.ic_status_channel_offline).mutate()
 
@@ -357,6 +418,8 @@ class BufferListAdapter(
           }
         )
 
+        itemView.isSelected = state.selected
+
         description.visibleIf(props.description.isNotBlank())
 
         status.setImageDrawable(
@@ -370,7 +433,8 @@ class BufferListAdapter(
 
     class QueryBuffer(
       itemView: View,
-      private val clickListener: ((BufferId) -> Unit)? = null
+      private val clickListener: ((BufferId) -> Unit)? = null,
+      private val longClickListener: ((BufferId) -> Unit)? = null
     ) : BufferViewHolder(itemView) {
       @BindView(R.id.status)
       lateinit var status: ImageView
@@ -400,6 +464,16 @@ class BufferListAdapter(
             clickListener?.invoke(buffer)
         }
 
+        itemView.setOnLongClickListener {
+          val buffer = bufferId
+          if (buffer != null) {
+            longClickListener?.invoke(buffer)
+            true
+          } else {
+            false
+          }
+        }
+
         online = itemView.context.getCompatDrawable(R.drawable.ic_status).mutate()
         away = itemView.context.getCompatDrawable(R.drawable.ic_status).mutate()
         offline = itemView.context.getCompatDrawable(R.drawable.ic_status_offline).mutate()
@@ -435,6 +509,8 @@ class BufferListAdapter(
           }
         )
 
+        itemView.isSelected = state.selected
+
         description.visibleIf(props.description.isNotBlank())
 
         status.setImageDrawable(
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
index a1f72252016598ccc5c99ed320a7c0248500146d..6e3b95730ae2fd6cc413a3c3edf13d74859c7c72 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
@@ -3,9 +3,7 @@ package de.kuschku.quasseldroid_ng.ui.chat.buffers
 import android.arch.lifecycle.ViewModelProviders
 import android.os.Bundle
 import android.support.v7.widget.*
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
+import android.view.*
 import android.widget.AdapterView
 import butterknife.BindView
 import butterknife.ButterKnife
@@ -44,6 +42,30 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
   private var ircFormatDeserializer: IrcFormatDeserializer? = null
   private lateinit var appearanceSettings: AppearanceSettings
 
+  private var isInActionMode = false
+
+  private val actionModeCallback = object : ActionMode.Callback {
+    override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
+      return true
+    }
+
+    override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+      isInActionMode = true
+      return true
+    }
+
+    override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+      return false
+    }
+
+    override fun onDestroyActionMode(mode: ActionMode?) {
+      isInActionMode = false
+      listAdapter.unselectAll()
+    }
+  }
+
+  private lateinit var listAdapter: BufferListAdapter
+
   override fun onCreate(savedInstanceState: Bundle?) {
     handlerThread.onCreate()
     super.onCreate(savedInstanceState)
@@ -75,7 +97,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
       }
     }
 
-    chatList.adapter = BufferListAdapter(
+    listAdapter = BufferListAdapter(
       this,
       viewModel.bufferList.zip(database.filtered().listen(accountId)).map {
         val (data, activityList) = it
@@ -107,8 +129,12 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
       },
       handlerThread::post,
       activity!!::runOnUiThread,
-      clickListener
+      clickListener,
+      longClickListener
     )
+    chatList.adapter = listAdapter
+
+    chatListToolbar.startActionMode(actionModeCallback)
     chatList.layoutManager = LinearLayoutManager(context)
     chatList.itemAnimator = DefaultItemAnimator()
     chatList.setItemViewCacheSize(10)
@@ -121,6 +147,17 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
   }
 
   private val clickListener: ((BufferId) -> Unit)? = {
-    viewModel.setBuffer(it)
+    if (isInActionMode) {
+      longClickListener?.invoke(it)
+    } else {
+      viewModel.setBuffer(it)
+    }
+  }
+
+  private val longClickListener: ((BufferId) -> Unit)? = {
+    if (!isInActionMode) {
+      chatListToolbar.startActionMode(actionModeCallback)
+    }
+    listAdapter.toggleSelection(it)
   }
 }
diff --git a/app/src/main/res/drawable-v21/bg_menuitem_dark.xml b/app/src/main/res/drawable-v21/bg_menuitem_dark.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6ac08543def8f754c2b4df42f7dc62d4c8db842b
--- /dev/null
+++ b/app/src/main/res/drawable-v21/bg_menuitem_dark.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:state_selected="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_dark" />
+    </shape>
+  </item>
+  <item>
+    <ripple android:color="@color/ripple_dark" />
+  </item>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/bg_menuitem_light.xml b/app/src/main/res/drawable-v21/bg_menuitem_light.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c86946bd169d81a7f324b141f34d99ae25af20e6
--- /dev/null
+++ b/app/src/main/res/drawable-v21/bg_menuitem_light.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:state_selected="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_light" />
+    </shape>
+  </item>
+  <item>
+    <ripple android:color="@color/ripple_light" />
+  </item>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_menuitem_dark.xml b/app/src/main/res/drawable/bg_menuitem_dark.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cd43fb02f5f81c1e097a9f9a2cb5e9ab9eaf33f9
--- /dev/null
+++ b/app/src/main/res/drawable/bg_menuitem_dark.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:state_selected="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_dark" />
+    </shape>
+  </item>
+  <item android:state_pressed="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_dark" />
+    </shape>
+  </item>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_menuitem_light.xml b/app/src/main/res/drawable/bg_menuitem_light.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bdf40bd8ada5b31e3dfd5177616935965a837a02
--- /dev/null
+++ b/app/src/main/res/drawable/bg_menuitem_light.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:state_selected="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_light" />
+    </shape>
+  </item>
+  <item android:state_pressed="true">
+    <shape android:shape="rectangle">
+      <solid android:color="@color/ripple_light" />
+    </shape>
+  </item>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/layout/widget_buffer.xml b/app/src/main/res/layout/widget_buffer.xml
index d181160f35ab0807698ebb607967154d133a5294..b162446dfbba5138df7462a7a61911c578821daa 100644
--- a/app/src/main/res/layout/widget_buffer.xml
+++ b/app/src/main/res/layout/widget_buffer.xml
@@ -3,7 +3,7 @@
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
-  android:foreground="?attr/selectableItemBackgroundBorderless"
+  android:background="?attr/backgroundMenuItem"
   android:minHeight="48dp"
   android:paddingBottom="8dp"
   android:paddingLeft="16dp"
diff --git a/app/src/main/res/layout/widget_network.xml b/app/src/main/res/layout/widget_network.xml
index 89af4b1c52a445d50db5290544a8f48f6b85554e..42128db09116daeae4c40bd2b3104846d0ecd474 100644
--- a/app/src/main/res/layout/widget_network.xml
+++ b/app/src/main/res/layout/widget_network.xml
@@ -4,7 +4,7 @@
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
-  android:background="?attr/selectableItemBackground"
+  android:background="?attr/backgroundMenuItem"
   android:orientation="vertical">
 
   <View
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index eeb7e7e311aa0f6dda78580cc847e80e23eea57e..2d2d7219d356f19028cfed58b868804443e3166f 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -71,4 +71,7 @@
   <attr name="buttonTheme" format="reference" />
   <attr name="buttonThemeColored" format="reference" />
   <attr name="cardStyle" format="reference" />
+
+  <!-- Menu Items -->
+  <attr name="backgroundMenuItem" format="reference" />
 </resources>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 1b74be2c0c09054ae5886367863895f9eff7c065..77aae29ab1817632cc2526efa4dd877c09df684b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -12,4 +12,7 @@
 
   <color name="colorAwayLight">#959595</color>
   <color name="colorAwayDark">#939393</color>
+
+  <color name="ripple_dark">#33ffffff</color>
+  <color name="ripple_light">#1f000000</color>
 </resources>
diff --git a/app/src/main/res/values/themes_base.xml b/app/src/main/res/values/themes_base.xml
index 0506b7d5841c64a249dc60b7cd450d95e0bd3ea8..6a519ac9a936985367d680f6b73daf2a4f610934 100644
--- a/app/src/main/res/values/themes_base.xml
+++ b/app/src/main/res/values/themes_base.xml
@@ -4,22 +4,30 @@
     <item name="colorPrimary">@color/colorPrimary</item>
     <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
     <item name="colorAccent">@color/colorAccent</item>
+
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_dark</item>
   </style>
 
   <style name="Theme.AppTheme.Light" parent="Theme.AppCompat.Light.DarkActionBar">
     <item name="colorPrimary">@color/colorPrimary</item>
     <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
     <item name="colorAccent">@color/colorAccent</item>
+
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_light</item>
   </style>
 
   <style name="Theme.AppTheme.NoActionBar" parent="Theme.AppTheme">
     <item name="windowActionBar">false</item>
     <item name="windowNoTitle">true</item>
+
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_dark</item>
   </style>
 
   <style name="Theme.AppTheme.Light.NoActionBar" parent="Theme.AppTheme.Light">
     <item name="windowActionBar">false</item>
     <item name="windowNoTitle">true</item>
+
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_light</item>
   </style>
 
   <style name="Theme.Base.ChatTheme" parent="Theme.AppTheme.NoActionBar" />
@@ -38,6 +46,8 @@
     <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
     <item name="actionBarPopupTheme">@style/Widget.PopupOverlay</item>
 
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_dark</item>
+
     <item name="windowActionModeOverlay">true</item>
 
     <item name="colorTextPrimary">#dedede</item>
@@ -85,6 +95,8 @@
     <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
     <item name="actionBarPopupTheme">@style/Widget.PopupOverlay.Light</item>
 
+    <item name="backgroundMenuItem">@drawable/bg_menuitem_light</item>
+
     <item name="windowActionModeOverlay">true</item>
 
     <item name="colorTextPrimary">#212121</item>