#include-once
#include <Array.au3>

; Disclaimer: If you experience "called with Const or expression on ByRef-param(s)", thats bad.
;             it is a bug in Au3Check that is already fixed, but is not included in the current 3.3.16.1 AutoIt-download
; Fix:        1. Move the global constants & includes part of List.au3 to the top of your script (hardcoded include)
;             2. Move the rest of List.au3 to the bottom of your script.
;             X. Maybe wrap everything in 2 files and include them at the top and the bottom of your script.
; Fix2        1. The error occurs only if you pass a constant to a byref param (which is allowed in AutoIt since 3.3.15.x?)
;                create a local variable everytime you want to do that. Local $a = 5 -> _ListRemove($list, $a) will work!

; #INDEX# =======================================================================================================================
; Title .........: List.au3 (version: 27.Nov.22)
; AutoIt Version : 3.3.16.1
; Language ......: English
; Description ...: Functions for manipulating doubly linked lists (map implementation)
; Author(s) .....: Mars@AutoIt.de
; ===============================================================================================================================

Global Const $LIST_IDENTIFIER = 'LIST123'
Global Const $LIST_FORWARD = 0
Global Const $LIST_BACKWARD = 1
Global Const $LIST_FRONT = 0
Global Const $LIST_BACK = 1
Global Const $LIST_BEFORE = 0
Global Const $LIST_AFTER = 1
Global Const $LIST_EMPTYSIZE = UBound(MapKeys(_ListCreate()))

; #CURRENT# =====================================================================================================================
;~ _ListBack      - Returns the last element in a list.
;~ _ListCreate    - Returns an empty list.
;~ _ListDisplay   - Like _ArrayDisplay, but for lists
;~ _ListFromArray - Returns a list created from an array
;~ _ListFront     - Returns the first element in a list.
;~ _ListInsert    - Inserts an element into an existing list at a given iterator or index
;~ _ListIterator  - Returns an iterator
;~ _ListNext      - Advances the iterator along the direction the iterator is set up
;~ _ListPopBack   - Returns and removes the last element in a list.
;~ _ListPopFront  - Returns and removes the first element in a list.
;~ _ListPrevious  - Advances the iterator in the reverse direction
;~ _ListPushBack  - Adds an element at the back of the list
;~ _ListPushFront - Adds an element at the front of the list
;~ _ListRead      - Returns the element at a given iterator or index
;~ _ListRemove    - Removes an element range at a given iterator or index
;~ _ListToArray   - Returns an array containing the contents of a list
;~ _ListWrite     - Writes into an element at a given iterator or index
; ===============================================================================================================================

; #INTERNAL_USE_ONLY# ===========================================================================================================
;~ __ListDisplay
;~ __ListExample
;~ __ListGetEmptyIndex
;~ __ListInsertList    - not implemented
;~ __ListIterator
;~ __ListPushBackList  - not implemented
;~ __ListPushFrontList - not implemented
; ===============================================================================================================================

If @ScriptName = 'List.au3' Then __ListExample()

