#!/bin/bash
# ==============================================================================
# title			:Ram Booter
# desoftwareion	:Boots your Entire O/S from RAM.
# author		:theemahn <theemahn@ultimateedition.info>
# date			:06/22/2021
# version		:1.0
# usage			:Ram Booter --help
# manual		:man Ram Booter
# notes			:See change-log below for further information.
# ==============================================================================
# Change-log: 1.0: unreleased
# ==============================================================================
# set -x # Debugging purposes.
# Modify the below information to correlate with the software you are designing.
# GRUB_DISABLE_OS_PROBER=false
APPNAME="ram-booter"
PROGNAME="Ram Booter"
PROGRAMMER="TheeMahn"
BUILDDATE="06/11/2025"
VERSION="2.1.4"
DOMAIN="rambooter.com"
WEBSITE="${DOMAIN}/"
EMAIL="<${PROGRAMMER}@${DOMAIN}>"

# Set defaults
ORIG_OS='/mnt/Original_OS/'
RAMSESSION=""
export LANG=C.UTF-8

if [[ -f "/ram_session" ]]; then
	RAMSESSION=true
fi

if [[ -f "ultimate-common" ]]; then
	source ultimate-common
elif [[ -f "/usr/share/ultimate_edition/ultimate-common" ]]; then
	source /usr/share/ultimate_edition/ultimate-common
else
	echo "No Ultimate Edition common source. Please install ultimate-edition-common."
	exit 1;
fi

# Logging output - Currently un-implemented
# exec 1> /var/log/Ram Booter.log
# exec 1>> /var/log/Ram Booter.log 2>&1
# Multiple log files?
declare -a LOG_FILE=( "/var/log/Ram_Booter.log" );
# Single Log
# LOG_FILE="/var/log/Ram Booter.log"
# exec 1 | tee ${LOG_FILE}
# exec 2 | tee ${LOG_FILE}

COMPRESSION=$(echo "$@" | grep -i "compression=")
PERSISTANCE=$(echo "$@" | grep -i "persistance=")
if [[ "${COMPRESSION}" ]]; then
	COMPRESSION=$(echo "$@" | grep -i "compression=" | sed "s/^.*compression=//g" | cut -d" " -f1)
else
	# Set default compression option as Fast null if not specified. << - we can expand here ;)
	COMPRESSION=""
fi
if [[ "${PERSISTANCE}" ]]; then
	PERSISTANCE=$(echo "$@" | grep -i "persistance=" | sed "s/^.*persistance=//g" | cut -d" " -f1)
fi

if [[ "${DEBUG}" ]]; then
	echo "DEBUG: Cacheoption set as ${CACHEOPTION} | Compression: ${COMPRESSION} | Recommended: ${RECOMMENDED} | REQUESTKERNEL: ${REQUESTKERNEL}"
fi
# get current hooks
hooks="$(grep -Po '^\s*HOOKS=\(\K.*?(?=\))' /etc/mkinitcpio.conf | \
        sed -E 's/\s+/ /g; s/\s+$//g')"
DisableHook () {
# remove ram-booter from mkinitcpio.conf HOOKS, rebuild all preset images:
	#global hooks
	if [[ " $hooks " =~ ' ram-booter ' ]]; then
		hooks="$(sed -E 's/^(.*) ram-booter(.*)/\1\2/g' <<<"$hooks")"
		sed -Ei "s/^(\s*HOOKS=).*/\1\(${hooks}\)/g" /etc/mkinitcpio.conf
		Encapsulate "${APPNAME} removed from /etc/mkinitcpio.conf HOOKS"
	fi
	mkinitcpio -P
}

EnableHook () {
# add ram-booter to mkinitcpio.conf HOOKS, rebuild all preset images:
	#global hooks
	if [[ ! " $hooks " =~ ' ram-booter ' ]]; then
		hooks="$(sed -E \
			's/^(.*(encrypt|udev|base|bash)) (.*)/\1 ram-booter \3/g' \
			<<<"$hooks")"
		sed -Ei "s/^(\s*HOOKS=).*/\1\(${hooks}\)/g" /etc/mkinitcpio.conf
		Encapsulate "${APPNAME} added to /etc/mkinitcpio.conf HOOKS"
	fi
	mkinitcpio -P
}
# Help system - I have re-wrote this section to work with code-cleanup.
Help () {

	if [[ "${2}" == "" ]]; then
		PRAM="ALL"
	else
		if ! [[ "${3}" ]]; then
			PRAM="${2}"
		else
			PRAM="${2}"
		fi
	fi

	case "${PRAM}" in
		ALL)
			Encapsulate "Usage: ${PROGNAME} -<-Command> [OPTION]"
			FullBar
			Encapsulate "Mandatory arguments to long options are identical for short options."
			Encapsulate "  possible commands..."
			Encapsulate " "
			Encapsulate "  -b  --benchmark      benchmarks any block device in your computer."
			Encapsulate "  -E  --enable         enable hook."
			Encapsulate "  -D  --disable        disable hook."
			Encapsulate "  -h  --help           this help message."
			Encapsulate "  -I  --iso            scan and add ISO(s) to boot menu."
			Encapsulate "  -i  --info           shows computer info and ram session info."
			Encapsulate "  -s  --setup          set up a bootable ram drive."
			Encapsulate "  -S  --session        select default session."
			Encapsulate "  -u  --uninstall      uninstalls Ram Session / custom ISO(S)."
			Encapsulate "  -w  --writesquashfs  re-writes squashfs (ram session only)."
			Encapsulate "  -v  --version        dump version info and exit."
			Encapsulate " "
			FullBar
			Center "${PROGNAME} --help [Command] for further information."
		FullBar;;

		# benchmark Help
		ALL|b|benchmark)
			Encapsulate "Usage benchmark;"
			FullBar
			Center "${PROGNAME} -b [DEVICE]"
			FullBar
			FormatText "Displays [DEVICE]'s read speed and exits.  Not providing the optional [DEVICE].  Will benchmark the current boot device.  Sudo command is recommended, but not required for permission to flush the cace in order to obtain more accurate results."
		FullBar;;

		# ISO Help
		ALL|I|iso|ISO)
			Encapsulate "Usage iso;"
			FullBar
			Center "${PROGNAME} -I [ISO IMAGE]"
			FullBar
			FormatText "Info switch will display information about your computer and Ram Drive."
		FullBar;;

		# ISO Help
		ALL|i|info)
			Encapsulate "Usage info;"
			FullBar
			Center "${PROGNAME} -i"
			FullBar
			FormatText "Ram Booter -I [ISO IMAGE].  Adds [ISO IMAGE] to your grub menu.  Not specifing the optional [ISO IMAGE] will add all ISO Images that are bootable to your grub menu."
		FullBar;;

		# Setup Help
		ALL|s|setup)
			Encapsulate "Usage setup;"
			FullBar
			Center "${PROGNAME} -s [COMPRESSION SWITCHES]"
			FullBar
			FormatText "This software will create a copy of your Ultimate Edition OS in /var/squashfs/ and then use that copy to create a squashfs image of it located at /live. After this separation, your current OS (the Original OS) and your new OS (the Ram Session) will be two completely separate entities. Updates of one OS will not affect the update of the other, and the setup of packages on one will not transfer to the other. Depending on what you choose however, your /home may be shared between the two systems."
			Encapsulate " "
			FormatText "Compression switches there are 3. Default compression is the same as not providing one.  Compression=fast which is case insensitive will compress the image fast and will run equally the same way once it is loaded, however will use the most space and memory.  Runs like an absolute rocket if you have the resources.  Compression=Maximum will take a long time to compress initially. Loads quickly into ram as it will be a smaller image.  Once it hits RAM is slow to decompress in memory.  Almost defeats the purpose of Ram Booter IMHO."
			Encapsulate " "
			FormatText "Persistance by default is enabled.  This engages the ram-booter-shutdown.service(8) to be enabled. Persistance=false will make your Operating System not store any changes."
		FullBar;;

		# Session Help
		ALL|S|session)
			Encapsulate "Usage session;"
			FullBar
			Center "${PROGNAME} -S"
			FullBar
			FormatText "Ram Booter --session.  Allows the end user to select the default session on next boot."
		FullBar;;

		# Uninstall Help
		ALL|u|uninstall)
			Encapsulate "Usage uninstall;"
			FullBar
			Center "${PROGNAME} -u"
			FullBar
			FormatText "Ram Booter --uninstall.  Uninstalls all ram sessions and any ISO's you may have added to the grub menu."
		FullBar;;

		# Writesquashfs Help
		ALL|w|writesquashfs)
			Encapsulate "Usage writesquashfs;"
			FullBar
			Center "${PROGNAME} -u"
			FullBar
			FormatText "Ram Booter --writesquashfs.  re-writes squashfs (ram session only)."
		FullBar;;

		# Version Help
		ALL|v|version)
			Encapsulate "Usage version;"
			FullBar
			Center "${PROGNAME} -v"
			FullBar
			Encapsulate "Displays ${PROGNAME}s version number and exits."
		FullBar;;

		# Help Help
		ALL|h|help|\?)
			Encapsulate "Usage Help [Command]"
			FullBar
			Center "${PROGNAME} -h [Command]"
			FullBar
			Encapsulate "Displays this message. For futher information ${PROGNAME} help [Command]"
			Encapsulate "or refer to the manpages."
			Encapsulate " "
			Encapsulate "man ${PROGNAME}"
			Encapsulate " "
			Encapsulate "Example: ${PROGNAME} -h version"
			Encapsulate "Will display help about the command switch version"
			FullBar
	esac
	exit 0
}

UpdateGrub () {
	GRUBB=$(type -p update-grub)
	if ! [[ "${ISARCH}" ]]; then
		if [[ "${GRUBB}" ]]; then
			Encapsulate "Updating Grub..."
			sudo update-grub 2>/dev/null & Spinner "Updating Grub..."
			Encapsulate "Updating initramfs..."
			sudo update-initramfs -u -k all >/dev/null 2>&1 & Spinner "Updating Initramfs..."
			if [[ "$?" != 0 ]]; then
				Error "Initramfs failed to update."
				Encapsulate "Exiting..."
				Uninstall_Ram_Booter quiet
				exit 1
			else
				Encapsulate "Initramfs updated successfully."
			fi
			FullBar
		fi
	else
		GRUBB=$(type -p grub-mkconfig)
		if [[ "${GRUBB}" ]]; then
			Encapsulate "Updating Grub..."
			sudo grub-mkconfig -o /boot/grub/grub.cfg 2>/dev/null & Spinner "Updating Grub..."
			Encapsulate "Updating initramfs..."
			sudo mkinitcpio -P >/dev/null 2>&1 & Spinner "Updating Initramfs..."
			if [[ "$?" != 0 ]]; then
				Error "Initramfs failed to update."
				Encapsulate "Exiting..."
				Uninstall_Ram_Booter quiet
				exit 1
			else
				Encapsulate "Initramfs updated successfully."
			fi
			FullBar
		fi
	fi
}

# PULL VARS
if [[ -f "/var/lib/ram_booter/conf" ]]; then
	#Figure out ${DEST}
	DEST=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep DEST= | sed 's/DEST=//g')
	#Remove leading slash from ${DEST}
	DEST="${DEST#/}"
	#The mountpoint of the Original OS device
	#Note: If you change it here, be sure to change it in the software as well
	COMPRESSION=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep -i compression= | sed 's/COMPRESSION=//g')
	#/boot and / of the Original OS
	ROOT_UUID=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep ROOT_UUID= | sed 's/ROOT_UUID=//g')
	BOOT_UUID=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep BOOT_UUID= | sed 's/BOOT_UUID=//g')
	HOME_UUID=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep HOME_UUID= | sed 's/HOME_UUID=//g')
	EFI_UUID=$(cat /var/lib/ram_booter/conf | grep -v '^#' | grep EFI_UUID= | sed 's/EFI_UUID=//g')
fi

#Convert input to lowercase
toLower()
{
	echo $@ | tr "[:upper:]" "[:lower:]"
}

#Writes all args directly to log file
LOGGER() {
	#If LOG file is empty, add top border
	if ! grep -q '================================================================================' ${LOG}
	then
		echo '================================================================================' >> ${LOG}
	fi

	while IFS= read -r LINE
	do
		echo "${LINE}" >> ${LOG}
	done < <(echo "$@")

	#Draw line
	echo '================================================================================' >> "${LOG}"
}

#Runs commands, and redirects the output to a log file
#Returns the exit code of the command so that it can easily be checked
#if the command succeeded or failed:
#	$ echo /etc/passwd | Command grep 'some_user' && echo "User 'some_user' found' || echo "User 'some_user' not found"
Command () {
	#Legend:
	#	STDIN - contains the FULL output being piped to the command that this function is to run
	#	$@ - contains the command itself that this function is supposed to run
	#	OUTPUT - the final output the command passed to this function produces

	#If LOG file is empty, add top border
	if ! [[ -f "${LOG}" ]]; then
		sudo touch "${LOG}";
	fi
	if ! grep -q '================================================================================' "${LOG}"; then
		echo '================================================================================' >> "${LOG}"
	fi

	#See if anything is being piped to our function
	#Eg:
	#	echo 'stuff and junk' | Command sudo sed 's/stuff/thing/g'
	if [[ -t 0 ]]; then
		#Nothing is being piped. Output is just the result of running the command
		OUTPUT=$("$@" 2>&1)
		EXIT_CODE=$?
	else
		#Something is being piped. Output is the result of piping
		#STDIN to $@
		STDIN=$(cat -)

		echo "STDIN:" >> ${LOG}

		#Indent STDIN lines for the log file
		while IFS= read -r LINE
		do
			echo -e "\t${LINE}" >> "${LOG}"
		done < <(echo "${STDIN}")

		#Pipe stdin to $@
		OUTPUT=$(echo "${STDIN}" | "$@" 2>&1)
		EXIT_CODE=$?
	fi

	echo "Command:" >> "${LOG}"

	#Write the command to the log file
	#Some commands (especially sed commands) span multiple lines
	#This indents every line
	while IFS= read -r LINE
	do
		echo -e "\t${LINE}" >> ${LOG}
	done < <(echo "$@")

	echo "OUTPUT:" >> ${LOG}

	#Write the stdout AND stderr to the log file
	#Most output spans multiple lines
	#This indents every line
	while IFS= read -r LINE
	do
		echo -e "\t${LINE}" >> ${LOG}
	done < <(echo "${OUTPUT}")

	#Draw line
	echo '================================================================================' >> ${LOG}

	return $EXIT_CODE
}

