@@ -29,7 +29,7 @@ function MagicButton_OnLoad(self)
 				self.LeftSeparator = relativeTo.RightSeparator;
 			else
 				-- Add a Middle separator
-				self.LeftSeparator = self:CreateTexture(self:GetName().."_LeftSeparator", "BORDER");
+				self.LeftSeparator = self:CreateTexture(self:GetName() and self:GetName().."_LeftSeparator" or nil, "BORDER");
 				relativeTo.RightSeparator = self.LeftSeparator;
 			end
 			
@@ -52,7 +52,7 @@ function MagicButton_OnLoad(self)
 				self.RightSeparator = relativeTo.LeftSeparator;
 			else
 				-- Add a Middle separator
-				self.RightSeparator = self:CreateTexture(self:GetName().."_RightSeparator", "BORDER");
+				self.RightSeparator = self:CreateTexture(self:GetName() and self:GetName().."_RightSeparator" or nil, "BORDER");
 				relativeTo.LeftSeparator = self.RightSeparator;
 			end
 			
@@ -85,7 +85,7 @@ function MagicButton_OnLoad(self)
 	if (not leftHandled) then
 		if (not self.LeftSeparator) then
 			-- Add a Left border
-			self.LeftSeparator = self:CreateTexture(self:GetName().."_LeftSeparator", "BORDER");
+			self.LeftSeparator = self:CreateTexture(self:GetName() and self:GetName().."_LeftSeparator" or nil, "BORDER");
 			self.LeftSeparator:SetTexture("Interface\\FrameGeneral\\UI-Frame");
 			self.LeftSeparator:SetTexCoord(0.24218750, 0.32812500, 0.63281250, 0.82812500);
 			self.LeftSeparator:SetWidth(11);
@@ -98,7 +98,7 @@ function MagicButton_OnLoad(self)
 	if (not rightHandled) then
 		if (not self.RightSeparator) then
 			-- Add a Right border
-			self.RightSeparator = self:CreateTexture(self:GetName().."_RightSeparator", "BORDER");
+			self.RightSeparator = self:CreateTexture(self:GetName() and self:GetName().."_RightSeparator" or nil, "BORDER");
 			self.RightSeparator:SetTexture("Interface\\FrameGeneral\\UI-Frame");
 			self.RightSeparator:SetTexCoord(0.90625000, 0.99218750, 0.00781250, 0.20312500);
 			self.RightSeparator:SetWidth(11);
@@ -176,4 +176,453 @@ function PortraitFrameCloseButton_OnClic
 	else
 		HideParentPanel(self);
 	end	
