diff --git a/gui/partitionlist.cpp b/gui/partitionlist.cpp
new file mode 100644
index 0000000..9f9321c
--- /dev/null
+++ b/gui/partitionlist.cpp
@@ -0,0 +1,926 @@
+/*
+	Copyright 2013 bigbiff/Dees_Troy TeamWin
+	This file is part of TWRP/TeamWin Recovery Project.
+
+	TWRP is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	TWRP is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <linux/input.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <ctype.h>
+
+#include <algorithm>
+
+extern "C" {
+#include "../common.h"
+#include "../roots.h"
+#include "../minuitwrp/minui.h"
+#include "../recovery_ui.h"
+}
+
+#include "rapidxml.hpp"
+#include "objects.hpp"
+#include "../data.hpp"
+#include "../twrp-functions.hpp"
+#include "../partitions.hpp"
+
+#define SCROLLING_SPEED_DECREMENT 6
+#define SCROLLING_FLOOR 10
+#define SCROLLING_MULTIPLIER 6
+
+GUIPartitionList::GUIPartitionList(xml_node<>* node)
+{
+	xml_attribute<>* attr;
+	xml_node<>* child;
+	int header_separator_color_specified = 0, header_separator_height_specified = 0, header_text_color_specified = 0, header_background_color_specified = 0;
+
+	mStart = mLineSpacing = startY = mFontHeight = mSeparatorH = scrollingY = scrollingSpeed = 0;
+	mIconWidth = mIconHeight = mSelectedIconHeight = mSelectedIconWidth = mUnselectedIconHeight = mUnselectedIconWidth = mHeaderIconHeight = mHeaderIconWidth = 0;
+	mHeaderSeparatorH = mLineHeight = mHeaderIsStatic = mHeaderH = actualLineHeight = 0;
+	mIconSelected = mIconUnselected = mBackground = mFont = mHeaderIcon = NULL;
+	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
+	mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0;
+	mFastScrollRectX = mFastScrollRectY = -1;
+	mUpdate = 0;
+	touchDebounce = 6;
+	ConvertStrToColor("black", &mBackgroundColor);
+	ConvertStrToColor("black", &mHeaderBackgroundColor);
+	ConvertStrToColor("black", &mSeparatorColor);
+	ConvertStrToColor("black", &mHeaderSeparatorColor);
+	ConvertStrToColor("white", &mFontColor);
+	ConvertStrToColor("white", &mHeaderFontColor);
+	ConvertStrToColor("white", &mFastScrollLineColor);
+	ConvertStrToColor("white", &mFastScrollRectColor);
+	hasHighlightColor = false;
+	hasFontHighlightColor = false;
+	isHighlighted = false;
+	updateList = false;
+	startSelection = -1;
+
+	// Load header text
+	child = node->first_node("header");
+	if (child)
+	{
+		attr = child->first_attribute("icon");
+		if (attr)
+			mHeaderIcon = PageManager::FindResource(attr->value());
+
+		attr = child->first_attribute("background");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mHeaderBackgroundColor);
+			header_background_color_specified = -1;
+		}
+		attr = child->first_attribute("textcolor");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mHeaderFontColor);
+			header_text_color_specified = -1;
+		}
+		attr = child->first_attribute("separatorcolor");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mHeaderSeparatorColor);
+			header_separator_color_specified = -1;
+		}
+		attr = child->first_attribute("separatorheight");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mHeaderSeparatorH = atoi(parsevalue.c_str());
+			header_separator_height_specified = -1;
+		}
+	}
+	child = node->first_node("text");
+	if (child)  mHeaderText = child->value();
+
+	memset(&mHighlightColor, 0, sizeof(COLOR));
+	child = node->first_node("highlight");
+	if (child) {
+		attr = child->first_attribute("color");
+		if (attr) {
+			hasHighlightColor = true;
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mHighlightColor);
+		}
+	}
+
+	// Simple way to check for static state
+	mLastValue = gui_parse_text(mHeaderText);
+	if (mLastValue != mHeaderText)
+		mHeaderIsStatic = 0;
+	else
+		mHeaderIsStatic = -1;
+
+	child = node->first_node("icon");
+	if (child)
+	{
+		attr = child->first_attribute("selected");
+		if (attr)
+			mIconSelected = PageManager::FindResource(attr->value());
+		attr = child->first_attribute("unselected");
+		if (attr)
+			mIconUnselected = PageManager::FindResource(attr->value());
+	}
+	child = node->first_node("background");
+	if (child)
+	{
+		attr = child->first_attribute("resource");
+		if (attr)
+			mBackground = PageManager::FindResource(attr->value());
+		attr = child->first_attribute("color");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mBackgroundColor);
+			if (!header_background_color_specified)
+				ConvertStrToColor(color, &mHeaderBackgroundColor);
+		}
+	}
+
+	// Load the placement
+	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
+	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
+
+	// Load the font, and possibly override the color
+	child = node->first_node("font");
+	if (child)
+	{
+		attr = child->first_attribute("resource");
+		if (attr)
+			mFont = PageManager::FindResource(attr->value());
+
+		attr = child->first_attribute("color");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mFontColor);
+			if (!header_text_color_specified)
+				ConvertStrToColor(color, &mHeaderFontColor);
+		}
+
+		attr = child->first_attribute("spacing");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mLineSpacing = atoi(parsevalue.c_str());
+		}
+
+		attr = child->first_attribute("highlightcolor");
+		memset(&mFontHighlightColor, 0, sizeof(COLOR));
+        if (attr)
+        {
+            std::string color = attr->value();
+			ConvertStrToColor(color, &mFontHighlightColor);
+			hasFontHighlightColor = true;
+        }
+	}
+
+	// Load the separator if it exists
+	child = node->first_node("separator");
+	if (child)
+	{
+		attr = child->first_attribute("color");
+		if (attr)
+		{
+			std::string color = attr->value();
+			ConvertStrToColor(color, &mSeparatorColor);
+			if (!header_separator_color_specified)
+				ConvertStrToColor(color, &mHeaderSeparatorColor);
+		}
+
+		attr = child->first_attribute("height");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mSeparatorH = atoi(parsevalue.c_str());
+			if (!header_separator_height_specified)
+				mHeaderSeparatorH = mSeparatorH;
+		}
+	}
+
+	// Handle the result variable
+	child = node->first_node("data");
+	if (child)
+	{
+		attr = child->first_attribute("name");
+		if (attr)
+			mVariable = attr->value();
+		attr = child->first_attribute("selectedlist");
+		if (attr)
+			selectedList = attr->value();
+	}
+
+	// Fast scroll colors
+	child = node->first_node("fastscroll");
+	if (child)
+	{
+		attr = child->first_attribute("linecolor");
+		if(attr)
+			ConvertStrToColor(attr->value(), &mFastScrollLineColor);
+
+		attr = child->first_attribute("rectcolor");
+		if(attr)
+			ConvertStrToColor(attr->value(), &mFastScrollRectColor);
+
+		attr = child->first_attribute("w");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mFastScrollW = atoi(parsevalue.c_str());
+		}
+
+		attr = child->first_attribute("linew");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mFastScrollLineW = atoi(parsevalue.c_str());
+		}
+
+		attr = child->first_attribute("rectw");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mFastScrollRectW = atoi(parsevalue.c_str());
+		}
+
+		attr = child->first_attribute("recth");
+		if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+			mFastScrollRectH = atoi(parsevalue.c_str());
+		}
+	}
+
+	// Retrieve the line height
+	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
+	mLineHeight = mFontHeight;
+	mHeaderH = mFontHeight;
+
+	if (mIconSelected && mIconSelected->GetResource())
+	{
+		mSelectedIconWidth = gr_get_width(mIconSelected->GetResource());
+		mSelectedIconHeight = gr_get_height(mIconSelected->GetResource());
+		if (mSelectedIconHeight > (int)mLineHeight)
+			mLineHeight = mSelectedIconHeight;
+		mIconWidth = mSelectedIconWidth;
+	}
+
+	if (mIconUnselected && mIconUnselected->GetResource())
+	{
+		mUnselectedIconWidth = gr_get_width(mIconUnselected->GetResource());
+		mUnselectedIconHeight = gr_get_height(mIconUnselected->GetResource());
+		if (mUnselectedIconHeight > (int)mLineHeight)
+			mLineHeight = mUnselectedIconHeight;
+		if (mUnselectedIconWidth > mIconWidth)
+			mIconWidth = mUnselectedIconWidth;
+	}
+
+	if (mHeaderIcon && mHeaderIcon->GetResource())
+	{
+		mHeaderIconWidth = gr_get_width(mHeaderIcon->GetResource());
+		mHeaderIconHeight = gr_get_height(mHeaderIcon->GetResource());
+		if (mHeaderIconHeight > mHeaderH)
+			mHeaderH = mHeaderIconHeight;
+		if (mHeaderIconWidth > mIconWidth)
+			mIconWidth = mHeaderIconWidth;
+	}
+
+	mHeaderH += mLineSpacing + mHeaderSeparatorH;
+	actualLineHeight = mLineHeight + mLineSpacing + mSeparatorH;
+	if (mHeaderH < actualLineHeight)
+		mHeaderH = actualLineHeight;
+
+	if (actualLineHeight / 3 > 6)
+		touchDebounce = actualLineHeight / 3;
+
+	if (mBackground && mBackground->GetResource())
+	{
+		mBackgroundW = gr_get_width(mBackground->GetResource());
+		mBackgroundH = gr_get_height(mBackground->GetResource());
+	}
+
+	child = node->first_node("listtype");
+	if (child) {
+		attr = child->first_attribute("name");
+		if (attr) {
+			ListType = attr->value();
+			PartitionManager.Get_Partition_List(ListType, &mList);
+		} else {
+			mList.clear();
+			LOGE("No partition listtype name specified for partitionlist GUI element\n");
+			return;
+		}
+	} else {
+		mList.clear();
+		LOGE("No partition listtype specified for partitionlist GUI element\n");
+		return;
+	}
+}
+
+GUIPartitionList::~GUIPartitionList()
+{
+}
+
+int GUIPartitionList::Render(void)
+{
+	// First step, fill background
+	gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
+	gr_fill(mRenderX, mRenderY + mHeaderH, mRenderW, mRenderH - mHeaderH);
+
+	// Next, render the background resource (if it exists)
+	if (mBackground && mBackground->GetResource())
+	{
+		mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
+		mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
+		gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
+	}
+
+	// This tells us how many lines we can actually render
+	int lines = (mRenderH - mHeaderH) / (actualLineHeight);
+	int line;
+
+	if (updateList) {
+		mList.clear();
+		PartitionManager.Get_Partition_List(ListType, &mList);
+		updateList = false;
+		if (ListType == "backup")
+			MatchList();
+	}
+
+	int listSize = mList.size();
+	int listW = mRenderW;
+
+	if (listSize < lines) {
+		lines = listSize;
+		scrollingY = 0;
+		mFastScrollRectX = mFastScrollRectY = -1;
+	} else {
+		lines++;
+		if (lines < listSize)
+			lines++;
+		if (listSize >= lines)
+			listW -= mFastScrollW; // space for fast scrollbar
+		else
+			mFastScrollRectX = mFastScrollRectY = -1; // no fast scrollbar
+	}
+
+	void* fontResource = NULL;
+	if (mFont)  fontResource = mFont->GetResource();
+
+	int yPos = mRenderY + mHeaderH + scrollingY;
+	int fontOffsetY = (int)((actualLineHeight - mFontHeight) / 2);
+	int currentIconHeight = 0, currentIconWidth = 0;
+	int currentIconOffsetY = 0, currentIconOffsetX = 0;
+	int UnselectedIconOffsetY = (int)((actualLineHeight - mUnselectedIconHeight) / 2), SelectedIconOffsetY = (int)((actualLineHeight - mSelectedIconHeight) / 2);
+	int UnselectedIconOffsetX = (mIconWidth - mUnselectedIconWidth) / 2, SelectedIconOffsetX = (mIconWidth - mSelectedIconWidth) / 2;
+	int actualSelection = mStart;
+
+	if (isHighlighted) {
+		int selectY = scrollingY;
+
+		// Locate the correct line for highlighting
+		while (selectY + actualLineHeight < startSelection) {
+			selectY += actualLineHeight;
+			actualSelection++;
+		}
+		if (hasHighlightColor) {
+			// Highlight the area
+			gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, 255);
+			int HighlightHeight = actualLineHeight;
+			if (mRenderY + mHeaderH + selectY + actualLineHeight > mRenderH + mRenderY) {
+				HighlightHeight = actualLineHeight - (mRenderY + mHeaderH + selectY + actualLineHeight - mRenderH - mRenderY);
+			}
+			gr_fill(mRenderX, mRenderY + mHeaderH + selectY, mRenderW, HighlightHeight);
+		}
+	}
+
+	for (line = 0; line < lines; line++)
+	{
+		Resource* icon;
+		std::string label;
+
+		if (line + mStart >= listSize)
+			continue;
+
+		label = mList.at(line + mStart).Display_Name;
+		if (isHighlighted && hasFontHighlightColor && line + mStart == actualSelection) {
+			// Use the highlight color for the font
+			gr_color(mFontHighlightColor.red, mFontHighlightColor.green, mFontHighlightColor.blue, 255);
+		} else {
+			// Set the color for the font
+			gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, 255);
+		}
+
+		if (mList.at(line + mStart).selected != 0)
+        {
+            icon = mIconSelected;
+			currentIconHeight = mSelectedIconHeight;
+			currentIconWidth = mSelectedIconWidth;
+			currentIconOffsetY = SelectedIconOffsetY;
+			currentIconOffsetX = SelectedIconOffsetX;
+        }
+        else
+        {
+            icon = mIconUnselected;
+			currentIconHeight = mSelectedIconHeight;
+			currentIconWidth = mSelectedIconWidth;
+			currentIconOffsetY = SelectedIconOffsetY;
+			currentIconOffsetX = SelectedIconOffsetX;
+        }
+
+		if (icon && icon->GetResource())
+		{
+			int rect_y = 0, image_y = (yPos + currentIconOffsetY);
+			if (image_y + currentIconHeight > mRenderY + mRenderH)
+				rect_y = mRenderY + mRenderH - image_y;
+			else
+				rect_y = currentIconHeight;
+			gr_blit(icon->GetResource(), 0, 0, currentIconWidth, rect_y, mRenderX + currentIconOffsetX, image_y);
+		}
+		gr_textExWH(mRenderX + mIconWidth + 5, yPos + fontOffsetY, label.c_str(), fontResource, mRenderX + listW, mRenderY + mRenderH);
+
+		// Add the separator
+		if (yPos + actualLineHeight < mRenderH + mRenderY) {
+			gr_color(mSeparatorColor.red, mSeparatorColor.green, mSeparatorColor.blue, 255);
+			gr_fill(mRenderX, yPos + actualLineHeight - mSeparatorH, listW, mSeparatorH);
+		}
+
+		// Move the yPos
+		yPos += actualLineHeight;
+	}
+
+	// Render the Header (last so that it overwrites the top most row for per pixel scrolling)
+	// First step, fill background
+	gr_color(mHeaderBackgroundColor.red, mHeaderBackgroundColor.green, mHeaderBackgroundColor.blue, 255);
+	gr_fill(mRenderX, mRenderY, mRenderW, mHeaderH);
+
+	// Now, we need the header (icon + text)
+	yPos = mRenderY;
+	{
+		Resource* headerIcon;
+		int mIconOffsetX = 0;
+
+		// render the icon if it exists
+		headerIcon = mHeaderIcon;
+		if (headerIcon && headerIcon->GetResource())
+		{
+			gr_blit(headerIcon->GetResource(), 0, 0, mHeaderIconWidth, mHeaderIconHeight, mRenderX + ((mHeaderIconWidth - mIconWidth) / 2), (yPos + (int)((mHeaderH - mHeaderIconHeight) / 2)));
+			mIconOffsetX = mIconWidth;
+		}
+
+		// render the text
+		gr_color(mHeaderFontColor.red, mHeaderFontColor.green, mHeaderFontColor.blue, 255);
+		gr_textExWH(mRenderX + mIconOffsetX + 5, yPos + (int)((mHeaderH - mFontHeight) / 2), mLastValue.c_str(), fontResource, mRenderX + mRenderW, mRenderY + mRenderH);
+
+		// Add the separator
+		gr_color(mHeaderSeparatorColor.red, mHeaderSeparatorColor.green, mHeaderSeparatorColor.blue, 255);
+		gr_fill(mRenderX, yPos + mHeaderH - mHeaderSeparatorH, mRenderW, mHeaderSeparatorH);
+	}
+
+	// render fast scroll
+	lines = (mRenderH - mHeaderH) / (actualLineHeight);
+	if(mFastScrollW > 0 && listSize > lines)
+	{
+		int startX = listW + mRenderX;
+		int fWidth = mRenderW - listW;
+		int fHeight = mRenderH - mHeaderH;
+
+		// line
+		gr_color(mFastScrollLineColor.red, mFastScrollLineColor.green, mFastScrollLineColor.blue, 255);
+		gr_fill(startX + fWidth/2, mRenderY + mHeaderH, mFastScrollLineW, mRenderH - mHeaderH);
+
+		// rect
+		int pct = ((mStart*actualLineHeight - scrollingY)*100)/((listSize)*actualLineHeight-lines*actualLineHeight);
+		mFastScrollRectX = startX + (fWidth - mFastScrollRectW)/2;
+		mFastScrollRectY = mRenderY+mHeaderH + ((fHeight - mFastScrollRectH)*pct)/100;
+
+		gr_color(mFastScrollRectColor.red, mFastScrollRectColor.green, mFastScrollRectColor.blue, 255);
+		gr_fill(mFastScrollRectX, mFastScrollRectY, mFastScrollRectW, mFastScrollRectH);
+	}
+
+	mUpdate = 0;
+	return 0;
+}
+
+int GUIPartitionList::Update(void)
+{
+	if (!mHeaderIsStatic) {
+		std::string newValue = gui_parse_text(mHeaderText);
+		if (mLastValue != newValue) {
+			mLastValue = newValue;
+			mUpdate = 1;
+		}
+	}
+
+	// Check for changes in mount points if the list type is mount and update the list and render if needed
+	if (ListType == "mount") {
+		int listSize = mList.size();
+		for (int i = 0; i < listSize; i++) {
+			if (PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && !mList.at(i).selected) {
+				mList.at(i).selected = 1;
+				mUpdate = 1;
+			} else if (!PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && mList.at(i).selected) {
+				mList.at(i).selected = 0;
+				mUpdate = 1;
+			}
+		}
+	}
+
+	if (mUpdate)
+	{
+		mUpdate = 0;
+		if (Render() == 0)
+			return 2;
+	}
+
+	// Handle kinetic scrolling
+	if (scrollingSpeed == 0) {
+		// Do nothing
+	} else if (scrollingSpeed > 0) {
+		if (scrollingSpeed < ((int) (actualLineHeight * 2.5))) {
+			scrollingY += scrollingSpeed;
+			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
+		} else {
+			scrollingY += ((int) (actualLineHeight * 2.5));
+			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
+		}
+		while (mStart && scrollingY > 0) {
+			mStart--;
+			scrollingY -= actualLineHeight;
+		}
+		if (mStart == 0 && scrollingY > 0) {
+			scrollingY = 0;
+			scrollingSpeed = 0;
+		} else if (scrollingSpeed < SCROLLING_FLOOR)
+			scrollingSpeed = 0;
+		mUpdate = 1;
+	} else if (scrollingSpeed < 0) {
+		int totalSize = mList.size();
+		int lines = (mRenderH - mHeaderH) / (actualLineHeight);
+
+		if (totalSize > lines) {
+			int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);
+
+			bottom_offset -= actualLineHeight;
+
+			if (abs(scrollingSpeed) < ((int) (actualLineHeight * 2.5))) {
+				scrollingY += scrollingSpeed;
+				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
+			} else {
+				scrollingY -= ((int) (actualLineHeight * 2.5));
+				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
+			}
+			while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
+				mStart++;
+				scrollingY += actualLineHeight;
+			}
+			if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
+				mStart = totalSize - lines - 1;
+				scrollingY = bottom_offset;
+			} else if (mStart + lines >= totalSize && scrollingY < 0) {
+				mStart = totalSize - lines;
+				scrollingY = 0;
+			} else if (scrollingSpeed * -1 < SCROLLING_FLOOR)
+				scrollingSpeed = 0;
+			mUpdate = 1;
+		}
+	}
+
+	return 0;
+}
+
+int GUIPartitionList::GetSelection(int x, int y)
+{
+	// We only care about y position
+	if (y < mRenderY || y - mRenderY <= mHeaderH || y - mRenderY > mRenderH) return -1;
+	return (y - mRenderY - mHeaderH);
+}
+
+int GUIPartitionList::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+	static int lastY = 0, last2Y = 0;
+	int selection = 0;
+
+	switch (state)
+	{
+	case TOUCH_START:
+		if (scrollingSpeed != 0)
+			startSelection = -1;
+		else
+			startSelection = GetSelection(x,y);
+		isHighlighted = (startSelection > -1);
+		if (isHighlighted)
+			mUpdate = 1;
+		startY = lastY = last2Y = y;
+		scrollingSpeed = 0;
+		break;
+
+	case TOUCH_DRAG:
+		// Check if we dragged out of the selection window
+		if (GetSelection(x, y) == -1) {
+			last2Y = lastY = 0;
+			if (isHighlighted) {
+				isHighlighted = false;
+				mUpdate = 1;
+			}
+			break;
+		}
+
+		// Fast scroll
+		if(mFastScrollRectX != -1 && x >= mRenderX + mRenderW - mFastScrollW)
+		{
+			int pct = ((y-mRenderY-mHeaderH)*100)/(mRenderH-mHeaderH);
+			int totalSize = mList.size();
+			int lines = (mRenderH - mHeaderH) / (actualLineHeight);
+
+			float l = float((totalSize-lines)*pct)/100;
+			if(l + lines >= totalSize)
+			{
+				mStart = totalSize - lines;
+				scrollingY = 0;
+			}
+			else
+			{
+				mStart = l;
+				scrollingY = -(l - int(l))*actualLineHeight;
+			}
+
+			startSelection = -1;
+			mUpdate = 1;
+			scrollingSpeed = 0;
+			isHighlighted = false;
+			break;
+		}
+
+		// Provide some debounce on initial touches
+		if (startSelection != -1 && abs(y - startY) < touchDebounce) {
+			isHighlighted = true;
+			mUpdate = 1;
+			break;
+		}
+
+		isHighlighted = false;
+		last2Y = lastY;
+		lastY = y;	
+		startSelection = -1;
+
+		// Handle scrolling
+		scrollingY += y - startY;
+		startY = y;
+		while(mStart && scrollingY > 0) {
+			mStart--;
+			scrollingY -= actualLineHeight;
+		}
+		if (mStart == 0 && scrollingY > 0)
+			scrollingY = 0;
+		{
+			int totalSize = mList.size();
+			int lines = (mRenderH - mHeaderH) / (actualLineHeight);
+
+			if (totalSize > lines) {
+				int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);
+
+				bottom_offset -= actualLineHeight;
+
+				while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
+					mStart++;
+					scrollingY += actualLineHeight;
+				}
+				if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
+					mStart = totalSize - lines - 1;
+					scrollingY = bottom_offset;
+				} else if (mStart + lines >= totalSize && scrollingY < 0) {
+					mStart = totalSize - lines;
+					scrollingY = 0;
+				}
+			} else
+				scrollingY = 0;
+		}
+		mUpdate = 1;
+		break;
+
+	case TOUCH_RELEASE:
+		isHighlighted = false;
+		if (startSelection >= 0)
+		{
+			// We've selected an item!
+			int listSize = mList.size();
+			int selectY = scrollingY, actualSelection = mStart;
+
+			// Move the selection to the proper place in the array
+			while (selectY + actualLineHeight < startSelection) {
+				selectY += actualLineHeight;
+				actualSelection++;
+			}
+
+			if (actualSelection < listSize && ListType == "mount") {
+				if (!mList.at(actualSelection).selected) {
+					if (PartitionManager.Mount_By_Path(mList.at(actualSelection).Mount_Point, true)) {
+						mList.at(actualSelection).selected = 1;
+						mUpdate = 1;
+					}
+				} else {
+					if (PartitionManager.UnMount_By_Path(mList.at(actualSelection).Mount_Point, true)) {
+						mList.at(actualSelection).selected = 0;
+						mUpdate = 1;
+					}
+				}
+			} else if (actualSelection < listSize && !mVariable.empty()) {
+				if (ListType == "storage") {
+					int i;
+					std::string str = mList.at(actualSelection).Mount_Point;
+					bool update_size = false;
+					TWPartition* Part = PartitionManager.Find_Partition_By_Path(str);
+					if (Part == NULL) {
+						LOGE("Unable to locate partition for '%s'\n", str.c_str());
+						return 0;
+					}
+					if (!Part->Is_Mounted() && Part->Removable)
+						update_size = true;
+					if (!Part->Mount(true)) {
+						// Do Nothing
+					} else if (update_size && !Part->Update_Size(true)) {
+						// Do Nothing
+					} else {
+						for (i=0; i<listSize; i++)
+							mList.at(i).selected = 0;
+
+						if (update_size) {
+							char free_space[255];
+							sprintf(free_space, "%llu", Part->Free / 1024 / 1024);
+							mList.at(actualSelection).Display_Name = Part->Storage_Name + " (";
+							mList.at(actualSelection).Display_Name += free_space;
+							mList.at(actualSelection).Display_Name += "MB)";
+						}
+						mList.at(actualSelection).selected = 1;
+						mUpdate = 1;
+						
+						DataManager::SetValue(mVariable, str);
+					}
+				} else {
+					if (mList.at(actualSelection).selected)
+						mList.at(actualSelection).selected = 0;
+					else
+						mList.at(actualSelection).selected = 1;
+
+					int i;
+					string variablelist;
+					for (i=0; i<listSize; i++) {
+						if (mList.at(i).selected) {
+							variablelist += mList.at(i).Mount_Point + ";";
+						}
+					}
+
+					mUpdate = 1;
+					if (selectedList.empty())
+						DataManager::SetValue(mVariable, variablelist);
+					else
+						DataManager::SetValue(selectedList, variablelist);
+				}
+			}
+		} else {
+			// This is for kinetic scrolling
+			scrollingSpeed = lastY - last2Y;
+			if (abs(scrollingSpeed) > SCROLLING_FLOOR)
+				scrollingSpeed *= SCROLLING_MULTIPLIER;
+			else
+				scrollingSpeed = 0;
+		}
+	case TOUCH_REPEAT:
+	case TOUCH_HOLD:
+		break;
+	}
+	return 0;
+}
+
+int GUIPartitionList::NotifyVarChange(std::string varName, std::string value)
+{
+	if (!mHeaderIsStatic) {
+		std::string newValue = gui_parse_text(mHeaderText);
+		if (mLastValue != newValue) {
+			mLastValue = newValue;
+			mStart = 0;
+			scrollingY = 0;
+			scrollingSpeed = 0;
+			mUpdate = 1;
+		}
+	}
+	if (varName == mVariable && !mUpdate)
+    {
+        if (ListType == "storage") {
+			int i, listSize = mList.size(), selected_index = 0;
+
+			currentValue = value;
+
+			for (i=0; i<listSize; i++) {
+				if (mList.at(i).Mount_Point == currentValue) {
+					mList.at(i).selected = 1;
+					selected_index = i;
+				} else
+					mList.at(i).selected = 0;
+			}
+
+			int lines = mRenderH / (mLineHeight + mLineSpacing);
+			int line;
+
+			if (selected_index > mStart + lines - 1) {
+				mStart = selected_index;
+			} else if (selected_index < mStart) {
+				mStart = selected_index;
+			}
+		} else if (ListType == "backup") {
+			MatchList();
+		} else if (ListType == "restore") {
+			updateList = true;
+		}
+
+		mUpdate = 1;
+        return 0;
+    }
+	return 0;
+}
+
+int GUIPartitionList::SetRenderPos(int x, int y, int w /* = 0 */, int h /* = 0 */)
+{
+	mRenderX = x;
+	mRenderY = y;
+	if (w || h)
+	{
+		mRenderW = w;
+		mRenderH = h;
+	}
+	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
+	mUpdate = 1;
+	return 0;
+}
+
+void GUIPartitionList::SetPageFocus(int inFocus)
+{
+	if (inFocus) {
+		if (ListType == "storage") {
+			int i, listSize = mList.size(), selected_index = 0;
+
+			DataManager::GetValue(mVariable, currentValue);
+
+			for (i=0; i<listSize; i++) {
+				if (mList.at(i).Mount_Point == currentValue) {
+					mList.at(i).selected = 1;
+					selected_index = i;
+				} else
+					mList.at(i).selected = 0;
+			}
+
+			int lines = mRenderH / (mLineHeight + mLineSpacing);
+			int line;
+
+			if (selected_index > mStart + lines - 1) {
+				mStart = selected_index;
+			} else if (selected_index < mStart) {
+				mStart = selected_index;
+			}
+		}
+		updateList = true;
+		mUpdate = 1;
+	}
+}
+
+void GUIPartitionList::MatchList(void) {
+	int i, listSize = mList.size();
+	string variablelist, searchvalue;
+	size_t pos;
+
+	DataManager::GetValue(mVariable, variablelist);
+
+	for (i=0; i<listSize; i++) {
+		searchvalue = mList.at(i).Mount_Point + ";";
+		pos = variablelist.find(searchvalue);
+		if (pos != string::npos) {
+			mList.at(i).selected = 1;
+		} else {
+			mList.at(i).selected = 0;
+		}
+	}
+}