# Uninstalls the RAM Session
Uninstall_Ram_Booter () {
	SHARE_HOME=$([[ -e /var/lib/ram_booter/conf ]] && { cat /var/lib/ram_booter/conf | grep -v '^#' | grep -q 'SHARE_HOME=.*true.*' && echo true; } || echo false)
	HOME_ALREADY_MOUNTED=$([[ -e /var/lib/ram_booter/conf ]] && { cat /var/lib/ram_booter/conf | grep -v '^#' | grep -q 'HOME_ALREADY_MOUNTED=.*true.*' && echo true; } || echo false)

	#This function can uninstall quietly if asked
	QUIET=''
	arg1_lcase=$(toLower $1)
	[[ $arg1_lcase == "quiet" ]] && QUIET=true || QUIET=false

	#Check if the software is running from within the RAM Session
	if [[ -e /ram_session ]]
	then
		Error "You can only uninstall the RAM Session from within the Original OS."
		exit 0
	fi

	${QUIET} ||
	${QUIET} || Center "Uninstalling..."

	#Delete /mnt/tmp
	if [[ -d "/mnt/tmp" ]];	then
		#Check if directory is a mountpoint
		CHECKMOUNT=$(mountpoint -q "/mnt/tmp")
		if [[ "${CHECKMOUNT}" ]]; then
			${QUIET} || Encapsulate "Unmounting /mnt/tmp..."
			sudo umount "/mnt/tmp" &>/dev/null

			#Check how unmount operation went
			if [[ "$?" != "0" ]]; then
				Error "/mnt/tmp failed to unmount. Is it in use?"
			else
				${QUIET} || Encapsulate "Removing /mnt/tmp..."
				sudo rmdir "/mnt/tmp"
			fi
		else
			Encapsulate "Removing /mnt/tmp..."
			sudo rmdir "/mnt/tmp"
		fi
	fi

	#Delete /mnt/root
	if [[ -d "/mnt/root" ]]; then
		#Check if directory is a mountpoint
		CHECKMOUNT=$(mountpoint -q "/mnt/root")
		if [[ "${CHECKMOUNT}" ]]; then
			${QUIET} || Encapsulate "Unmounting /mnt/root..."
			sudo umount "/mnt/root" &>/dev/null
			#Check how unmount operation went
			if [[ "$?" != "0" ]]
			then
				Error "/mnt/root failed to unmount. Is it in use?"
			else
				${QUIET} || Encapsulate "Removing /mnt/root..."
				sudo rmdir /mnt/root
			fi
		else

			${QUIET} || Encapsulate "Removing /mnt/root..."
			sudo rmdir /mnt/root
		fi
	fi

	#Delete ${DEST}
	if [[ -d "${DEST}" ]]; then

		${QUIET} || Encapsulate "Removing ${DEST}..."
		sudo rm -rf "${DEST}" &>/dev/null & Spinner "Removing ${DEST}..."

		#Check how delete operation went
		if [[ "$?" != "0" ]]
		then
			Error "Failed to remove ${DEST}"
		fi
	fi

	#Delete /var/lib/ram_booter/
	if [[ -d "/var/lib/ram_booter" ]]; then
		${QUIET} || Encapsulate "Removing /var/lib/ram_booter..."
		sudo rm -rf "/var/lib/ram_booter"
		Encapsulate "Disabling ${PROGNAME} shutdown service."
		sudo systemctl disable ${APPNAME} &>/dev/null
	fi

	#Delete /live
	if [[ -d "/live" ]]; then
		${QUIET} || Encapsulate "Removing /live..."
		sudo rm -rf /live &>/dev/null
		#Check how delete operation went
		if [[ "$?" != "0" ]]; then
			Error "Failed to remove /live"
		fi
	fi

	# Remove added ISO(s) grub entrie(s)
	shopt -s nullglob
	declare -a GENTRIES=();
	declare -i NENTRIES
	declare -i COUNT
	CD="${PWD}"
	if [[ -d "/etc/grub.d/" ]]; then
		cd "/etc/grub.d/" || exit 1;
		GENTRIES=(./07*)
		NENTRIES="${#GENTRIES[@]}"
		${QUIET} || Encapsulate "Removing custom ISO grub entry(s)."
		for EACH in "${GENTRIES[@]}"
		do
			((COUNT++))
			PCOMP=$((100*COUNT / NENTRIES))
			ProgressBar "${PCOMP}" "Removing Bootable ISO entries: ${COUNT} of ${NENTRIES}"
			sudo rm -rf "${EACH}" &>/dev/null
			if [[ "$?" != "0" ]]; then
				Error "Failed to remove ${EACH}"
			fi
		done
		cd "${CD}" || exit 1;
	else
		Error "/etc/grub.d/ not found exiting..."
		exit 1;
	fi

	#Delete /etc/grub.d/RAMBOOTER
	if [[ -e "/etc/grub.d/06_rambooter" ]]; then
		${QUIET} || Encapsulate "Removing /etc/grub/06_rambooter..."
		sudo rm -f "/etc/grub.d/06_rambooter"
	fi

	#Delete /original_os
	if [[ -e "/original_os" ]];	then
		${QUIET} || Encapsulate "Removing /original_os..."
		sudo rm -f "/original_os"
	fi

	#Delete zb_version_check file
	if ! [[ "${ISARCH}" ]]; then
		if [[ -e "/etc/kernel/postinst.d/zb_version_check" ]]; then
			${QUIET} || Encapsulate "Removing /etc/kernel/postinst.d/zb_version_check..."
			sudo rm -f "/etc/kernel/postinst.d/zb_version_check"
		fi
	fi

	#Delete /etc/kernel/postinst.d/zc_sort_kernels
	if ! [[ "${ISARCH}" ]]; then
		if [[ -e "/etc/kernel/postinst.d/zc_sort_kernels" ]]; then
			${QUIET} || Encapsulate "Removing /etc/kernel/postinst.d/zc_sort_kernels..."
			sudo rm -f "/etc/kernel/postinst.d/zc_sort_kernels"
		fi
	fi

	#Delete /boot/Orig
	if [[ -e /boot/Orig ]]
	then
		${QUIET} || Encapsulate "Removing /boot/orig..."
		sudo rm -f "/boot/orig"
	fi

	#Delete /boot/ram_sess
	if [[ -e "/boot/ram_sess" ]]; then
		${QUIET} || Encapsulate "Removing /boot/ram_sess..."
		sudo rm -f "/boot/ram_sess"
	fi

	#Delete /boot/rs_kernels/
	if [[ -d "/boot/rs_kernels" ]]; then
		${QUIET} || Encapsulate "Removing /boot/rs_kernels/..."
		sudo rm -rf "/boot/rs_kernels"
	fi

	#Fix grub menu
	GRUBMENU=$(grep -q '#GRUB_HIDDEN_TIMEOUT=0' "/etc/default/grub")
	if [[ "${GRUBMENU}" ]]; then
		${QUIET} || Encapsulate "Restoring grub menu..."
		sudo sed -i 's/#\(GRUB_HIDDEN_TIMEOUT=0\)/\1/g' "/etc/default/grub"

		#Update grub
		UpdateGrub "$@"
	fi

	# Purge live-boot
	INSTALLED=$(sudo dpkg -l live-boot 2>/dev/null)
	if [[ "${INSTALLED}" ]]; then
		Encapsulate "Purging live-boot..."
		sudo apt-get autoremove -y --purge live-boot &>/dev/null & Spinner "Purging live-boot..."
		if [[ "$?" != "0" ]]; then
			Error "Failed to purge live-boot"
		fi
	fi

	#Purge live-tools
	INSTALLED=$(sudo dpkg -l live-tools 2>/dev/null)
	if [[ "${INSTALLED}" ]]; then
		Encapsulate "Purging live-tools..."
		Command sudo apt-get autoremove -y --purge live-tools &>/dev/null & Spinner "Purging live-tools..."
		if [[ "$?" != "0" ]]; then
			Error "Failed to purge live-tools"
		fi
	fi

	# Purge live-boot-initramfs-tools
	INSTALLED=$(sudo dpkg -l live-boot-initramfs-tools 2>/dev/null)
	if [[ "${INSTALLED}" ]]; then
		Encapsulate "Purging live-boot-initramfs-tools..."
		Command sudo apt-get autoremove -y --purge live-boot-initramfs-tools &>/dev/null & Spinner "Purging live-boot-initramfs-tools..."
		if [[ "$?" != "0" ]]; then
			Error "Failed to purge live-boot-initramfs-tools"
		fi
	fi

	#Tell user if /home was not restored in /etc/fstab
	if [[ "${SHARE_HOME}" && ! "${HOME_ALREADY_MOUNTED}" ]]; then
		${QUIET} || Encapsulate "You chose to have your Original OS's /home use a separate partition during install. This will NOT be undone. /etc/fstab will still mount that partition as /home. If you want this undone, you can do so manually by modifying /etc/fstab."
	fi

	#Done
	${QUIET} || Encapsulate "Uninstall Complete!"
	UpdateGrub
	Session "$@"
	exit 0;
}

#Ask user if he really wants to uninstall
#Note: Does NOT actually uninstall - that would be the
#	Uninstall_Ram_Booter function
Uninstall_Prompt() {
	shopt -s nullglob
	declare -a RAMBOOTERISOS=();
	declare -i RAMBOOTERNISOS
	declare -i ARRAYCOUNTER
	INFOLDER="${PWD}"
	if [[ -d "/etc/grub.d/" ]]; then
		cd "/etc/grub.d/" || exit 1;
		RAMBOOTERISOS=(./07_*)
		RAMBOOTERNISOS="${#RAMBOOTERISOS[@]}"
		cd "${INFOLDER}" || exit 1;
	fi
	if ! [[ "${RAMSESSION}" ]]; then
		if [[ -d "/var/squashfs/" || "${RAMBOOTERNISOS}" -gt 0 ]]; then
			Center "This will delete your RAM Session and / or any ${RAMBOOTERNISOS} custom ISO(s) you may have added!"
			echo -n "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Would you like to proceed with the uninstall? [y/N]: "
			PromptYN
			echo -en "\033[1A\033[2K"
			#Convert ANSWER to lowercase
			YN=$(toLower "${YN}")

			case "${YN}" in
				y|yes)
					Uninstall_Ram_Booter
					exit 0
				;;
				*)
					FullBar
					Encapsulate "Invalid response or No selected, Uninstall Cancelled."
					exit 0
				;;
			esac
		else
			Error "${PROGNAME}, is not installed. Exiting..."
			exit 1;
		fi
	else
		Error "You can only un-install from the Original O/S."
		Encapsulate "You can either select the original Operating system from the grub menu or use:"
		Encapsulate "${APPNAME} --session"
		exit 1;
	fi
}

#Allows usage of "ECHO" instead of "echo"
#for long sentences that need to be wrapped
ECHO() {
	echo "$@" | fmt -w `tput cols`
}

#Ask user what device he wants to use for /home
Ask_User_About_Home() {
	#Ask user which partition to use for /home

	Encapsulate "Which partition do you want to use as /home?"
	FullBar
	read -p "Your choice: " -e HOME_DEV

	#Check if device exists
	if [[ ! -b "${HOME_DEV}" ]]; then
		Encapsulate "\"${HOME_DEV}\" is not a valid device. Please rerun the software and specify the device name of a partition or logical volume."
		Encapsulate "Exiting..."
		FullBar
		Uninstall_Ram_Booter quiet
		exit 1
	fi

	#Make sure the device is a partition (not an entire physical drive) or a logical volume
	#We also check if the device is the real device that a logical volume symbolic link points to
	#	Ex:
	#		If /dev/mapper/test_vol-home is a symlink to /dev/dm-0, we test for /dev/dm-0
	if ! (echo "${HOME_DEV}" | grep -q '/dev/sd[a-z][0-9]') && ! (sudo lvdisplay "${HOME_DEV}" &>/dev/null) && ! (readlink -f `sudo lvdisplay 2>/dev/null | grep 'LV Path' | tr -s ' ' | sed 's/ LV Path //g'` 2>/dev/null | grep -q "${HOME_DEV}")
	then
		echo
		ECHO "\"${HOME_DEV}\" is neither a partition, nor a logical volume. Please rerun the software and specify the device name of a partition or logical volume."
		echo "Exiting..."
		Uninstall_Ram_Booter quiet
		exit 1
	fi

	#Make sure nothing is currently using /mnt as a mount point
	if mountpoint -q /mnt
	then
		echo
		echo "Unable to mount ${HOME_DEV} to /mnt/tmp"
		echo "Is something already using /mnt as a mountpoint?"
		echo "Exiting..."
		Uninstall_Ram_Booter quiet
		exit 1
	fi

	#Make sure the device is really empty
	echo
	echo "Running file check on your device..."

	#Make sure an /mnt/tmp doesn't exist from an earlier exit of
	#our software
	if [[ -d /mnt/tmp ]]
	then
		Command sudo umount /mnt/tmp
	else
		Command sudo mkdir -p /mnt/tmp
	fi

	Command sudo mount ${HOME_DEV} /mnt/tmp

	#Check if there were problems mounting the device
	if [[ "$?" != 0 ]];	then
		Error "There was a problem with the device you gave. It would not mount. If this is a brand new drive and the partition has never been formatted, please format it as ext4 before running this software. Otherwise, please fix the problem before rerunning the software."
		Encapsulate "Exiting..."
		sudo rmdir /mnt/tmp
		Uninstall_Ram_Booter quiet
		exit 1
	fi

	#Count how many files are on the newly mounted device
	FILE_COUNT=`sudo ls -lR /mnt/tmp | grep ^- | wc -l`
	if [[ "${FILE_COUNT}" -gt 0 ]]; then
		Error "The device you chose is NOT empty! Are you sure you want to delete all data on it? Type \"I am sure\" to proceed, or \"ls\" to see what's on the device you chose."
		read -p "Your choice: " ANSWER

		#Convert ANSWER to lowercase
		ANSWER=$(toLower ${ANSWER})

		if [[ "${ANSWER}" == "ls" ]];	then
			#Without running in the background, nautilus doesn't release the terminal
			nautilus /mnt/tmp 2>/dev/null >/dev/null &

			Encapsulate "Do you still wish to format the device and erase all this data? Type \"I do\" to proceed or anything else to exit."
			read -p "Your choice: " ANSWER

			#Convert ANSWER to lowercase
			ANSWER=$(toLower ${ANSWER})

			if [[ "${ANSWER}" == "i do" ]]; then
				Encapsulate -e "Formatting ${HOME_DEV}\n"
			else
				Encapsulate "Exiting..."
				sudo umount /mnt/tmp && sudo rmdir /mnt/tmp
				Uninstall_Ram_Booter quiet
				exit 1
			fi
			elif [[ "${ANSWER}" == "i am sure" ]]; then
			Encapsulate "Formatting ${HOME_DEV}\n"
		else
			Encapsulate "${ANSWER} is an invalid choice"
			Encapsulate "Exiting..."
			sudo umount /mnt/tmp && sudo rmdir /mnt/tmp
			Uninstall_Ram_Booter quiet
			exit 1
		fi
	else
		Encapsulate "Everything checks out."
		Encapsulate "Formatting ${HOME_DEV}\n"
	fi

	#Unmount the device
	sudo umount /mnt/tmp
	sudo rmdir /mnt/tmp

	#Format the device
	sudo mkfs.ext4 -L home ${HOME_DEV}

	#Check if there was a problem formatting the device
	if [[ "$?" != 0 ]];	then
		Encapsulate "Formatting ${HOME_DEV} failed."
		Encapsulate "Exiting..."
		Uninstall_Ram_Booter quiet
		exit 1
	else
		Encapsulate "${HOME_DEV} formatted successfully"
	fi
}

CtrlC () {
	Encapsulate "You interupted the software while it was running. Would you like to revert all the changes it made so you can start fresh next time you run the software?"
	Center "WARNING: This will delete any existing RAM Session!"
	read -p "Your choice [Y/n]: " ANSWER
	echo -en "\033[1A\033[2K"
	#Convert ANSWER to lowercase
	ANSWER=$(toLower "${ANSWER}")

	case "${ANSWER}" in
		n|no)
			Encapsulate "If you say so. You may want to run \"$0 --uninstall\" however before running the software again, just to make sure nothing is left to get in its way."
			exit 0
		;;
		*)
			echo
			#Note: Normally, we would use the Uninstall_Prompt function, but since we already confirmed
			#that the user wants to do this, and since it's relatively safe, since the RAM Session is
			#presumably empty (we were just installing it), we run the Uninstall_Ram_Booter function instead
			Uninstall_Ram_Booter
			exit 0
		;;
	esac
}