-end
\ No newline at end of file
+end
+
+
+-- Function to handle the update of manually calculated scrollframes.  Used mostly for listings with an indeterminate number of items
+function FauxScrollFrame_Update(frame, numItems, numToDisplay, buttonHeight, button, smallWidth, bigWidth, highlightFrame, smallHighlightWidth, bigHighlightWidth, alwaysShowScrollBar )
+	-- If more than one screen full of skills then show the scrollbar
+	local frameName = frame:GetName();
+	local scrollBar = _G[ frameName.."ScrollBar" ];
+	local showScrollBar;
+	if ( numItems > numToDisplay or alwaysShowScrollBar ) then
+		frame:Show();
+		showScrollBar = 1;
+	else
+		scrollBar:SetValue(0);
+		frame:Hide();
+	end
+	if ( frame:IsShown() ) then
+		local scrollChildFrame = _G[ frameName.."ScrollChildFrame" ];
+		local scrollUpButton = _G[ frameName.."ScrollBarScrollUpButton" ];
+		local scrollDownButton = _G[ frameName.."ScrollBarScrollDownButton" ];
+		local scrollFrameHeight = 0;
+		local scrollChildHeight = 0;
+
+		if ( numItems > 0 ) then
+			scrollFrameHeight = (numItems - numToDisplay) * buttonHeight;
+			scrollChildHeight = numItems * buttonHeight;
+			if ( scrollFrameHeight < 0 ) then
+				scrollFrameHeight = 0;
+			end
+			scrollChildFrame:Show();
+		else
+			scrollChildFrame:Hide();
+		end
+		local maxRange = (numItems - numToDisplay) * buttonHeight;
+		if (maxRange < 0) then
+			maxRange = 0;
+		end
+		scrollBar:SetMinMaxValues(0, maxRange); 
+		scrollBar:SetValueStep(buttonHeight);
+		scrollBar:SetStepsPerPage(numToDisplay-1);
+		scrollChildFrame:SetHeight(scrollChildHeight);
+		
+		-- Arrow button handling
+		if ( scrollBar:GetValue() == 0 ) then
+			scrollUpButton:Disable();
+		else
+			scrollUpButton:Enable();
+		end
+		if ((scrollBar:GetValue() - scrollFrameHeight) == 0) then
+			scrollDownButton:Disable();
+		else
+			scrollDownButton:Enable();
+		end
+		
+		-- Shrink because scrollbar is shown
+		if ( highlightFrame ) then
+			highlightFrame:SetWidth(smallHighlightWidth);
+		end
+		if ( button ) then
+			for i=1, numToDisplay do
+				_G[button..i]:SetWidth(smallWidth);
+			end
+		end
+	else
+		-- Widen because scrollbar is hidden
+		if ( highlightFrame ) then
+			highlightFrame:SetWidth(bigHighlightWidth);
+		end
+		if ( button ) then
+			for i=1, numToDisplay do
+				_G[button..i]:SetWidth(bigWidth);
+			end
+		end
+	end
+	return showScrollBar;
+end
+
+function FauxScrollFrame_OnVerticalScroll(self, value, itemHeight, updateFunction)
+	local scrollbar = _G[self:GetName().."ScrollBar"];
+	scrollbar:SetValue(value);
+	self.offset = floor((value / itemHeight) + 0.5);
+	if ( updateFunction ) then
+		updateFunction(self);
+	end
+end
+
+function FauxScrollFrame_GetOffset(frame)
+	return frame.offset;
+end
+
+function FauxScrollFrame_SetOffset(frame, offset)
+	frame.offset = offset;
+end
+
+-- Scrollframe functions
+function ScrollFrame_OnLoad(self)
+	_G[self:GetName().."ScrollBarScrollDownButton"]:Disable();
+	_G[self:GetName().."ScrollBarScrollUpButton"]:Disable();
+
+	local scrollbar = _G[self:GetName().."ScrollBar"];
+	scrollbar:SetMinMaxValues(0, 0);
+	scrollbar:SetValue(0);
+	self.offset = 0;
+	
+	if ( self.scrollBarHideable ) then
+		_G[self:GetName().."ScrollBar"]:Hide();
+		_G[scrollbar:GetName().."ScrollDownButton"]:Hide();
+		_G[scrollbar:GetName().."ScrollUpButton"]:Hide();
+	else
+		_G[scrollbar:GetName().."ScrollDownButton"]:Disable();
+		_G[scrollbar:GetName().."ScrollUpButton"]:Disable();
+		_G[scrollbar:GetName().."ScrollDownButton"]:Show();
+		_G[scrollbar:GetName().."ScrollUpButton"]:Show();
+	end
+	if ( self.noScrollThumb ) then
+		_G[scrollbar:GetName().."ThumbTexture"]:Hide();
+	end
+end
+
+function ScrollFrameTemplate_OnMouseWheel(self, value, scrollBar)
+	scrollBar = scrollBar or _G[self:GetName() .. "ScrollBar"];
+	local scrollStep = scrollBar.scrollStep or scrollBar:GetHeight() / 2
+	if ( value > 0 ) then
+		scrollBar:SetValue(scrollBar:GetValue() - scrollStep);
+	else
+		scrollBar:SetValue(scrollBar:GetValue() + scrollStep);
+	end
+end
+
+function ScrollFrame_OnScrollRangeChanged(self, xrange, yrange)
+	local scrollbar = self.ScrollBar or _G[self:GetName().."ScrollBar"];
+	if ( not yrange ) then
+		yrange = self:GetVerticalScrollRange();
+	end
+	local value = scrollbar:GetValue();
+	if ( value > yrange ) then
+		value = yrange;
+	end
+	scrollbar:SetMinMaxValues(0, yrange);
+	scrollbar:SetValue(value);
+	if ( floor(yrange) == 0 ) then
+		if ( self.scrollBarHideable ) then
+			_G[self:GetName().."ScrollBar"]:Hide();
+			_G[scrollbar:GetName().."ScrollDownButton"]:Hide();
+			_G[scrollbar:GetName().."ScrollUpButton"]:Hide();
+			_G[scrollbar:GetName().."ThumbTexture"]:Hide();
+		else
+			_G[scrollbar:GetName().."ScrollDownButton"]:Disable();
+			_G[scrollbar:GetName().."ScrollUpButton"]:Disable();
+			_G[scrollbar:GetName().."ScrollDownButton"]:Show();
+			_G[scrollbar:GetName().."ScrollUpButton"]:Show();
+			if ( not self.noScrollThumb ) then
+				_G[scrollbar:GetName().."ThumbTexture"]:Show();
+			end
+		end
+	else
+		_G[scrollbar:GetName().."ScrollDownButton"]:Show();
+		_G[scrollbar:GetName().."ScrollUpButton"]:Show();
+		_G[self:GetName().."ScrollBar"]:Show();
+		if ( not self.noScrollThumb ) then
+			_G[scrollbar:GetName().."ThumbTexture"]:Show();
+		end
+		-- The 0.005 is to account for precision errors
+		if ( yrange - value > 0.005 ) then
+			_G[scrollbar:GetName().."ScrollDownButton"]:Enable();
+		else
+			_G[scrollbar:GetName().."ScrollDownButton"]:Disable();
+		end
+	end
+	
+	-- Hide/show scrollframe borders
+	local top = _G[self:GetName().."Top"];
+	local bottom = _G[self:GetName().."Bottom"];
+	local middle = _G[self:GetName().."Middle"];
+	if ( top and bottom and self.scrollBarHideable ) then
+		if ( self:GetVerticalScrollRange() == 0 ) then
+			top:Hide();
+			bottom:Hide();
+		else
+			top:Show();
+			bottom:Show();
+		end
+	end
+	if ( middle and self.scrollBarHideable ) then
+		if ( self:GetVerticalScrollRange() == 0 ) then
+			middle:Hide();
+		else
+			middle:Show();
+		end
+	end
+end
+
+function ScrollBar_AdjustAnchors(scrollBar, topAdj, bottomAdj, xAdj)
+	-- assumes default anchoring of topleft-topright, bottomleft-bottomright
+	local topY = 0;
+	local bottomY = 0;
+	local point, parent, refPoint, x, y;
+	for i = 1, 2 do
+		point, parent, refPoint, x, y = scrollBar:GetPoint(i);
+		if ( point == "TOPLEFT" ) then
+			topY = y;
+		elseif ( point == "BOTTOMLEFT" ) then
+			bottomY = y;
+		end
+	end
+	xAdj = xAdj or 0;
+	topAdj = topAdj or 0;
+	bottomAdj = bottomAdj or 0;
+	scrollBar:SetPoint("TOPLEFT", parent, "TOPRIGHT", x + xAdj, topY + topAdj);
+	scrollBar:SetPoint("BOTTOMLEFT", parent, "BOTTOMRIGHT", x + xAdj, bottomY + bottomAdj);
+end
+
+function HideParentPanel(self)	
+	HideUIPanel(self:GetParent());
+end
+
+function EditBox_HandleTabbing(self, tabList)
+	local editboxName = self:GetName();
+	local index;
+	for i=1, #tabList do
+		if ( editboxName == tabList[i] ) then
+			index = i;
+			break;
+		end
+	end
+	if ( IsShiftKeyDown() ) then
+		index = index - 1;
+	else
+		index = index + 1;
+	end
+
+	if ( index == 0 ) then
+		index = #tabList;
+	elseif ( index > #tabList ) then
+		index = 1;
+	end
+
+	local target = tabList[index];
+	_G[target]:SetFocus();
+end
+
+function EditBox_ClearFocus (self)
+	self:ClearFocus();
+end
+
+function EditBox_SetFocus (self)
+	self:SetFocus();
+end
+
+function EditBox_HighlightText (self)
+	self:HighlightText();
+end
+
+function EditBox_ClearHighlight (self)
+	self:HighlightText(0, 0);
+end
+
+function InputBoxInstructions_OnTextChanged(self)
+	self.Instructions:SetShown(self:GetText() == "")
+end
+
+
+-- functions to manage tab interfaces where only one tab of a group may be selected
+function PanelTemplates_Tab_OnClick(self, frame)
+	PanelTemplates_SetTab(frame, self:GetID())
+end
+
+function PanelTemplates_SetTab(frame, id)
+	frame.selectedTab = id;
+	PanelTemplates_UpdateTabs(frame);
+end
+
+function PanelTemplates_GetSelectedTab(frame)
+	return frame.selectedTab;
+end
+
+function PanelTemplates_UpdateTabs(frame)
+	if ( frame.selectedTab ) then
+		local tab;
+		for i=1, frame.numTabs, 1 do
+			tab = _G[frame:GetName().."Tab"..i];
+			if ( tab.isDisabled ) then
+				PanelTemplates_SetDisabledTabState(tab);
+			elseif ( i == frame.selectedTab ) then
+				PanelTemplates_SelectTab(tab);
+			else
+				PanelTemplates_DeselectTab(tab);
+			end
+		end
+	end
+end
+
+function PanelTemplates_GetTabWidth(tab)
+	local tabName = tab:GetName();
+
+	local sideWidths = 2 * _G[tabName.."Left"]:GetWidth();
+	return tab:GetTextWidth() + sideWidths;
+end
+	
+function PanelTemplates_TabResize(tab, padding, absoluteSize, minWidth, maxWidth, absoluteTextSize)
+	local tabName = tab:GetName();
+	
+	local buttonMiddle = tab.Middle or _G[tabName.."Middle"];
+	local buttonMiddleDisabled = tab.MiddleDisabled or _G[tabName.."MiddleDisabled"];
+	local sideWidths = tab.Left and 2 * tab.Left:GetWidth() or 2 * _G[tabName.."Left"]:GetWidth();
+	local tabText = tab.Text or _G[tab:GetName().."Text"];
+	local highlightTexture = tab.HighlightTexture or _G[tabName.."HighlightTexture"];
+	
+	local width, tabWidth;
+	local textWidth;
+	if ( absoluteTextSize ) then
+		textWidth = absoluteTextSize;
+	else
+		tabText:SetWidth(0);
+		textWidth = tabText:GetWidth();
+	end
+	-- If there's an absolute size specified then use it
+	if ( absoluteSize ) then
+		if ( absoluteSize < sideWidths) then
+			width = 1;
+			tabWidth = sideWidths
+		else
+			width = absoluteSize - sideWidths;
+			tabWidth = absoluteSize
+		end
+		tabText:SetWidth(width);
+	else
+		-- Otherwise try to use padding
+		if ( padding ) then
+			width = textWidth + padding;
+		else
+			width = textWidth + 24;
+		end
+		-- If greater than the maxWidth then cap it
+		if ( maxWidth and width > maxWidth ) then
+			if ( padding ) then
+				width = maxWidth + padding;
+			else
+				width = maxWidth + 24;
+			end
+			tabText:SetWidth(width);
+		else
+			tabText:SetWidth(0);
+		end
+		if (minWidth and width < minWidth) then
+			width = minWidth;
+		end
+		tabWidth = width + sideWidths;
+	end
+	
+	if ( buttonMiddle ) then
+		buttonMiddle:SetWidth(width);
+	end
+	if ( buttonMiddleDisabled ) then
+		buttonMiddleDisabled:SetWidth(width);
+	end
+	
+	tab:SetWidth(tabWidth);
+	
+	if ( highlightTexture ) then
+		highlightTexture:SetWidth(tabWidth);
+	end
+end
+
+function PanelTemplates_SetNumTabs(frame, numTabs)
+	frame.numTabs = numTabs;
+end
+
+function PanelTemplates_DisableTab(frame, index)
+	_G[frame:GetName().."Tab"..index].isDisabled = 1;
+	PanelTemplates_UpdateTabs(frame);
+end
+
+function PanelTemplates_EnableTab(frame, index)
+	local tab = _G[frame:GetName().."Tab"..index];
+	tab.isDisabled = nil;
+	-- Reset text color
+	tab:SetDisabledFontObject(GameFontHighlightSmall);
+	PanelTemplates_UpdateTabs(frame);
+end
+
+function PanelTemplates_DeselectTab(tab)
+	local name = tab:GetName();
+	
+	local left = tab.Left or _G[name.."Left"];
+	local middle = tab.Middle or _G[name.."Middle"];
+	local right = tab.Right or _G[name.."Right"];
+	left:Show();
+	middle:Show();
+	right:Show();
+	--tab:UnlockHighlight();
+	tab:Enable();
+	local text = tab.Text or _G[name.."Text"];
+	text:SetPoint("CENTER", tab, "CENTER", (tab.deselectedTextX or 0), (tab.deselectedTextY or 2));
+	
+	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
+	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
+	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
+	leftDisabled:Hide();
+	middleDisabled:Hide();
+	rightDisabled:Hide();
+end
+
+function PanelTemplates_SelectTab(tab)
+	local name = tab:GetName();
+	
+	local left = tab.Left or _G[name.."Left"];
+	local middle = tab.Middle or _G[name.."Middle"];
+	local right = tab.Right or _G[name.."Right"];
+	left:Hide();
+	middle:Hide();
+	right:Hide();
+	--tab:LockHighlight();
+	tab:Disable();
+	tab:SetDisabledFontObject(GameFontHighlightSmall);
+	local text = tab.Text or _G[name.."Text"];
+	text:SetPoint("CENTER", tab, "CENTER", (tab.selectedTextX or 0), (tab.selectedTextY or -3));
+	
+	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
+	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
+	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
+	leftDisabled:Show();
+	middleDisabled:Show();
+	rightDisabled:Show();
+	
+	if ( GameTooltip and GameTooltip:IsOwned(tab) ) then
+		GameTooltip:Hide();
+	end
+end
+
+function PanelTemplates_SetDisabledTabState(tab)
+	local name = tab:GetName();
+	local left = tab.Left or _G[name.."Left"];
+	local middle = tab.Middle or _G[name.."Middle"];
+	local right = tab.Right or _G[name.."Right"];
+	left:Show();
+	middle:Show();
+	right:Show();
+	--tab:UnlockHighlight();
+	tab:Disable();
+	tab.text = tab:GetText();
+	-- Gray out text
+	tab:SetDisabledFontObject(GameFontDisableSmall);
+	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
+	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
+	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
+	leftDisabled:Hide();
+	middleDisabled:Hide();
+	rightDisabled:Hide();
+end