Func __ListExample()
	Local $list = _ListCreate() ; Create an empty list

	; push some values
	_ListPushBack($list, 'back 1')
	_ListPushBack($list, 'back 2')
	_ListPushBack($list, 'back 3')
	_ListPushBack($list, 'back 4')
	_ListPushFront($list, 'front 1')
	_ListPushFront($list, 'front 2')
	_ListPushFront($list, 'front 3')
	_ListPushFront($list, 'front 4')

	; get specific values (read access via index)
	ConsoleWrite(@CRLF)
	ConsoleWrite('> List values at specific locations:' & @CRLF)
	ConsoleWrite('list[0] = ' & _ListRead($list, 0) & @CRLF)
	ConsoleWrite('list[3] = ' & _ListRead($list, 3) & @CRLF)
	ConsoleWrite('list[5] = ' & _ListRead($list, 5) & @CRLF)
	ConsoleWrite('list[7] = ' & _ListRead($list, 7) & @CRLF & @CRLF)
	_ListDisplay($list) ; compare console output with these lines of code

	; set specific values (write access via index)
	_ListWrite($list, 0, 'overwrite list at index 0')
	_ListWrite($list, 3, 'overwrite list at index 3')
	_ListWrite($list, 5, 'overwrite list at index 5')
	_ListWrite($list, 7, 'overwrite list at index 7')
	_ListDisplay($list)

	; read access via iterator
	ConsoleWrite('> List contents read via iterator:' & @CRLF)
	Local $iter = _ListIterator($list)
	While $iter[0]
		ConsoleWrite(_ListRead($list, $iter) & @CRLF)
		_ListNext($list, $iter)
	WEnd
	ConsoleWrite(@CRLF)

	; read in reverse order from the back of the list
	ConsoleWrite('> List contents read via iterator in reverse order:' & @CRLF)
	Local $iter = _ListIterator($list, $LIST_BACKWARD, $LIST_BACK)
	While $iter[0]
		ConsoleWrite(_ListRead($list, $iter) & @CRLF)
		_ListNext($list, $iter)
	WEnd
	ConsoleWrite(@CRLF)

	; write access via iterator
	Local $iter = _ListIterator($list), $i = 0
	While $iter[0]
		_ListWrite($list, $iter, 'written via iterator: ' & $i)
		_ListNext($list, $iter)
		$i += 1
	WEnd

	; insert via Index
	_ListInsert($list, 2, 'inserted after the element at index 2', $LIST_AFTER)
	_ListInsert($list, 5, 'inserted before the element at index 5 (which was previously at index 4 and is now at index 6)', $LIST_BEFORE)
	_ListDisplay($list)

	; insert via iterator
	Local $t = TimerInit()
	Local $aString = StringSplit('I am a string that contains many words', ' ', 3)
	Local $list = _ListFromArray($aString), $iter = _ListIterator($list)
	While $iter[0]
		If _ListRead($list, $iter) = 'that' Then
;~ 			_ListInsert($list, $iter, 'hopefully', $LIST_BEFORE) ; insert "hopefully" BEFORE the current element "that"
			_ListInsert($list, $iter, 'hopefully', $LIST_AFTER) ; insert "hopefully" AFTER the current element "that"
		EndIf
		_ListNext($list, $iter) ; -> Iterator is still at "that" after inserting something, so stuff inserted AFTER will be part of the next loop.
	WEnd
	_ListDisplay($list, $LIST_BACKWARD)

	; remove via index
	Local $a = [0, 1, 2, 3, 4, 5, 6, 7 ,8 ,9]
	Local $list = _ListFromArray($a)
	_ListRemove($list, 7) ; Remove Element 7
	_ListRemove($list, 2, 3) ; Remove Element 2, 3, 4
	_ListDisplay($list) ; -> Remaining elements: 0, 1, 5, 6, 8, 9

	; remove via iterator
	Local $a = [0, 1, 2, 3, 4, 5, 6, 7 ,8 ,9]
	Local $list = _ListFromArray($a), $iter = _ListIterator($list)
	While $iter[0]
		If _ListRead($list, $iter) = 3 Then _ListRemove($list, $iter, 5) ; Removes element 3, 4, 5, 6, 7. Iterator set to the last valid iterator. (in this case for element: 2)
		_ListNext($list, $iter)
	WEnd
	_ListDisplay($list)

EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Remove value at iterator position. The iterator is automatically set to the last valid value.
; Parameters ....: $aIterator: - This is what you get from _ListIterator, use it here.
;                              - Also accepts integers (interpreted as index), the function will be in O(n/2) then.
;                  $iLen:      Defines how many elements should be removed along the iterator.
; Known Bugs ....: This only works for iterators running forward.
; Author ........: Mars
; ===============================================================================================================================
Func _ListRemove(ByRef $mList, ByRef $aIterator, $iLen = 1)
	If Not IsArray($aIterator) Then $aIterator = __ListIterator($mList, $aIterator)
	If @error Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListRemove: Iterator is invalid.'))
	Local $mCurrent, $iStartIndex = $mList[$aIterator[0]].Previous
	For $i = 0 To $iLen - 1 Step 1
		If $aIterator[0] <> 0 Then
			$mCurrent = $mList[$aIterator[0]]
			MapRemove($mList, $aIterator[0])
			$mList.Size -= 1
		EndIf
		$aIterator[0] = $mCurrent.Next
	Next
	Local $iEndIndex = $aIterator[0]
	If $iEndIndex <> 0 Then
		Local $mEnd = $mList[$iEndIndex]
		$mEnd.Previous = $iStartIndex
		$mList[$iEndIndex] = $mEnd
	EndIf
	If $iStartIndex <> 0 Then
		Local $mStart = $mList[$iStartIndex]
		$mStart.Next = $iEndIndex
		$mList[$iStartIndex] = $mStart
	EndIf
	If $iStartIndex = 0 Then $mList.Front = $iEndIndex
	If $iEndIndex = 0 Then $mList.Back = $iStartIndex
	$aIterator[0] = $iStartIndex
	Return $iStartIndex
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Inserts a value at iterator position.
; Parameters ....: $aIterator: - This is what you get from _ListIterator, use it here.
;                              - Also accepts integers (interpreted as index), the function will be in O(n/2) then.
;                  $iWhere:    $LIST_BEFORE (0) or $LIST_AFTER (1) defines if the new element will be inserted BEFORE the
;                              current element, or AFTER the current element.
; Author ........: Mars
; ===============================================================================================================================
Func _ListInsert(ByRef $mList, $aIterator, $xValue, $iWhere = $LIST_AFTER)
	If Not IsArray($aIterator) Then
		If $aIterator <= -1 Then Return _ListPushFront($mList, $xValue)
		If $aIterator >= $mList.Size Then Return _ListPushBack($mList, $xValue)
		$aIterator = __ListIterator($mList, $aIterator)
	EndIf
	If IsList($xValue) Then Return __ListInsertList($mList, $aIterator, $xValue, $iWhere)
	Local $mCurrent = $mList[$aIterator[0]] ; existiert immer
	Local $iNewIndex = __ListGetEmptyIndex($mList), $mNew[]
	$mNew.Value = $xValue
	If $iWhere = $LIST_BEFORE Then
		Local $iPreviousIndex = $mCurrent.Previous ; existiert vielleicht
		$mNew.Previous = $iPreviousIndex
		If $iPreviousIndex <> 0 Then
			Local $mPrevious = $mList[$iPreviousIndex]
			$mNew.Next = $mPrevious.Next
			$mPrevious.Next = $iNewIndex
			$mList[$iPreviousIndex] = $mPrevious
		Else
			$mNew.Next = $mList.Front
			$mList.Front = $iNewIndex
		EndIf
		$mCurrent.Previous = $iNewIndex
	Else
		Local $iNextIndex = $mCurrent.Next ; existiert vielleicht
		$mNew.Next = $iNextIndex
		If $iNextIndex <> 0 Then
			Local $mNext = $mList[$iNextIndex]
			$mNew.Previous = $mNext.Previous
			$mNext.Previous = $iNewIndex
			$mList[$iNextIndex] = $mNext
		Else
			$mNew.Previous = $mList.Back
			$mList.Back = $iNewIndex
		EndIf
		$mCurrent.Next = $iNewIndex
	EndIf
	$mList[$aIterator[0]] = $mCurrent
	$mList[$iNewIndex] = $mNew
	$mList.Size += 1
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...:
; Parameters ....: $aIterator: - This is what you get from _ListIterator, use it here.
;                              - Also accepts integers (interpreted as index), the function will be in O(n/2) then.
; Author ........: Mars
; ===============================================================================================================================
Func _ListRead(ByRef $mList, $aIterator)
	If Not IsArray($aIterator) Then $aIterator = __ListIterator($mList, $aIterator)
	If $aIterator[0] = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListRead: Iterator is invalid.'))
	Return $mList[$aIterator[0]].Value
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...:
; Parameters ....: $aIterator: - This is what you get from _ListIterator, use it here.
;                              - Also accepts integers (interpreted as index), the function will be in O(n/2) then.
; Author ........: Mars
; ===============================================================================================================================
Func _ListWrite(ByRef $mList, $aIterator, $xValue)
	If Not IsArray($aIterator) Then $aIterator = __ListIterator($mList, $aIterator)
	If $aIterator[0] = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListWrite: Iterator is invalid.'))
	$mList[$aIterator[0]].Value = $xValue
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: It is just an _ListToArray + _ArrayDisplay. Why reinvent the wheel.
;                  $iDirection: $LIST_FORWARD  (0) -> Iterator runs forwards
;                               $LIST_BACKWARD (1) -> Iterator runs backwards
; Author ........: Mars
; ===============================================================================================================================
Func _ListDisplay(ByRef $mList, $iDirection = $LIST_FORWARD)
	Local $aList = _ListToArray($mList, $iDirection)
	_ArrayDisplay($aList)
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Returns the last value of the list and removes this value from the list.
; Author ........: Mars
; ===============================================================================================================================
Func _ListPopBack(ByRef $mList)
	Local $iCurrentIndex = $mList.Back
	If $iCurrentIndex = 0 Then Return SetError(1, 0, 0*ConsoleWrite('error: List.au3: _ListPopBack: List is empty.'))
	Local $mCurrent = $mList[$iCurrentIndex]
	Local $iPreviousIndex = $mCurrent.Previous
	If $iPreviousIndex <> 0 Then
		Local $mPrevious = $mList[$iPreviousIndex]
		$mPrevious.Next = 0
		$mList[$iPreviousIndex] = $mPrevious
	EndIf
	$mList.Back = $iPreviousIndex
	$mList.Size -= 1
	If $mList.Size = 0 Then $mList.Front = 0
	MapRemove($mList, $iCurrentIndex)
	Return $mCurrent.Value
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Returns the first value of the list and removes this value from the list.
; Author ........: Mars
; ===============================================================================================================================
Func _ListPopFront(ByRef $mList)
	Local $iCurrentIndex = $mList.Front
	If $iCurrentIndex = 0 Then Return SetError(1, 0, 0*ConsoleWrite('error: List.au3: _ListPopFront: List is empty.'))
	Local $mCurrent = $mList[$iCurrentIndex]
	Local $iNextIndex = $mCurrent.Next
	If $iNextIndex <> 0 Then
		Local $mNext = $mList[$iNextIndex]
		$mNext.Previous = 0
		$mList[$iNextIndex] = $mNext
	EndIf
	$mList.Front = $iNextIndex
	$mList.Size -= 1
	If $mList.Size = 0 Then $mList.Back = 0
	MapRemove($mList, $iCurrentIndex)
	Return $mCurrent.Value
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Appends a value to the back of the list
; Author ........: Mars
; ===============================================================================================================================
Func _ListPushBack(ByRef $mList, $xValue)
	If IsList($xValue) Then Return __ListPushBackList($mList, $xValue)
	Local $iCurrentIndex = __ListGetEmptyIndex($mList), $mCurrent[]
	$mCurrent.Value = $xValue
	$mCurrent.Previous = 0
	$mCurrent.Next = 0
	If $mList.Front = 0 Then $mList.Front = $iCurrentIndex
	If $mList.Back = 0 Then
		$mList.Back = $iCurrentIndex
	Else
		Local $iPreviousIndex = $mList.Back
		Local $mPrevious = $mList[$iPreviousIndex]
		$mPrevious.Next = $iCurrentIndex
		$mCurrent.Previous = $iPreviousIndex
		$mList.Back = $iCurrentIndex
		$mList[$iPreviousIndex] = $mPrevious
	EndIf
	$mList[$iCurrentIndex] = $mCurrent
	$mList.Size += 1
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Appends a value to the front of the list
; Author ........: Mars
; ===============================================================================================================================
Func _ListPushFront(ByRef $mList, $xValue)
	If IsList($xValue) Then Return __ListPushFrontList($mList, $xValue)
	Local $iCurrentIndex = __ListGetEmptyIndex($mList), $mCurrent[]
	$mCurrent.Value = $xValue
	$mCurrent.Previous = 0
	$mCurrent.Next = 0
	If $mList.Back = 0 Then $mList.Back = $iCurrentIndex
	If $mList.Front = 0 Then
		$mList.Front = $iCurrentIndex
	Else
		Local $iNextIndex = $mList.Front
		Local $mNext = $mList[$iNextIndex]
		$mNext.Previous = $iCurrentIndex
		$mCurrent.Next = $iNextIndex
		$mList.Front = $iCurrentIndex
		$mList[$iNextIndex] = $mNext
	EndIf
	$mList[$iCurrentIndex] = $mCurrent
	$mList.Size += 1
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Returns an array containing the elements of the list (the elements are copied).
;                  $iDirection: $LIST_FORWARD  (0) -> Iterator runs forwards
;                               $LIST_BACKWARD (1) -> Iterator runs backwards
; Author ........: Mars
; ===============================================================================================================================
Func _ListToArray(ByRef $mList, $iDirection = $LIST_FORWARD)
	Local $aKeys = MapKeys($mList), $xCurrent, $aRet[UBound($aKeys) - $LIST_EMPTYSIZE], $i = 0
	Local $iIterator = $iDirection = $LIST_FORWARD ? $mList.Front : $mList.Back
	If $iDirection = $LIST_FORWARD Then
		For $i = 0 To $mList.Size - 1 Step 1
			$aRet[$i] = $mList[$iIterator].Value
			$iIterator = $mList[$iIterator].Next
		Next
	Else
		For $i = 0 To $mList.Size - 1 Step 1
			$aRet[$i] = $mList[$iIterator].Value
			$iIterator = $mList[$iIterator].Previous
		Next
	EndIf
	Return $aRet
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Creates a list that contains everything from a 1D Array
; Remakrs........: This can be done 3x faster, but this version is easy and it works. Complexity is linear either way.
; Author ........: Mars
; ===============================================================================================================================
Func _ListFromArray(ByRef $aArray)
	Local $mList = _ListCreate()
	For $i = 0 To UBound($aArray) - 1 Step 1
		_ListPushBack($mList, $aArray[$i])
	Next
	Return $mList
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Advances the iterator to the next element.
; Parameters ....: $aIterator: This is what you get from _ListIterator, use it here.
; Author ........: Mars
; ===============================================================================================================================
Func _ListNext(ByRef $mList, ByRef $aIterator)
	If $aIterator[0] = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListNext: Iterator is invalid.'))
	$aIterator[0] = $aIterator[1] ? $mList[$aIterator[0]].Previous : $mList[$aIterator[0]].Next
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Advances the iterator to the previous element.
; Parameters ....: $aIterator: This is what you get from _ListIterator, use it here.
; Author ........: Mars
; ===============================================================================================================================
Func _ListPrevious(ByRef $mList, ByRef $aIterator)
	If $aIterator[0] = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListNext: Iterator is invalid.'))
	$aIterator[0] = $aIterator[1] ? $mList[$aIterator[0]].Next : $mList[$aIterator[0]].Previous
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Gets an Iterator
; Parameters ....: $xStart:     $LIST_FRONT (0)                       -> Iterator starts at List.Front
;                               $LIST_BACK (1)                        -> Iterator starts at List.Back
;                               Int32 (between 0x100000 and 0xFFFFFF) -> Iterator starts at List[Int32]
;                  $iDirection: $LIST_FORWARD (0)                     -> Iterator runs forwards
;                               $LIST_BACKWARD (1)                    -> Iterator runs backwards
; Return ........: Array[2] = [Int32: Current Iterator Position, Int32: Current Direction]
; Author ........: Mars
; ===============================================================================================================================
Func _ListIterator(ByRef $mList, $xStart = $LIST_FRONT, $iDirection = $LIST_FORWARD)
	Local $aIterator = [$xStart = $LIST_FRONT ? $mList.Front : $xStart = $LIST_BACK ? $mList.Back : $xStart, $iDirection]
	Return $aIterator
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Returns the first value of the list
; Author ........: Mars
; ===============================================================================================================================
Func _ListFront(ByRef $mList)
	If $mList.Size = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListFront: List is empty.'))
	Return $mList[$mList.Front].Value
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Returns the last value of the list
; Author ........: Mars
; ===============================================================================================================================
Func _ListBack(ByRef $mList)
	If $mList.Size = 0 Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: _ListFront: List is empty.'))
	Return $mList[$mList.Back].Value
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Creates a new doubly linked list (map implementation)
; Author ........: Mars
; ===============================================================================================================================
Func _ListCreate()
	Local $mList[]
	$mList.Front = 0
	$mList.Back = 0
	$mList.Size = 0
	$mList[$LIST_IDENTIFIER] = 1 ; Identifier. Maps with this Key will be treated as lists.
	Return $mList
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Analogue to IsArray, IsMap etc.
; Author ........: Mars
; ===============================================================================================================================
Func IsList(ByRef $x)
	Return IsMap($x) And $x[$LIST_IDENTIFIER]
EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Description ...: Returns a random number that is not currently used as key for a list
; Remarks .......: If the list is really full (around 15 Mio elements), this method is not suitable anymore.
; Author ........: Mars
; ===============================================================================================================================
Func __ListGetEmptyIndex(ByRef $mList)
	Local $iRandom = Random(0x100000, 0xFFFFFF, 1)
	If MapExists($mList, $iRandom) Then Return __ListGetEmptyIndex($mList)
	Return $iRandom
EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Description ...: Debugversion of _ListDisplay, Shows everything and not only values.
; Author ........: Mars
; ===============================================================================================================================
Func __ListDisplay(ByRef $mList)
	Local $aKeys = MapKeys($mList), $xCurrent, $aRet[UBound($aKeys)][2]
	For $i = 0 To UBound($aKeys) - 1 Step 1
		$aRet[$i][0] = $aKeys[$i]
		$xCurrent = $mList[$aKeys[$i]]
		$aRet[$i][1] = IsMap($xCurrent) ? ('[' & $xCurrent.Value & ', ' & $xCurrent.Previous & ', ' & $xCurrent.Next & ']') : $xCurrent
	Next
	_ArrayDisplay($aRet)
EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Description ...: Get an iterator for the List at some position.
; Author ........: Mars
; ===============================================================================================================================
Func __ListIterator(ByRef $mList, $iIndex)
	If $mList.Size <= $iIndex Then Return SetError(1, 0, 0 * ConsoleWrite('error: List.au3: __ListIterator: Index[' & $iIndex & '] is not inside the list.'))
	Local $iIterator = $mList.Front
	If $iIndex >= Abs($mList.Size - $iIndex) Then
		$iIterator = $mList.Back
		For $i = 0 To Abs($mList.Size - $iIndex) - 2 Step 1
			$iIterator = $mList[$iIterator].Previous
		Next
	Else
		For $i = 0 To $iIndex - 1 Step 1
			$iIterator = $mList[$iIterator].Next
		Next
	EndIf
	Local $aIterator = [$iIterator, $LIST_FORWARD]
	Return $aIterator
EndFunc

Func __ListPushBackList(ByRef $mList, ByRef $mOther)
	; not implemented
EndFunc

Func __ListPushFrontList(ByRef $mList, ByRef $mOther)
	; not implemented
EndFunc

Func __ListInsertList(ByRef $mList, ByRef $aIterator, ByRef $mOther, ByRef $bAfter)
	; not implemented
EndFunc