#Copy the OS to ${DEST}
CopyFileSystem() {
	Encapsulate "Ready to copy your filesystem to ${DEST}..."
	FullBar
	#Set timeout incase the user left so the software continues to run
	read -t 60 -n 1 -s -r -p "Press any key to continue or CTRL+C to abort."

	#Copy the filesystem to ${DEST}
	#Note: Always skips /home
	INFOOUT=$(sudo rsync -aAXSH -hv --delete / ${DEST} --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/home/*","/etc/mtab","/live","/Original_OS","/ram_session","/var/cache/apt/archives/*.deb","${DEST}","${LOG}",/lost+found} | sed '0,/^$/d') & Spinner "Copying your filesystem to ${DEST}: please wait..."
	Encapsulate "${INFOOUT}"
	#Check how the operation went
	#Exit code 24 indicates some source files vanished, which is pretty
	#normal considering we are copying a filesystem that is currently in use
	case "$?" in
		0|24)
			FullBar
			Encapsulate "Filesystem copied successfully."
		;;
		*)
			Error "Copying filesystem failed."
			Encapsulate "Exiting..."
			Uninstall_Ram_Booter quiet
			exit 1
		;;
	esac

	#Remove entry for / in RAM Session's fstab
	sudo sed -i '/^UUID=[^ \t]\{1,\}[ \t]\{1,\}\/[ \t]/d' "${DEST}/etc/fstab"
	sudo sed -i '/^\/dev\/[^ \t]\{1,\}[ \t]\{1,\}\/[ \t]/d' "${DEST}/etc/fstab"
}

#Copies /home to either ${DEST}/home or to a new partition
#Also modifies /etc/fstab and ${DEST}/etc/fstab where appropriate
CopyHome () {
	####################
	# Global Variables #
	####################

	if [[ "${COPY_HOME}" ]]; then
		DESTINATION="${DEST}/home/"
	else
		DESTINATION="/mnt/tmp/"
	fi

	#######################################
	# Skip copying /home if not necessary #
	#######################################

	#If user chose to use the same partition for /home that the
	#Original OS is already using, than there's no need to copy
	#anything - if any users are using home directory encryption,
	#the /home partition should already be setup to properly use it
	if ! [[ "${COPY_HOME}" ]]; then
		if [[ "${HOME_ALREADY_MOUNTED}" ]]; then
			return 0
		fi
	fi

	#######################################
	# Modify fstab where/when appropriate #
	#######################################

	#/home was being mounted, but user chose to copy it instead
	#Remove entry of current partition being used for /home from
	#${DEST}/etc/fstab
	if [[ "${COPY_HOME}" ]]; then
		if [[ "${HOME_ALREADY_MOUNTED}" ]]; then
			sudo sed -i '/^UUID=[^ \t]\{1,\}[ \t]\{1,\}\/home[/]*[ \t]/d' "${DEST}/etc/fstab"
			sudo sed -i '/^\/dev\/[^ \t]\{1,\}[ \t]\{1,\}\/home[/]*[ \t]/d' "${DEST}/etc/fstab"
		fi
	fi

	#If /home is being copied to a separate empty partition
	if ! ${COPY_HOME} && ! ${HOME_ALREADY_MOUNTED}
	then
		#Tell RAM Session to use that partition as /home
		sudo bash -c 'echo -e "UUID='${HOME_UUID}'\t/home\text4\terrors=remount-ro\t0\t1" >> '${DEST}'/etc/fstab'

		#If user chose to do so, also tell the Original OS to
		#use that partition as /home
		if [[ "${SHARE_HOME}" ]]; then
			sudo bash -c 'echo -e "UUID='${HOME_UUID}'\t/home\text4\terrors=remount-ro\t0\t1" >> /etc/fstab'
		fi
	fi

	#################################################################
	# Prepare /mnt/root/home (Source)							   #
	# Note: We do this in all cases to make sure that we never copy #
	# decrypted home user directories in case a user is using	   #
	# encryption													#
	#################################################################

	sudo mkdir -p /mnt/root
	sudo mount -o bind / /mnt/root

	#If /home is using a separate partition, we mount that, while
	#ignoring any mounted user home directories (/home/USERNAME)
	if [[ "${HOME_ALREADY_MOUNTED}" ]]; then
		sudo mount -o bind /home /mnt/root/home
	fi

	#######################
	# Prepare destination #
	#######################

	if ! [[ "${COPY_HOME}" ]]; then
		#Mount ${HOME_DEV}
		sudo mkdir -p /mnt/tmp
		sudo mount ${HOME_DEV} /mnt/tmp
	fi

	##############################
	# Tell user what we're doing #
	##############################

	if [[ "${COPY_HOME}" ]]; then
		Encapsulate "Copying /home to ${DEST%/}/home/:"
	else
		Encapsulate "Copying /home to ${HOME_DEV}:"
	fi
	##############################
	# Copy /home to DESTINATION #
	##############################

	INFOOUT=$(sudo rsync -aAXSH -hv --delete "/mnt/root/home/" "${DESTINATION}" --exclude=.local/share/Trash/files/* | sed '0,/^$/d') & Spinner "Copying your home to ${DEST}, please wait..."
	Encapsulate "${INFOOUT}"
	EXIT_CODE="$?"

	############
	# Clean up #
	############

	#Unmount and remove /mnt/tmp, which we have to do
	#whether the rsync command succedded or not
	if ! [[ "${COPY_HOME}" ]]; then
		sudo umount /mnt/tmp
		sudo rmdir /mnt/tmp
	fi

	#Unmount and remove /mnt/root/home and /mnt/root, which
	#we have to do whether the rsync command succedded or not
	sudo umount -R /mnt/root
	sudo rmdir /mnt/root

	#Check how it went
	case "${EXIT_CODE}" in
		0|24)
			if [[ "${COPY_HOME}" ]]; then
				FullBar
				Encapsulate "/home copied to ${DEST%/}/home/ successfully"
			else
				FullBar
				Encapsulate "/home copied to ${HOME_DEV} successfully"
			fi
		;;
		*)
			if [[ "${COPY_HOME}" ]]; then
				Error "Failed to copy /home to ${DEST%/}/home/"
			else
				Error "Failed to copy /home to ${HOME_DEV}"
			fi
			Encapsulate "Exiting..."
			Uninstall_Ram_Booter quiet
			exit 1
		;;
	esac
}

#Kills any PID passed to it
#At first it tries nicely with SIGTERM
#After a timeout, it uses SIGKILL
KILL_PID () {
	PROC_TO_KILL="${1}"

	#Make sure we never have no args
	if [[ "${PROC_TO_KILL}" == "" ]]; then
		Error "KILL_PID: \$1 cannot be empty"
		exit 1
	fi

	#Try to kill it nicely
	kill -0 "${PROC_TO_KILL}" &>/dev/null && kill -15 "${PROC_TO_KILL}"

	#Check every second for 5 seconds to see if ${PROC_TO_KILL} is dead
	WAIT_TIME=5

	#Do a quick check to see if it's still running
	#It usually takes a second, so this often doesn't help
	kill -0 "${PROC_TO_KILL}" &>/dev/null &&
	for SEC in $(seq 1 "${WAIT_TIME}")
	do
		if [[ "${SEC}" != "${WAIT_TIME}" ]]
		then
			#If it's dead, exit
			kill -0 "${PROC_TO_KILL}" &>/dev/null || break
		else
			#If time's up, kill it
			kill -0 "${PROC_TO_KILL}" &>/dev/null && kill -9 "${PROC_TO_KILL}"
		fi
	done
}

CheckRoot () {
	if [[ "${EUID}" -ne 0 ]]; then
		Error "Please run as root or sudo privilages."
		exit 1;
	fi
}

GlobalVars () {
	####################
	# Global Variables #
	####################

	#The folder where this software is located
	#Used to make sure that the software can be run from any folder
	#SOURCE="${BASH_SOURCE[0]}"
	#while [ -h "${SOURCE}" ]; do # resolve ${SOURCE} until the file is no longer a symlink
	#	DIR="$( cd -P "$( dirname "${SOURCE}" )" >/dev/null 2>&1 && pwd )"
	#	SOURCE="$(readlink "${SOURCE}")"
	#	[[ ${SOURCE} != /* ]] && SOURCE="${DIR}/${SOURCE}" # if ${SOURCE} was a relative symlink, we need to resolve it relative to the path where the symlink file was located
	#done
	DIR="$( cd -P "$( dirname "${SOURCE}" )" >/dev/null 2>&1 && pwd )"
	SOFTWARE_DIR="/usr/share/ultimate_edition"

	#The log file
	LOG='/var/log/ram_booter.log'

	#Path to the RAMBOOTER
	GRUB_RAMBOOTER_SOFTWARE="${SOFTWARE_DIR}/extras/both/grub.d/06_rambooter"

	#Path to the za_ram_session_initramfs kernel postinst software
	INITRAMFS_SOFTWARE="${SOFTWARE_DIR}/extras/ram_session/postinst.d/za_ram_session_initramfs"

	#Path to the zb_version_check kernel postinst software
	VER_CHECK_SOFTWARE="${SOFTWARE_DIR}/extras/both/postinst.d/zb_version_check"

	#Path to the zc_sort_kernels kernel postinst software
	SORT_KERNELS_SOFTWARE="${SOFTWARE_DIR}/extras/both/postinst.d/zc_sort_kernels"

	#Path to the zd_warn kernel postinst software
	WARN_SOFTWARE="${SOFTWARE_DIR}/extras/ram_session/postinst.d/zd_warn"

	#True if home is already on another partition. False otherwise
	HOME_ALREADY_MOUNTED=$(df /home | tail -1 | grep -q '/home' && echo true || echo false)

	#True if /home should just be copied over to ${DEST}/home
	#False otherwise
	#Note: Do NOT remove the default value
	COPY_HOME=true

	#The new location of /home
	#Note: Here, we check the old location of /home, but later we can change it
	#to reflect the new location
	if [[ -f "/ram_session" ]]; then
		Center "Current Session: RAM Session."
	else
		HOME_DEV=$(readlink -f `df /home | grep -o '/dev/[^ ]*'`)

		#The device of the root partition
		ROOT_DEV=$(readlink -f `df / | grep -o '/dev/[^ ]*'`)

		#The device of the boot partition
		BOOT_DEV=$(readlink -f `df /boot | grep -o '/dev/[^ ]*'`)

		#The device of /boot/efi, if it exists
		EFI_DEV=$(readlink -f `df /boot/efi 2>/dev/null | grep -o '/dev/[^ ]*'` 2>/dev/null || echo None)
	fi

	#The UUID of the home partition
	#Gets set later
	HOME_UUID=''

	#The UUID of the root partition
	if ! [[ "${ROOT_UUID}" ]]; then
		ROOT_UUID=$(sudo blkid -o value -s UUID "${ROOT_DEV}")
	fi

	#The UUID of the boot partition
	BOOT_UUID=$(sudo blkid -o value -s UUID "${BOOT_DEV}")

	#The UUID of the /boot/efi partition, if it exists
	EFI_UUID=$([[ "${EFI_DEV}" != "None" ]] && sudo blkid -o value -s UUID $"{EFI_DEV}" || echo None)

	#The folder where the Ram Session will be stored
	DEST="/var/squashfs/"

	#Only applies when the Original OS starts out having /home on the same partition as /
	#and the user chooses to use a separate partition for /home on the Ram Session
	#true if the Original OS's /etc/fstab should be modified to also use
	#	the partition that the Ram Session will be using as /home
	#false if it should not
	SHARE_HOME=false
}

QuestionReboot () {
	declare -i TESTIT;
	declare -i RESULTS;
	if [[ -f "/etc/default/grub" ]]; then
		TESTIT=1
		RESULTS=1
		if [[ -f "/etc/default/grub" ]]; then
			TIMEOUT=$(grep -i "GRUB_TIMEOUT=" "/etc/default/grub" | sed "s/GRUB_TIMEOUT=//g")
			TESTIT=$(grep -m1 -i "GRUB_DEFAULT=" "/etc/default/grub")
			TEMPRESULTS=$(grep -m1 -i "GRUB_DEFAULT=" "/etc/default/grub" | sed "s/GRUB_DEFAULT=//g")
			TSTYLE=$(grep -i "GRUB_TIMEOUT_STYLE=" "/etc/default/grub" | sed "s/GRUB_TIMEOUT_STYLE=//g")
			RESULTS=$(echo "${TEMPRESULTS}" | sed 's/"//g')
			TRESULT=$(echo "${TSTYLE}" | sed 's/"//g')
		else
			Error "Critical: /etc/default/grub not found. Exiting."
			exit 1;
		fi
		if [[ "${TSTYLE}" ]]; then
			Encapsulate "GRUB_TIMEOUT_STYLE=${TSTYLE}"
			Encapsulate "Timeout in seconds: ${TIMEOUT}"
			if ! [[ "${TSTYLE}" == "menu" ]]; then
				Encapsulate "Setting menu to on."
				sed -i "s/^GRUB_TIMEOUT_STYLE=.*/GRUB_TIMEOUT_STYLE=menu/g" "/etc/default/grub"
				UpdateGrub
			fi
		else
			Encapsulate "GRUB_TIMEOUT_STYLE has not been set. Setting to menu."
			echo "GRUB_TIMEOUT_STYLE=menu" | sudo tee -a "/etc/default/grub" 1>/dev/null;
			Encapsulate "Timeout in seconds: ${TIMEOUT}"
			UpdateGrub
		fi
		if [[ "${TESTIT}" == 0 ]]; then
			if [[ -f "/original_os" && ! "${RAMSESSION}" ]]; then
				Center "Original O/S is current."
				if ! [[ "${SUPPRESS}" && "${RESULTS}" == 0 ]]; then
					read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Do you wish to reboot now to use your Ram Session? [y/N]: " ANSWER
					echo -en "\033[1A\033[2K"
					case "${ANSWER}" in
						y) Center "Rebooting...";
						sudo reboot now;;
						*) 	FullBar;;
					esac
				fi
			fi
		fi
	else
		Encapsulate "Default is not boot from RAM, exiting..."
		exit 0;
	fi
}

#Unmount ${DEST} (RAM Session)
UMOUNT_RS () {
	#The location of the chroot, nicely formatted (without double
	#'/'s) for printing to stdout
	CHROOT="${ORIG_OS%/}/${DEST#/}"

	#If ${ORIG_OS} is not mounted (like if that was the step that failed to mount),
	#just return
	if ! mountpoint -q "${ORIG_OS}"
	then
		sudo rmdir ${ORIG_OS}
		return 0
	fi

	#Only do these tests if we did NOT do a root_only mount
	TESTCOND=$(df -a | grep -q "${CHROOT%/}/dev")
	if [[ "${TESTCOND}" ]];	then
		#Quietly tell any upstart services that may have been started (manually,
		#or by postinst softwares during installation) to stop. We later detect
		#and kill all remaining processes - this is just a nice initial step
		#sudo chroot $CHROOT /bin/bash -c '
		#while IFS= read -r SRV
		#do
		#	stop $SRV &>/dev/null
		#done < <(initctl list | grep -v stop | cut -d " " -f 1)'

		#Quietly unmount any filesystems that may have been moounted
		#inside of the chroot
		#Ex: When the dbus package updates, it uses invoke-rc.d to launch
		#	the dbus service, which, as a prerequisite, also runs
		#	cgmanager. cgmanager mounts virtual filesystems when
		#	it starts, but does NOT unmount them when it stops,
		#	which prevents the chroot from unmounting. This finds
		#	and unmounts anything like that
		sudo chroot "${CHROOT}" /bin/bash -c '
		while IFS= read -r FS
		do
			#Things that were mounted outside of the chroot
			#are better left alone for now so they can be
			#unmounted outside of the chroot later
			echo $FS | grep -qx "/" && continue
			echo $FS | grep -qx "/dev" && continue
			echo $FS | grep -qx "/run" && continue
			echo $FS | grep -qx "/boot" && continue
			#Encrypted home directories
			echo $FS | grep -qx "/home/[^/]*" && continue
			echo $FS | grep -qx "/home" && continue
			echo $FS | grep -qx "/run/user" && continue
			umount "$FS" &>/dev/null
		done < <(df | tail -n+2 | tr -s " " | cut -d " " -f 6- | sort -r)'

		#Find processes who's root folder is actually the chroot
		for ROOT in $(find /proc/*/root)
		do
			LINK=$(readlink -f "${ROOT}")
			if echo "${LINK}" | grep -q "${CHROOT%/}"
			then
				PID=$(basename $(dirname "${ROOT}"))
				KILL_PID "${PID}"
			fi
		done
	fi

	#Unmount all filesystems under ${ORIG_OS} recursively
	sudo umount -R "${ORIG_OS}" 2>/dev/null

	#Check how it went
	if [[ "$?" == "0" ]];	then
		#Remove the temp folder
		sudo rmdir "${ORIG_OS}"
		return $?
	fi

	#Failed to unmount - use lsof to figure out what's holding it up:

	Error "Failed to unmount chroot"
	Encapsulate "Scanning for processes holding it up..."

	#Get a list of PIDs that are using ${ORIG_OS} for anything
	PID_LIST=$(sudo lsof +D "${ORIG_OS}" 2>/dev/null | tail -n+2 | tr -s ' ' | cut -d ' ' -f 2 | sort -nu)

	#If there are none, give message and exit
	if [[ -z "${PID_LIST}" ]]; then
		Encapsulate "None found"
		return 1
	fi

	Encapsulate "These are the processes preventing ${ORIG_OS} from unmounting:"

	for PID in "${PID_LIST}"
	do
		PROCESS_NAME=$(ps -p "${PID}" -o comm=)
		Encapsulate "${PROCESS_NAME}"
	done
	read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Would you like to kill them and try unmounting again? [Y\n]: " ANSWER
	echo -en "\033[1A\033[2K"
	#Convert ANSWER to lowercase
	ANSWER=$(toLower "${ANSWER}")

	case "${ANSWER}" in
		n|no)
			return 1
		;;
		*)
			#Kill all PIDs holding up unmounting ${ORIG_OS}
			for PID in "${PID_LIST}"
			do
				KILL_PID "${PID}"
			done

			#Try unmounting again:

			#Unmount all filesystems under ${ORIG_OS} recursively
			sudo umount -R "${ORIG_OS}" 2>/dev/null

			if [[ "$?" == "0" ]]
			then
				#Give user message
				Encapsulate "Processes terminated, and ${ORIG_OS} unmounted successfully"

				#Remove the folder
				sudo rmdir "${ORIG_OS}" 2>/dev/null ||
				{
					Error "Failed to remove ${ORIG_OS} - are there files in it?"
				}

				return 0
			else
				#Still failed
				return 1
			fi
		;;
	esac
}

#Mount ${DEST} (RAM Session)
#If function is passed "root_only" as arg, only mount ${ROOT_UUID} to
#${ORIG_OS} and nothing else
MOUNT_RS () {

	#Make ORIG_OS folder
	sudo mkdir -p "${ORIG_OS}"

	#Try to mount ${ROOT_UUID} to ${ORIG_OS}
	if [[ "${DEBUG}" ]]; then
		echo "Try to mount ROOT_UUID:${ROOT_UUID} to ORIG_OS:${ORIG_OS}"
	fi
	sudo mount -U "${ROOT_UUID}" "${ORIG_OS}" &>/dev/null ||
	{
		Error "Failed to mount ${ROOT_UUID} to ${ORIG_OS}"
		UMOUNT_RS
		exit 1
	}

	#If this function was passed the arg "root_only", return here
	if [[ "${1}" == "root_only" ]]; then
		return 0
	fi

	#Bind /proc
	sudo mount -o bind /proc "${ORIG_OS}/${DEST}/proc" ||
	{
		Error "Failed to bind /proc to ${ORIG_OS%/}/${DEST%/}/proc"
		UMOUNT_RS
		exit 1
	}

	#Bind /dev
	sudo mount -o bind /dev "${ORIG_OS}/${DEST}/dev" ||
	{
		Error "Failed to bind /dev to ${ORIG_OS%/}/${DEST%/}/dev"
		UMOUNT_RS
		exit 1
	}

	#Bind /dev/pts
	sudo mount -o bind /dev/pts "${ORIG_OS}/${DEST}/dev/pts" ||
	{
		Error "Failed to bind /dev/pts to ${ORIG_OS%/}/${DEST%/}/dev/pts"
		UMOUNT_RS
		exit 1
	}

	#Bind /sys
	sudo mount -o bind /sys "${ORIG_OS}/${DEST}/sys" ||
	{
		Error "Failed to bind /sys to ${ORIG_OS%/}/${DEST%/}/sys"
		UMOUNT_RS
		exit 1
	}

	#Bind /run
	sudo mount -o bind /run "${ORIG_OS}/${DEST}/run" ||
	{
		Error "Failed to bind /run to ${ORIG_OS%/}/${DEST%/}/run"
		UMOUNT_RS
		exit 1
	}

	#Mount tmpfs to /dev/shm
	sudo mount -t tmpfs tmpfs "${ORIG_OS}/${DEST}/dev/shm" ||
	{
		Error "Failed to mount tmpfs to ${ORIG_OS%/}/${DEST%/}/dev/shm"
		UMOUNT_RS
		exit 1
	}

	#Mount tmpfs to /run/user
	sudo mount -t tmpfs none "${ORIG_OS}/${DEST}/run/user" ||
	{
		Error "Failed to mount tmpfs to ${ORIG_OS%/}/${DEST%/}/run/user"
		UMOUNT_RS
		exit 1
	}

	#Mount /boot, if it's not on the same partition as /
	if [[ "${BOOT_UUID}" != "${ROOT_UUID}" ]]; then
		sudo mount -U ${BOOT_UUID} "${ORIG_OS}/${DEST}/boot" ||
		{
			Error "Failed to mount ${BOOT_UUID} to ${ORIG_OS%/}/${DEST%/}/boot"
			UMOUNT_RS
			exit 1
		}
	else
		sudo mount -o bind "${ORIG_OS}/boot" "${ORIG_OS}/${DEST}/boot" ||
		{
			Error "Failed to bind ${ORIG_OS%/}/boot to ${ORIG_OS%/}/${DEST%/}/boot"
			UMOUNT_RS
			exit 1
		}
	fi

	#Mount /boot/efi, if we are running an efi system
	if [[ -d "/sys/firmware/efi" ]] && [[ "${EFI_UUID}" != "None" ]]
	then
		sudo mount -U "${EFI_UUID}" "${ORIG_OS}/${DEST}/boot/efi" ||
		{
			Error "Failed to mount ${EFI_UUID} to ${ORIG_OS%/}/${DEST%/}/boot/efi"
			UMOUNT_RS
			exit 1
		}
	fi

	#Mount /home, if it's not on the same partition as /
	if [[ "${HOME_UUID}" != "${ROOT_UUID}" ]]; then
		sudo mount -U ${HOME_UUID} "${ORIG_OS}/${DEST}/home" ||
		{
			Error "Failed to mount ${HOME_UUID} to ${ORIG_OS%/}/${DEST%/}/home"
			UMOUNT_RS
			exit 1
		}
	fi

	#When the /home being used by the running system (RAM Session)
	#is using EXACTLY the same files as the one inside of ram-booter,
	#ecryptfs-mount-private fails to mount the /home directory of
	#any user that is already logged into the RAM Session. This
	#only applies to users that are using ecryption on their /home
	#directory. To fix this, we bind the decrypted home directory
	#of any logged-in user from the running system to the chroot
	#environment
	if [[ "${HOME_UUID}" != "${ROOT_UUID}" ]]; then
		for DIR in /home/*
		do
			if [[ -e "${DIR}/.ecryptfs" ]];	then
				MOUNTCHECK=$(mountpoint -q "${DIR}")
				if [[ "${MOUNTCHECK}" ]]; then
					sudo mount -o bind "${DIR}" "${ORIG_OS}/${DEST}/${DIR}"
				fi
			fi
		done
	fi

	#Setup mtab. Some programs (like df) use it to read partition table data
	sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash -c "grep -v rootfs /proc/mounts > /etc/mtab"

	#Enable X (GUI programs)
	INSTALLED=$(type -p xhost)
	if [[ "${INSTALLED}" ]]; then
		xhost +local: >/dev/null
	fi

	#Change permissions on /dev/shm
	sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash -c "chmod 1777 /dev/shm" ||
	{
		Error "Failed to set permissions on ${ORIG_OS%/}/${DEST%/}/dev/shm to 1777"
		UMOUNT_RS
		exit 1
	}
}

Session () {
	declare -a ENTRIES=();
	declare -i INDEX;
	declare -i RAM_SESSION;
	INDEX=0
	RAM_SESSION=0
	if [[ -f "/ram_session" ]]; then
		Encapsulate "Ram Session found."
		#Mount only the root filesystem of the Original OS
		# MOUNT_RS root_only
		############################
		# Let user into the chroot #
		############################


		if ! [[ -f "${ORIG_OS}/${DEST}/bin/bash" ]]; then
			sudo mkdir -p "$ORIG_OS"
			sudo mount -U "${ROOT_UUID}" "${ORIG_OS}" &>/dev/null ||
			{
				echo "Failed to mount ${ROOT_UUID} to ${ORIG_OS}"
				UMOUNT_RS
				exit 1
			}
			if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
				Encapsulate "Installing ram-editor into the chroot environment."
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/bin/"
			else
				Error "Error ram-editor, not found. Continuing."
			fi
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor -g"
		else
			if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
				Encapsulate "Installing ram-editor into the chroot environment."
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/bin/"
			else
				Error "Error ram-editor, not found. Continuing."
			fi
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor -g"
		fi
	fi

	if ! [[ "${RAMSESSION}" ]]; then
		Encapsulate "Original O/S found."
		if [[ -f "/etc/default/grub" ]]; then
			GREPIT=$(grep -i "GRUB_DEFAULT=" "/etc/default/grub" | head -1 | sed "s/GRUB_DEFAULT=//g")
			case "${GREPIT}" in
				saved) Center "Grub Default is currently saved to the last.";;
				*) Center "Grub Default is currently set to: GRUB_DEFAULT=${GREPIT}";;
			esac
			OIFS=$IFS
			IFS=$'\n'
			ENTRIES=($(awk -F\' '/menuentry / {print $2}' "/boot/grub/grub.cfg"))
			IFS=$OIFS
			for EACH in "${ENTRIES[@]}"
			do
				Encapsulate "[${INDEX}] ${EACH}"
				INDEX=$((INDEX + 1))
			done
			FullBar
			ANSWER=-1
			MAX=$((INDEX -1))
			# Encapsulate "ANSWER:${ANSWER} INDEX: ${INDEX} | MAX: ${MAX} ENTRIES: ${#ENTRIES}"
			while [[ ! "${ANSWER}" =~ ^[0-9]+$ || "${ANSWER}" -gt "${MAX}" ]];
			do
				read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Default session? [#]: " ANSWER
				echo -en "\033[1A\033[2K"
				if [[ ! "${ANSWER}" =~ ^[0-9]+$ || "${ANSWER}" -gt "${MAX}" ]]; then
					Error "Invaild input: ${ANSWER}, enter 0 - ${MAX}, please try again."
				fi
			done
			if ! [[ "${GREPIT}" == "${ANSWER}" ]]; then
				Encapsulate "Updating default grub entry to: [${ANSWER}] ${ENTRIES[${ANSWER}]}"
				if [[ "${GREPIT}" ]]; then
					sudo sed -i "s/GRUB_DEFAULT=.*/GRUB_DEFAULT=${ANSWER}/g" "/etc/default/grub"
				else
					echo "GRUB_DEFAULT=${ANSWER}" | sudo tee -a "/etc/default/grub" &>/dev/null
				fi
				UpdateGrub
				FullBar
			else
				Encapsulate "Grub entry unchanged: ${ANSWER}, not updating Grub."
				if [[ "${ANSWER}" == 0 ]]; then
					TESTIT="${ENTRIES[${ANSWER}]}"
					GREPIT=$(echo "${TESTIT}" | grep "RAM")
					if [[ "${GREPIT}" ]]; then
						QuestionReboot "$@"
						exit 0;
					fi
				fi
			fi
		fi
	else
		if ! [[ "${RAMSESSION}" ]]; then
			Error "Default grub not found, exiting."
			exit 1;
		fi
	fi
}

# Create squashfs image
CreateSquashfs () {
	#Mount only the root filesystem of the Original OS
	MOUNT_RS root_only

	#Create squashfs image
	#Note: We do NOT write the file directly to the one we boot
	#from so that if the process gets interrupted and we reboot,
	#we can still boot into the old image
	# sudo mksquashfs ${ORIG_OS%/}/${DEST#/} ${ORIG_OS%/}/live/filesystem.squashfs.new -noappend -always-use-fragments
	FullBar
	Encapsulate "Creating Squash filesystem image..."
	FullBar
	# Use Maximum compression.
	if [[ "${COMPRESSION}" == "maximum" ]]; then
		Encapsulate "Using Maximum compression."
		FullBar
		sudo mksquashfs "${ORIG_OS%/}/${DEST#/}" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments -b 1048576 -comp xz -Xdict-size 100%
		SQUASHCOMPLETE=1
		FullBar
	fi
	# Use fast compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		if [[ "${COMPRESSION}" == "fast" ]]; then
			Encapsulate "Using fast compression."
			FullBar
			sudo mksquashfs "${ORIG_OS%/}/${DEST#/}" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments -comp lz4
			SQUASHCOMPLETE=1
		fi
	fi
	# Default compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		Encapsulate "Using default compression."
		sudo mksquashfs "${ORIG_OS%/}/${DEST#/}" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments
	fi

	#See how it went
	if [[ "$?" != 0 ]];	then
		Error "Squash filesystem image creation failed."
		Error "You may want to run \"${PROGNAME} --uninstall\" to remove the partially-installed stuff"
		Encapsulate "Exiting..."
		FullBar
		exit 1
	else
		FullBar
		Center "Squash filesystem image created successfully."
	fi

	#If there was an error, exit 1
	if [[ "$?" != "0" ]]; then
		Error "Failed to create ${ORIG_OS%/}/live/filesystem.squashfs"
		UMOUNT_RS
		exit 1
	fi

	#Move the newly created squashfs image to the location we boot from
	sudo mv "${ORIG_OS%/}/live/filesystem.squashfs.new" "${ORIG_OS%/}/live/filesystem.squashfs"

	#Inform user we are done
	FullBar
	Encapsulate "Squash filesystem image created successfully."
	FullBar
	#Unmount the root filesystem
	UMOUNT_RS
	QuestionReboot "$@"
	exit 0;
}

BasicTools () {
	Center "Installing Basic Tools."
	############################################
	# Enable service if persistance is enabled #
	############################################
	if [[ "${PERSISTANCE}" ]]; then
		Encapsulate "Enabling ${PROGNAME} shutdown service."
		sudo systemctl enable ${APPNAME} &>/dev/null
	else
		Encapsulate "Disabling ${PROGNAME} shutdown service."
		sudo systemctl disable ${APPNAME} &>/dev/null
	fi

	###################################
	# Install some essential packages #
	###################################


	Encapsulate "Installing essential packages:"
	if ! [[ "${ISARCH}" ]]; then
		Encapsulate "Running apt-get update..."
		Command sudo apt-get update & Spinner "Running apt-get update..."
	else
		Encapsulate "Running Pacman Update..."
		Command sudo pacman -Syuu --noconfirm & Spinner "Running Pacman update..."
	fi
	INSTALLED=$(type -p mksquashfs)
	if [[ "${INSTALLED}" ]]; then
		Encapsulate "Squash File System tools are already installed."
	else
		if ! [[ "${ISARCH}" ]]; then
			Encapsulate "Installing squashfs-tools..."
			Command sudo apt-get -y --force-yes install squashfs-tools ||
			{
				Error "squashfs-tools failed to install. You'll have to download and install it manually..."
				Uninstall_Ram_Booter quiet
				exit 1
			}
		else
			Encapsulate "Installing squashfs-tools..."
			Command sudo pacman -Syuu --noconfirm squashfs-tools ||
			{
				Error "squashfs-tools failed to install. You'll have to download and install it manually..."
				Uninstall_Ram_Booter quiet
				exit 1
			}
		fi
		if ! [[ "${ISARCH}" ]]; then
			Encapsulate "Installing live-boot-initramfs-tools..."
			Command sudo apt-get -y --force-yes install live-boot-initramfs-tools & Spinner "Installing live-boot-initramfs-tools..." ||
			{
				Error "live-boot-initramfs-tools failed to install. You'll have to download and install it manually..."
				Uninstall_Ram_Booter quiet
				exit 1
			}

			Command sudo apt-get -y --force-yes install live-boot ||
			{
				Encapsulate "live-boot failed to install. You'll have to download and install it manually..."
				Uninstall_Ram_Booter quiet
				exit 1
			}
		fi
	fi
	Encapsulate "Packages installed successfully"
	FullBar

	##################################
	# Remove ureadahead if installed #
	##################################
	# Reasoning:
	# ureadahead preloads commonly used programs to ram. Since we're loading
	# everything into Ram, it's unnecessary
	#######################################

	ISINSTALLED=$(type -p ureadahead)
	if [[ "${ISINSTALLED}" ]]; then
		Encapsulate "Removing ureadahead..."
		Command sudo apt-get -y purge ureadahead ||
		{
			Error "Failed to remove ureadahead. This is NOT a major problem."
		}
	fi
	############################################################################
	# Tell /bin/live-update-initramfs not to worry about creating an initramfs #
	# image when a new kernel is installed - we'll be doing this ourselves	 #
	############################################################################

	#Note: /bin/live-update-initramfs tries to write to
	#/lib/live/mount/medium/live without checking it if exists, which it does
	#not. All we do here is tell it to check first, which has the desired
	#effect of it not messing with the initramfs image apt-get installs
	#in /boot
	[[ -e "/bin/live-update-initramfs" ]] &&
	sudo sed -i 's|\(/proc/mounts\)$|\1 \&\& [ -d /lib/live/mount/medium/live/ ]|g' "/bin/live-update-initramfs"

	#########################################
	# Update the kernel module dependencies #
	#########################################

	Encapsulate "Updating the kernel module dependencies..."
	sudo depmod -a

	if [[ "$?" != 0 ]]; then
		Error "Kernel module dependencies failed to update."
		Error "Exiting..."
		Uninstall_Ram_Booter quiet
		exit 1
	else
		Encapsulate "Kernel module dependencies updated successfully."
	fi
	#######################################################
	# Change a few things to make boot process look nicer #
	#######################################################
	if ! [[ "${ISARCH}" ]]; then
	Encapsulate "Making boot process look nicer..."

	# Hide expr error on boot
	HIDEBOOT=$(sudo sed -i 's/\(size=$( expr $(ls -la ${MODULETORAMFILE} | awk "{print $5}") \/ 1024 + 5000\)\( )\)$/\1 2>\/dev\/null\2/' "/lib/live/boot/9990-toram-todisk.sh")

	#Hide 'sh:bad number' error on boot
	HIDESH=$(sudo sed -i 's#\(if \[ "\${freespace}" -lt "\${size}" ]\)$#\1 2>/dev/null#' "/lib/live/boot/9990-toram-todisk.sh")

	#Make rsync at boot use human readable byte counter
	RSYNC=$(sudo sed -i 's/rsync -a --progress/rsync -a -h --progress/g' "/lib/live/boot/9990-toram-todisk.sh")

	grep -q '033c' "/lib/live/boot/9990-toram-todisk.sh" ||
	sudo sed -i 's#\(echo " [*] Copying ${MODULETORAMFILE} to RAM (RANDOM ACCESS MEMORY)" 1>/dev/console\)#sleep 1\
				echo -ne "\\033c" 1>/dev/console\
				\1\
				echo -n " * `basename $MODULETORAMFILE` is: " 1>/dev/console\
				rsync -h -n -v ${MODULETORAMFILE} ${copyto} | grep "total size is" | grep -Eo "[0-9]+[.]*[0-9]*[mMgG]" 1>/dev/console\
	echo 1>/dev/console#g' "/lib/live/boot/9990-toram-todisk.sh"

	grep -q '#Part 2' "/lib/live/boot/9990-toram-todisk.sh" ||
	sudo sed -i 's#\(rsync -a -h --progress .*\)#\1\
				\#Part 2\
				echo 1>/dev/console\
	echo 1>/dev/console#g' "/lib/live/boot/9990-toram-todisk.sh"

	#Fix the "can't create /root/etc/fstab.d/live: nonexistent directory" error at boot
	#Appears on Ubuntu 14.10
	sudo sed -i 's|^\(\t\t\)\(echo.*/root/etc/fstab.d/live$\)|\1[ -d /root/etc/fstab.d ] \&\& \2|g' "/lib/live/boot/9990-fstab.sh"
	fi
}

Main () {
	if ! [[ -e "/ram_session" ]]; then
		if ! [[ -e "/original_os" ]]; then
			Timer "Start" "Setup RamDrive"
		fi
	fi
	###################################################
	# Make sure user didn't force software to run in sh #
	###################################################

	ps ax | grep $$ | grep bash > /dev/null ||
	{
		Encapsulate "You are forcing the software to run in sh when it was written for bash."
		Encapsulate "Please run it in bash instead, and NEVER run any software the way you just did."
		exit 1
	}


	##############################################################################
	# Check if the user is trying to run this software from within the Ram Session #
	##############################################################################

	if [ -e "/ram_session" ];	then
		Error "Request is denied. This section of the software cannot be run from inside the Ram Session."
		Encapsulate "You are running in a ram session.  Why would you want to setup another session in RAM?"
		exit 0
	fi

	##################################
	# Check if system is using btrfs #
	##################################

	if df -T / /boot | grep -qi btrfs; then
		Encapsulate "This software does NOT work with btrfs"
		exit 0
	fi

	############################
	# Check if OS is supported #
	############################
	ULTIMATE_VERSION="Ultimate"
	OS_NAME=$(grep -i "PRETTY_NAME" /etc/os-release | cut -d "=" -f2 | tr -d '"')
	OS_VERSION=$(grep -i "VERSION_ID" /etc/os-release | cut -d "=" -f2 | tr -d '"')
	ISULTIMATE=$(echo "${OS_NAME}" | grep -i "${ULTIMATE_VERSION}")
	if ! [[ "${ISULTIMATE}" ]]; then
		Encapsulate "This software was written to work with Ultimate Edition. You are running ${OS_NAME}."
		Encapsulate "This means the software has NOT been tested for your OS."
		Encapsulate "Run this at your own risk. The author takes no responsibily if you bork your O/S."
		FullBar
		Encapsulate "Press enter to continue or Ctrl+C to exit"
		FullBar
		read -rs key
	fi

	########################
	# Check for RAMBOOTER #
	########################

	if [[ ! -e "${GRUB_RAMBOOTER_SOFTWARE}" ]]; then
		Error "\"${GRUB_RAMBOOTER_SOFTWARE}\" not found!"
		exit 1
	fi

	######################################
	# Check for za_ram_session_initramfs #
	######################################

	if [[ ! -e "${INITRAMFS_SOFTWARE}" ]]; then
		Error "\"${INITRAMFS_SOFTWARE}\" not found!"
		exit 1
	fi

	##############################
	# Check for zb_version_check #
	##############################

	if [[ ! -e "${VER_CHECK_SOFTWARE}" ]]; then
		Error "\"${VER_CHECK_SOFTWARE}\" not found!"
		exit 1
	fi

	#############################
	# Check for zc_sort_kernels #
	#############################

	if [[ ! -e "${SORT_KERNELS_SOFTWARE}" ]];	then
		Error "\"${SORT_KERNELS_SOFTWARE}\" not found!"
		exit 1
	fi

	#####################
	# Check for zd_warn #
	#####################

	if [[ ! -e "${WARN_SOFTWARE}" ]];	then
		Error "\"${WARN_SOFTWARE}\" not found!"
		exit 1
	fi

	########################################################
	# Check if Ram_booter has already run on this machine #
	########################################################

	if [[ -e "/original_os" ]]; then
		FormatText "${PROGNAME} has already ran on this computer. It will not run again until you uninstall it."
		FullBar
		Uninstall_Prompt
	fi

	#############################################################################
	# If at any point the user hits Ctrl+C, quietly clean up any files we	   #
	# may have created.														 #
	#																		   #
	# Note: If the user hits Ctrl+C AFTER we start copying the filesystem to	#
	# ${DEST}, a different trap will be activated which will be a lot less quiet  #
	#																		   #
	# Note 2: If user hit Ctrl+C when 'read' was waiting for user input, even   #
	# if read wasn't waiting for a password, the terminal will be messed up:	#
	# 	-echoing will be disabled										   #
	#	-the next time the software runs, 'read key' will show ^M when you	#
	#			   hit enter												   #
	#	 All the stty commands below restore stty settings to normal (use	  #
	#	 stty -a to see what they are before and after you Ctrl+C during read) #
	#############################################################################
	trap 'stty echo; stty icrnl; stty icanon; stty lnext ^V; echo; Uninstall_Ram_Booter quiet; exit 1' SIGINT

	###################################################################
	# Overwrite old logfile, and check if we can write to ${LOG} at all #
	###################################################################

	echo -n '' | sudo tee ${LOG} &>/dev/null ||
	{
		Encapsulate "Failed to write to '${LOG}' log file"
		Encapsulate "Exiting..."
		FullBar
		Uninstall_Ram_Booter quiet
		exit 1
	}

	##################################
	# Write some useful info to ${LOG} #
	##################################

	#/etc/fstab
	LOGGER "$(echo -e "/etc/fstab:\n"; cat /etc/fstab)"

	#/etc/lsb-release
	LOGGER "$(echo -e "/etc/lsb-release:\n"; cat /etc/lsb-release)"

	#fdisk
	LOGGER "$(echo "fdisk -l:"; sudo fdisk -l)"

	#gdisk
	#Note: Only runs if gdisk exists
	#Note 2: Since 'gdisk -l' isn't a thing, this figures out
	#	which drives use gdisk first
	#Note 3: This section would be a lot less elaborate if I didn't already
	#	have the code for it from a different project
	sudo which gdisk &>/dev/null &&
	for DEVICE in $(cat /proc/partitions  | tail -n+3 | tr -s ' ' | cut -d ' ' -f 5)
	do
		#If /dev/"${DEVICE}" is a block device, add /dev prefix to it
		#If it doesn't exist, skip it
		[[ -b /dev/"${DEVICE}" ]] && DEVICE=/dev/"${DEVICE}" || continue

		#Ignore partitions
		if echo "${DEVICE}" | grep -q '^/dev/sd[a-z][0-9][0-9]*'
		then
			continue
		fi

		#Ignore CDs/DVDs
		if echo "${DEVICE}" | grep -q '^/dev/sr'
		then
			continue
		fi

		#Ignore floppy disks
		if echo "${DEVICE}" | grep -q '^/dev/fd'
		then
			continue
		fi

		#Do what fdisk does - ignore loop devices directly under /dev
		if echo "${DEVICE}" | grep -q '^/dev/loop'
		then
			continue
		fi

		#If "${DEVICE}" has a mapping under /dev/mapper (as determined by 'dmsetup'),
		#use that instead of the regular /dev/ device
		#Note: We don't explicitly check for existence of 'dmsetup' on the system
		#	   because if it doesn't, the command below will quietly fail anyway,
		#	   and we only care if it succeeds
		if dmsetup info "${DEVICE}" &>/dev/null
		then
			DEV_MAPPER_DEVICE="/dev/mapper/$(dmsetup info "${DEVICE}" | grep Name | tr -s ' ' | cut -d ' ' -f 2)"
			if [[ -b ${DEV_MAPPER_DEVICE} ]]; then
				DEVICE="${DEV_MAPPER_DEVICE}"
			fi
		fi

		#If "${DEVICE}" is a logical volume, ignore it. It's basically like running
		#fdisk on a partition
		#Note: We don't explicitly check for existence of 'lvdisplay' on the system
		#	   because if it doesn't, the command below will quietly fail anyway,
		#	   and we only care if it succeeds
		if lvdisplay "${DEVICE}" &>/dev/null; then
			continue
		fi

		#If "${DEVICE}" ends in #p#, it's a partition, so ignore it.
		if echo "${DEVICE}" | grep -q '[0-9]p[0-9][0-9]*$';	then
			continue
		fi

		#Only run gdisk on device if fdisk says it's using GPT
		if sudo fdisk -l "${DEVICE}" 2>/dev/null | grep -q -i gpt; then
			LOGGER "$(echo -e "gdisk -l ${DEVICE}:\n"; sudo gdisk -l "${DEVICE}" 2>/dev/null | grep -A 100 'Disk /')"
		fi
	done

	#blkid which shows the UUIDs that fstab uses
	LOGGER "$(echo -e "blkid:\n"; sudo blkid)"

	#LVM
	if which lvdisplay &>/dev/null;	then
		LOGGER "$(echo -e "pvdisplay:\n"; sudo pvdisplay 2>&1)"
		LOGGER "$(echo -e "vgdisplay:\n"; sudo vgdisplay 2>&1)"
		LOGGER "$(echo -e "lvdisplay:\n"; sudo lvdisplay 2>&1)"
	fi

	######################################
	# Create /var/lib/ram_booter folder #
	######################################

	#If the folder already exists (wasn't cleaned up on last run), delete it
	if [[ -d "/var/lib/ram_booter" ]]; then
		sudo rm -rf "/var/lib/ram_booter"
	fi

	#Create the folder
	sudo mkdir -p "/var/lib/ram_booter"

	#Set permissions on the folder
	sudo chown "root:root" "/var/lib/ram_booter"
	sudo chmod 755 "/var/lib/ram_booter"

	###############################################################
	# Create /var/lib/ram_booter/conf							 #
	#		 and the Uninstall_Ram_Booter function can use	   #
	###############################################################

	#Create /var/lib/ram_booter/conf
	sudo touch "/var/lib/ram_booter/conf" &>/dev/null

	#Check exit status
	if [[ "$?" != "0" ]]; then
		Error "Failed to create /var/lib/ram_booter/conf"
		Encapsulate "Exiting..."
		Uninstall_Ram_Booter quiet
		exit 1
	fi

	#Set permissions on the file
	sudo chown "root:root" "/var/lib/ram_booter/conf"
	sudo chmod 644 "/var/lib/ram_booter/conf"

	#########################################################################
	# Add zb_version_check kernel postinst software to /etc/kernel/postinst.d #
	#########################################################################

	SOFTWARE_FILE_NAME=$(basename "${VER_CHECK_SOFTWARE}")
	if ! [[ "${ISARCH}" ]]; then
		sudo cp "${VER_CHECK_SOFTWARE}" "/etc/kernel/postinst.d/"
		sudo chown "root:root" "/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
		sudo chmod 755 "/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
	fi

	########################################################################
	# Add zc_sort_kernels kernel postinst software to /etc/kernel/postinst.d #
	########################################################################

	SOFTWARE_FILE_NAME=$(basename "${SORT_KERNELS_SOFTWARE}")
	if ! [[ "${ISARCH}" ]]; then
		sudo cp "${SORT_KERNELS_SOFTWARE}" "/etc/kernel/postinst.d/"
		sudo chown "root:root" "/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
		sudo chmod 755 "/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
	fi


	#################################################
	# Find out what the user wants to do with /home #
	#################################################

	Center "INTRODUCTION"
	FormatText "This software will create a copy of your Ultimate Edition OS in ${DEST} and then use that copy to create a squashfs image of it located at /live. After this separation, your current OS (the Original OS) and your new OS (the Ram Session) will be two completely separate entities. Updates of one OS will not affect the update of the other, and the setup of packages on one will not transfer to the other. Depending on what you choose however, your /home may be shared between the two systems."
	Center "INFORMATION"
	FormatText "/home is the place where your desktop, documents, music, pictures, and program settings are stored. Would you like /home to be stored on a [s]eparate partition so that any changes you make to it (saved files, config files store on it, etc.) will survive a reboot? If you choose [s]erperate, you will need to provide a device name of a partition. If you choose [c]opy, /home will be copied to the Ram session as is, and will become permanent. This means everytime you reboot, it will revert to the way it was the last time you created a squashfs image. Moving it to a [s]eparate partition is also the first step in making /home shared between the two systems, if that's what you're after."
	FullBar
	#If /home is already on a separate partition, let the user know
	if [[ "${HOME_ALREADY_MOUNTED}" ]]; then
		Encapsulate "Your /home is currently located on: ${HOME_DEV}."
		Encapsulate "If you choose to have it [s]eparate, the Ram Session will"
		Encapsulate "mount the ${HOME_DEV} device as /home as well."
		FullBar
	fi
	read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}What would you like to do?: [s]eparate/[c]opy as is]: " ANSWER
	echo -en "\033[1A\033[2K"
	case "${ANSWER}" in
		s|separate)
			COPY_HOME=false

			if [[ "${HOME_ALREADY_MOUNTED}" ]]; then
				#/home is already on a separate partition, so we know exactly what to use
				FullBar
				Encapsulate "You chose to use ${HOME_DEV} as your /home for the Ram Session"
			else
				#Ask user what he wants to use as /home
				#Note: This function sets the global variable ${HOME_DEV}
				Ask_User_About_Home
			fi
		;;
		c|copy)
			COPY_HOME=true

			#If the Original OS was already using some partition
			#as /home, and you chose to copy /home to ram_session
			#instead of use that partition, force HOME_DEV to be the
			#same as ROOT_DEV
			if [[ "${HOME_ALREADY_MOUNTED}" ]];	then
				HOME_DEV="${ROOT_DEV}"
			fi
		;;
		*)
			Error "Invalid Response: ${ANSWER}"
			Error "Exiting..."
			Uninstall_Ram_Booter quiet
			exit 1
		;;
	esac

	####################################################################################
	# If the Original OS's /home was on the same partition as /, and the user chose	#
	# to have the Ram Session's /home on a separate partition, ask if we should change #
	# the Original OS's /etc/fstab to also mount that partition as /home			   #
	####################################################################################

	if ! [[ "${COPY_HOME}" ]]; then
		if ! [[ "${HOME_ALREADY_MOUNTED}" ]]; then
			#Ask user if they want to share /home

			Encapsulate "Would you like to have your Original OS use ${HOME_DEV} as its /home as well?"
			Encapsulate "If you choose yes, your Original OS's /home and your Ram Session's /home will be shared"
			Encapsulate "If you choose no, your Original OS's /home and your Ram Session's /home will be different"
			read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Your choice [Y/n]: " ANSWER
			echo -en "\033[1A\033[2K"
			case "${ANSWER}" in
				n|no)
					SHARE_HOME=false
					Encapsulate "Your Original OS's /home and your Ram Session's /home will remain separate."
				;;
				*)
					SHARE_HOME=true
					Encapsulate "Your /etc/fstab will be modified to mount ${HOME_DEV} as your /home at boot"
					Encapsulate "WARNING: Your current system (Original OS) will NOT use ${HOME_DEV} as"
					Encapsulate "/home until you reboot, so nothing you save to it now will appear in"
					Encapsulate "either the Original OS or the Ram Session when you reboot. As such,"
					Encapsulate "it is recommended that you reboot immediately after this software is"
					Encapsulate "done running."
					Encapsulate "Press enter to continue"
					FullBar
					read key
				;;
			esac
		else
			#If user chose to use a separate partition for /home,
			#and the Original OS was already doing this, we are still
			#sharing /home
			SHARE_HOME=true
		fi
	fi

	############################################################
	# Write some global variables to /var/lib/ram_booter/conf #
	############################################################

	#Figure out the UUID of the home partition
	HOME_UUID=$(sudo blkid -o value -s UUID "${HOME_DEV}")

	echo "#This file was created by the Ram Booter software" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "#Do NOT edit or delete this file" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#Path to the Ram Session dir on the Original OS" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "DEST=${DEST}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#True if both the Original OS and the Ram Session are sharing /home. False otherwise" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "SHARE_HOME=${SHARE_HOME}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#True if /home was already a mountpoint for some partition before we installed the Ram Session. False otherwise" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "HOME_ALREADY_MOUNTED=${HOME_ALREADY_MOUNTED}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#The device and UUID for / on the Original OS" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "ROOT_DEV=${ROOT_DEV}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "ROOT_UUID=${ROOT_UUID}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#The device and UUID for /boot on the Original OS" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "#Note: If BOOT_DEV/BOOT_UUID is the same as ROOT_DEV/ROOT_UUID, we are NOT using a separate partition for /boot" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "#IMPORTANT NOTE: The Ram Session NEVER mounts the real /boot - it uses a copy of /boot (a fake /boot). Only the ${APPNAME} -w software actually mount /boot." | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "BOOT_DEV=$BOOT_DEV" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "BOOT_UUID=${BOOT_UUID}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#The device and UUID for /home that the Ram Session should be using" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "#IMPORTANT NOTE: This may be different than what the Original OS is using" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "#IMPORTANT NOTE 2: If HOME_DEV/HOME_UUID is the same as ROOT_DEV/ROOT_UUID, we are NOT using a separate partition for /home" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "HOME_DEV=${HOME_DEV}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "HOME_UUID=${HOME_UUID}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#The device and UUID for the ESP (EFI partition) if they exist" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "EFI_DEV=${EFI_DEV}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "EFI_UUID=${EFI_UUID}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#Default compression" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "COMPRESSION=${COMPRESSION}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	echo "#Persistance" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "PERSISTANCE=${PERSISTANCE}" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null
	echo "" | sudo tee -a /var/lib/ram_booter/conf &>/dev/null

	########################################################################
	# If the user hits Ctrl+C at any point, have the software ask to cleanup #
	########################################################################

	trap CtrlC SIGINT

	BasicTools "$@"

	##################################################
	# Create folder where Ram Session will be stored #
	##################################################

	sudo mkdir -p "${DEST}"

	###########################################################################
	# Write files to / to identify where you are - Original OS or Ram Session #
	###########################################################################

	sudo bash -c 'echo "This is the Ram Session. Your OS is running from within Ram." > '${DEST}'/ram_session'
	sudo bash -c 'echo "This is your Original OS. You are NOT inside the Ram Session." > /original_os'

	###############################################
	# Run /etc/kernel/postinst.d/zb_version_check #
	###############################################

	SOFTWARE_FILE_NAME=$(basename "${VER_CHECK_SOFTWARE}")

	#Create list of kernels the Original OS supports
	if ! [[ "${ISARCH}" ]]; then
		sudo "/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
	fi

	#The list of kernels the Original OS supports is
	#exactly the same while the Ram Session is being installed
	if [[ -f "/boot/orig" ]]; then
		sudo cp -a "/boot/orig" "/boot/ram_sess"
	fi
	###########################
	# Add Grub2 entry to menu #
	###########################

	SOFTWARE_FILE_NAME=$(basename "${GRUB_RAMBOOTER_SOFTWARE}")

	#Adding entry to Grub2 menu
	Encapsulate "Adding entry to Grub2 menu"

	#Copy RAMBOOTER to grub folder
	cp "${GRUB_RAMBOOTER_SOFTWARE}" "/etc/grub.d/"

	#Set permissions
	sudo chown "root:root" "/etc/grub.d/${SOFTWARE_FILE_NAME}"
	sudo chmod 755 "/etc/grub.d/${SOFTWARE_FILE_NAME}"

	#Unhide grub menu by uncommenting line in /etc/default/grub
	sudo sed -i 's/\(GRUB_HIDDEN_TIMEOUT=0\)/#\1/g' "/etc/default/grub"

	#Inform user everything went well
	Encapsulate "Grub entry added successfully."

	########################
	# Copy the OS to ${DEST} #
	########################

	CopyFileSystem

	########################################################################
	# Copy /home to either ${DEST}/home or to a new partition				#
	# The reason CopyFileSystem doesn't handle copying /home anymore is	#
	# because even if it just needs to be copied to ${DEST}/home, we do some #
	# tricks to make sure that any encrypted user home directories are not #
	# copied over in decrypted form										#
	########################################################################

	if [[ "${COPY_HOME}" ]]; then
		CopyHome
	fi

	###########################################################################
	# Block update-grub from running in the Ram Session without ram-booter -w #
	# since it fails when it runs there, and it's unnecessary				 #
	###########################################################################

	#Modify ${DEST}/usr/sbin/update-grub
	if ! [[ -e  "${DEST}/usr/sbin/update-grub" ]]; then
		sudo touch "${DEST}/usr/sbin/update-grub"
	fi
	sudo sed -i '$i\
if [ -e /ram_session ]\
then\
	if [ "$(ls -di / | cut -d " " -f 1)" = 2 ] || [ "$(ls -di / | cut -d " " -f 1)" = 128 ]\
	then\
		echo "update-grub cannot be run from Ram Session unless you are using ram-booter -w"\
		echo "Ignoring grub-update request"\
		exit 0\
	fi\
	fi' "${DEST}/usr/sbin/update-grub"

	###############
	# Update Grub #
	###############
	UpdateGrub "$@"

	##############################################
	# Remove /boot from Ram Session's /etc/fstab #
	##############################################
	#Reasoning:
	#Because of the nature of the Ram Session - the fact that it reverts
	#back to a previous state after a reboot, if /boot was placed into a
	#separate partition, it would be exempt from this action. In cases where
	#software is installed that makes changes to /boot, such as changes
	#to initrd images, a reboot would result in the software that made the
	#changes being removed while the initrd image would still contain the
	#changes. This would cause the OS to be in an inconsistent state. I'm no
	#expert on the linux kernel by any means, and I have no idea if this is
	#dangerous in any way, but updating /boot only when a permanent software
	#update is going to be made just seems like the cleanest alternative.
	#Note:
	#	Below regex handles UUID, LVM and regular device entries
	sudo sed -i '/^UUID=[^ \t]\{1,\}[ \t]\{1,\}\/boot[/]*[ \t]/d' "${DEST}/etc/fstab"
	sudo sed -i '/^\/dev\/[^ \t]\{1,\}[ \t]\{1,\}\/boot[/]*[ \t]/d' "${DEST}/etc/fstab"

	#Also remove /boot/efi if it's there
	sudo sed -i '/^UUID=[^ \t]\{1,\}[ \t]\{1,\}\/boot\/efi[/]*[ \t]/d' "${DEST}/etc/fstab"
	sudo sed -i '/^\/dev\/[^ \t]\{1,\}[ \t]\{1,\}\/boot\/efi[/]*[ \t]/d' "${DEST}/etc/fstab"

	#################
	# Cleanup Tasks #
	#################

	#Clean some unnecessary files
	#Note: The 'root' we skip is the name of root's cron file. Since we
	#might be writing to it, we don't want to delete it
	Encapsulate "Cleaning unnecessary files:"
	if [[ "${ISARCH}" ]]; then
		sudo find "${DEST}/var/run" "${DEST}/var/mail" "${DEST}/var/spool" "${DEST}/var/lock" "${DEST}/var/tmp" -type f -not -name "root" -exec rm {} \;
	else
		sudo find "${DEST}/var/run" "${DEST}/var/mail" "${DEST}/var/spool" "${DEST}/var/lock" "${DEST}/var/backups" "${DEST}/var/tmp" -type f -not -name "root" -exec rm {} \;
	fi
	#${DEST}/var/crash might not exist, but should be cleaned if it does
	[[ -d "${DEST}/var/crash" ]] &&
	sudo find "${DEST}/var/crash" -type f -exec rm {} \;

	#Delete only OLD log files
	Encapsulate "Deleting old log files:"
	sudo find "${DEST%/}/var/log" -type f -iregex '.*\.[0-9].*' -exec rm {} \;
	sudo find "${DEST%/}/var/log" -type f -iname '*.gz' -exec rm {} \;

	#Clean current log files
	Encapsulate "Cleaning recent log files:"
	sudo find "${DEST%/}/var/log" -type f | while read FILE; do Encapsulate "emptied ${FILE}" | sudo tee "${FILE}"; done

	######################################################
	# Add za_ram_session_initramfs software to Ram Session #
	######################################################

	SOFTWARE_FILE_NAME=$(basename "${INITRAMFS_SOFTWARE}")
	if ! [[ "${ISARCH}" ]]; then
		sudo cp "${INITRAMFS_SOFTWARE}" "${DEST}/etc/kernel/postinst.d/"
		sudo chown "root:root" "${DEST}/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
		sudo chmod 755 "${DEST}/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
	fi

	#####################################
	# Add zd_warn software to Ram Session #
	#####################################

	SOFTWARE_FILE_NAME=$(basename "${WARN_SOFTWARE}")
	if ! [[ "${ISARCH}" ]]; then
		sudo cp "${WARN_SOFTWARE}" "${DEST}/etc/kernel/postinst.d/"
		sudo chown "root:root" "${DEST}/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
		sudo chmod 755 "${DEST}/etc/kernel/postinst.d/${SOFTWARE_FILE_NAME}"
	fi
	##################################
	# Write some useful info to ${LOG} #
	##################################

	#${DEST}/etc/fstab
	LOGGER "$(echo -e "${DEST%/}/etc/fstab:\n"; cat ${DEST}/etc/fstab)"

	#######################
	# Make squashfs image #
	#######################
	FullBar
	Encapsulate "Creating Squash filesystem image..."
	FullBar
	sudo mkdir -p "/live"
	# Use Maximum compression.
	if [[ "${COMPRESSION}" == "maximum" ]]; then
		Encapsulate "Using Maximum compression."
		FullBar
		sudo mksquashfs "${DEST}" "/live/filesystem.squashfs" -noappend -always-use-fragments -b 1048576 -comp xz -Xdict-size 100%
		SQUASHCOMPLETE=1
		FullBar
	fi
	# Use fast compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		if [[ "${COMPRESSION}" == "fast" ]]; then
			Encapsulate "Using fast compression."
			FullBar
			sudo mksquashfs "${DEST}" "/live/filesystem.squashfs" -noappend -always-use-fragments -comp lz4
			SQUASHCOMPLETE=1
		fi
	fi
	# Default compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		sudo mksquashfs "${DEST}" "/live/filesystem.squashfs" -noappend -always-use-fragments
	fi

	#See how it went
	if [[ "$?" != 0 ]];	then
		Error "Squash filesystem image creation failed."
		Error "You may want to run \"${PROGNAME} --uninstall\" to remove the partially-installed stuff"
		Encapsulate "Exiting..."
		FullBar
		exit 1
	else
		FullBar
		Center "Squash filesystem image created successfully."
	fi

	###########################################
	# Tell user how much Ram they should have #
	###########################################

	#Find out how big the squashfs image ended up being
	IMAGE_SIZE=$(sudo du -h "/live/filesystem.squashfs" | awk '{ print $1 }')
	declare -i MEMTOTAL
	MEMTOTAL=$(cat /proc/meminfo | grep -i "MemTotal" | cut -d":" -f2 | cut -d "k" -f1)
	GIGS=$(free -m -h | grep -i "mem:" | awk '{print $2}')

	#Convert to comma seperated values...Memory
	if [[ "${MEMTOTAL}" && "${GIGS}" ]]; then
		MEMSIZE=$(printf "%'.3f\n" "${MEMTOTAL}")
		MEMORY=$(echo "${MEMSIZE}" | cut -d. -f1)
		Encapsulate "Physical Memory: ${MEMORY} bytes. Gigs: (${GIGS})"
	else
		Error "Cannot retrieve memory information..."
	fi
	#Tell user how much Ram they should have
	Center " IMAGE INFORMATION"
	FormatText "The size of the image is ${IMAGE_SIZE}. This MUST fit in your total Ram: ${MEMORY} bytes. Gigs: (${GIGS}), with room to spare. If it does not, you either need to buy more RAM, or manually remove unimportant packages from your OS until the image fits. Note: Do NOT format your Original OS that you made the Ram Session out of, as the squashfs image still resides there. So does ${DEST}, the folder the image gets recreated from everytime you make any changes to the Ram Session through software. You should be able to shrink the partition with your Original OS, however in order to save space. Also, if you switch between your Original OS and your Ram Session a lot, and forget which one you are in, do an 'ls /'. If you see the /original_os file, you are in the Original OS. If you see the /ram_session file, you are in the Ram Session. You may now reboot to use your Ram Session."
	FullBar
	Session "$@"
	QuestionReboot "$@"
	FullBar
	Timer "Stop" "Setup RamDrive"
}

NVMEInfo () {
	# Set hard-coded variables
	ISHDDTEMP=$(type -p hddtemp)
	ISHDDEXEC="NO"
	SENSORS=$(type -p sensors)
	NF=0
	#NVME Drive(s)?
	awk '/dev\/nvme/ {print $1}' "/etc/mtab" | sort | while read line
	do
		if [[ "$DEBUG" ]]; then
			echo "DEBUGGING: ${line}"
		fi
		(( NF = NF + 1 ))
		NVTEMP=$(sensors -f | grep -a2 'nvme' | grep -m "${NF}" 'Composite:' | cut -d '+' -f2 | cut -d '.' -f1 | tail -n 1)
		MOUNTPOINT=$(df "${line}" | awk '{ s = ""; for (i = 6; i <= NF; i++) s = s $i " "; print s }' | sed '1d' | sed -e 's/[[:space:]]*$//')
		FileSize -d "${MOUNTPOINT}"
		DISPMOUNTPOINT=$(echo "${MOUNTPOINT}" | sed "s/${USER}\///g" | sed "s/\/media\///g" | sed "s/media\///g" | sed "s/\/mnt\///g")
		STRIPPED=$(echo "${MOUNTPOINT}" | sed 's/\/media\///g')
		#if [[ -w "/tmp/mpoint.txt" ]]; then
		#	echo "${MOUNTPOINT}" >> "/tmp/mpoint.txt"
		#fi
		#if [ "${STRIPPED}" = "/" ]; then
		#	STRIPPED="Root"
		#fi

		HDDTMP=$(echo "${line}" | sed 's/[0-9]*//g')
		#Future implementation?
		HDSIZE=$(df -H "${line}" | sed "1d" | awk '{print $2}')

		#See if hddtemp is installed & SUID executable, if not don't do squat
		if [[ "${ISHDDTEMP}" ]]; then

			# TEST 2 conditions:
			# 1. NON-EXISTANT OUTPUT IE USB HDD / Burner
			# 2. Permissions to hddtemp SUID
			# Catch erronious output, eject it to null and skip smart checks.
			TSTVAR=$(hddtemp "${line}" /dev/null 2>&1 |grep 'Permission denied')
			if ! [[ "${TSTVAR}" ]]; then
				TSTVAR=$(hddtemp "${line}" /dev/null 2>&1 | grep -i "t have a temperature sensor.")
				TSTVAR=$(hddtemp "${line}" /dev/null 2>&1 | grep -i "determine")
			fi

			# hddtemp permissions are correct and a sensor exists on current drive.
			if ! [[ "${TSTVAR}" ]]; then
				HDTEMP=$(hddtemp "${line}" --unit=f --numeric)
				SMART=$(echo "${HDTEMP}" | grep -v "S.M.A.R.T. not available")
				SENSOR=$(echo "${HDTEMP}" | grep -v "have a temperature sensor")
			fi
		fi
		#TSPACE=$(expr ${TSPACE} + ${HDSIZE})
		# If Temperature was detected populate Conky as well display info to user.
		if [[ "${NVTEMP}" != "" ]]; then
			Columnize "${line}" "${DISPMOUNTPOINT}" "NVME" "${NVTEMP}°F" "${FORMATTED} bytes (${HDSIZE})"
		else
			Columnize "${line}" "${DISPMOUNTPOINT}" "NVME" "N/A" "${FORMATTED} bytes (${HDSIZE})"
		fi
	done;
}

TestCreateSquashfs () {
	#Mount only the root filesystem of the Original OS
	MOUNT_RS root_only
	############################
	# Let user into the chroot #
	############################
	if ! [[ "${SUPPRESS}" ]]; then
		if [[ -f "/run/resolvconf/resolv.conf" ]]; then
			Encapsulate "Setting up Internet for the chroot environment."
			sudo cp "/run/resolvconf/resolv.conf" "${ORIG_OS}/${DEST}/run/resolvconf/resolv.conf"
		else
			Error "Error: /run/resolvconf/resolv.conf does not exist, this could be a critical error, proceeding."
			Encapsulate "Attempting to set nameserver(s)"
			if [[ -f "/etc/resolv.conf" ]]; then
				if [[ -f "/run/systemd/resolve/resolv.conf" ]]; then
					mkdir -p "${ORIG_OS}/${DEST}/run/systemd/resolve/"
					sudo cp "/run/systemd/resolve/resolv.conf" "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf"
					PUNCHIT=$(sudo echo "nameserver 127.0.0.1" > "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf" > /dev/null)
					PUNCHIT=$(sudo echo "nameserver 8.8.8.8" | tee "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf" > /dev/null)
				else
					PUNCHIT=$(sudo echo "nameserver 127.0.0.1" > "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf" > /dev/null)
					PUNCHIT=$(sudo echo "nameserver 8.8.8.8" | tee "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf" > /dev/null)
				fi
			else
				Error "/etc/resolv.conf does not exist on the host system. This could be a critical error, proceeding."
				Encapsulate "Setting nameserver to 8.8.8.8 & 127.0.0.1, trying to save us from a undesireable situation of no internet."
				if [[ "${DEBUG}" ]]; then
					echo "DEBUGGING FROM ${PWD}"
				fi
				PUNCHIT=$(sudo echo "nameserver 8.8.8.8" | tee "${ORIG_OS}/${DEST}/run/systemd/resolve/resolv.conf" > /dev/null)
				fi
		fi
	fi
	if ! [[ "${SUPPRESS}" ]]; then
		if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
			Encapsulate "Installing ram-editor into the chroot environment."
			sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}/${DEST}/bin/"
		else
			Error "Error ram-editor, not found. Continuing."
		fi

		if [[ -f "${ORIG_OS}/${DEST}/bin/bash" ]]; then
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}/${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor $*"
			sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash
			Center "Exiting: Chroot Environment"
		fi
	fi

	######################
	# Some quick cleanup #
	######################

	#Clean apt cache quietly
	sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash -c "apt-get -y clean" &>/dev/null

	#Update fake /boot, just in case any packages being installed in the
	#RAM Session want /boot to be consistent with the running system
	#Note: This is usually only necessary during an update, but we do it
	#	anyway in case the user did updates in the redit instead of
	#	using rupdate
	sudo mount -o bind "${ORIG_OS}/${DEST}/" "${ORIG_OS}/${DEST}/mnt/" &>/dev/null &&
	sudo rsync --delete -a "${ORIG_OS}/${DEST}/boot/" "${ORIG_OS}/${DEST}/mnt/boot/" --exclude=/IMPORTANT_README &>/dev/null &&
	sudo umount "${ORIG_OS}/${DEST}/mnt/" &>/dev/null

	##########################################################################
	# Check if /etc/kernel/postinst.d/zd_warn has set a flag that shows that #
	# a kernel update occurred. If it has, the user should get a warning	 #
	##########################################################################

	if [[ -e "${ORIG_OS}/${DEST}/WARN" ]]; then
		FormatText "WARNING: A KERNEL UPDATE JUST OCCURRED, AND THE RAM SESSION GRUB ENTRY HAS BEEN MODIFIED TO USE THE NEW KERNEL. YOU MUST RECREATE THE SQUASHFS IMAGE BEFORE YOU REBOOT OR YOUR RAM SESSION WILL NOT HAVE THE MODULES TO USE THE NEW KERNEL, AND MAY FAIL TO BOOT!"
		rm "${ORIG_OS}/${DEST}/WARN"
	fi
	#Create squashfs image
	#Note: We do NOT write the file directly to the one we boot
	#from so that if the process gets interrupted and we reboot,
	#we can still boot into the old image
	# sudo mksquashfs ${ORIG_OS%/}/${DEST#/} ${ORIG_OS%/}/live/filesystem.squashfs.new -noappend -always-use-fragments
	FullBar
	Encapsulate "Creating Squash filesystem image..."
	FullBar
	# Use Maximum compression.
	if [[ "${COMPRESSION}" == "maximum" ]]; then
		Encapsulate "Using Maximum compression."
		FullBar
		sudo mksquashfs "${ORIG_OS%/}/${DEST#/}" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments -b 1048576 -comp xz -Xdict-size 100%
		SQUASHCOMPLETE=1
		FullBar
	fi
	# Use fast compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		if [[ "${COMPRESSION}" == "fast" ]]; then
			Encapsulate "Using fast compression."
			FullBar
			sudo mksquashfs "/run/live/rootfs/filesystem.squashfs/" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments -comp lz4
			SQUASHCOMPLETE=1
		fi
	fi
	# Default compression
	if ! [[ "${SQUASHCOMPLETE}" ]]; then
		sudo mksquashfs "${ORIG_OS%/}/${DEST#/}" "${ORIG_OS%/}/live/filesystem.squashfs.new" -noappend -always-use-fragments
	fi

	#See how it went
	if [[ "$?" != 0 ]];	then
		Error "Squash filesystem image creation failed."
		Error "You may want to run \"${PROGNAME} --uninstall\" to remove the partially-installed stuff"
		Encapsulate "Exiting..."
		FullBar
		exit 1
	else
		FullBar
		Center "Squash filesystem image created successfully."
	fi

	#If there was an error, exit 1
	if [[ "$?" != "0" ]]; then
		Error "Failed to create ${ORIG_OS%/}/live/filesystem.squashfs"
		UMOUNT_RS
		exit 1
	fi

	#Move the newly created squashfs image to the location we boot from
	sudo mv "${ORIG_OS%/}/live/filesystem.squashfs.new" "${ORIG_OS%/}/live/filesystem.squashfs"

	#Inform user we are done
	FullBar
	Encapsulate "Squash filesystem image created successfully."
	FullBar
	#Unmount the root filesystem
	UMOUNT_RS
}

WriteSquashfs () {
	############################
	# Only run if user is root #
	############################
	if ! [[ "${RAMSESSION}" ]]; then
		Center "This section of the software will only run from the RAM session."
		exit 0;
	fi

	##################################################################################
	# Check if the user is trying to run this software from outside of the RAM Session #
	##################################################################################

	if [ ! -e "/ram_session" ]; then
		Center "This software cannot be run from outside of the RAM Session."
		exit 0
	fi

	##########################################################################
	# Check if the user is trying to run this software from inside of a chroot #
	##########################################################################

	ischroot
	if [ $? -eq 0 ]; then
		Center "This software cannot be run from inside of a chroot"
		exit 0
	fi

	####################
	# Global Variables #
	####################
	#Figure out ${DEST}
	DEST=$(cat "/var/lib/ram_booter/conf" | grep -v '^#' | grep DEST= | sed 's/DEST=//g')
	#Remove leading slash from ${DEST}
	DEST="${DEST#/}"
	#The mountpoint of the Original OS device
	#Note: If you change it here, be sure to change it in the rupdate software as well
	ORIG_OS='/mnt/Original_OS/'

	case "$1" in
		-w|--writesquashfs)
			if ! [[ "${SUPPRESS}" ]]; then
				VersionDump
				#Ask user if he wants to recreate filesystem.squashfs
				#This basically just lets the user skip the chroot completely
				Center "Rebuild Squash Filesystem?"
				Encapsulate "Are you sure you want to re-create the squashfs image?"
				Encapsulate "This may take some time to complete"
				Encapsulate "You may use the computer normally during this process. You will NOT disrupt it"
				FullBar
				read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Your choice [y/N]: " ANSWER
				echo -en "\033[1A\033[2K"
			else
				ANSWER="y"
			fi

			#Convert ANSWER to lowercase
			ANSWER=$(toLower ${ANSWER})

			case ${ANSWER} in
				y|yes)
					#Create squashfs image
					CreateSquashfs
				;;
				*)
					FullBar
					Encapsulate "You chose to NOT recreate the squashfs image"
					exit 0
				;;
			esac

			exit 0
		;;
		-h|--help)
			Usage
			exit 0
		;;
		"")
			#No args is fine
		;;
		*)
			Encapsulate "'$1' is not a valid argument"
			Usage
			exit 1
		;;
	esac


	############
	# Mount FS #
	############

	#Mount the RAM Session, and bind all the pseudo filesystems to it
	MOUNT_RS

	#####################################################
	# Tell user about any user home dirs we had to bind #
	#####################################################

	if mount | grep bind | grep -q "${ORIG_OS%/}/${DEST%/}/home/[^ \t]*"
	then
		Encapsulate "The following encrypted home directories were automatically mounted,"
		Encapsulate "since you are currently logged into them:"
		mount | grep bind | grep "${ORIG_OS%/}/${DEST%/}/home/[^ \t]*" | sed 's/on.*//g'
	fi

	############################
	# Let user into the chroot #
	############################
	if ! [[ "${SUPPRESS}" ]]; then
		if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
			Encapsulate "Installing ram-editor into the chroot environment."
			cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}/${DEST}/bin/"
		else
			Error "Error ram-editor, not found. Continuing."
		fi

		if [[ -f "${ORIG_OS}/${DEST}/bin/bash" ]]; then
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}/${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor $*"
			sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash
			Center "Exiting: Chroot Environment"
		fi
	fi

	######################
	# Some quick cleanup #
	######################

	#Clean apt cache quietly
	sudo chroot "${ORIG_OS}/${DEST}/" /bin/bash -c "apt-get -y clean" &>/dev/null

	#Update fake /boot, just in case any packages being installed in the
	#RAM Session want /boot to be consistent with the running system
	#Note: This is usually only necessary during an update, but we do it
	#	anyway in case the user did updates in the redit instead of
	#	using rupdate
	sudo mount -o bind "${ORIG_OS}/${DEST}/" "${ORIG_OS}/${DEST}/mnt/" &>/dev/null &&
	sudo rsync --delete -a "${ORIG_OS}/${DEST}/boot/" "${ORIG_OS}/${DEST}/mnt/boot/" --exclude=/IMPORTANT_README &>/dev/null &&
	sudo umount "${ORIG_OS}/${DEST}/mnt/" &>/dev/null

	##########################################################################
	# Check if /etc/kernel/postinst.d/zd_warn has set a flag that shows that #
	# a kernel update occurred. If it has, the user should get a warning	 #
	##########################################################################

	if [[ -e "${ORIG_OS}/${DEST}/WARN" ]]; then
		Encapsulate "WARNING: A KERNEL UPDATE JUST OCCURRED, AND THE RAM SESSION GRUB ENTRY"
		Encapsulate "HAS BEEN MODIFIED TO USE THE NEW KERNEL. YOU MUST RECREATE THE SQUASHFS"
		Encapsulate "IMAGE BEFORE YOU REBOOT OR YOUR RAM SESSION WILL NOT HAVE THE MODULES"
		Encapsulate "TO USE THE NEW KERNEL, AND MAY FAIL TO BOOT!"
		rm "${ORIG_OS}/${DEST}/WARN"
	fi

	#Unmount everything
	UMOUNT_RS

	#If there was a problem unmounting stuff, tell user to reboot
	if [[ "$?" != "0" ]]; then
		Encapsulate "There was an error unmounting ${ORIG_OS}"
		Encapsulate "A reboot should fix that"
		Encapsulate "After the reboot, if you need to save your changes by re-creating"
		Encapsulate "the squashfs image, just run \"sudo ${APPNAME} -w\""
		exit 1
	fi

	#################################
	# Recreating the SquashFS Image #
	#################################

	#Ask user if he wants to recreate filesystem.squashfs
	if ! [[ "${SUPPRESS}" ]]; then
		VersionDump
		Encapsulate "Would you like to save your changes by recreating the squashfs image?"
		Encapsulate "This may take some time to complete"
		Encapsulate "You may use the computer normally during this process - you will NOT disrupt it"
		FullBar
		read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Your choice [y/N]: " ANSWER
		echo -en "\033[1A\033[2K"
	else
		ANSWER="y"
	fi

	#Convert ANSWER to lowercase
	ANSWER=$(toLower "${ANSWER}")

	case "${ANSWER}" in
		y|yes)
			FullBar
			#Create squashfs image
			CreateSquashfs "$@"
		;;
		*)
			FullBar
			Encapsulate "You chose to NOT recreate the squashfs image"
			Encapsulate "If you change your mind, run 'sudo ${APPNAME} -w'"
			exit 0
		;;
	esac

}

DiskImageInfo () {
	declare -i ARRAYCOUNTER
	IINFO=$(type -p isoinfo)
	declare -a ISOINFO=('System id' 'Volume id' 'Publisher id' 'Data preparer' 'Volume size');
	# parse command line switches
	shopt -u nullglob
	ARRAYCOUNTER=0
	for EACH in "$@";
	do
		GREPIT=$(echo "${EACH}" | grep -i '.iso')
		if [[ "${GREPIT}" ]]; then
			EXTENSION="${EACH##*.}"
			ISO="${EACH}"
		fi
		GREPIT=$(echo "${EACH}" | grep -i '.img')
		if [[ "${GREPIT}" ]]; then
			EXTENSION="${EACH##*.}"
			ISO="${EACH}"
		fi
		if [[ -d "${EACH}" ]]; then
			FOLDER="${EACH}"
		fi
		((ARRAYCOUNTER++))
	done

	if ! [[ "${ISO}" ]]; then
		Error "Critical Error no ISO or Img specified."
		exit 1;
	fi
	# Set needed varibles, we do not need to check for existance of $1 we
	# would not be here if it does not exist
	EXTENSION="${1##*.}"
	FILENAME="${ISO}"
	BOOTABLE=$(file "${ISO}" | grep -m1 "bootable" 2> /dev/null)

	# Don't put full trust in utility "file" for ISO's use the right tool
	# for the right job if file failed.
	if [[ "${EXTENSION}" == "iso" && "${BOOTABLE}" == "" ]]; then
		if [[ "${IINFO}" ]]; then
			#echo "${ISO}"
			BOOTABLE=$(isoinfo -i "${ISO}" -f -d | grep -m1 "bootable" 2> /dev/null)
		fi
	fi

	# Set Boot Flag
	if [[ "${BOOTABLE}" ]]; then
		BOOTABLE="Yes"
	else
		BOOTABLE=""
	fi

	# Come here my pretty ;)
	#Encapsulate "Processing File: ${ISO}"
	# ISO Image? Dump info defined in Array. Makes it simple to add remove info.
	ARRAYCOUNTER=0
	#for NUMBER in "${ISOINFO[@]}"
	#do
	#	TITLEINFO="${ISOINFO[${ARRAYCOUNTER}]}"
	#	if [[ "${IINFO}" ]]; then
	#		DISPLAYINFO=$(isoinfo -d -i "${ISO}" | grep -m1 -i "${NUMBER}" | cut -d: -f2 | sed -e 's/^[ \t]*//')
	#	fi
	#	if [[ "${DISPLAYINFO}" && "${TITLEINFO}" ]]; then
	#		Encapsulate "${TITLEINFO}: ${DISPLAYINFO}"
	#	fi
	#	((ARRAYCOUNTER++))
	#done

	# Dump info on boot info as detected, we may need some work here,
	# lots of different types of iso's and image files
	#if [[ "${BOOTABLE}" ]]; then
	#	Encapsulate	"Bootable: ${BOOTABLE}"
	#else
	#	Center "Note: This image most likely will not boot."
	#	Encapsulate "${APPNAME} will not process an un-bootable disk."
	#fi

	#if [[ "${IINFO}" ]]; then
	#	WINISO=$(isoinfo -d -i "${ISO}" | grep -i "win\|microsoft" 2> /dev/null)
	#	LINUX=$(isoinfo -d -i "${ISO}" | grep -i "LINUX" 2> /dev/null)
	#	APPLE=$(isoinfo -d -i "${ISO}" | grep -i "APPLE" 2> /dev/null)
	#fi
	# Drop additional info if acclible
	#if [[ "${BOOTABLE}" && "${WINISO}" ]]; then
	#	Encapsulate "Disk Type: ©Microsoft Windows bootable ISO"
	#fi
	#if [[ "${BOOTABLE}" && "${LINUX}" ]]; then
	#	Encapsulate "Disk Type: Linux based bootable operating system"
	#fi
	#if [[ "${BOOTABLE}" && "${APPLE}" ]]; then
	#	Encapsulate "Disk Type:  bootable Apple / MAC based operating system"
	#fi
}

ProcessISOS () {
	if [[ "${RAMSESSION}" ]]; then
		Center "This section of the software will NOT run from the RAM session."
		exit 0;
	fi
	BASECORES=0
	BASECORE=$(echo "$@" | grep -i "BASECORE")
	if [[ "${BASECORE}" ]]; then
		BASECORES=1
	fi
	# Snatch the number of CPU Core(s) / threads the end user has.
	CORES=$(grep -i "processor" "/proc/cpuinfo" | sed '/model/d' | wc -l)
	(( ACTUALCORES = ${CORES} -1 ))
	Encapsulate "Number of CPU Core(s) / threads(s) detected: ${CORES}"
	#CORES=$(("${CORES}" +3))
	CONTAINS=$(echo "$@" | grep -i 'threads')
	if [[ "${CONTAINS}" ]]; then
		THREADS=$(echo "$@" | grep -i "threads=" | sed "s/^.*threads=//g" | cut -d" " -f1)
		Encapsulate "Threads Specified as: ${THREADS}"
		CALCULATE=$(( "${THREADS}" + 3 + "${BASECORES}" ))
		CORES="${CALCULATE}"
	fi
	SOFTWARE_DIR="/usr/share/ultimate_edition"
	shopt -s nullglob
	declare -a ISOS=();
	declare -i NISOS
	declare -i ARRAYCOUNTER
	IINFO=$(type -p isoinfo)
	declare -a ISOINFO=('System id' 'Volume id' 'Publisher id' 'Data preparer' 'Volume size');
	ISOS=(./*.iso)
	NISOS="${#ISOS[@]}"
	SINGLEISO=$(echo "$@"| grep -i ".iso" | sed "s/--iso //g" | sed "s/-I //g"| sed "s/${APPNAME} //g")
	ISO=$(echo "${SINGLEISO}" | cut -d " " -f2)
	#echo "ISO is $ISO"
	CISO=1
	if [[ -f "${ISO}" ]]; then
		Encapsulate "Processing ${ISO}"
		BasicTools "$@"
		FNAME="${ISO}"
		DiskImageInfo "${ISO}"
		FileSize "${ISO}"
		ISOUUID=$(sudo blkid -o value $(\df --output=source "${ISO}"|tail -1)|head -1)
		ISOPATH="${PWD}"
		if ! [[ "${ISOPATH}" == "/" ]]; then
			ISOPATH+="/"
			ISOPATH+="${ISO}"
		fi
		Command echo "ISO Path: ${ISOPATH}"
		for NUMBER in "${ISOINFO[@]}"
		do
			TITLEINFO="${ISOINFO[${ARRAYCOUNTER}]}"
			if [[ "${IINFO}" ]]; then
				DISPLAYINFO=$(isoinfo -d -i "${ISO}" | grep -m1 -i "${NUMBER}" | cut -d: -f2 | sed -e 's/^[ \t]*//')
			fi
			if [[ "${DISPLAYINFO}" && "${TITLEINFO}" ]]; then
				Encapsulate "${TITLEINFO}: ${DISPLAYINFO}"
			fi
			((ARRAYCOUNTER++))
		done
		Encapsulate "ISO Path: ${ISOPATH}"
		Encapsulate "ISO Filesize: ${FORMATTED} bytes (${TRUESIZE})."
		FILEDATE=$(date -r "${FNAME}" "+%m-%d-%Y %H:%M:%S")
		Encapsulate "File Date: ${FILEDATE}"
		if [[ "${BOOTABLE}" ]]; then
			Encapsulate "Setting up grub entry for: ${FNAME}"
			sudo cp "${SOFTWARE_DIR}/extras/both/40_custom" "/etc/grub.d/07_${FNAME}"
		fi
		TITLE=$(isoinfo -d -i "${FNAME}" | grep -m1 -i "Volume id" | cut -d: -f2 | sed -e 's/^[ \t]*//')
		if [[ "${TITLE}" ]]; then
			TITLE+=" (${FNAME})"
		else
			TITLE="${FNAME}"
		fi
		if [[ "${BOOTABLE}" ]]; then
			Encapsulate "Impregnating: /etc/grub.d/07_${FNAME}"
			sudo sed -i "s/#TITLE/${TITLE}/g" "/etc/grub.d/07_${FNAME}"
			sudo sed -i "s|#ISONAME|${ISOPATH}|g" "/etc/grub.d/07_${FNAME}"
			sudo sed -i "s/#ISOUUID/${ISOUUID}/g" "/etc/grub.d/07_${FNAME}"
			((BISO++))
		fi
	else
		if [[ "${NISOS}" -gt 0 ]]; then
			Encapsulate "Number of ISOs found: ${NISOS} processing..."
			BasicTools "$@"
			Encapsulate "Launching ${CORES} threads to accelerate the scanning process, please wait."
			for EACH in "${ISOS[@]}"
			do
				PCOMP=$((100*CISO / NISOS))
				ProgressBar "${PCOMP}" "Processing ISO: ${CISO} of ${NISOS}"
				FNAME=$(sudo basename "${EACH}")
				if [[ -f "${EACH}" ]]; then
					DiskImageInfo "${FNAME}"
					FileSize "${EACH}"
					ISOUUID=$(sudo blkid -o value $(\df --output=source "${FNAME}"|tail -1)|head -1)
					#Encapsulate "Drive UUID: ${ISOUUID}"
					ISOPATH="${PWD}"
					if ! [[ "${ISOPATH}" == "/" ]]; then
						ISOPATH+="/"
						ISOPATH+="${FNAME}"
					fi
					Command echo "ISO Path: ${ISOPATH}"
					# Encapsulate "ISO Filesize: ${FORMATTED} bytes (${TRUESIZE})."
					# FILEDATE=$(date -r "${FNAME}" "+%m-%d-%Y %H:%M:%S")
					# Encapsulate "File Date: ${FILEDATE}"
					# sudo cp "${EACH}" "/live/" & Spinner "Copying ${FNAME} to /live/: "
					if [[ "${BOOTABLE}" ]]; then
						#Encapsulate "Setting up grub entry for: ${FNAME}"
						sudo cp "${SOFTWARE_DIR}/extras/both/40_custom" "/etc/grub.d/07_${FNAME}"
					fi
					TITLE=$(isoinfo -d -i "${FNAME}" | grep -m1 -i "Volume id" | cut -d: -f2 | sed -e 's/^[ \t]*//')
					if [[ "${TITLE}" ]]; then
						TITLE+=" (${FNAME})"
					else
						TITLE="${FNAME}"
					fi
					if [[ "${BOOTABLE}" ]]; then
						#Encapsulate "Impregnating: /etc/grub.d/07_${FNAME}"
						sudo sed -i "s/#TITLE/${TITLE}/g" "/etc/grub.d/07_${FNAME}"
						sudo sed -i "s|#ISONAME|${ISOPATH}|g" "/etc/grub.d/07_${FNAME}"
						sudo sed -i "s/#ISOUUID/${ISOUUID}/g" "/etc/grub.d/07_${FNAME}"
						((BISO++))
					fi
				fi
				((CISO++))
			done
		else
			Encapsulate "Number of ISO files: ${NISOS}, not doing squat."
			BISO=0
		fi
	fi
	Encapsulate "Bootable ISO(s) found: ${BISO} Added to grub: ${BISO}"
	if [[ "${BISO}" -gt 0 ]]; then
		UpdateGrub "$@"
		Session "$@"
	fi
}

DistUpgrade () {
	declare -a POUNDLOADS=();
	POUNDLOADS=( "ultimate-edition-7.5-developer-core-files.deb" "ultimate-edition-grub-7.5_all.deb" "ultimate-edition-plymouth-7.5_all.deb" "ultimate-edition-theme-7.5_all.deb" "ultimate-edition-repositories-0.2.5-apt-source_all.deb" )
	export DEBIAN_FRONTEND=noninteractive
	export DEBIAN_PRIORITY=critical
	sudo dpkg-reconfigure debconf --frontend=noninteractive
	INSTALLED=$(dpkg -l | grep "ultimate-edition-animated")
	if ! [[ "${INSTALLED}" ]]; then
		Center "Downloading..."
		Download "http://os-builder.com/UETOYS/ultimate-edition-animated-1.0_all.deb"
		if [[ -f "ultimate-edition-animated-1.0_all.deb" ]]; then
			sudo dpkg -i "ultimate-edition-animated-1.0_all.deb"
			rm "ultimate-edition-animated-1.0_all.deb"
		fi
	else
		Encapsulate "ultimate-edition-animated is already installed, skipping."
	fi
	CURRENTBRANCH=$(lsb_release -c | cut -d ":" -f2 | sed "s/ //g" | sed "s/\t//g")
	if [[ "${CURRENTBRANCH}" != "noble" ]]; then
		Encapsulate "Replacing ${CURRENTBRANCH} with noble Jellifish sources to distibution upgrade."
		sudo sed -i "s/${CURRENTBRANCH}/noble/g" "/etc/apt/sources.list"
		Encapsulate "Running apt-get update..."
		Command sudo apt-get update & Spinner "Running apt-get update..."
		Encapsulate "Installing latest low-latency kernel..."
		Command sudo apt-get install -f -y linux-lowlatency linux-headers-lowlatency linux-image-lowlatency & Spinner "Installing latest low-latency kernel..."
		sudo apt-get -f -y dist-upgrade & Spinner "Distribution is upgrading, please wait..."
		for EACH in "${POUNDLOADS[@]}"
		do
			Download "http://os-builder.com/7.5/${EACH}"
			if [[ -f "${EACH}" ]]; then
				sudo dpkg -i "${EACH}"
				rm "${EACH}"
			else
				Error "http://os-builder.com/7.5/${EACH} not found, exiting..."
				exit 1;
			fi
		done
	else
		Error "Current Branch is already set, exiting."
		exit 1;
	fi
}



if ! [[ "${SUPPRESS}" ]]; then
	VersionDump "$@"
	Timer "Start" "${APPNAME}"
fi
ChrootIn () {
	if [[ -f "/ram_session" ]]; then
		Encapsulate "Ram Session found."
		#Mount only the root filesystem of the Original OS
		# MOUNT_RS root_only
		############################
		# Let user into the chroot #
		############################


		if ! [[ -f "${ORIG_OS}/${DEST}/bin/bash" ]]; then
			sudo mkdir -p "$ORIG_OS"
			sudo mount -U "${ROOT_UUID}" "${ORIG_OS}" &>/dev/null ||
			{
				echo "Failed to mount ${ROOT_UUID} to ${ORIG_OS}"
				UMOUNT_RS
				exit 1
			}
			if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
				Encapsulate "Installing ram-editor into the chroot environment."
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/bin/"
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/tmp/"
			else
				Error "Error ram-editor, not found. Continuing."
			fi
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor"
			sudo chroot "${ORIG_OS}${DEST}"
		else
			if [[ -f "/usr/share/ultimate_edition/extras/both/ram-editor" ]]; then
				Encapsulate "Installing ram-editor into the chroot environment."
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/bin/"
				sudo cp "/usr/share/ultimate_edition/extras/both/ram-editor" "${ORIG_OS}${DEST}/tmp/"
			else
				Error "Error ram-editor, not found. Continuing."
			fi
			Center "You are about to enter chroot. Please type exit when done."
			sudo chroot "${ORIG_OS}${DEST}" /bin/bash -c "cd /tmp/ ; ram-editor"
			sudo chroot "${ORIG_OS}${DEST}"
		fi
		Encapsulate "Unmounting points..."
		umount "${ORIG_OS}${DEST}/dev/pts" 2>/dev/null
		umount "${ORIG_OS}${DEST}/proc/sys/fs/binfmt_misc" 2>/dev/null
		umount "${ORIG_OS}${DEST}/proc" 2>/dev/null
		umount "${ORIG_OS}${DEST}/sys" 2>/dev/null
	else
		Error " That command can only be ran from within the Ram Session, exiting."
		exit 1;
	fi
}

Info () {
	Information
	BenchmarkRam
	BenchmarkDisk
}
case "${1}" in
	-t|--test)
		if ! [[ "${SUPPRESS}" ]]; then
			VersionDump
			#Ask user if he wants to recreate filesystem.squashfs
			#This basically just lets the user skip the chroot completely
			Center "Rebuild Squash Filesystem?"
			Encapsulate "Are you sure you want to re-create the squashfs image?"
			Encapsulate "This may take some time to complete"
			Encapsulate "You may use the computer normally during this process - you will NOT disrupt it"
			FullBar
			read -p "${BRIGHT}${bldblu}▒ ${BRIGHT}${txtgrn}Your choice [y/N]: " ANSWER
			echo -en "\033[1A\033[2K"
		else
			ANSWER="y"
		fi
		case "${ANSWER}" in
			y|yes)
				#Create squashfs image
				TestCreateSquashfs "$@"
			;;
			*)
				FullBar
				Encapsulate "You chose to NOT recreate the squashfs image"
				exit 0
			;;
		esac

		exit 0
	;;
	-b|--benchmark) BenchmarkDisk "$@"; exit 0;; # Undocumented switch
	-c|--chroot) CheckRoot "$@"; GlobalVars "$@"; ChrootIn "$@";; # Undocumented switch
	-E|--enable) CheckRoot "$@"; EnableHook; exit 0;;
	-D|--disable) CheckRoot "$@"; DisableHook; exit 0;;
	-h|--help|-\?) Help "$@"; exit 0;; # TODO: Enhance this section.
	-i|--info)  Info "$@"; exit 0;; # Undocumented switch
	-I|--iso)  CheckRoot "$@"; GlobalVars "$@"; ProcessISOS "$@"; exit 0;; # Undocumented switch
	-k|--kernel)  CheckRoot "$@"; GlobalVars "$@"; TestBar "$@"; exit 0;; # Hidden switch to increase program advancement
	-s|--setup)  CheckRoot "$@"; GlobalVars "$@"; Main "$@"; exit 0;;
	-S|--session)  CheckRoot "$@"; GlobalVars "$@"; Session "$@"; exit 0;;
	-U|--upgrade)  CheckRoot "$@"; GlobalVars "$@"; DistUpgrade "$@"; exit 0;; # Hidden switch to increase program advancement
	-u|--uninstall)  CheckRoot "$@"; GlobalVars "$@"; Uninstall_Prompt "$@"; exit 0;;
	-w|--writesquashfs)  CheckRoot "$@"; GlobalVars "$@"; WriteSquashfs "$@"; exit 0;;
	-v|--version) VersionDump "$@"; exit 0;;
	*) Help; exit 0;;
esac
Timer "Stop" "${APPNAME}"
