[Runtime tests] Added test for https://github.com/X-Sharp/XSharpPublic/issues/699 (scope problem)

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit
USING System.Globalization

DEFINE GLOBAL_FLD := 123
GLOBAL DEFINE_FLD := "abc"

BEGIN NAMESPACE XSharp.VO.Tests

	CLASS DbfCdxTests

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBCreate_Tests() AS VOID
			LOCAL aFields AS ARRAY
			aFields := {{"TEST","C",10,0}}

			LOCAL cFileName_WithExt AS STRING
			LOCAL cFileName_NoExt AS STRING
			cFileName_NoExt := "DBCreate_Tests"
			cFileName_WithExt := cFileName_NoExt + ".dbf"
			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_NoExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )

			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_WithExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )

			cFileName_WithExt := cFileName_NoExt + ".none"
			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_WithExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_Exclusive() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cFileName AS STRING
			aFields := {{"TEST","C",10,0}}
			cFileName := "DBAppend_Exclusive"

			Assert.True(  DbCreate(cFileName , aFields , "DBFCDX")  )
			Assert.True(  DbUseArea(,"DBFCDX",cFileName,,FALSE) )
			Assert.True(  RecCount() == 0 )
			Assert.True(  DbAppend() )
			FieldPut(1 , "test")
			Assert.True(  AllTrim(FieldGet(1)) == "test" )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_Shared() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cFileName AS STRING
			aFields := {{"TEST","C",10,0}}
			cFileName := "DBAppend_Shared"

			Assert.True(  DbCreate(cFileName , aFields , "DBFCDX")  )
			Assert.True(  DbUseArea(,"DBFCDX",cFileName,,TRUE) )
			Assert.True(  RecCount() == 0 )
			Assert.True(  DbAppend() )
			FieldPut(1 , "test")
			Assert.True(  AllTrim(FieldGet(1)) == "test" )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_more() AS VOID
		LOCAL cDbf AS STRING
			cDbf := "testappend.DbF"
			RddSetDefault( "DBFCDX" )
			Assert.True(  DbCreate(cDbf , { {"TEST","C",10,0} }) )
			// Appending in exclusive mode:
			Assert.True( DbUseArea(, , cDbf , "alias1" , FALSE) )
			Assert.True( DbAppend() )
			Assert.True( RecCount() == 1 )
			FieldPut(1, "test") // ok
			Assert.True( AllTrim(FieldGet(1)) == "test" )
			Assert.True( DbCloseArea() )

			// Appending in SHARED mode:
			Assert.True( DbUseArea(, , cDbf , "alias2" , TRUE) )
			Assert.True( RecCount() == 1 )
			Assert.True( DbAppend() )// returns true but does not append record
			Assert.True( RecCount() == 2 )
			FieldPut(1, "test2") // ok
			Assert.True( AllTrim(FieldGet(1)) == "test2" )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBUseArea_same_file_twice() AS VOID
		LOCAL cDbf AS STRING
			RddSetDefault( "DBFCDX" )
			cDbf := "testtwice.DbF"
			Assert.True(  DbCreate(cDbf , { {"TEST","C",10,0} }) )

			// shared mode
			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD VODBInfoTest() AS VOID

			LOCAL cFileName AS STRING
			cFileName := GetTempFileName("test")
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName , { {"CFIELD","C",10,0} })
			DbUseArea(,,cFileName)
			DbAppend()
			Assert.Equal(1, (LONG) RecNo())
			LOCAL u := NIL AS USUAL
			VoDbSkip(-1)

			VoDbInfo(DBI_FULLPATH , REF u)
			LOCAL c AS STRING
			c := u
			? c
			Assert.True(c:EndsWith("test.DBF") .AND. c:Contains(":\"))
			VoDbInfo(DBI_DB_VERSION , REF u)
			Assert.True(SLen(u) > 1)
			VoDbInfo(DBI_ALIAS , REF u)
			Assert.Equal("TEST" , u)

			VoDbInfo(DBI_BOF , REF u)
			Assert.Equal(TRUE , (LOGIC) u)
			VoDbInfo(DBI_EOF , REF u)
			Assert.Equal(FALSE ,(LOGIC)  u)
			VoDbInfo(DBI_ISANSI , REF u)
			Assert.Equal(SetAnsi() ,(LOGIC)  u)
			VoDbInfo(DBI_FCOUNT , REF u)
			Assert.Equal(1, (LONG)  u)
			VoDbInfo(DBI_READONLY , REF u)
			Assert.Equal(FALSE,(LOGIC)  u)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD AppendShared() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName("testAppendShared")
			FErase(cDbf + ".cdx")

			RddSetDefault( "DBFCDX" )
			DbCreate(cDbf , { {"TEST","C",10,0} })

//			Appending in exclusive mode:
			DbUseArea(, , cDbf , "alias2" , FALSE)
			Assert.True( DbAppend() )
			Assert.Equal( 1 , RecCount() )
			FieldPut(1, "test") // ok
			DbCloseArea()

//			Appending in SHARED mode:
			DbUseArea(, , cDbf , "alias2" , TRUE)
			Assert.True( DbAppend() ) // returns true but does not append record
			Assert.Equal( 2 , RecCount() ) // returns 1, wrong
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD AliasNameReuse() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName("testdbf")
			FErase(cDbf + ".cdx")

			RddSetDefault( "DBFCDX" )

			DbCreate(cDbf , { {"TEST","C",10,0} })

//			opening and closing once
			DbUseArea(, , cDbf , , FALSE)
			DbCloseArea()

//			opening and closing again
			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SavingDecimalValues() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,2},{"FLD2","N",10,0}})
			DbUseArea(,,cFileName)
			DbAppend()

			SetDecimalSep(Asc(","))
			FieldPut(1 , 12.34) // not saved in the dbf
			Assert.Equal(12.34 , (FLOAT) FieldGet(1)) // 0,00

			SetDecimalSep(Asc("."))
			FieldPut(1 , 12.34)
			Assert.Equal(12.34 , (FLOAT) FieldGet(1))

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBCommitAfterFieldput() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,4}})
			DbUseArea( , , cFileName , "tempalias")
			DbAppend()
			DbCloseArea()

			DbUseArea( , , cFileName)
			FieldPut(1 , FLOAT{46.11}) // ! a float isn/t stored !
			DbCommit()
			Assert.Equal(46.11 , (FLOAT) FieldGet(1)) // runtime exception
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD FieldNameSym() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,4}})
			DbUseArea( , , cFileName , "tempalias")
			DbAppend()
			Assert.Equal("", FieldName(100)) // exception
			Assert.Equal("", FieldName(0))
			Assert.Equal(NULL_SYMBOL, FieldSym(100))
			Assert.Equal(NULL_SYMBOL, FieldSym(0))
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRLockListTest() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0}})
			DbUseArea( , , cFileName , "tempalias" , TRUE)
			DbAppend()
			DbAppend()
			DbGoTop()
			DbRLock()
			DbRLockList()
			Assert.Equal(1, (INT) ALen(DbRLockList()))
			Assert.Equal(1, (INT) DbRLockList()[1])
			DbUnLock()
			DbSkip()
			DbRLock()
			Assert.Equal(1, (INT)  ALen(DbRLockList()))
			Assert.Equal(2, (INT) DbRLockList()[1])
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBFilter() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			IF System.IO.File.Exists(cDbf)
				System.IO.File.Delete(cDbf)
			END IF
			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")
			DbAppend()
			FieldPut(1, "DEF")
			DbAppend()
			FieldPut(1, "GHI")
			DbAppend()
			FieldPut(1, "JKL")
			Assert.Equal(4 , (INT) RecCount())
			Assert.Equal(4 , (INT) LastRec())
			DbCloseArea()

			DbUseArea(,,cDbf)
//			"Setting filter to GHI, should be one record:"
//			"Instead, record 1 and 3 are shown"
			DbSetFilter({||AllTrim(FIELD->CFIELD) == "GHI"})
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				Assert.Equal(3 , (INT) RecNo())
				FieldGet(1)
				DbSkip(+1)
				nCount ++
			END DO
			Assert.Equal(1 , nCount)

			DbGoBottom()
			Assert.False( Eof() )
			nCount := 0
			DO WHILE .NOT. EoF()
				Assert.Equal(3 , (INT) RecNo())
				nCount ++
				FieldGet(1)
				DbSkip(+1)
			END DO
			Assert.Equal(1 , nCount)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRecordInfo_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL l AS LOGIC
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")

			l := DbRecordInfo( DBRI_RECNO ) // exception
			Assert.True(l)
			l := DbRecordInfo( DBRI_DELETED ) // exception
			Assert.False(l)
			l := DbRecordInfo( DBRI_LOCKED ) // exception
			Assert.True(l)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBFieldInfo_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"NFIELD","N",10,3}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, 1.23)

			Assert.Equal("NFIELD",	DbFieldInfo( DBS_NAME , 1 ) ) // NullReferenceException
			Assert.Equal("N",		DbFieldInfo( DBS_TYPE , 1 ) )
			Assert.Equal(10,		(INT) DbFieldInfo( DBS_LEN , 1 ) )
			Assert.Equal(3,			(INT) DbFieldInfo( DBS_DEC , 1 ) )
			Assert.Equal(5,			(INT) DbFieldInfo( DBS_PROPERTIES , 1 ) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRecordInfo_test2() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")
			DbAppend()
			FieldPut(1, "DEF")

			DbGoTop()
			Assert.Equal(1, (INT) RecNo())
			Assert.Equal(FALSE, Eof())

//			 Any of the below cause the record pointer to go EOF
			Assert.False( DbRecordInfo(DBRI_DELETED , 0) )
			DbRecordInfo(DBRI_BUFFPTR , 0)
			DbRecordInfo(DBRI_RAWDATA , 0)

			Assert.Equal(1, (INT) RecNo())
			Assert.Equal(FALSE, Eof())

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBContinue_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cDbf, {{"NFIELD","N",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, 123)
			DbAppend()
			FieldPut(1, 456)
			DbAppend()
			FieldPut(1, 789)

			DbGoTop()
			Assert.True( DbLocate({||_FIELD->NFIELD > 300} , , , , TRUE) ) // DBSCOPEREST
			Assert.True( Found() )
			Assert.Equal(456.0 , (FLOAT)  FieldGet(1) )

//			DBContinue() returns TRUE (correct) but does not move record pointer at all
			Assert.True( DbContinue() )
			Assert.True( Found() )
			Assert.Equal( 789.0 , (FLOAT)  FieldGet(1) )

			Assert.True( DbContinue() )
			Assert.False( Found() )
			Assert.Equal( 0.0 , (FLOAT) FieldGet(1) )

			Assert.True( DbContinue() )
			Assert.False( Found() )
			Assert.Equal( 0.0 , (FLOAT) FieldGet(1) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBAppendWithNoWorkarea() AS VOID
			RddSetDefault("DBFCDX")

			DbCloseAll()
			Assert.False( DbAppend() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Shared_Cdx() AS VOID
			SELF:Shared_Cdx_helper(TRUE)
			SELF:Shared_Cdx_helper(FALSE)
		RETURN
		PRIVATE METHOD Shared_Cdx_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
            RddSetDefault("DBFCDX")
			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
            FErase(cCdx)

			Assert.True( DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }}) )
			Assert.True( DbUseArea(,,cDbf,,FALSE) )
			Assert.True( DbAppend() )
			FieldPut ( 1 , "B")
			Assert.True( DbAppend() )
			FieldPut ( 1 , "A")
			Assert.True( DbCloseArea() )

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////94B//8AAA8PEAQEAwAGMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABURVNUQ0RYAAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBDRklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////+AB//8AAA8PEAQEAwIAkAEAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJB"))
			ELSE
				Assert.True( DbUseArea(,,cDbf,,TRUE) ) // ----- opening in SHARED mode
				Assert.True( DbCreateIndex(cCdx , "CFIELD") ) // returns TRUE
				Assert.True( DbCloseArea() )
			END IF

			Assert.True( DbUseArea(,,cDbf,,FALSE) )
			Assert.True( DbSetIndex(cCdx) )
			DbGoTop()
			Assert.True( AllTrim(FieldGet(1)) == "A" )
			DbGoBottom()
			Assert.True( AllTrim(FieldGet(1)) == "B" )
			Assert.True( DbCloseArea() ) // XSharp.RDD.RddError here

            Assert.True( FErase(cDbf + ".dbf") )
            Assert.True( FErase(cCdx) ) // false if still in use

		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Save_NULL_DATE() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			Assert.True(  DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 },;
			{"DFIELD" , "D" , 8 , 0 }}) )
			Assert.True( DbUseArea(,,cDbf) )
			DbAppend()
			FieldPut ( 1 , "B")
			DbAppend()
			FieldPut ( 1 , "A")
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(,,cDbf) )
			LOCAL u AS USUAL
			u := FieldGet(2) // it should be a NULL_DATE
			Assert.True( u == NULL_DATE )
			FieldPut(2,u) // exception
			FieldPut(2,NULL_DATE) // exception
			Assert.True( FieldGet(2) == NULL_DATE )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Issues() AS VOID
			SELF:Cdx_Issues_Helper(TRUE)
			SELF:Cdx_Issues_Helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Issues_Helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			LOCAL aResult AS ARRAY

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName("testcdx1"+IIF(lUseIndexFormVO, "V","X"))
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }} , "DBFCDX")
			DbUseArea(,,cDbf)
			DbAppend()
			FieldPut ( 1 , "ABC")
			DbAppend()
			FieldPut ( 1 , "GHI")
			DbAppend()
			FieldPut ( 1 , "DEF")
			DbAppend()
			FieldPut ( 1 , "K")
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgxAAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBDRklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9IB//8AAA8PEAQEAwEAcAMAcAIAcAQAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLR0hJREVGQUJD"))
			ELSE
				Assert.True( DbUseArea(,,cDbf) )
				Assert.True( DbCreateIndex(cCdx , "CFIELD") )
				Assert.True( DbCloseArea() )
			END IF

			Assert.True( DbUseArea(,,cDbf,,FALSE) )
//			Assert.True( DBSetIndex(cCdx) )
			Assert.True( DbSetOrder(1) )

			aResult := GetRecords()
//			should be ABC, DEF, GHI, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "DEF")
			Assert.True( aResult[3] == "GHI")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip()
			FieldPut(1,"HHH")
			aResult := GetRecords()
//			should be ABC, GHI, HHH, K, because the record has been moved in the index
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "GHI")
			Assert.True( aResult[3] == "HHH")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip(2)
			FieldPut(1,"DEF") // restore it

			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(,,cDbf,,TRUE) )
			Assert.True( DbSetIndex(cCdx) )
			aResult := GetRecords()
//			should be ABC, DEF, GHI, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "DEF")
			Assert.True( aResult[3] == "GHI")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip()
			Assert.True(RLock())
			FieldPut(1,"III")
			aResult := GetRecords()
//			should be ABC, GHI, III, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "GHI")
			Assert.True( aResult[3] == "III")
			Assert.True( aResult[4] == "K")

			Assert.True( DbCloseArea() )
		RETURN

		PRIVATE STATIC METHOD GetRecords() AS ARRAY
			LOCAL aResult AS ARRAY
			aResult := {}
			DbGoTop()
			DO WHILE .NOT. Eof()
				AAdd(aResult , AllTrim(FieldGet(1)))
				DbSkip()
			END DO
		RETURN aResult

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Issues2() AS VOID
			SELF:Cdx_Issues2_helper(TRUE)
			SELF:Cdx_Issues2_helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Issues2_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cFileName AS STRING
			LOCAL cCdx AS STRING
			cFileName := GetTempFileName("testcdx")
			cCdx := cFileName + ".cdx"
			FErase(cCdx)

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0},{"FLD2","N",10,0}})
			DbUseArea( , , cFileName , , FALSE)
			FOR LOCAL n := 1 AS INT UPTO 10
				DbAppend()
				FieldPut(1, n:ToString())
				FieldPut(2, n)
			NEXT
			IF lUseIndexFormVO
				Assert.True( DbCloseArea() )
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgyAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQABAAAABQBGTEQyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMACgD//////////78B//8AAA8PEAQEAwEAYAIAcAMAYQQAYQUAYQYAYQcAYQgAYQkAYQoAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQiIBwYFBAIwL/w"))
			ELSE
				Assert.True( DbCreateIndex(cCdx , "FLD2") )
				Assert.True( DbCloseArea() )
			END IF

			DbUseArea( , , cFileName , , FALSE)
//			Assert.True( DBSetIndex(cCdx) )
			Assert.True( DbSetOrder(1) )
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
				nCount ++
				Assert.True( FieldGet(2) == RecNo() )
				Assert.True( FieldGet(2) == nCount )
				Assert.True( DbSkip() )
			END DO
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD WorkareaNums() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			Assert.True( DbCreate(cFileName, {{"FLD1","C",10,0}}) )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a1") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a2") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a3") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )
		RETURN

		// FOX-ES1QLR6Y5L , dbRecordInfo ( DBRI_LOCKED ) always returns .f.
		[Fact, Trait("Category", "DBF")];
		METHOD DBRI_LOCKED_test() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")
            TRY
			SetExclusive ( FALSE )
			DbCreate ( cFileName , { {"id", "C", 5, 0} })

			DbUseArea ( , , cFileName )
			DbAppend()
			DbAppend()
			DbAppend()
			DbGoTop()

			Assert.True( DbRLock ( RecNo() ) )
			Assert.True( DbRecordInfo ( DBRI_LOCKED ) ) // Should show TRUE
			Assert.True( AScan ( DbRLockList() , RecNo() ) > 0 )

			DbSkip()
//			record 2 - no lock
			Assert.False( DbRecordInfo ( DBRI_LOCKED ) )
			Assert.False( AScan ( DbRLockList() , RecNo() ) > 0 )

			DbSkip()
			Assert.True( DbRLock ( RecNo() ) )
			Assert.True( DbRecordInfo ( DBRI_LOCKED ) ) // Should show TRUE
			Assert.True( AScan ( DbRLockList() , RecNo() ) > 0 )

			LOCAL a AS ARRAY
			a:= DbRLockList()
			Assert.Equal( 2 , (INT) ALen(a) )
			Assert.Equal( 1 , (INT) a[1] )
			Assert.Equal( 3 , (INT) a[2] )

            FINALLY
			DbCloseArea()

			SetExclusive ( TRUE ) // restore
            END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Alias_test() AS VOID

			RddSetDefault("DBFCDX")

			DbCloseAll()
			Assert.True( Alias() == "" )
			Assert.True( Alias0() == "" )
			Assert.True( Alias0Sym() == "" )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBCreate_test() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0}})
			DbUseArea(,,cFileName,,FALSE)
			DbCloseArea()

//			exception here
			Assert.True( DbCreate(cFileName, {{"FLD1","N",10,0}}) )

			Assert.True( DbUseArea(,,cFileName) )
			DbAppend()
			FieldPut(1 , 123)
			Assert.True( FieldGet(1) == 123 )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBError_test() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }})
			DbUseArea(,,cDbf,,TRUE)
			Assert.True( DbAppend() )
			Assert.True( DbUnLock() )
			TRY
				? FieldPut ( 1 , "ABC") // record not locked
			CATCH e AS XSharp.Error
				? e:Message
				? e:GenCodeText
				? e:SubCodeText // check if this displays correctly
				? e:OSCodeText
				? e:ToString() // exception here
			FINALLY
				Assert.True( DbCloseArea() )
			END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Eof_test() AS VOID
			SELF:Cdx_Eof_test_helper(TRUE)
			SELF:Cdx_Eof_test_helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Eof_test_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,123)
			DbAppend()
			FieldPut(1,456)
			IF lUseIndexFormVO
				DbCloseArea()
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgzAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBORklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////90B//8AAA8PEAQEAwEAUAIAUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHyAwF7A"))
			ELSE
				DbCreateIndex(cCdx, "NFIELD")
				DbCloseArea()
			END IF

			// necessary sequence to reproduce the problem below
			DbUseArea(,,cDbf,,FALSE)
//			DBSetIndex(cCdx)
			DbSetOrder(1)
			DbGoTop()
			Assert.Equal(1, (INT)RecNo()) // 1
			DbGoBottom()
			Assert.Equal(2, (INT)RecNo()) // 2
			DbSkip(-1)
			Assert.Equal(1, (INT)RecNo()) // 1
			DbGoto(2)
			Assert.Equal(2, (INT)RecNo()) // 2

			DbSkip(+1)
			Assert.Equal(TRUE, (LOGIC)Eof()) // FALSE, wrong
			Assert.Equal(3, (INT)RecNo()) // 2, wrong

			DbSkip(+1)
			Assert.Equal(TRUE, (LOGIC)Eof()) // TRUE
			Assert.Equal(3, (INT)RecNo()) // 3

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_SETCODEBLOCK() AS VOID
			LOCAL cDBF, cCDX AS STRING

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("test")
			cCDX := cDBF + ".cdx"
			FErase(cCdx)

			DbCreate( cDBF , {{"ID" , "C" , 5 , 0 }})
			DbUseArea(,,cDBF)

			DbAppend()
			FieldPut(1, "one")

			DbCreateIndex(cCDX , "Upper (ID)")
			DbCloseArea()

			DbUseArea(,,cDBF)
			DbSetIndex(cCDX)

			? "DBOI_SETCODEBLOCK" , DbOrderInfo( DBOI_SETCODEBLOCK )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_test() AS VOID
			SELF:OrdScope_test_helper(TRUE)
			SELF:OrdScope_test_helper(FALSE)
		RETURN
		PRIVATE METHOD OrdScope_test_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			RddSetDefault("DBFCDX")

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg0AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBORklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAFAD//////////5cB//8AAA8PEAQEAwEAYAIAcAMAYQQAYQUAYQYAYQcAYQgAYQkAYQoAYQsAYQwAYQ0AYQ4AYQ8AYRAAYREAYRIAYRMAYRQAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDMyMTAuLCooJiQiIBwYFBAIwL/w"))
			ELSE
				DbCreateIndex(cDbf , "NFIELD")
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDbf) // 20 records
//			DBSetIndex ( cDbf )
			DbSetOrder(1)
			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 20)
			Assert.Equal( (INT) OrdScope(TOPSCOPE, 5) , 0) // returns previous scope
			Assert.Equal( (INT) OrdScope(BOTTOMSCOPE, 10) , 0) // returns previous scope
			DbGoTop()

			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 6) // still 20 - but must be 6
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof() // all 20 records are listed
				? FieldGet ( 1 )
				DbSkip ( 1 )
				nCount ++
			ENDDO
			Assert.Equal( 6 , nCount)
			Assert.Equal( 5 , (INT) DbOrderInfo( DBOI_SCOPETOP ) ) // {(0x0000)0x00000000} CLASS
			Assert.Equal( 10 , (INT) DbOrderInfo( DBOI_SCOPEBOTTOM ) ) // {(0x0000)0x00000000} CLASS
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_test_with_Ordinal_Collation() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			LOCAL uCollation AS USUAL
			uCollation := SetCollation(#ORDINAL)

			DbCreate( cDbf, {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			DbCreateIndex(cDbf + ".cdx" , "NFIELD")
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDbf)
			DbSetIndex ( cDbf + ".cdx" )
			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 20)
			Assert.Equal( (INT) UsualType( DbOrderInfo( DBOI_KEYCOUNT )  ) , 1) // first time returns 6
			Assert.Equal( (INT) UsualType( DbOrderInfo( DBOI_KEYCOUNT )  ) , 1) // second time it returns 1 correctly
			DbCloseArea()

			SetCollation(uCollation)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_index_without_extension() AS VOID
			LOCAL cDbf AS STRING
			cDbf := "noextension"
			FErase(cDbf + ".cdx")
			FErase(cDbf)

			RddSetDefault("DBFCDX")

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			DbCreateIndex(cDbf , "NFIELD")
			Assert.True( File(cDbf + ".dbf" ) )
			Assert.True( File(cDbf + ".cdx" ) )
			Assert.False( File(cDbf) )
			DbCloseArea()

		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_test() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDBF, cCDX AS STRING

			RddSetDefault("DBFCDX")

			aValues := { "ssss" , "hhhh", "wwww" , "aaaa" }
			cDBF := GetTempFileName()
			cCDX := cDbf
			FErase(cCdx + ".cdx")
			DbCreate( cDBF , {{"LAST" , "C" , 20 , 0 } , ;
								{"TEXT1" , "C" , 10 , 0 } , ;
								{"NUM1" , "N" , 10 , 2 }})

			DbUseArea(,,cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbCreateIndex(cCDX, "Upper ( Last)")
			DbCloseArea()

			DbUseArea(,,cDBF,,TRUE) // open shared !
			DbSetIndex(cCDX)
			DbGoTop()
			? "current (indexed) order"
			DO WHILE ! Eof()
				? FieldGet ( 1 )
				DbSkip ( 1 )
			ENDDO
			DbGoTop()
			// "now replace the index field #LAST content 'aaaa' with 'pppp'"
			// "and also update another field"
			Assert.True( DbRLock ( RecNo() )  )
			// "Replacing", AllTrim(FieldGet(1)), "with 'pppp'"
			FieldPut ( 1 , "pppp" ) // Note: This is the index field

//	 this is what causes the problem, updating a second field
//	 if this fieldput is put above the first one, then sample works correctly
//	 either one of the fieldputs below cause the problem to surface
			FieldPut ( 2 , "Eins" )
			FieldPut ( 3 , 123.45 )

			DbCommit()

			DbRUnLock ( RecNo() )

			Assert.False( DbSeek( "AAAA" ) ) // must show .F.
			Assert.True( DbSeek ("PPPP" ) ) // must show .T.
			// "Record order now:"
			// "(should be hhhh, pppp, ssss , wwww)"
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
				? AllTrim(FieldGet(1)) , FieldGet(3) , AllTrim(FieldGet(2))
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.Equal( "hhhh", AllTrim(FieldGet(1)) )
				CASE nCount == 2
					Assert.Equal( "pppp", AllTrim(FieldGet(1)) )
				CASE nCount == 3
					Assert.Equal( "ssss", AllTrim(FieldGet(1)) )
				CASE nCount == 4
					Assert.Equal( "wwww", AllTrim(FieldGet(1)) )
				END CASE
				DbSkip ( 1 )
			ENDDO
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_KEYCOUNT() AS VOID
			SELF:DBOrderInfo_DBOI_KEYCOUNT_helper(TRUE)
			SELF:DBOrderInfo_DBOI_KEYCOUNT_helper(FALSE)
		RETURN
		PRIVATE METHOD DBOrderInfo_DBOI_KEYCOUNT_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			aValues := { 44 , 12, 34 , 21 }
			DbCreate( cDBF , {{"AGE" , "N" , 3 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			Assert.Equal(0 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 0,  ok
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 0,  ok

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg1AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAAAABABhZ2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAo"))
			ELSE
				DbCreateIndex(cDbf, "age" )
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbSetOrder(1)
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DbGoTop()
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DO WHILE ! Eof()
//			? FieldGet ( 1 )
				DbSkip(1)
			ENDDO
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // NIL, should be 4
			DbSkip(-1)
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DbCloseArea ()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_FALSE() AS VOID
			SELF:SetDeleted_FALSE_helper(TRUE)
			SELF:SetDeleted_FALSE_helper(FALSE)
		RETURN
		PRIVATE METHOD SetDeleted_FALSE_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")
			SetDeleted(FALSE)

//			test also with those
//			aValues := { "vaa" , "abba", "acb" , "aaab"  , "adab"  , "baac"  , "aeab"  , "baaAaa" }
			aValues := { "vvv" , "abb", "acb" , "aaa"  , "bbb" }
			DbCreate( cDBF , {{"LAST" , "C" ,10 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			IF lUseIndexFormVO
				DbCloseArea()
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg2AAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAABAAAADABVcHBlcihMQVNUKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABQD//////////8wB//8AAA8PEAQEAwQAcAIAcQMAcQUAcAEAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWVlZCQkJDQkJCQUFB"))
			ELSE
				DbCreateIndex(cDbf, "Upper(LAST)" )
				DbCloseArea()
			END IF

			DbUseArea(,"DBFCDX",cDBF,,TRUE)
			DbSetOrder(1)
			Assert.Equal(5 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			// ? "Setting scope"
			LOCAL u AS USUAL
			u := "A"
			VoDbOrderInfo( DBOI_SCOPETOP, "", NIL, REF u )
			u := "A"
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF u )

			DbGoTop()
			Assert.Equal(4 , (INT)RecNo())
			DbGoBottom()
			Assert.Equal(3 , (INT)RecNo())

			DbGoTop()

			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DO WHILE ! Eof()
				DbSkip(1)
			ENDDO
			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_TRUE() AS VOID
			SELF:SetDeleted_TRUE_helper(TRUE)
			SELF:SetDeleted_TRUE_helper(FALSE)
		RETURN
		PRIVATE METHOD SetDeleted_TRUE_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			SetDeleted(TRUE)

//			test also with those
//			aValues := { "vaa" , "abba", "acb" , "aaab"  , "adab"  , "baac"  , "aeab"  , "baaAaa" }
			aValues := { "vvv" , "abb", "acb" , "aaa"  , "bbb" }
			DbCreate( cDBF , {{"LAST" , "C" ,10 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg2AAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAABAAAADABVcHBlcihMQVNUKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABQD//////////8wB//8AAA8PEAQEAwQAcAIAcQMAcQUAcAEAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWVlZCQkJDQkJCQUFB"))
				DbUseArea(,"DBFCDX",cDBF,,TRUE)
			ELSE
				DbUseArea(,"DBFCDX",cDBF,,TRUE)
				DbCreateIndex(cDbf, "Upper(LAST)" )
			END IF

			DbSetOrder(1)
			Assert.Equal(5 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			// ? "Setting scope"
			LOCAL u AS USUAL
			u := "A"
			VoDbOrderInfo( DBOI_SCOPETOP, "", NIL,  REF u )
			u := "A"
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL,  REF u )

			DbGoTop()
			Assert.Equal(4 , (INT)RecNo())
			DbGoBottom()
			Assert.Equal(3 , (INT)RecNo())

			DbGoTop()

			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DO WHILE ! Eof()
				DbSkip(1)
			ENDDO
			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_NUMBER() AS VOID
			SELF:DBOrderInfo_DBOI_NUMBER_helper(TRUE)
			SELF:DBOrderInfo_DBOI_NUMBER_helper(FALSE)
		RETURN
		PRIVATE METHOD DBOrderInfo_DBOI_NUMBER_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDBF AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			aValues := { 44 , 12, 34 , 21 }
			cDBF := GetTempFileName("testcdx8")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)
			IF System.IO.File.Exists(cCdx)
				System.IO.file.Delete(cCdx)
			END IF
			DbCreate( cDBF , {{"AGE" , "N" , 3 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_KEYCOUNT ) )   //  0  ok
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_KEYCOUNT ) ) //  0 ,ok
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_NUMBER ) )  //  -1,  but should show 0

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg4AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAAAABABhZ2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAo"))
			ELSE
				DbCreateIndex( cCdx, "age" )
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbSetOrder(1)

			DbGoTop()
			DO WHILE ! Eof()
//				? FieldGet ( 1 )
				DbSkip(1)
			ENDDO

			Assert.True( DbClearIndex(, cCdx) )

			DbGoTop()
			Assert.Equal(1, (INT)RecNo())

			Assert.True( DbSetIndex ( cCdx ) )

			Assert.Equal(4, (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, ok
			Assert.Equal(1, (INT) DbOrderInfo( DBOI_NUMBER ) )  // still  -1 , but should show  1
			Assert.Equal("TESTCDX8", (STRING) DbOrderInfo( DBOI_NAME ) )  // ok , "TESTDBF"
			DbCloseArea ()
		RETURN

		[Fact, Trait("Category", "DBF")];
			METHOD DBSetOrderCondition_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")
			aValues := { 1,4,2,3 }
			DbCreate( cDBF , {{"NUM" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbGoTop()

			// DESCENDING = TRUE
			Assert.True( DbSetOrderCondition(,,,,,,,,,,TRUE) )
			Assert.True( DbCreateIndex(cDbf, "NUM" ) )

			DbGoTop()
			aValues := { 4,3,2,1 }
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				nCount ++
				Assert.Equal((INT)aValues[nCount] , (INT)FieldGet(1))
				DbSkip()
			END DO

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Fields_Named_After_Funcs() AS VOID
			LOCAL cDbf AS STRING
			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			DbCloseAll() // worakaroudn for previous test crashing

			DbCreate( cDBF , {{"LEFT" , "N" ,5 , 0 } , {"STR" , "C" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()
			FieldPut(1,1)
			FieldPut(2,"A")
			DbAppend()
			FieldPut(1,11)
			FieldPut(2,"B")
			DbGoTop()
			Assert.True( DbCreateIndex(cDbf, "STR" ) )
			Assert.True( DbSetFilter(&("{||LEFT<10}")) )
			DbGoTop()
			DbSkip()
			Assert.True( Eof() )
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Uninitialized_fields() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")
			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbAppend() // no field assigned
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF)
			Assert.True( DbCreateIndex(cDbf, "FIELDN" ) )
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_KEYTYPE() AS VOID
			LOCAL cDbf AS STRING
			DbCloseAll()

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testnewer")
			FErase(cDbf + ".cdx")
			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } , ;
			{"FIELDS" , "C" ,15 , 0 } , ;
			{"FIELDL" , "L" ,1 , 0 } , ;
			{"FIELDD" , "D" ,8 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF)
			DbCreateIndex(cDbf + ".cdx", "FIELDN" )
			Assert.Equal(3, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 14 (), should be 3 (FLOAT)
			DbCloseArea()
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDS" )
			Assert.Equal(7, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 18 (PTR), should be 7 (STRING)
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDD" )
			Assert.Equal(2, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 16, should be 2 (DATE)
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDL" )
			Assert.Equal(8, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 3 (FLOAT), should be 8

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetOrderCondition_with_FOR() AS VOID
			SELF:DBSetOrderCondition_with_FOR_helper(TRUE)
			SELF:DBSetOrderCondition_with_FOR_helper(FALSE)
		RETURN
		PRIVATE METHOD DBSetOrderCondition_with_FOR_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			DbCloseAll()

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx9")
			FErase(cDbf + ".cdx")

			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbAppend()
			FieldPut(1,4)
			DbAppend()
			FieldPut(1,2)
			DbAppend()
			FieldPut(1,3)
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg5AAoAAAAAAAAAAAAACABoAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABwAJAAAABwBGSUVMRE4ARklFTEROPjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////98B//8AAA8PEAQEAwQAYAIAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMAI"))
				DbUseArea(,"DBFCDX",cDBF)
			ELSE
				DbUseArea(,"DBFCDX",cDBF)
				DbSetOrderCondition( "FIELDN>2",{||_FIELD->FIELDN>2},,,,,,,,, TRUE)
				DbCreateIndex(cDbf, "FIELDN" )
			END IF

			// Should show only 4,3, but it shows all records 4,3,2,1
			Assert.True( DbSetOrder(1) )
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				nCount ++
				IF nCount == 1
					Assert.Equal(4 ,(INT)FieldGet(1))
				ELSEIF nCount == 1
					Assert.Equal(3 ,(INT)FieldGet(1))
				END IF
				DbSkip()
			END DO

			Assert.Equal(2 ,nCount)

			// Should both show true, but both return false
			Assert.True( DbOrderInfo( DBOI_ISCOND ) )
			Assert.True( DbOrderInfo( DBOI_ISDESC ) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
			aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()

			Assert.False( Found() )// FALSE, ok
			Assert.True( DbSetFound( FALSE ) )
			Assert.False( Found() ) // TRUE! wrong
			Assert.True( DbSetFound( TRUE ) )
			Assert.True( Found() ) // TRUE correct
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test2() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
			aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

		    DbCreate( cDBF , aDbf)
		    DbUseArea(,"DBFCDX",cDBF,,FALSE)

		    DbAppend()

		    DbCloseArea()

		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE )
		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE )

		    Assert.True( DbSelectArea ( "AREA1" ) )
		    Assert.Equal("AREA1", Alias() )
		    Assert.False( Found() )
		    Assert.True( DbSetFound ( TRUE ) )
		    Assert.True( Found() )

		    Assert.True( DbSelectArea ( "AREA2" ) )
		    Assert.Equal( "AREA2" , Alias() )
		    Assert.False( Found() )
		    Assert.True( DbSetFound  ( FALSE ) )
		    Assert.False( Found() )

		    Assert.True( DbCloseArea() )
		    Assert.True( DbSelectArea ( "AREA1" ) )
		    Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test3() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
		    aDbf := {{ "AGE" , "N" , 2 , 0 }}
		    DbCreate( cDBF , aDbf)
		    DbUseArea(,,cDBF,,FALSE)

		    DbAppend()
		    FieldPut(1,1)
		    DbCloseArea()

		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE )
		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE )

		    DbSelectArea ( "AREA1" )
		    Assert.True( DbLocate({||_FIELD->AGE == 1}) )
		    Assert.True( Found() )

		    DbSelectArea ( "AREA2" )
		    Assert.False( Found() )

		    DbCloseAll()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD FLock_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := __FUNCTION__
			FErase(cDbf + ".cdx")

		    aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()
			DbAppend()
			DbAppend()
			DbCloseArea()

			Assert.True( DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE ) )// open shared
			DbGoTop()
			Assert.True( DbRLock ( RecNo() ) ) // lock first record
			Assert.Equal( 1 , (INT) ALen ( DbRLockList() ) )

			Assert.True( DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE ) ) // open shared
			DbGoBottom()
			Assert.True( DbRLock ( RecNo() ) ) // lock last record
			Assert.Equal( 1 , (INT) ALen ( DbRLockList() ) )

			Assert.False( Flock() )
			// what's the correct return value here??
			// Assert.Equal( 0 , (INT) ALen ( DBRLockList() ) )
			DbCloseAll()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD IndexExt_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")
			Assert.True( IndexKey() == "")
			Assert.True( IndexOrd() == 0)
			Assert.True( IndexCount() == 0)
			Assert.True( Upper(IndexExt()) ==  ".CDX")
			Assert.True( DbOrderInfo(DBOI_INDEXEXT) == NIL )

			aValues := { 44 , 12, 34 , 21 }
			aDbf := {{ "AGE" , "N" , 2 , 0 }}

			DbCreate( cDBF , aDbf)
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbCreateIndex( cDbf, "age" )

			Assert.Equal( "age" , (STRING) IndexKey() )
			Assert.True( IndexOrd() == 1 )
			Assert.True( IndexCount() == 1 )
			Assert.True( Upper(IndexExt()) == ".CDX")
			Assert.True( DbOrderInfo(DBOI_INDEXEXT) == ".CDX")

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Multi_Order() AS VOID
			SELF:Cdx_Multi_Order_helper(1)
			SELF:Cdx_Multi_Order_helper(2)
			SELF:Cdx_Multi_Order_helper(3)
		RETURN
		PRIVATE METHOD Cdx_Multi_Order_helper(nTestType AS INT) AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			LOCAL d AS DATE
			d := ConDate(2019,02,22)

			cDBF := GetTempFileName("testcdx")
			aValues := { {44,d} , {12,d-1}, {34,NULL_DATE} , {21,d+1} }

			RddSetDefault("DBFCDX")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)
			DbCreate( cDbf , {{"FIELDN" , "N" , 3 , 0 } , {"FIELDD" , "D" , 8 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i,1])
				FieldPut(2,aValues [i,2])
			NEXT
			DbCloseArea()

			IF nTestType == 1
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAwD//////////88B//8AAA8PEAQEAwASQAAMNQAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABURVNUQ0RYOE4yRklFTEREAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBGSUVMRE4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAoABAAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAABAAAACAAtRklFTEROAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////78B//8AAA8PEAQEAwEAAAMAAQQAAQIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANf////////K////////vv///////z+5////////ABYAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBGSUVMREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9UB//8AAA8PEAQEAwMAcAIAQAEANAQAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVgMFCwdSA"))
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
			ELSEIF nTestType == 2
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
				DbCreateIndex( cCdx, "FIELDN" )
				DbCreateOrder("FIELDN2", cCdx, "-FIELDN" )
				DbCreateOrder("FIELDD", cCdx, "FIELDD" )
                DbSetOrder(1)
			ELSE
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
				DbCreateIndex( cCdx, "FIELDN" )
				DbCreateOrder("FIELDN2", cCdx, "-FIELDN" )
				DbCreateOrder("FIELDD", cCdx, "FIELDD" )

				DbCloseArea()
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
			END IF

			LOCAL nCount := 0 AS INT

			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 2)
				CASE nCount == 2
					Assert.True(RecNo() == 4)
				CASE nCount == 3
					Assert.True(RecNo() == 3)
				CASE nCount == 4
					Assert.True(RecNo() == 1)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(1)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 2)
				CASE nCount == 2
					Assert.True(RecNo() == 4)
				CASE nCount == 3
					Assert.True(RecNo() == 3)
				CASE nCount == 4
					Assert.True(RecNo() == 1)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(2)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 1)
				CASE nCount == 2
					Assert.True(RecNo() == 3)
				CASE nCount == 3
					Assert.True(RecNo() == 4)
				CASE nCount == 4
					Assert.True(RecNo() == 2)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(3)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 3)
				CASE nCount == 2
					Assert.True(RecNo() == 2)
				CASE nCount == 3
					Assert.True(RecNo() == 1)
				CASE nCount == 4
					Assert.True(RecNo() == 4)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			DbCloseArea()
		RETURN

		// TECH-5YYVPE1A8T, DBFCDX StackOverflow with Shared mode, DBSelete() and DBUnlock()
		[Fact, Trait("Category", "DBF")];
		METHOD DBFCDX_StackOverflow() AS VOID
			LOCAL cDBF AS STRING

            TRY
			RddSetDefault("DBFCDX")
			SetExclusive( FALSE )

			cDBF := GetTempFileName()
			FErase(cDBF)
			FErase(cDBF + ".cdx")

			DbfTests.CreateDatabase(cDBF , { { "CFIELD" , "C" , 5 , 0 }} , { "AAA" , "CCC" , "BBB" } )
			DbCreateIndex(cDbf , "CFIELD")
			DbCloseAll()

			DbUseArea(,"DBFCDX",cDBF )
			DbGoTop()
			DbSkip()

			Assert.Equal( 3, (INT) RecNo() )
			Assert.Equal( "BBB  ", FieldGet(1) )

			Assert.True( DbRLock()  )
			Assert.True( DbDelete() )
			Assert.True( DbUnLock() ) // StackOverflow here

            FINALLY
			DbCloseAll()
            SetExclusive ( TRUE )
            END TRY
		RETURN

		// TECH-545T6VKW27, Problems with OrdScope() and DBSeek()
		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_and_DBSeek_test() AS VOID
			LOCAL cDBF AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			aValues := {"Gas" , "Abc", "Golden" , "Guru" , "Ddd" , "Aaa" , "Ggg"}
			aFields := { {"CFIELD" , "C" , 10 , 0} }

			DbCreate(cDbf , aFields)
			DbUseArea(,,cDBF )
			DbCreateIndex(cDbf , "Upper(CFIELD)")
			FOR i := 1 UPTO ALen(aValues)
				IF DbAppend()
				    FieldPut(1, aValues[i])
                ENDIF
			NEXT

			DbGoTop()
            DbCommit()
			Assert.Equal(7 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 7, correct

			// Setting order scope
			OrdScope(TOPSCOPE, "G")
			OrdScope(BOTTOMSCOPE, "G")
			DbGoTop()

			// VO: -2 with NTX, 4 with CDX
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )

			Assert.True( DbSeek("G")    ) // TRUE, correct
			Assert.True( DbSeek("GOLD") ) // TRUE with NTX, FALSE with CDX. VO TRUE in both

			// Clearing order scope
			OrdScope(TOPSCOPE, NIL)
			OrdScope(BOTTOMSCOPE, NIL)
			Assert.Equal( 7 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True( DbSeek("G") )
			Assert.True( DbSeek("GOLD") )

			// Setting order scope again
			OrdScope(TOPSCOPE, "G")
			OrdScope(BOTTOMSCOPE, "G")
			DbGoTop()
			// VO: -2 with NTX, 4 with CDX
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )

			Assert.True( DbSeek("G")    ) // TRUE, correct
			Assert.True( DbSeek("GOLD") ) // TRUE with NTX, FALSE with CDX. VO TRUE in both

			DbCloseArea()
		RETURN

		// TECH-6010F6ZSY9, DBFCDX OrdDescend() not working
		[Fact, Trait("Category", "DBF")];
		METHOD DBFCDX_OrdDescend_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )
			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "b" , "d" , "c", "e" , "a" }
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )
			cIndex := cDbf + "x"
			FErase ( cIndex + IndexExt() )
//			 -----------------
			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			DbCreateOrder ( "ORDER1" , cIndex , "upper(LAST)" , { || Upper(_FIELD->LAST) } )
			DbSetOrder ( 1 )

			Assert.False( DbOrderInfo(DBOI_ISDESC) ) // false, correct
			Assert.False( OrdDescend() ) // true, incorrect

			DbGoTop()
			LOCAL aResult AS ARRAY
			LOCAL nIndex AS INT
			aResult := {5,1,3,2,4}
			nIndex := 0
			DO WHILE ! Eof()
//				5,1,3,2,4 correct
				nIndex ++
				Assert.Equal((INT) aResult[nIndex] , (INT) RecNo() )
				DbSkip(1)
			ENDDO

			Assert.False( OrdDescend ( ,, TRUE ) )
			Assert.True( DbOrderInfo(DBOI_ISDESC) ) // false, wrong
			Assert.True( OrdDescend() )

			DbGoTop()
			aResult := {4,2,3,1,5}
			nIndex := 0
			DO WHILE ! Eof()
//				5,1,3,2,4 again, wrong, should be 4,2,3,1,5
				nIndex ++
				Assert.Equal((INT) aResult[nIndex] , (INT) RecNo() )
				DbSkip(1)
			ENDDO

			DbCloseAll()
		RETURN

		// TECH-8H9WL71978, OrdIsUnique() always returns TRUE
		[Fact, Trait("Category", "DBF")];
		METHOD OrdIsUnique_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL lUnique AS LOGIC

			lUnique := SetUnique()
			RddSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "a" , "d" , "f", "c" }

			cDBF := GetTempFileName()
			cIndex := cDbf

			FErase ( cIndex + IndexExt() )
//			 -----------------
			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			Assert.True( OrdCondSet() )
			Assert.True( OrdCreate(cIndex, "ORDER1", "upper(LAST)", { || Upper ( _FIELD-> LAST) } ) )
			DbSetOrder ( 1 )
			Assert.Equal( "ORDER1" , OrdName() ) // "ORDER1"
			Assert.False( OrdIsUnique() ) // always returns true !
			Assert.False( DbOrderInfo(DBOI_UNIQUE ) ) // ok
			Assert.False( DbOrderInfo(DBOI_ISDESC ) ) // ok

			Assert.True( OrdCondSet() )
//			 create a descend and unique order
			Assert.True( OrdCondSet(,,,,,,,,,,TRUE) )
			SetUnique ( TRUE )
			OrdCreate(cIndex, "ORDER2", "upper(LAST)", { || Upper ( _FIELD-> LAST) } )

			DbSetOrder ( 2 )
			Assert.Equal( "ORDER2" , OrdName() ) // "ORDER2"
			Assert.True( OrdIsUnique() ) // always returns true !
			Assert.True( DbOrderInfo(DBOI_UNIQUE ) ) // ok
			Assert.True( DbOrderInfo(DBOI_ISDESC ) ) // ok
			DbCloseAll()
			Assert.True( SetUnique ( lUnique ) )
		RETURN

		// TECH-679F75W648, Cannot create custom DBFCDX index
		[Fact, Trait("Category", "DBF")];
		METHOD Custom_DBFCDX_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}

			aValues := { "Goethe" , "Goldmann" , "Ober",;
			"Osterreich" , "Gothe" , "Gotz" , "Gobel" ,;
			"Otter" , "Anfang" , "Art" , "Arger" }

			cDBF := __FUNCTION__
			cIndex := cDbf
			FErase ( cIndex + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			FOR i := 1 UPTO 2
				DbSetOrderCondition()
				IF i == 2
//					 second order should be a custom order.
					DbSetOrderCondition(,,,,,,,,,,,,, TRUE)
				ENDIF
				DbCreateOrder ( "ORDER"+ NTrim(i) , cIndex , "upper(LAST)" , { ||Upper ( _FIELD->LAST) } )
//				? OrdCreate(cIndex, "ORDER"+NTrim(i), "upper(LAST)", { || Upper ( _Field->LAST) } ) // ok
			NEXT

			DbSetOrder ( 1 )
			Assert.Equal( "ORDER1", OrdName() ) // "ORDER1" ok
			Assert.Equal( 1 , (INT) OrdNumber() ) // 1 ok
			Assert.Equal( "upper(LAST)" ,  OrdKey(1) ) // "UPPER(LAST)" ok
			Assert.False( (LOGIC) DbOrderInfo ( DBOI_CUSTOM ) ) // returns FALSE ok
			Assert.Equal( 11 , (INT) DbOrderInfo ( DBOI_KEYCOUNT ) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( 1 , cIndex ) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( "ORDER1" , cIndex) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( 1 ) )
			Assert.Equal( 11 , (INT) OrdKeyCount() )

			DbSetOrder ( 2 )
			Assert.Equal( "ORDER2", OrdName() ) // "ORDER2" ok
			Assert.Equal( 2 , (INT) OrdNumber() ) // 2 ok
			Assert.Equal( "upper(LAST)" ,  OrdKey(2) ) // "UPPER(LAST)" ok
			Assert.True( (LOGIC) DbOrderInfo ( DBOI_CUSTOM ) ) // NOTE: returns FALSE instead of TRUE
			Assert.Equal( 0 , (INT) DbOrderInfo ( DBOI_KEYCOUNT ) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( 2 , cIndex ) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( "ORDER2" , cIndex) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( 2 ) )
			Assert.Equal( 0 , (INT) OrdKeyCount() )

			Assert.Equal( 2 , (INT) IndexCount() ) // 2 ok

//			 NOTE: ORDDESTROY() problem. if the order doesnt exist the func returns TRUE and
//			 seems to do nothing. VO throws an error if a order doesnexist.
			LOCAL lException := FALSE AS LOGIC
			TRY
				OrdDestroy("ORDER4") // NOTE: "ORDER4" does not exist
			CATCH
				lException := TRUE
				Assert.Equal( 2 , (INT) IndexCount() )
				Assert.Equal( 2 , (INT) IndexOrd() )
			END TRY
			Assert.True( lException )
			DbCloseAll()
		RETURN

		// TECH-679F75W648, Cannot create custom DBFCDX index
		[Fact, Trait("Category", "DBF")];
		METHOD Custom_DBFCDX_test2() AS VOID
			#warning Custom order test not added, feature is not supported yet
/*
			LOCAL cDBF, cPfad, cIndex, cDriver AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL aRecnos AS ARRAY

			cDriver := RDDSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}

			aValues := { "Goethe" , "Goldmann" , "Ober",;
			"Osterreich" , "Gothe" , "Gotz" , "Gobel" ,;
			"Otter" , "Anfang" , "Art" , "Arger" }

			cPfad := "" // "c:\xide\projects\project1\bin\debug\"
			cDBF := cPfad + "Foo"
			cIndex := cPfad + "Foox"

			FErase ( cIndex + IndexExt() )
//			 -----------------
			? DBCreate( cDBF , AFields)
			? DBUseArea(,"DBFCDX",cDBF )

			FOR i := 1 UPTO ALen ( aValues )
			DBAppend()
			FieldPut ( 1 , aValues [ i ] )
			NEXT

			FOR i := 1 UPTO 2
			DBSetOrderCondition()
			IF i == 2
			DBSetOrderCondition(,,,,,,,,,,,,, TRUE)
			ENDIF

//			 ? DBCREATEORDER ( "ORDER"+ NTrim(i) , cIndex ,"upper(LAST)" , { || Upper ( _Field->LAST) } )
			? OrdCreate(cIndex, "ORDER"+ NTrim(i), "upper(LAST)", { || Upper (_Field->LAST) } )
			NEXT

//			 -------------
			?
			? IndexCount() // ok 2
			? OrdName() // ok current order is "ORDER2"
			? OrdKeyCount() // 0 before OrdKeyAdd()
			?

//			 add 4 records to the custom order
			aRecnos := { 1 , 11 , 4 , 9 }
			FOR i := 1 UPTO ALen ( aRecnos )
			DBGoTo ( aRecnos [ i ] )
			OrdKeyAdd ()
			NEXT
			? OrdKeyCount() // 4 after OrdKeyAdd()
			?

			DBGoTop()

//			 "Last" names shown are:
//			 Anfang
//			 Arger
//			 Gothe
//			 Osterreich

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO
			?
//
			? "Delete the entry 'Arger'"
			DBSeek( Upper ( "Arger" ))
			OrdKeyDel () // delete the entry
			? OrdKeyCount() // 3
			?
			DBGoTop()

//			 "Last" names shown are now:
//			 Anfang
//			 Gothe
//			 Osterreich

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO
			?
			? "Delete all entries"

			DBGoTop()
			DO WHILE OrdKeyCount() > 0
			OrdKeyDel()
			DBGoTop()
			ENDDO

			? "Entries now:" , OrdKeyCount()
			?
//			 "ORDER2" order is no longer needed
			? OrdDestroy("ORDER2")
			? IndexCount() // 1
			?
//			 --- switch to the first order ---
			? DBSetOrder ( 1 )
			? OrdName() // ok "ORDER1"
			?
//			 List all "Last" names
			DBGoTop()

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO

			DBCloseAll()
			RDDSetDefault ( cDriver )*/
		RETURN

		// TECH-5OD246EMC4, VODBOrdListAdd() fails when index filename passed without extension
		[Fact, Trait("Category", "DBF")];
		METHOD VODBOrdListAdd_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")
			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "b" , "c" , "d", "e" , "a" }

			cDBF := __FUNCTION__
			cIndex := cDbf
			FErase ( cIndex + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,,cDBF)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT
			DbCreateOrder ( "ORDER1" , cIndex , "upper(LAST)" , { || Upper (_FIELD->LAST) } )
			DbCloseAll()

//			 When ".cdx" is added SetIndex() returns true
//			 cIndex := cIndex + IndexExt()
			DbUseArea(,,cDBF)
			Assert.True( VoDbOrdListAdd(cIndex , NIL) ) // Returns FALSE, error
			DbCloseAll()
		RETURN

		// TECH-0YI914Z4I2, Problem opening dbf with dbt via SetDefault()
		[Fact, Trait("Category", "DBF")];
		METHOD SetDefault_test() AS VOID
			LOCAL cPath, cDbf AS STRING
			LOCAL cDefault AS STRING
			RddSetDefault("DBFCDX")

			cPath := System.IO.Path.GetTempPath()
			IF .NOT. cPath:EndsWith("\")
				cPath += "\"
			END IF
			cDbf := "fpttest"
			FErase(cPath + cDBF + ".dbf")
			FErase(cPath + cDBF + ".ntx")
			FErase(cPath + cDBF + ".cdx")
			FErase(cPath + cDBF + ".dbt")
			FErase(cPath + cDBF + ".fpt")

			cDefault := GetDefault()
			SetDefault(cPath)

			Assert.True( DbCreate( cPath + cDbf , { { "ID" , "C" , 5 , 0 } , {"MEM" , "M" , 10 , 0}} ) )
//			 System.IO.FileNotFoundException
//			 Could not find file '<path_of_exe>\mydbf.DBT'.
			Assert.True( DbUseArea(,,cDbf ) )
			Assert.True( DbCloseArea()      )

			SetDefault(cDefault)
		RETURN

		// TECH-ZW8D1S87CH, Problem updating cdx
		[Fact, Trait("Category", "DBF")];
		METHOD CdxUpdating() AS VOID
			LOCAL cDBF AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL cPrev AS STRING
			LOCAL nCount AS INT
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )

			aFields := { { "NUM" , "N" , 8 , 0 },{ "LAST" , "C" , 100 , 0 }}
			aValues := { "b" , "c" , "d", "e" , "a" , "r" , "t" , "g" , "m" , "n" , "t" , "b" , "h" , "f" , "y", "r", "t", "y", "z", "v", "e", "r", "b", "z", "b", "m", "w", "e" }

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,,cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , i )
				FieldPut ( 2 , Replicate( aValues [ i ] , 50) )
			NEXT
			DbCreateIndex ( cDBF , "NUM" , {||_FIELD->NUM})
			DbCreateOrder ( "LAST" , cDBF , "LAST" , {||_FIELD->LAST})
			DbCloseAll()

			DbUseArea(,,cDBF )
			DbSetOrder(2)       // Last
			DbGoBottom()

			FieldPut(2, "a")    // Change Z to "a"  Note that at this moment the DeleteKey fails

			DbSkip(-5)
			FieldPut(2, "d")
			DbSkip(5)
			FieldPut(2, "z")

			cPrev := NULL
			nCount := 0
			DbGoTop()
			DO WHILE .NOT. EoF()
				nCount ++
                VAR cCurrent := FieldGet(2)
				IF cPrev != NULL

					Assert.True( cPrev <=  cCurrent)
				END IF
				cPrev := cCurrent
				DbSkip()
			END DO
			Assert.Equal( nCount, (INT) ALen(aValues) )

			DbCloseArea()
		RETURN

		// TECH-78PAZ508AE, Problems with creating/opening DBFCDX memo files
		[Fact, Trait("Category", "DBF")];
		METHOD MemoCreateAndOpen() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := System.IO.Path.GetTempPath() + "cdxtest"

			aFields := { { "LAST" , "C" , 20 , 0 } , { "COMMENTS" , "M" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)
//			DBCreate( cDBF , AFields , "DBFCDX") // same

			Assert.False( (LOGIC) File(cDBF + ".dbt") )
			Assert.True( (LOGIC) File(cDBF + ".fpt") )

			IF File(cDBF + ".dbt")
				FRename(cDBF + ".dbt",cDBF + ".fpt")
			END IF

			TRY
				DbUseArea(,,cDBF)
			FINALLY
				DbCloseAll()
			END TRY

			RddSetDefault("DBFNTX")
			cDBF := System.IO.Path.GetTempPath() + "ntxtest"

			aFields := { { "LAST" , "C" , 20 , 0 } , { "COMMENTS" , "M" , 10 , 0 }}
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			Assert.True( (LOGIC) File(cDBF + ".dbt") )
			Assert.False( (LOGIC) File(cDBF + ".fpt") )

			IF File(cDBF + ".fpt")
				FRename(cDBF + ".fpt",cDBF + ".dbt")
			END IF

			TRY
				DbUseArea(,,cDBF)
			FINALLY
				DbCloseAll()
			END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_DBGoTop() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := System.IO.Path.GetTempPath() + "cdxtest1"

			aFields := { { "LAST" , "C" , 20 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)

			DbUseArea(,"DBFCDX" , cDbf)
			FOR LOCAL n := 1 AS INT UPTO 1000
				DbAppend()
				FieldPut(1,"A"+AsString(n % 77))
			NEXT
			DbCreateOrder( "ORDER1" , cDbf + ".cdx" , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )
			DbCloseArea()

			LOCAL nCount AS INT
			DbUseArea(,"DBFCDX" , cDbf)

			DbGoTop()
			DbGoTop()
			nCount := 0
			DO WHILE .NOT. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal( nCount, 1000 )

			DbGoBottom()
			DbGoBottom()
			nCount := 0
			DO WHILE .NOT. Bof()
				nCount ++
				DbSkip(-1)
			END DO
			Assert.Equal( nCount, 1000 )
			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_SeekEmptyDbf() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 20 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)

			DbUseArea(,"DBFCDX" , cDbf)
			DbCreateOrder( "ORDER1" , cDbf + ".cdx" , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )

			DbGoTop()
            DbSeek("A")
			DbCloseArea()

		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdKeyCount() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL dwCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			DbUseArea( ,"DBFCDX",cDBF , , TRUE )
			FOR LOCAL n := 1 AS DWORD UPTO 1000
				DbAppend()
				FieldPut(1, Chr(65 + (n % 5)) )
			NEXT
			DbAppend()
			FieldPut(1, "D" )
			DbAppend()
			FieldPut(1, "E" )
			DbAppend()
			FieldPut(1, "D" )
			DbAppend()
			FieldPut(1, "F" )

			DbGoTop()

			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )
			DbGoTop()

			OrdScope( TOPSCOPE, "C" )
			OrdScope( BOTTOMSCOPE, "C" )

			DbGoTop()

			Assert.Equal(200, (INT) OrdKeyCount() )

			DbGoTop()
			DO WHILE ! Eof()
				dwCount += 1
				DbSkip(1)
			ENDDO
			Assert.Equal(200, dwCount)

			DbGoTop()
			DbSkip(2)
			Assert.False( Eof() )

			OrdScope( TOPSCOPE, "D" )
			OrdScope( BOTTOMSCOPE, "D" )
			DbGoTop()
			Assert.Equal(202, (INT) OrdKeyCount() )

			OrdScope( TOPSCOPE, "E" )
			OrdScope( BOTTOMSCOPE, "E" )
			DbGoTop()
			Assert.Equal(201, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(5)
			Assert.False( Eof() )

			OrdScope( TOPSCOPE, "F" )
			OrdScope( BOTTOMSCOPE, "F" )
			DbGoTop()
			Assert.Equal(1, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(2)
			Assert.True( Eof() )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_DbSetOrderCondition() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL dwCount AS INT
			LOCAL cDBF AS STRING
			LOCAL n AS DWORD

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			DbUseArea( ,"DBFCDX",cDBF , , TRUE )
			FOR n := 1 UPTO 600
				DbAppend()
				FieldPut(1, Chr(65 + (n % 3)) )
			NEXT

			DbSetOrderCondition (,,,,,,,600,,,,,,,)
			DbGoTop()
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			Assert.Equal(600, (INT) OrdKeyCount() )

			DbGoTop()
			dwCount := 0
			DO WHILE .NOT. eof()
				dwCount ++
				DbSkip()
			END DO
			Assert.Equal(600, dwCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdDescend() AS VOID
			LOCAL cResult AS STRING
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "b" , "d" , "c", "e" , "g1" , "g3" , "g45" , "a" , "o" , "p" , "r"})

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE,  "C")
			OrdScope(BOTTOMSCOPE, "O")
			DbGoTop()
			Assert.Equal(7, (INT) OrdKeyCount())

			cResult := ""
			DO WHILE ! Eof()
				cResult += AllTrim(FieldGet(1)) + " "
				DbSkip ( 1)
			ENDDO
			Assert.Equal( "c d e g1 g3 g45 o" , AllTrim(cResult) )

			OrdDescend( , , TRUE)
			DbGoTop()
			Assert.Equal(7, (INT) OrdKeyCount())

			cResult := ""
			DO WHILE ! Eof()
				cResult += AllTrim(FieldGet(1)) + " "
				DbSkip ( 1)
			ENDDO
			Assert.Equal( "o g45 g3 g1 e d c" , AllTrim(cResult) )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_Deleted() AS VOID
			LOCAL cDBF AS STRING
			LOCAL nCount := 0 AS INT

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "e" , "o" , "g" })

		  	DbSetOrderCondition ( "! DELETED()" , { || ! Deleted()  } )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbSetOrder(1)

			DbGoTop()
			Assert.Equal(3, (INT) OrdKeyCount())
			DbGoBottom()
			Assert.True( DbDelete() )
			DbGoTop()
			Assert.Equal(2, (INT) OrdKeyCount())

			DO WHILE ! Eof()
				nCount ++
				DbSkip(1)
			ENDDO
			Assert.Equal( 2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_DeletedScope() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			SetDeleted(TRUE)

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "d" , "c",  "o" , "r" , "go1" , "g" , "go2" , "g2" , "go3" } )

			DbGoBottom()
			DbDelete()

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "GO" )
			OrdScope ( BOTTOMSCOPE, "GO" )

			DbGoTop()
			DO WHILE ! Eof()
				Assert.Equal( "go" , (STRING) Left(FieldGet(1) , 2) )
				nCount ++
				DbSkip (1)
		 	ENDDO

		 	Assert.Equal(2 , nCount )       // go3 is deleted and should not be counted
		 	Assert.Equal(2 , (INT) OrdKeyCount() ) // go3 is deleted and should not be counted

		 	LOCAL nOrdKey AS INT
		 	nOrdKey := OrdKeyCount()
		 	Assert.True(nOrdKey == 2 ) // returns 0 when the test was added

		 	// make sure it still always gives the same result
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoTop()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip(-1)
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoBottom()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )

            SetDeleted(FALSE)
            // When SetDeleted = FALSE then go3 will be included in the count
		 	nOrdKey := OrdKeyCount()
		 	Assert.True(nOrdKey == 3 ) // returns 0 when the test was added

		 	// make sure it still always gives the same result
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoTop()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip(-1)
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoBottom()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )

			DbCloseArea()

		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdKeyCount_at_EOF() AS VOID
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			SetDeleted(TRUE)

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "d" , "c",  "o" , "r" } )

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )

			DbGoBottom()
			Assert.Equal(4, (INT) OrdKeyCount() )
			DbSkip()
			Assert.Equal(4, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(-1)
			Assert.Equal(4, (INT) OrdKeyCount() )

			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdScope_and_SetFilter() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "A1" ,"A3" , "A2",  "Go1" , "G1" , "g2" , "g3", "go2"  , "h2" , "h4" } )

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "A" )
			OrdScope ( BOTTOMSCOPE, "G" )

			Assert.Equal(8 , (INT) OrdKeyCount() )

			LOCAL cFilter AS STRING
			cFilter := "GO"

			Assert.True( DbSetFilter ( { || Upper ( _Field->LAST ) = cFilter  } )  )
			DbGoTop()
			Assert.False( Eof() )
			Assert.Equal(2 , (INT) OrdKeyCount() )
			Assert.False( Eof() )
			DbGoTop()
			Assert.False( Eof() )

			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1 )
			ENDDO
			Assert.Equal(2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdScope_and_SetFilter_numerics() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "N" , 20 , 0 }} , ;
							{ 1,2,3,4,5,6,3,4 } )

			DbCreateOrder ( "ORDER1" , cDbf , "LAST" , { || _Field->LAST } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, 2 )
			OrdScope ( BOTTOMSCOPE, 5 )

			Assert.Equal(6 , (INT) OrdKeyCount() )

			Assert.True( DbSetFilter ( { || _Field->LAST == 3  } )  )
			DbGoTop()
			Assert.False( Eof() )
			Assert.Equal(2 , (INT) OrdKeyCount() )
			Assert.False( Eof() )
			DbGoTop()
			Assert.False( Eof() )

			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1 )
			ENDDO
			Assert.Equal(2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_and_SetDeleted() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					Assert.True( DbDelete() )
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			SetDeleted ( TRUE )

			OrdScope ( TOPSCOPE, "G" )
			OrdScope ( BOTTOMSCOPE, "G" )
		 	DbGoTop()

			Assert.Equal(3, (INT) OrdKeyCount() ) // 3 ok

			SetDeleted ( FALSE )
			DbGoTop()

			Assert.Equal(5, (INT) OrdKeyCount() ) // 3 ok

			OrdScope ( TOPSCOPE, NIL )
			OrdScope ( BOTTOMSCOPE, NIL )

			// If TOPSCOPE and BOTTOMSCOPE is not equal
			// OrdKeyCount() seems to ignore a SetDeleted( TRUE ) ?

			OrdScope ( TOPSCOPE, "A" )
			OrdScope ( BOTTOMSCOPE, "G" )

            // We are now VO compatible and return the same number that VO does
			SetDeleted( TRUE )
			Assert.Equal(11, (INT) OrdKeyCount() ) // 11 ok

			SetDeleted( FALSE )
			Assert.Equal(11, (INT) OrdKeyCount() ) // 11 ok

			DbCloseArea()
		RETURN

		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands
		[Fact, Trait("Category", "DBFCDX")];
		METHOD Cdx_SoftSeek_Test_Numeric() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := __FUNCTION__
			cCdx := cDbf + ".cdx"

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,123)
			DbAppend()
			FieldPut(1,456)
			DbCreateIndex(cCdx, "NFIELD")
			DbCloseArea()
			DbUseArea(,,cDbf,,FALSE)
			DbSetIndex(cCdx)
           SET(_SET_SOFTSEEK, "on")
            DbSeek(100)
            Assert.Equal(123, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek(200)
            Assert.Equal(456, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(FALSE)
            DbSeek(200)
            Assert.Equal(0, (INT)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(TRUE)
            DbSeek(100)
            Assert.Equal(123, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek(200)
            Assert.Equal(456, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
           SET(_SET_SOFTSEEK, "off")
            DbSeek(200)
            Assert.Equal(0, (INT)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())
            RETURN

   		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands
		[Fact, Trait("Category", "DBFCDX")];
		METHOD CDX_SoftSeek_Test_String() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := __FUNCTION__
			cCdx := cDbf + ".cdx"

			DbCreate( cDbf , {{"CFIELD" , "C" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,"bbbbb")
			DbAppend()
			FieldPut(1,"kkkkk")
			DbCreateIndex(cCdx, "CFIELD")
			DbCloseArea()
			DbUseArea(,,cDbf,,FALSE)
			DbSetIndex(cCdx)
            SetSoftSeek(TRUE)
            DbSeek("aaaaa")
            Assert.Equal("bbbbb", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek("ccccc")
            Assert.Equal("kkkkk", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(FALSE)
            DbSeek("ccccc")
            Assert.Equal("     ", (STRING)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())

           SET(_SET_SOFTSEEK, "on")
            DbSeek("aaaaa")
            Assert.Equal("bbbbb", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek("ccccc")
            Assert.Equal("kkkkk", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
           SET(_SET_SOFTSEEK, "off")
            DbSeek("ccccc")
            Assert.Equal("     ", (STRING)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())

RETURN

		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands

        [Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_SetDeleted_and_OrdScope1() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			TRY

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "G" )
			OrdScope ( BOTTOMSCOPE, "G" )
//			OrdScope ( TOPSCOPE, "A" )
//			OrdScope ( BOTTOMSCOPE, "G" )

			Assert.Equal(5, (INT) OrdKeyCount() )

			SetDeleted ( TRUE )  // no problem if set to FALSE

			OrdDescend ( , , TRUE )
			DbGoTop()

			// SetDeleted(TRUE) causes a endless loop ...
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
//				? AllTrim(FieldGet ( 1 ) ) , RecNo(), Eof(), Bof()
				DbSkip ( 1 )
				nCount ++
				IF nCount > 100
					THROW Exception{"Skip() loop never ends"}
				END IF
			ENDDO

			Assert.Equal(3, (INT) OrdKeyCount() )

			DbCloseAll()

			CATCH

				THROW

			FINALLY

			SetDeleted(FALSE)

			END TRY
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_SetDeleted_and_OrdScope2() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			TRY

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			// create a descending order

			DbSetOrderCondition( , , , , , , , , , ,TRUE )
			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )
			DbGoTop()

			DO WHILE ! Eof()
				FieldGet ( 1 )
				DbSkip ( 1 )
			ENDDO

			SetDeleted ( FALSE )

			Assert.Equal(20 , (INT) OrdKeyCount() ) // 20  ok

			SetDeleted ( TRUE  )

//			#warning disabled following test because it makes tests stop responding
			//  Here it hangs because SetDeleted() is true
			// We are now VO compatible and return 20 instead of 17
            Assert.Equal(20 , (INT) OrdKeyCount() ) // 20  ok
			DbCloseAll()

			FINALLY

				SetDeleted(FALSE)

			END TRY
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD Filter_Descending_and_OrdKeyCount1() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL cFilter AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )

			cFilter := "G"  // result does include deleted records  !

			SetDeleted ( FALSE )
			DbSetFilter ( { || Upper ( _Field->LAST ) = cFilter  }  )
			DbGoTop()

			Assert.Equal(5, (INT) OrdKeyCount() ) //  5 ok

			SetDeleted ( TRUE  )

			Assert.Equal(3, (INT) OrdKeyCount() ) //  3 ok

			// now change the filter to descend sort on the fly

			OrdDescend ( , , TRUE )
			SetDeleted ( FALSE )
			DbSetFilter ( { || Upper ( _FIELD->LAST ) = cFilter  }  )

			Assert.Equal(5, (INT) OrdKeyCount() ) //  shows 0  ...

			SetDeleted ( TRUE  )

			Assert.Equal(3, (INT) OrdKeyCount() ) // 	shows 0  ...

		   // switch back to ascending sort

			OrdDescend ( , , FALSE )
			SetDeleted ( FALSE )
			Assert.Equal(5, (INT) OrdKeyCount() ) //  5, ok

			SetDeleted ( TRUE )

			Assert.Equal(3, (INT) OrdKeyCount() ) // 	3, ok

			DbCloseAll()

			SetDeleted ( FALSE )
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD Filter_Descending_and_OrdKeyCount2() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL cFilter AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )
			FOR LOCAL i := 1 AS DWORD UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbSetOrder ( 1 )

			cFilter := "A"  // result does include *no* deleted records  !

			DbSetFilter ( { || Upper ( _FIELD->LAST ) = cFilter  }  )
			Assert.Equal(6, (INT) OrdKeyCount() ) // 6 , ok

			OrdDescend ( , , TRUE )

//			SetDeleted ( FALSE )
//			SetDeleted ( TRUE )

			// OrdKeyCount() hangs no matter how the SetDeleted() setting is.
//			#warning disabled following test because it makes tests stop responding
			Assert.Equal(6, (INT) OrdKeyCount() ) // 6 , ok

			DbCloseAll()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyNo_with_no_condition() AS VOID
			LOCAL cDBF AS STRING
			LOCAL lDeleted AS LOGIC
			LOCAL nCounter AS INT

			lDeleted := SetDeleted()

			TRY
				RddSetDefault("DBFCDX")
				cDBF := GetTempFileName()

				DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "a1" , "g1", "g2" , "o5"  } )

				DbUseArea( ,,cDBF , , TRUE )
				DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
				DbSetOrder ( 1 )

				lDeleted := SetDeleted ( FALSE  )
				DbGoTop()
				nCounter := 1
				DO WHILE ! Eof()
			       // ordKeyNo() returns zero based values if no condition is set,
			       // e.g. if no filter, no scope or the setting setdeleted (false) is used.
	//				? FieldGet ( 1 ) , OrdKeyNo()
					Assert.Equal(nCounter , (INT)OrdKeyNo())
					DbSkip(1)
					nCounter ++
				ENDDO

				SetDeleted ( TRUE  ) // Now the ordkeyno() values are correctly one based.

				DbGoTop()
				nCounter := 1
				DO WHILE ! Eof()
	//				? FieldGet ( 1 ) , OrdKeyNo()
					Assert.Equal(nCounter , (INT)OrdKeyNo())
					DbSkip(1)
					nCounter ++
				ENDDO

				DbCloseAll()
			FINALLY

				SetDeleted( lDeleted )

			END TRY
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest() AS VOID
			FOR LOCAL i := 0 AS INT UPTO 5
				SELF:ZapTest_helper(i)
			NEXT
		END METHOD

		METHOD ZapTest_helper(nType AS INT) AS VOID
			LOCAL cDBF AS STRING
			LOCAL nCount AS INT

			cDBF := GetTempFileName()
			FErase(cDbf + ".dbf")
			FErase(cDbf + ".cdx")
			FErase(cDbf + ".ntx")

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "a1" , "g1", "g2" , "o5"  } )

			DO CASE
			CASE  nType % 3 == 0
				? "testing with no index:"
			CASE nType % 3 == 1
				? "testing with NTX:"
				RddSetDefault ( "DBFNTX" )
			CASE nType % 3 == 2
				? "testing with CDX:"
				RddSetDefault ( "DBFCDX" )
			END CASE

			IF nType % 3 != 0
				DbUseArea( ,,cDBF , , TRUE )
				DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
				DbCloseAll()
			END IF

			DbUseArea( ,,cDBF , , FALSE )
			IF nType >= 3
				DbAppend()
				FieldPut(1,"testing")
				DbAppend()
				FieldPut(1,"some")
				DbAppend()
				FieldPut(1,"values")
				DbAppend()
				FieldPut(1,"last one")
			END IF
			IF nType % 3 != 0
				DbSetIndex ( cDBF )
			ENDIF
			Assert.True( DbZap() )
			DbCloseAll()

			DbUseArea( ,,cDBF , , TRUE )
			IF nType % 3 != 0
				DbSetIndex ( cDBF )
				DbSetOrder ( 1 )
			ENDIF

			DbGoTop()
			Assert.True( Eof() )
			Assert.Equal( 0 , (INT) RecCount() )
			Assert.False( IsNil( OrdKeyCount() ) )
			Assert.Equal( 0 , (INT) OrdKeyCount() )
			nCount := 0
			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1)
			ENDDO
			Assert.Equal( 0 , nCount )
			DbCloseArea()

		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD PackTest() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDbf AS STRING
			LOCAL cRet AS STRING
			LOCAL i AS INT

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "g1", "g2" , "o5"  }

			DbUseArea( ,,cDBF , , TRUE )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [i] ) , "G1" )
					? "DBDelete()" , DbDelete()
				ENDIF
			NEXT
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbCloseAll()

			DbUseArea( ,,cDBF , , FALSE )
			DbSetIndex ( cDbf )
			Assert.True( DbPack() ) //   NOTE:   returns TRUE  , though a DBFCDX DBPack() creates garbage.
			DbCloseAll()

			Assert.True( DbUseArea( ,,cDBF , , TRUE ) )
			Assert.True( DbSetIndex ( cDbf ) )
			Assert.True( DbSetOrder ( 1 ) )

			DbGoTop()

			Assert.False( Eof() )
			Assert.False( IsNil( OrdKeyCount() ) )
			Assert.Equal(3 , (INT) OrdKeyCount() )
			// should print a1 g2 o5
			cRet := ""
			DO WHILE ! Eof()
				? FieldGet ( 1 )
				cRet += AllTrim(FieldGet ( 1 ))
				DbSkip ( 1)
			ENDDO
			Assert.Equal("a1g2o5" , cRet )
			DbCloseArea()

		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD DBSeek_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cRet AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "u1" , "u2", "o2" , "o1"  } )

			DbUseArea( ,,cDBF , , TRUE )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )
			DbGoTop()
			cRet := ""
			DO WHILE ! Eof()
				cRet += AllTrim( FieldGet ( 1 ) )
				DbSkip ( 1 )
			ENDDO
			Assert.Equal( "o1o2u1u2" , cRet )
			Assert.False( DbSeek ( "P" , FALSE , TRUE ) ) // seek for last occurence

			OrdDescend ( , , TRUE )
			DbGoTop()
			cRet := ""
			DO WHILE ! Eof()
				cRet += AllTrim( FieldGet ( 1 ) )
				DbSkip ( 1 )
			ENDDO
			Assert.Equal( "u2u1o2o1" , cRet )
			Assert.False( DbSeek ( "P" , FALSE , TRUE ) ) // seek for last occurence

			DbCloseAll()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD Update_from_two_workareas() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "CFIELD" , "C" , 10 , 0 } , { "MFILED" , "M" , 10 , 0 } } )

			DbUseArea(TRUE,  , cDbf)
			DbCreateIndex(cDbf , "CFIELD")
			DbAppend()
			FieldPut(1,"z-ALIAS1")
			FieldPut(2,"z-ALIAS1_memo")
			DbAppend()
			FieldPut(1,"a-ALIAS1")
			FieldPut(2,"a-ALIAS1_memo")

			DbCloseArea()

			DbUseArea(TRUE, , cDbf , "alias1" , TRUE)
			DbGoTop()
			alias1->RLock()
			alias1->FieldPut(1 , "c-ALIAS1")
			alias1->FieldPut(2 , "c-ALIAS1_memo")
			Assert.Equal(2 , (INT)alias1->RecCount() )

				DbUseArea(TRUE, , cDbf , "alias2" , TRUE)
				Assert.Equal(2 , (INT)alias2->RecCount() )
				alias2->DbAppend()
				alias2->FieldPut(1,"b-ALIAS2")
				alias2->FieldPut(2,"b-ALIAS2_memo")
				Assert.Equal(3 , (INT)alias2->RecCount() )
				alias2->DbCloseArea()

			alias1->DbCloseArea()

			DbUseArea(TRUE, , cDbf , , TRUE)
			Assert.Equal(3 , (INT) RecCount() )

			DbGoTop()
			Assert.Equal("b-ALIAS2" , AllTrim(FieldGet(1)) )
			Assert.Equal("b-ALIAS2_memo" , AllTrim(FieldGet(2)) )
			DbGoBottom()
			Assert.Equal("z-ALIAS1" , AllTrim(FieldGet(1)) )
			Assert.Equal("z-ALIAS1_memo" , AllTrim(FieldGet(2)) )
			DbSkip(-1)
			Assert.Equal("c-ALIAS1" , AllTrim(FieldGet(1)) )
			Assert.Equal("c-ALIAS1_memo" , AllTrim(FieldGet(2)) )
			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD Check_numeric_values() AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aValues := {123.45, 894837823.0, -323212, 564342.99, -54323.11, 0, 0.00, -0.02, -442, -42523423.7, 12345678, 4324, -6653342.16,;
						-5563423.44, 64346542.11, 566666.1, -1, -1.5, -5555, 1000000, -432423, 53453, 111, 9999999.99, -999999.99}

			DbfTests.CreateDatabase(cDbf , { { "NFIELD" , "N" , 12 , 0 } , { "NFIELDDEC" , "N" , 12 , 2 } } )
			DbUseArea(TRUE,  , cDbf)
			DbCreateIndex(cDbf , "NFIELDDEC")
			FOR LOCAL n := 1 AS INT UPTO ALen(aValues)
				DbAppend()
				FieldPut(1, aValues[n])
				FieldPut(2, aValues[n])
			NEXT

			aValues := ASort(aValues , , , {|a,b| a < b})
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .not. EOF()
				nCount ++
				Assert.True(FieldGet(1) == Round(aValues[nCount] , 0))
				Assert.True(FieldGet(2) == aValues[nCount])
				DbSkip()
			END DO
			Assert.Equal(nCount, (INT)ALen(aValues))

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest2() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , { { "LAST" , "C" , 20 , 0 } } )
			DbUseArea( ,,cDBF )
			DbAppend()
			FieldPut ( 1 , "BC" )
			DbCreateOrder ( "ORDER1"  , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbCloseArea()
			DbUseArea( ,,cDBF)
//			DbOrderInfo(DBOI_KEYCOUNT)

			? DbZap()

			? DbGoTop()	 // <-----------  ArgumentNullException

			Assert.True( Eof() )
			Assert.True( Bof() )
			Assert.True( DbOrderInfo(DBOI_KEYCOUNT) == 0 )

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest3() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , { { "LAST" , "C" , 20 , 0 } } )
			DbUseArea( ,,cDBF )
			DbAppend()
			FieldPut ( 1 , "here" )
			DbAppend()
			FieldPut ( 1 , "are" )
			DbAppend()
			FieldPut ( 1 , "some" )
			DbAppend()
			FieldPut ( 1 , "values" )
			DbCreateOrder ( "ORDER1"  , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

//			DbCloseArea()
//			DbUseArea( ,,cDBF)
			Assert.Equal( 4, (INT) DbOrderInfo(DBOI_KEYCOUNT) )

			Assert.True( DbZap() )

			? DbGoTop()	 // <-----------  ArgumentNullException

			Assert.True( Eof() )
			Assert.True( Bof() )
			Assert.True( DbOrderInfo(DBOI_KEYCOUNT) == 0 )

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD LongIndexTest() AS VOID
			LOCAL cPrev, cCurrent AS USUAL
			LOCAL nRecords AS INT
			LOCAL nCount AS INT
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			nRecords := 500

			DbCreate( cDBF , { { "LAST" , "C" , 200 , 0 } })
			DbUseArea( ,,cDBF , , FALSE )  // open shared
			FOR LOCAL n := 1 AS DWORD UPTO nRecords
				DbAppend()
				FieldPut ( 1 , Replicate( Chr(50 + n % 50) , 50 + n % 80) )
			NEXT
			DbCreateIndex ( cDBF , "LAST" , {||_FIELD->LAST})
			DbGoBottom()

			FOR LOCAL n := 1 AS DWORD UPTO 500
				DbGoto((n * 17) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))
				DbGoto((n * 37) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))
				DbGoto((n * 97) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))

				cPrev := NIL
				nCount := 0
				DbGoTop()
				DO WHILE .NOT. EoF()
					nCount ++
					cCurrent := FieldGet(1)
					IF cPrev != NIL
						Assert.True(cPrev <=  cCurrent)
						IF .not. cPrev <=  cCurrent
							? "Failed at values:" , n
							? Left(cPrev,10)
							? Left(cCurrent,10)
						END IF
					END IF
					cPrev := cCurrent
					DbSkip()
				END DO
				Assert.Equal(500, nCount)
			NEXT

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD UniqeTest() AS VOID
			LOCAL cDbf AS STRING
			LOCAL nCount AS INT

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "g1" , "o5" , "g2", "g1" , "g8" , "g1"} )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } , TRUE) // Unique

			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))

			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				? RecNo(), FieldGet(1)
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(4 , nCount)
			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE )    // open not shared
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))

			DbPack()
//			DBZap()
//			DbReindex()

			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(4 , nCount)
			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE ) // FALSE, wrong
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD PackZapReindexTest() AS VOID
			SELF:PackZapReindexTest_helper(1)
			SELF:PackZapReindexTest_helper(2)
			SELF:PackZapReindexTest_helper(3)
		END METHOD

		METHOD PackZapReindexTest_helper(nWitch AS INT) AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "g1" , "o5" , "g2", "g1" , "g8" , "g1"} )
			DbGoto(2)
			DbDelete()
			DbGoto(4)
			DbDelete()

			DBClearOrderCondition () // descend + condition + unique       order
			DbSetOrderCondition( "Upper(LAST) = 'G'", {||Upper(_Field->LAST) = "G" } ,,,,,,,,, TRUE)
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } , TRUE)

			DBClearOrderCondition ()
			DbSetOrderCondition(,,,,,,,,,,,,, TRUE) // custom + unique    order
			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } , TRUE )

			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE )    // open not shared
			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			SWITCH nWitch
			CASE 1
				DbPack()
			CASE 2
				DbZap()
			CASE 3
				DbReindex()
			END SWITCH

			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			DbCloseArea()
			DbUseArea( ,,cDBF , , FALSE )    // open shared

			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD OrdSetFocus_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := "ORDSETFOCUS"
			DbfTests.CreateDatabase(cDbf , { { "NUMFIELD" , "N" , 5 , 0 } } , { 2,1,3} )
			DbCreateOrder("ORDER1", cDbf, "NUMFIELD")
			DbCreateOrder("ORDER2", , "-NUMFIELD")
			DbCloseArea()
			DbUseArea(TRUE, "DBFCDX", cDbf)

			Assert.Equal("ORDER1", (STRING)OrdSetFocus(0))
			Assert.Equal("", (STRING)OrdSetFocus(0))
			DbGoTop()
			Assert.Equal(2, (INT)FieldGet(1))

			Assert.Equal("", (STRING)OrdSetFocus(1))
			Assert.Equal("ORDER1", (STRING)OrdSetFocus(1))
			DbGoTop()
			Assert.Equal(1, (INT)FieldGet(1))

			Assert.Equal("ORDER1", (STRING)OrdSetFocus(2))
			Assert.Equal("ORDER2", (STRING)OrdSetFocus(2))
			DbGoTop()
			Assert.Equal(3, (INT)FieldGet(1))

			Assert.Equal("ORDER2", (STRING)OrdSetFocus(3))
			Assert.Equal("", (STRING)OrdSetFocus(3))
			DbGoTop()
			Assert.Equal(2, (INT)FieldGet(1))

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD VoDbOrdSetFocus_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := "VODBORD"
			DbfTests.CreateDatabase(cDbf , { { "NUMFIELD" , "N" , 5 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf)
			DbCreateOrder("ORDER1", cDbf, "NUMFIELD")
			DbCloseArea()
			DbUseArea(TRUE, "DBFCDX", cDbf)

			LOCAL cPrevious := "" AS STRING
			Assert.False(VoDbOrdSetFocus("",123,REF cPrevious))
			Assert.False(VoDbOrdSetFocus("","abc",REF cPrevious))
			Assert.False(VoDbOrdSetFocus("abc","",REF cPrevious))
			Assert.True(VoDbOrdSetFocus("",1,REF cPrevious))
			Assert.True(VoDbOrdSetFocus("",1,REF cPrevious))
			Assert.Equal("ORDER1", cPrevious)
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_BoF_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , ;
									{ "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "A1" , "a2" , "p", "q" , "r" , "s" } )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			OrdScope(BOTTOMSCOPE, "G")
			OrdScope(TOPSCOPE, "G")

			Assert.Equal(5, (INT)OrdKeyCount() )

			DbGoTop()

			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )

			DbGoBottom()

			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			LOCAL cbExpression AS USUAL
			LOCAL u1,u2 AS USUAL
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild  , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parent" , TRUE)
			parent->DbAppend()
			parent->FieldPut(1,3)

			DbUseArea(TRUE,"DBFCDX", cChild, "child" , TRUE)
			child->DbCreateIndex(cChild,"FLD")
			FOR LOCAL n := 1 AS INT UPTO 5
			child->DbAppend()
			child->FieldPut(1,n)
			NEXT

			cbExpression := &( "{ || FLD }")
			child->DbGoBottom()
			? "evaluate in bottom, must be 5:", child->Eval( cbExpression ) // 3
			Assert.Equal(5 , (INT)child->Eval( cbExpression ))

			Assert.True( parent->VoDbSetRelation("child" , cbExpression ,"FLD") )
			parent->DbGoTop()

			child->DbSkip(0) // this throws a runtime error in __FieldGet()

			? "Recno must be 3:",child->RecNo()
			Assert.Equal(3U , child->RecNo() )
			?
			? "evaluate after SetRelation(), must be 3:", child->Eval( cbExpression )
			Assert.Equal(3 , (INT) child->Eval( cbExpression ))
			? "Recno should be 3:", child->RecNo()
			Assert.Equal(3U , child->RecNo() )

			u1 := u2 := 3
			Assert.True( child->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 ) )
			Assert.True( child->VoDbOrderInfo( DBOI_SCOPEBottom, "", NIL, REF u2 ) )
			parent->DbGoTop()

			child->DbGoTop()
			? "recno after set scope, must be 3:", child->RecNo()
			Assert.Equal(3U , child->RecNo() )

			? "Skipping forward, all must be 6 , FALSE, TRUE"
			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U ,  child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			? "Skipping backward"
			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, false, false
			Assert.Equal(3U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbCloseArea()
			parent->DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test_larger() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			LOCAL cbExpression AS USUAL
			LOCAL u1,u2 AS USUAL
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild  , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parent2" , TRUE)
			parent2->DbAppend()
			parent2->FieldPut(1,3)

			DbUseArea(TRUE,"DBFCDX", cChild, "child2" , TRUE)
			child2->DbCreateIndex(cChild,"FLD")
			FOR LOCAL n := 1 AS INT UPTO 15
			child2->DbAppend()
			child2->FieldPut(1,n)
			NEXT

			cbExpression := &( "{ || FLD }")
			child2->DbGoBottom()
			? "evaluate in bottom, must be 5:", child2->Eval( cbExpression ) // 3
			Assert.Equal(15 , (INT)child2->Eval( cbExpression ))

			Assert.True( parent2->VoDbSetRelation("child2" , cbExpression ,"FLD") )
			parent2->DbGoTop()

//			child2->DbSkip(0) // this throws a runtime error in __FieldGet()

			? "Recno must be 3:",child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )
			?
			? "evaluate after SetRelation(), must be 3:", child2->Eval( cbExpression )
//			Assert.Equal(3 , (INT)child2->Eval( cbExpression ))
			? "Recno should be 3:", child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )

			u1 := u2 := 3
			Assert.True( child2->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 ) )
			Assert.True( child2->VoDbOrderInfo( DBOI_SCOPEBottom, "", NIL, REF u2 ) )
			parent2->DbGoTop()

			child2->DbGoTop()
			? "recno after set scope, must be 3:", child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )

			? "Skipping forward, all must be 16 , FALSE, TRUE"
			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			? "Skipping backward"
			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, false, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbCloseArea()
			parent2->DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test_for_526() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parentnew" , TRUE)
			parentnew->DbAppend()
			parentnew->FieldPut(1,1)
			parentnew->DbAppend()
			parentnew->FieldPut(1,2)

			DbUseArea(TRUE,"DBFCDX", cChild, "childnew" , TRUE)
			childnew->DbCreateIndex(cChild,"FLD")
			childnew->DbAppend()
			childnew->FieldPut(1,1)
			childnew->DbAppend()
			childnew->FieldPut(1,2)

			DbCloseAll()

			DbUseArea(TRUE,"DBFCDX", cChild, "childnew" , TRUE)
			DbUseArea(TRUE,"DBFCDX", cParent, "parentnew" , TRUE)
			parentnew->VoDbSetRelation("childnew" , &( "{ ||FLD}") ,"FLD")

			FOR LOCAL nMode := 0 AS INT UPTO 2

//			In the next two, childnew EoF() is false as expected
			// ? "move parent to first record"
			parentnew->DbGoTop()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(1U , childnew->RecNo() )

			// ? "move parent to second record"
			parentnew->DbSkip(+1)
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

//			Here, childnew EoF() becomes true, correct
			// ? "move parent to EoF"
			parentnew->DbSkip(+1)
			DoRelation(nMode)
			Assert.True(childnew->Eof())
			Assert.Equal(3U , childnew->RecNo() )

//			In all the below, childnew EoF() remains TRUE, should had turned to false. Also RecNo remains at 3 (above the last rec)
			// ? "move parent back to last record"
			parentnew->DbSkip(-1)
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

			// ? "move parent to top"
			parentnew->DbGoTop()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(1U , childnew->RecNo() )

			// ? "move parent to bottom"
			parentnew->DbGoBottom()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

			NEXT

			DbCloseAll()

		INTERNAL STATIC METHOD DoRelation(nMode := 0 AS INT) AS VOID
			LOCAL u1,u2 AS USUAL
			? "Parent value:", u1 := u2 := parentnew->FieldGet(1)
			childnew->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 )
			childnew->VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF u2 )
			IF nMode == 1
				childnew->DbGoBottom() // no problem with this instead
			ELSEIF nMode == 2
				childnew->DbGoTop() // <---------- this is what makes the problem manifest itself
			END IF
			? "Child Eof, RecNo:", childnew->Eof(), childnew->RecNo()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD SetScope_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "FLD" , "N" , 4 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf)

			DbAppend()
			FieldPut(1,101)
			DbAppend()
			FieldPut(1,202)
			DbAppend()
			FieldPut(1,301)
			DbAppend()
			FieldPut(1,402)

			DbCreateIndex(cDbf,"FLD")

			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 1 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 1 , TestScope(401,410,FALSE) )
			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(501,510,TRUE)  )
			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbAppend()
			FieldPut(1,103)
			DbAppend()
			FieldPut(1,201)
			DbAppend()
			FieldPut(1,501)
			DbAppend()
			FieldPut(1,403)

			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 2 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 2 , TestScope(401,410,FALSE) )
			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 1 , TestScope(501,510,FALSE) )
			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbAppend()
			FieldPut(1,110)
			DbAppend()
			FieldPut(1,205)
			DbAppend()
			FieldPut(1,321)
			DbAppend()
			FieldPut(1,503)

			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 3 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 2 , TestScope(401,410,FALSE) )
			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 2 , TestScope(501,510,FALSE) )
			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbCloseArea()

		INTERNAL STATIC METHOD TestScope(first AS INT,last AS INT,expected AS LOGIC) AS INT
			LOCAL uValue1,uValue2 AS USUAL
			LOCAL nRecords AS INT
			uValue1 := first
			uValue2 := last
			VoDbOrderInfo( DBOI_SCOPETOP,    "", NIL, REF uValue1 )
			DbGoTop() // without this, the problem does not happen
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF uValue2 )
			DbGoTop()
			Assert.Equal(expected , Eof() )
			nRecords := 0
			DO WHILE .not. EoF()
				nRecords ++
				DbSkip()
			END DO
		RETURN nRecords

        [Fact, Trait("Category", "DBF")];
		METHOD CreateOrder_fieldname_conflict() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "DEFINE_FLD" , "C" , 10 , 0 } , { "GLOBAL_FLD" , "D" , 8 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf, , FALSE)
			Assert.True( DbCreateOrder("TEST1" , cDbf , "Left(DEFINE_FLD,5)") )
			Assert.True( DbCreateOrder("TEST2" , cDbf , "DToS(GLOBAL_FLD)")   )
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD Empty_Filter_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "TESTFLD" , "C" , 10 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf, , FALSE)
			LOCAL uInfo := NIL AS USUAL
			VoDbInfo(DBI_DBFILTER, REF uInfo)
			Assert.False( IsNil(uInfo) )
			Assert.True( uInfo == "" )
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/578
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE, "X")     // "A"
			OrdScope(BOTTOMSCOPE, "X")  // "A"

			Assert.Equal(0, (INT)OrdKeyCount())

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_OrdDescend_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/579
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdDescend ( , , TRUE )  // switch to descend view
			OrdScope(TOPSCOPE, "B")     // Note: must be "R" !
			OrdScope(BOTTOMSCOPE, "R")  // Note: must be "B" !

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyCount())
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyNo())
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()

            SetDeleted(TRUE)
			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdDescend ( , , TRUE )  // switch to descend view
			OrdScope(TOPSCOPE, "B")     // Note: must be "R" !
			OrdScope(BOTTOMSCOPE, "R")  // Note: must be "B" !

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyCount())
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyNo())
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()
            SetDeleted(FALSE)

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyCount_OrdKeyNo_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/583
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 9
				DbSkip()
				Assert.False(Eof())
			NEXT
			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Eof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Eof())

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 2
				DbSkip(-1)
				Assert.False(Bof())
			NEXT
			DbSkip(-1)
			Assert.True(Bof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Bof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Bof())

			DbCloseArea()

			SetDeleted(TRUE)
			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 9
				DbSkip()
				Assert.False(Eof())
			NEXT
			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Eof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Eof())

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 2
				DbSkip(-1)
				Assert.False(Bof())
			NEXT
			DbSkip(-1)
			Assert.True(Bof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Bof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Bof())

			DbCloseArea()
			SetDeleted(FALSE)

        [Fact, Trait("Category", "DBF")];
		METHOD DbOrderInfo_DBOI_POSITION_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/593
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "a" , "b", "c" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )

			DbGoTop()
			Assert.False(Eof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.False(Eof())
			Assert.Equal(2 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.False(Eof())
			Assert.Equal(3 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_POSITION ) )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD Found_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/582
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "a" , "b", "c" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )

			DbSeek ( "B" )
			Assert.True( Found() )

			DbSeek ( "D" )
			Assert.False( Found() )

			DbSeek ( "B" )
			DbSkip()
			Assert.False( Found() )

			DbSeek ( "B" )
			DbSkip(-1)
			Assert.False( Found() )

			DbSeek ( "B" )
			DbGoTop()
			Assert.False( Found() )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyCount_SetDeleted() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/599
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )

			DbGoto(5)
			DbDelete()
			DbGoto(8)
			DbDelete()
			DbGoto(9)
			DbDelete()

			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE, "A")    // "A"  "A"
			OrdScope(BOTTOMSCOPE, "S") // "Z"  "S"

			DbGoTop()
			Assert.Equal( 12, (INT)RecCount() )

			SetDeleted ( TRUE )
			Assert.Equal( 12, (INT)OrdKeyCount() )

			SetDeleted ( FALSE )
			Assert.Equal( 12, (INT)OrdKeyCount() )

			DbCloseArea()
			SetDeleted( FALSE )

        [Fact, Trait("Category", "DBF")];
		METHOD FPT_OpenShared() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/592
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"MEMOFLD","M",10,0}} )
			DbUseArea( TRUE,,cDBF,,FALSE )
			FOR LOCAL n := 1 AS INT UPTO 10
				DbAppend()
			NEXT
			DbCloseArea()

			DbUseArea( TRUE,,cDBF,,TRUE )

			FOR LOCAL n := 1 AS INT UPTO 200
				Assert.True( DbUseArea(TRUE,"DBFCDX",cDbf,"alias" + AsString(n),TRUE) )
				Assert.True( DbCloseArea() )
			NEXT

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD DBClose_tests() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/611
			Assert.False( DbCloseArea() )
			Assert.True( DbCloseAll() )
			Assert.False( DbCloseArea() )
			Assert.True( DbCloseAll() )

        [Fact, Trait("Category", "DBF")];
		METHOD ReadOnly_Test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/610
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","C",10,0}} , {"a","b"} )
			DbCloseArea()

			Assert.True( DbUseArea( TRUE,,cDBF,,FALSE,TRUE ) )
			Assert.True( DbCreateIndex(cDbf,"FLD") )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(TRUE,"DBFCDX", cDbf , , TRUE) )
			Assert.True( DbCloseArea() )

        [Fact, Trait("Category", "DBF")];
		METHOD DbOrderInfo_withnoindex_Test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/627
			// https://github.com/X-Sharp/XSharpPublic/issues/666
			// https://github.com/X-Sharp/XSharpPublic/issues/684

			// Insane inconsistent VO behavior...
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","C",10,0}} , {"a","b"} )
			DbCloseArea()

			LOCAL uRet AS USUAL

			uRet := DbOrderInfo(DBOI_NAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_FULLPATH)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_EXPRESSION)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_CONDITION)
			Assert.True( IsNil(uRet) )

			uRet := DbOrderInfo(DBOI_POSITION)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYTYPE)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYSIZE)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ISCOND)
			Assert.True( IsNil(uRet) )

			DbUseArea(TRUE, "DBFNTX", cDbf)

			uRet := DbOrderInfo(DBOI_NAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_FULLPATH)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_EXPRESSION) // NIL in VO, empty string in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_CONDITION)  // NIL in VO, empty string in X#
			Assert.True( IsNil(uRet) )

			uRet := DbOrderInfo(DBOI_POSITION)   // 0 in VO, 1 in X#
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )

			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".NTX" )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".NTX" )
			uRet := DbOrderInfo(DBOI_KEYTYPE)    // NIL in VO, 0 in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYSIZE)    // NIL in VO, 0 in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ISCOND)     // NIL in VO, .F. in X#
			Assert.True( IsNil(uRet) )

			DbCloseArea()

			DbUseArea(TRUE, "DBFCDX", cDbf)

			uRet := DbOrderInfo(DBOI_NAME)       // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_BAGNAME)    // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_INDEXNAME)  // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_FULLPATH)   // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_EXPRESSION)
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_CONDITION)
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )

			uRet := DbOrderInfo(DBOI_POSITION)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 1 )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 1 )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )

			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".CDX" )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".CDX" )
			uRet := DbOrderInfo(DBOI_KEYTYPE)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_KEYSIZE)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_ISCOND)
			Assert.True( IsLogic(uRet) )
			Assert.True( uRet == FALSE )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD FieldGet_After_Skip_zero() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/698

			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","N",5,0}} , {1,2} )
			DbCreateOrder("ORDER1", cDbf, "FLD")

			DbGoTop()
			DbSkip(-1)
			Assert.True( Bof() )
			Assert.True( FieldGet(1) == 1 )
			Assert.Equal( 1U , RecNo() )

			DbSkip(0)
			Assert.True( Bof() )
			Assert.True( FieldGet(1) == 1 )
			Assert.Equal( 1U , RecNo() )

			DbGoBottom()
			Assert.False( Eof() )
			Assert.True( FieldGet(1) == 2 )
			Assert.Equal( 2U , RecNo() )

			DbSkip(+1)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			DbSkip(0)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			DbSkip(+1)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			Assert.True( Eof() )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD Scope_Updating_From_another_woarkarea() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/699

			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","N",5,0}} , {1,2,3} )
			DbCreateOrder("ORDER1", cDbf, "FLD")
			DbCloseArea()

			LOCAL nScope AS DWORD
			nScope := 22

			DbUseArea(TRUE, "DBFCDX" , cDbf , "one" , TRUE)
			DbUseArea(TRUE, "DBFCDX" , cDbf , "two" , TRUE)

			one->DbSetOrder( "ORDER1" )
			one->DbOrderInfo(DBOI_SCOPETOP ,NIL ,NIL ,nScope)
			one->DbOrderInfo(DBOI_SCOPEBOTTOM ,NIL,NIL , nScope)

			one->DbGoTop()
			Assert.True( one->Eof() )

			two->DbAppend()
			two->FieldPut( 1 , nScope )
			two->DbCommit()
			two->DbUnLock()

			LOCAL cRecords AS STRING

			one->DbGoTop()
			Assert.False( one->Eof() )
			cRecords := ""
			WHILE ! one->Eof()
				cRecords += AsString( one->FieldGet( 1 ) )
				one->DbSkip()
			ENDDO
			Assert.Equal( "22" , cRecords )

			one->DbOrderInfo(DBOI_SCOPETOP ,NIL ,NIL ,nScope)
			one->DbOrderInfo(DBOI_SCOPEBOTTOM ,NIL,NIL , nScope)
			one->DbGoTop()
			Assert.False( one->Eof() )
			cRecords := ""
			WHILE ! one->Eof()
				cRecords += AsString( one->FieldGet( 1 ) )
				one->DbSkip()
			ENDDO
			Assert.Equal( "22" , cRecords )

			one->DbCloseArea()
			two->DbCloseArea()

		STATIC PRIVATE METHOD GetTempFileName() AS STRING
           STATIC nCounter AS LONG
            ++nCounter
		    RETURN GetTempFileName("testcdx"+NTrim(nCounter))

		STATIC PRIVATE METHOD GetTempFileName(cFileName AS STRING) AS STRING
			// we may want to put them to a specific folder etc
		RETURN cFileName

	END CLASS
END NAMESPACE

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit
USING System.Globalization

DEFINE GLOBAL_FLD := 123
GLOBAL DEFINE_FLD := "abc"

BEGIN NAMESPACE XSharp.VO.Tests

	CLASS DbfCdxTests

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBCreate_Tests() AS VOID
			LOCAL aFields AS ARRAY
			aFields := {{"TEST","C",10,0}}

			LOCAL cFileName_WithExt AS STRING
			LOCAL cFileName_NoExt AS STRING
			cFileName_NoExt := "DBCreate_Tests"
			cFileName_WithExt := cFileName_NoExt + ".dbf"
			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_NoExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )

			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_WithExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )

			cFileName_WithExt := cFileName_NoExt + ".none"
			IF System.IO.File.Exists(cFileName_WithExt)
				System.IO.File.Delete(cFileName_WithExt)
			END IF
			Assert.True(  DbCreate(cFileName_WithExt , aFields , "DBFCDX")  )
			Assert.True(  System.IO.File.Exists(cFileName_WithExt) )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_Exclusive() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cFileName AS STRING
			aFields := {{"TEST","C",10,0}}
			cFileName := "DBAppend_Exclusive"

			Assert.True(  DbCreate(cFileName , aFields , "DBFCDX")  )
			Assert.True(  DbUseArea(,"DBFCDX",cFileName,,FALSE) )
			Assert.True(  RecCount() == 0 )
			Assert.True(  DbAppend() )
			FieldPut(1 , "test")
			Assert.True(  AllTrim(FieldGet(1)) == "test" )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_Shared() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cFileName AS STRING
			aFields := {{"TEST","C",10,0}}
			cFileName := "DBAppend_Shared"

			Assert.True(  DbCreate(cFileName , aFields , "DBFCDX")  )
			Assert.True(  DbUseArea(,"DBFCDX",cFileName,,TRUE) )
			Assert.True(  RecCount() == 0 )
			Assert.True(  DbAppend() )
			FieldPut(1 , "test")
			Assert.True(  AllTrim(FieldGet(1)) == "test" )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBAppend_more() AS VOID
		LOCAL cDbf AS STRING
			cDbf := "testappend.DbF"
			RddSetDefault( "DBFCDX" )
			Assert.True(  DbCreate(cDbf , { {"TEST","C",10,0} }) )
			// Appending in exclusive mode:
			Assert.True( DbUseArea(, , cDbf , "alias1" , FALSE) )
			Assert.True( DbAppend() )
			Assert.True( RecCount() == 1 )
			FieldPut(1, "test") // ok
			Assert.True( AllTrim(FieldGet(1)) == "test" )
			Assert.True( DbCloseArea() )

			// Appending in SHARED mode:
			Assert.True( DbUseArea(, , cDbf , "alias2" , TRUE) )
			Assert.True( RecCount() == 1 )
			Assert.True( DbAppend() )// returns true but does not append record
			Assert.True( RecCount() == 2 )
			FieldPut(1, "test2") // ok
			Assert.True( AllTrim(FieldGet(1)) == "test2" )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBFFuncs")];
		METHOD DBUseArea_same_file_twice() AS VOID
		LOCAL cDbf AS STRING
			RddSetDefault( "DBFCDX" )
			cDbf := "testtwice.DbF"
			Assert.True(  DbCreate(cDbf , { {"TEST","C",10,0} }) )

			// shared mode
			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD VODBInfoTest() AS VOID

			LOCAL cFileName AS STRING
			cFileName := GetTempFileName("test")
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName , { {"CFIELD","C",10,0} })
			DbUseArea(,,cFileName)
			DbAppend()
			Assert.Equal(1, (LONG) RecNo())
			LOCAL u := NIL AS USUAL
			VoDbSkip(-1)

			VoDbInfo(DBI_FULLPATH , REF u)
			LOCAL c AS STRING
			c := u
			? c
			Assert.True(c:EndsWith("test.DBF") .AND. c:Contains(":\"))
			VoDbInfo(DBI_DB_VERSION , REF u)
			Assert.True(SLen(u) > 1)
			VoDbInfo(DBI_ALIAS , REF u)
			Assert.Equal("TEST" , u)

			VoDbInfo(DBI_BOF , REF u)
			Assert.Equal(TRUE , (LOGIC) u)
			VoDbInfo(DBI_EOF , REF u)
			Assert.Equal(FALSE ,(LOGIC)  u)
			VoDbInfo(DBI_ISANSI , REF u)
			Assert.Equal(SetAnsi() ,(LOGIC)  u)
			VoDbInfo(DBI_FCOUNT , REF u)
			Assert.Equal(1, (LONG)  u)
			VoDbInfo(DBI_READONLY , REF u)
			Assert.Equal(FALSE,(LOGIC)  u)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD AppendShared() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName("testAppendShared")
			FErase(cDbf + ".cdx")

			RddSetDefault( "DBFCDX" )
			DbCreate(cDbf , { {"TEST","C",10,0} })

//			Appending in exclusive mode:
			DbUseArea(, , cDbf , "alias2" , FALSE)
			Assert.True( DbAppend() )
			Assert.Equal( 1 , RecCount() )
			FieldPut(1, "test") // ok
			DbCloseArea()

//			Appending in SHARED mode:
			DbUseArea(, , cDbf , "alias2" , TRUE)
			Assert.True( DbAppend() ) // returns true but does not append record
			Assert.Equal( 2 , RecCount() ) // returns 1, wrong
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD AliasNameReuse() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName("testdbf")
			FErase(cDbf + ".cdx")

			RddSetDefault( "DBFCDX" )

			DbCreate(cDbf , { {"TEST","C",10,0} })

//			opening and closing once
			DbUseArea(, , cDbf , , FALSE)
			DbCloseArea()

//			opening and closing again
			Assert.True( DbUseArea(, , cDbf , , FALSE) )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SavingDecimalValues() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,2},{"FLD2","N",10,0}})
			DbUseArea(,,cFileName)
			DbAppend()

			SetDecimalSep(Asc(","))
			FieldPut(1 , 12.34) // not saved in the dbf
			Assert.Equal(12.34 , (FLOAT) FieldGet(1)) // 0,00

			SetDecimalSep(Asc("."))
			FieldPut(1 , 12.34)
			Assert.Equal(12.34 , (FLOAT) FieldGet(1))

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBCommitAfterFieldput() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,4}})
			DbUseArea( , , cFileName , "tempalias")
			DbAppend()
			DbCloseArea()

			DbUseArea( , , cFileName)
			FieldPut(1 , FLOAT{46.11}) // ! a float isn/t stored !
			DbCommit()
			Assert.Equal(46.11 , (FLOAT) FieldGet(1)) // runtime exception
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD FieldNameSym() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","N",10,4}})
			DbUseArea( , , cFileName , "tempalias")
			DbAppend()
			Assert.Equal("", FieldName(100)) // exception
			Assert.Equal("", FieldName(0))
			Assert.Equal(NULL_SYMBOL, FieldSym(100))
			Assert.Equal(NULL_SYMBOL, FieldSym(0))
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRLockListTest() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0}})
			DbUseArea( , , cFileName , "tempalias" , TRUE)
			DbAppend()
			DbAppend()
			DbGoTop()
			DbRLock()
			DbRLockList()
			Assert.Equal(1, (INT) ALen(DbRLockList()))
			Assert.Equal(1, (INT) DbRLockList()[1])
			DbUnLock()
			DbSkip()
			DbRLock()
			Assert.Equal(1, (INT)  ALen(DbRLockList()))
			Assert.Equal(2, (INT) DbRLockList()[1])
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBFilter() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			IF System.IO.File.Exists(cDbf)
				System.IO.File.Delete(cDbf)
			END IF
			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")
			DbAppend()
			FieldPut(1, "DEF")
			DbAppend()
			FieldPut(1, "GHI")
			DbAppend()
			FieldPut(1, "JKL")
			Assert.Equal(4 , (INT) RecCount())
			Assert.Equal(4 , (INT) LastRec())
			DbCloseArea()

			DbUseArea(,,cDbf)
//			"Setting filter to GHI, should be one record:"
//			"Instead, record 1 and 3 are shown"
			DbSetFilter({||AllTrim(FIELD->CFIELD) == "GHI"})
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				Assert.Equal(3 , (INT) RecNo())
				FieldGet(1)
				DbSkip(+1)
				nCount ++
			END DO
			Assert.Equal(1 , nCount)

			DbGoBottom()
			Assert.False( Eof() )
			nCount := 0
			DO WHILE .NOT. EoF()
				Assert.Equal(3 , (INT) RecNo())
				nCount ++
				FieldGet(1)
				DbSkip(+1)
			END DO
			Assert.Equal(1 , nCount)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRecordInfo_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL l AS LOGIC
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")

			l := DbRecordInfo( DBRI_RECNO ) // exception
			Assert.True(l)
			l := DbRecordInfo( DBRI_DELETED ) // exception
			Assert.False(l)
			l := DbRecordInfo( DBRI_LOCKED ) // exception
			Assert.True(l)

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBFieldInfo_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"NFIELD","N",10,3}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, 1.23)

			Assert.Equal("NFIELD",	DbFieldInfo( DBS_NAME , 1 ) ) // NullReferenceException
			Assert.Equal("N",		DbFieldInfo( DBS_TYPE , 1 ) )
			Assert.Equal(10,		(INT) DbFieldInfo( DBS_LEN , 1 ) )
			Assert.Equal(3,			(INT) DbFieldInfo( DBS_DEC , 1 ) )
			Assert.Equal(5,			(INT) DbFieldInfo( DBS_PROPERTIES , 1 ) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBRecordInfo_test2() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			DbCreate(cDbf, {{"CFIELD","C",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, "ABC")
			DbAppend()
			FieldPut(1, "DEF")

			DbGoTop()
			Assert.Equal(1, (INT) RecNo())
			Assert.Equal(FALSE, Eof())

//			 Any of the below cause the record pointer to go EOF
			Assert.False( DbRecordInfo(DBRI_DELETED , 0) )
			DbRecordInfo(DBRI_BUFFPTR , 0)
			DbRecordInfo(DBRI_RAWDATA , 0)

			Assert.Equal(1, (INT) RecNo())
			Assert.Equal(FALSE, Eof())

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBContinue_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cDbf, {{"NFIELD","N",10,0}}, "DBFCDX", TRUE)
			DbAppend()
			FieldPut(1, 123)
			DbAppend()
			FieldPut(1, 456)
			DbAppend()
			FieldPut(1, 789)

			DbGoTop()
			Assert.True( DbLocate({||_FIELD->NFIELD > 300} , , , , TRUE) ) // DBSCOPEREST
			Assert.True( Found() )
			Assert.Equal(456.0 , (FLOAT)  FieldGet(1) )

//			DBContinue() returns TRUE (correct) but does not move record pointer at all
			Assert.True( DbContinue() )
			Assert.True( Found() )
			Assert.Equal( 789.0 , (FLOAT)  FieldGet(1) )

			Assert.True( DbContinue() )
			Assert.False( Found() )
			Assert.Equal( 0.0 , (FLOAT) FieldGet(1) )

			Assert.True( DbContinue() )
			Assert.False( Found() )
			Assert.Equal( 0.0 , (FLOAT) FieldGet(1) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBAppendWithNoWorkarea() AS VOID
			RddSetDefault("DBFCDX")

			DbCloseAll()
			Assert.False( DbAppend() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Shared_Cdx() AS VOID
			SELF:Shared_Cdx_helper(TRUE)
			SELF:Shared_Cdx_helper(FALSE)
		RETURN
		PRIVATE METHOD Shared_Cdx_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
            RddSetDefault("DBFCDX")
			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
            FErase(cCdx)

			Assert.True( DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }}) )
			Assert.True( DbUseArea(,,cDbf,,FALSE) )
			Assert.True( DbAppend() )
			FieldPut ( 1 , "B")
			Assert.True( DbAppend() )
			FieldPut ( 1 , "A")
			Assert.True( DbCloseArea() )

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////94B//8AAA8PEAQEAwAGMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABURVNUQ0RYAAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBDRklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////+AB//8AAA8PEAQEAwIAkAEAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJB"))
			ELSE
				Assert.True( DbUseArea(,,cDbf,,TRUE) ) // ----- opening in SHARED mode
				Assert.True( DbCreateIndex(cCdx , "CFIELD") ) // returns TRUE
				Assert.True( DbCloseArea() )
			END IF

			Assert.True( DbUseArea(,,cDbf,,FALSE) )
			Assert.True( DbSetIndex(cCdx) )
			DbGoTop()
			Assert.True( AllTrim(FieldGet(1)) == "A" )
			DbGoBottom()
			Assert.True( AllTrim(FieldGet(1)) == "B" )
			Assert.True( DbCloseArea() ) // XSharp.RDD.RddError here

            Assert.True( FErase(cDbf + ".dbf") )
            Assert.True( FErase(cCdx) ) // false if still in use

		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Save_NULL_DATE() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			Assert.True(  DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 },;
			{"DFIELD" , "D" , 8 , 0 }}) )
			Assert.True( DbUseArea(,,cDbf) )
			DbAppend()
			FieldPut ( 1 , "B")
			DbAppend()
			FieldPut ( 1 , "A")
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(,,cDbf) )
			LOCAL u AS USUAL
			u := FieldGet(2) // it should be a NULL_DATE
			Assert.True( u == NULL_DATE )
			FieldPut(2,u) // exception
			FieldPut(2,NULL_DATE) // exception
			Assert.True( FieldGet(2) == NULL_DATE )
			Assert.True(  DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Issues() AS VOID
			SELF:Cdx_Issues_Helper(TRUE)
			SELF:Cdx_Issues_Helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Issues_Helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			LOCAL aResult AS ARRAY

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName("testcdx1"+IIF(lUseIndexFormVO, "V","X"))
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }} , "DBFCDX")
			DbUseArea(,,cDbf)
			DbAppend()
			FieldPut ( 1 , "ABC")
			DbAppend()
			FieldPut ( 1 , "GHI")
			DbAppend()
			FieldPut ( 1 , "DEF")
			DbAppend()
			FieldPut ( 1 , "K")
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgxAAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBDRklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9IB//8AAA8PEAQEAwEAcAMAcAIAcAQAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLR0hJREVGQUJD"))
			ELSE
				Assert.True( DbUseArea(,,cDbf) )
				Assert.True( DbCreateIndex(cCdx , "CFIELD") )
				Assert.True( DbCloseArea() )
			END IF

			Assert.True( DbUseArea(,,cDbf,,FALSE) )
//			Assert.True( DBSetIndex(cCdx) )
			Assert.True( DbSetOrder(1) )

			aResult := GetRecords()
//			should be ABC, DEF, GHI, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "DEF")
			Assert.True( aResult[3] == "GHI")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip()
			FieldPut(1,"HHH")
			aResult := GetRecords()
//			should be ABC, GHI, HHH, K, because the record has been moved in the index
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "GHI")
			Assert.True( aResult[3] == "HHH")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip(2)
			FieldPut(1,"DEF") // restore it

			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(,,cDbf,,TRUE) )
			Assert.True( DbSetIndex(cCdx) )
			aResult := GetRecords()
//			should be ABC, DEF, GHI, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "DEF")
			Assert.True( aResult[3] == "GHI")
			Assert.True( aResult[4] == "K")

			DbGoTop()
			DbSkip()
			Assert.True(RLock())
			FieldPut(1,"III")
			aResult := GetRecords()
//			should be ABC, GHI, III, K
			Assert.True( aResult[1] == "ABC")
			Assert.True( aResult[2] == "GHI")
			Assert.True( aResult[3] == "III")
			Assert.True( aResult[4] == "K")

			Assert.True( DbCloseArea() )
		RETURN

		PRIVATE STATIC METHOD GetRecords() AS ARRAY
			LOCAL aResult AS ARRAY
			aResult := {}
			DbGoTop()
			DO WHILE .NOT. Eof()
				AAdd(aResult , AllTrim(FieldGet(1)))
				DbSkip()
			END DO
		RETURN aResult

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Issues2() AS VOID
			SELF:Cdx_Issues2_helper(TRUE)
			SELF:Cdx_Issues2_helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Issues2_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cFileName AS STRING
			LOCAL cCdx AS STRING
			cFileName := GetTempFileName("testcdx")
			cCdx := cFileName + ".cdx"
			FErase(cCdx)

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0},{"FLD2","N",10,0}})
			DbUseArea( , , cFileName , , FALSE)
			FOR LOCAL n := 1 AS INT UPTO 10
				DbAppend()
				FieldPut(1, n:ToString())
				FieldPut(2, n)
			NEXT
			IF lUseIndexFormVO
				Assert.True( DbCloseArea() )
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgyAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQABAAAABQBGTEQyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMACgD//////////78B//8AAA8PEAQEAwEAYAIAcAMAYQQAYQUAYQYAYQcAYQgAYQkAYQoAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQiIBwYFBAIwL/w"))
			ELSE
				Assert.True( DbCreateIndex(cCdx , "FLD2") )
				Assert.True( DbCloseArea() )
			END IF

			DbUseArea( , , cFileName , , FALSE)
//			Assert.True( DBSetIndex(cCdx) )
			Assert.True( DbSetOrder(1) )
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
				nCount ++
				Assert.True( FieldGet(2) == RecNo() )
				Assert.True( FieldGet(2) == nCount )
				Assert.True( DbSkip() )
			END DO
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD WorkareaNums() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			Assert.True( DbCreate(cFileName, {{"FLD1","C",10,0}}) )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a1") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a2") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea ( TRUE , , cFileName , "a3") )
			Assert.Equal( 1u , DbGetSelect() )
			Assert.True( DbCloseArea() )
		RETURN

		// FOX-ES1QLR6Y5L , dbRecordInfo ( DBRI_LOCKED ) always returns .f.
		[Fact, Trait("Category", "DBF")];
		METHOD DBRI_LOCKED_test() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")
            TRY
			SetExclusive ( FALSE )
			DbCreate ( cFileName , { {"id", "C", 5, 0} })

			DbUseArea ( , , cFileName )
			DbAppend()
			DbAppend()
			DbAppend()
			DbGoTop()

			Assert.True( DbRLock ( RecNo() ) )
			Assert.True( DbRecordInfo ( DBRI_LOCKED ) ) // Should show TRUE
			Assert.True( AScan ( DbRLockList() , RecNo() ) > 0 )

			DbSkip()
//			record 2 - no lock
			Assert.False( DbRecordInfo ( DBRI_LOCKED ) )
			Assert.False( AScan ( DbRLockList() , RecNo() ) > 0 )

			DbSkip()
			Assert.True( DbRLock ( RecNo() ) )
			Assert.True( DbRecordInfo ( DBRI_LOCKED ) ) // Should show TRUE
			Assert.True( AScan ( DbRLockList() , RecNo() ) > 0 )

			LOCAL a AS ARRAY
			a:= DbRLockList()
			Assert.Equal( 2 , (INT) ALen(a) )
			Assert.Equal( 1 , (INT) a[1] )
			Assert.Equal( 3 , (INT) a[2] )

            FINALLY
			DbCloseArea()

			SetExclusive ( TRUE ) // restore
            END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Alias_test() AS VOID

			RddSetDefault("DBFCDX")

			DbCloseAll()
			Assert.True( Alias() == "" )
			Assert.True( Alias0() == "" )
			Assert.True( Alias0Sym() == "" )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBCreate_test() AS VOID
			LOCAL cFileName AS STRING
			cFileName := GetTempFileName()
			FErase(cFileName + ".cdx")

			RddSetDefault("DBFCDX")

			DbCreate(cFileName, {{"FLD1","C",10,0}})
			DbUseArea(,,cFileName,,FALSE)
			DbCloseArea()

//			exception here
			Assert.True( DbCreate(cFileName, {{"FLD1","N",10,0}}) )

			Assert.True( DbUseArea(,,cFileName) )
			DbAppend()
			FieldPut(1 , 123)
			Assert.True( FieldGet(1) == 123 )
			Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBError_test() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			DbCreate( cDbf , {{"CFIELD" , "C" , 10 , 0 }})
			DbUseArea(,,cDbf,,TRUE)
			Assert.True( DbAppend() )
			Assert.True( DbUnLock() )
			TRY
				? FieldPut ( 1 , "ABC") // record not locked
			CATCH e AS XSharp.Error
				? e:Message
				? e:GenCodeText
				? e:SubCodeText // check if this displays correctly
				? e:OSCodeText
				? e:ToString() // exception here
			FINALLY
				Assert.True( DbCloseArea() )
			END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Eof_test() AS VOID
			SELF:Cdx_Eof_test_helper(TRUE)
			SELF:Cdx_Eof_test_helper(FALSE)
		RETURN
		PRIVATE METHOD Cdx_Eof_test_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,123)
			DbAppend()
			FieldPut(1,456)
			IF lUseIndexFormVO
				DbCloseArea()
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFgzAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBORklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////90B//8AAA8PEAQEAwEAUAIAUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHyAwF7A"))
			ELSE
				DbCreateIndex(cCdx, "NFIELD")
				DbCloseArea()
			END IF

			// necessary sequence to reproduce the problem below
			DbUseArea(,,cDbf,,FALSE)
//			DBSetIndex(cCdx)
			DbSetOrder(1)
			DbGoTop()
			Assert.Equal(1, (INT)RecNo()) // 1
			DbGoBottom()
			Assert.Equal(2, (INT)RecNo()) // 2
			DbSkip(-1)
			Assert.Equal(1, (INT)RecNo()) // 1
			DbGoto(2)
			Assert.Equal(2, (INT)RecNo()) // 2

			DbSkip(+1)
			Assert.Equal(TRUE, (LOGIC)Eof()) // FALSE, wrong
			Assert.Equal(3, (INT)RecNo()) // 2, wrong

			DbSkip(+1)
			Assert.Equal(TRUE, (LOGIC)Eof()) // TRUE
			Assert.Equal(3, (INT)RecNo()) // 3

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_SETCODEBLOCK() AS VOID
			LOCAL cDBF, cCDX AS STRING

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("test")
			cCDX := cDBF + ".cdx"
			FErase(cCdx)

			DbCreate( cDBF , {{"ID" , "C" , 5 , 0 }})
			DbUseArea(,,cDBF)

			DbAppend()
			FieldPut(1, "one")

			DbCreateIndex(cCDX , "Upper (ID)")
			DbCloseArea()

			DbUseArea(,,cDBF)
			DbSetIndex(cCDX)

			? "DBOI_SETCODEBLOCK" , DbOrderInfo( DBOI_SETCODEBLOCK )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_test() AS VOID
			SELF:OrdScope_test_helper(TRUE)
			SELF:OrdScope_test_helper(FALSE)
		RETURN
		PRIVATE METHOD OrdScope_test_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			cDbf := GetTempFileName("testcdx")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)

			RddSetDefault("DBFCDX")

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cCdx , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg0AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBORklFTEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAFAD//////////5cB//8AAA8PEAQEAwEAYAIAcAMAYQQAYQUAYQYAYQcAYQgAYQkAYQoAYQsAYQwAYQ0AYQ4AYQ8AYRAAYREAYRIAYRMAYRQAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDMyMTAuLCooJiQiIBwYFBAIwL/w"))
			ELSE
				DbCreateIndex(cDbf , "NFIELD")
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDbf) // 20 records
//			DBSetIndex ( cDbf )
			DbSetOrder(1)
			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 20)
			Assert.Equal( (INT) OrdScope(TOPSCOPE, 5) , 0) // returns previous scope
			Assert.Equal( (INT) OrdScope(BOTTOMSCOPE, 10) , 0) // returns previous scope
			DbGoTop()

			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 6) // still 20 - but must be 6
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof() // all 20 records are listed
				? FieldGet ( 1 )
				DbSkip ( 1 )
				nCount ++
			ENDDO
			Assert.Equal( 6 , nCount)
			Assert.Equal( 5 , (INT) DbOrderInfo( DBOI_SCOPETOP ) ) // {(0x0000)0x00000000} CLASS
			Assert.Equal( 10 , (INT) DbOrderInfo( DBOI_SCOPEBOTTOM ) ) // {(0x0000)0x00000000} CLASS
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_test_with_Ordinal_Collation() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			LOCAL uCollation AS USUAL
			uCollation := SetCollation(#ORDINAL)

			DbCreate( cDbf, {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			DbCreateIndex(cDbf + ".cdx" , "NFIELD")
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDbf)
			DbSetIndex ( cDbf + ".cdx" )
			Assert.Equal( (INT) DbOrderInfo( DBOI_KEYCOUNT ) , 20)
			Assert.Equal( (INT) UsualType( DbOrderInfo( DBOI_KEYCOUNT )  ) , 1) // first time returns 6
			Assert.Equal( (INT) UsualType( DbOrderInfo( DBOI_KEYCOUNT )  ) , 1) // second time it returns 1 correctly
			DbCloseArea()

			SetCollation(uCollation)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_index_without_extension() AS VOID
			LOCAL cDbf AS STRING
			cDbf := "noextension"
			FErase(cDbf + ".cdx")
			FErase(cDbf)

			RddSetDefault("DBFCDX")

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,"DBFCDX",cDbf)
			FOR LOCAL n := 1 AS INT UPTO 20
				DbAppend()
				FieldPut(1,n)
			NEXT
			DbCreateIndex(cDbf , "NFIELD")
			Assert.True( File(cDbf + ".dbf" ) )
			Assert.True( File(cDbf + ".cdx" ) )
			Assert.False( File(cDbf) )
			DbCloseArea()

		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_test() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDBF, cCDX AS STRING

			RddSetDefault("DBFCDX")

			aValues := { "ssss" , "hhhh", "wwww" , "aaaa" }
			cDBF := GetTempFileName()
			cCDX := cDbf
			FErase(cCdx + ".cdx")
			DbCreate( cDBF , {{"LAST" , "C" , 20 , 0 } , ;
								{"TEXT1" , "C" , 10 , 0 } , ;
								{"NUM1" , "N" , 10 , 2 }})

			DbUseArea(,,cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbCreateIndex(cCDX, "Upper ( Last)")
			DbCloseArea()

			DbUseArea(,,cDBF,,TRUE) // open shared !
			DbSetIndex(cCDX)
			DbGoTop()
			? "current (indexed) order"
			DO WHILE ! Eof()
				? FieldGet ( 1 )
				DbSkip ( 1 )
			ENDDO
			DbGoTop()
			// "now replace the index field #LAST content 'aaaa' with 'pppp'"
			// "and also update another field"
			Assert.True( DbRLock ( RecNo() )  )
			// "Replacing", AllTrim(FieldGet(1)), "with 'pppp'"
			FieldPut ( 1 , "pppp" ) // Note: This is the index field

//	 this is what causes the problem, updating a second field
//	 if this fieldput is put above the first one, then sample works correctly
//	 either one of the fieldputs below cause the problem to surface
			FieldPut ( 2 , "Eins" )
			FieldPut ( 3 , 123.45 )

			DbCommit()

			DbRUnLock ( RecNo() )

			Assert.False( DbSeek( "AAAA" ) ) // must show .F.
			Assert.True( DbSeek ("PPPP" ) ) // must show .T.
			// "Record order now:"
			// "(should be hhhh, pppp, ssss , wwww)"
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
				? AllTrim(FieldGet(1)) , FieldGet(3) , AllTrim(FieldGet(2))
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.Equal( "hhhh", AllTrim(FieldGet(1)) )
				CASE nCount == 2
					Assert.Equal( "pppp", AllTrim(FieldGet(1)) )
				CASE nCount == 3
					Assert.Equal( "ssss", AllTrim(FieldGet(1)) )
				CASE nCount == 4
					Assert.Equal( "wwww", AllTrim(FieldGet(1)) )
				END CASE
				DbSkip ( 1 )
			ENDDO
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_KEYCOUNT() AS VOID
			SELF:DBOrderInfo_DBOI_KEYCOUNT_helper(TRUE)
			SELF:DBOrderInfo_DBOI_KEYCOUNT_helper(FALSE)
		RETURN
		PRIVATE METHOD DBOrderInfo_DBOI_KEYCOUNT_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			aValues := { 44 , 12, 34 , 21 }
			DbCreate( cDBF , {{"AGE" , "N" , 3 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			Assert.Equal(0 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 0,  ok
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 0,  ok

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg1AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAAAABABhZ2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAo"))
			ELSE
				DbCreateIndex(cDbf, "age" )
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbSetOrder(1)
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DbGoTop()
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DO WHILE ! Eof()
//			? FieldGet ( 1 )
				DbSkip(1)
			ENDDO
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // NIL, should be 4
			DbSkip(-1)
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, correct
			DbCloseArea ()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_FALSE() AS VOID
			SELF:SetDeleted_FALSE_helper(TRUE)
			SELF:SetDeleted_FALSE_helper(FALSE)
		RETURN
		PRIVATE METHOD SetDeleted_FALSE_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")
			SetDeleted(FALSE)

//			test also with those
//			aValues := { "vaa" , "abba", "acb" , "aaab"  , "adab"  , "baac"  , "aeab"  , "baaAaa" }
			aValues := { "vvv" , "abb", "acb" , "aaa"  , "bbb" }
			DbCreate( cDBF , {{"LAST" , "C" ,10 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			IF lUseIndexFormVO
				DbCloseArea()
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg2AAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAABAAAADABVcHBlcihMQVNUKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABQD//////////8wB//8AAA8PEAQEAwQAcAIAcQMAcQUAcAEAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWVlZCQkJDQkJCQUFB"))
			ELSE
				DbCreateIndex(cDbf, "Upper(LAST)" )
				DbCloseArea()
			END IF

			DbUseArea(,"DBFCDX",cDBF,,TRUE)
			DbSetOrder(1)
			Assert.Equal(5 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			// ? "Setting scope"
			LOCAL u AS USUAL
			u := "A"
			VoDbOrderInfo( DBOI_SCOPETOP, "", NIL, REF u )
			u := "A"
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF u )

			DbGoTop()
			Assert.Equal(4 , (INT)RecNo())
			DbGoBottom()
			Assert.Equal(3 , (INT)RecNo())

			DbGoTop()

			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DO WHILE ! Eof()
				DbSkip(1)
			ENDDO
			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_TRUE() AS VOID
			SELF:SetDeleted_TRUE_helper(TRUE)
			SELF:SetDeleted_TRUE_helper(FALSE)
		RETURN
		PRIVATE METHOD SetDeleted_TRUE_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx")
			FErase(cDbf + ".cdx")

			SetDeleted(TRUE)

//			test also with those
//			aValues := { "vaa" , "abba", "acb" , "aaab"  , "adab"  , "baac"  , "aeab"  , "baaAaa" }
			aValues := { "vvv" , "abb", "acb" , "aaa"  , "bbb" }
			DbCreate( cDBF , {{"LAST" , "C" ,10 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg2AAoAAAAAAAAAAAAACgBgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAABAAAADABVcHBlcihMQVNUKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABQD//////////8wB//8AAA8PEAQEAwQAcAIAcQMAcQUAcAEAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWVlZCQkJDQkJCQUFB"))
				DbUseArea(,"DBFCDX",cDBF,,TRUE)
			ELSE
				DbUseArea(,"DBFCDX",cDBF,,TRUE)
				DbCreateIndex(cDbf, "Upper(LAST)" )
			END IF

			DbSetOrder(1)
			Assert.Equal(5 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			// ? "Setting scope"
			LOCAL u AS USUAL
			u := "A"
			VoDbOrderInfo( DBOI_SCOPETOP, "", NIL,  REF u )
			u := "A"
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL,  REF u )

			DbGoTop()
			Assert.Equal(4 , (INT)RecNo())
			DbGoBottom()
			Assert.Equal(3 , (INT)RecNo())

			DbGoTop()

			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DO WHILE ! Eof()
				DbSkip(1)
			ENDDO
			Assert.Equal(3 , (INT)DbOrderInfo( DBOI_KEYCOUNT ))
			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_NUMBER() AS VOID
			SELF:DBOrderInfo_DBOI_NUMBER_helper(TRUE)
			SELF:DBOrderInfo_DBOI_NUMBER_helper(FALSE)
		RETURN
		PRIVATE METHOD DBOrderInfo_DBOI_NUMBER_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDBF AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			aValues := { 44 , 12, 34 , 21 }
			cDBF := GetTempFileName("testcdx8")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)
			IF System.IO.File.Exists(cCdx)
				System.IO.file.Delete(cCdx)
			END IF
			DbCreate( cDBF , {{"AGE" , "N" , 3 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_KEYCOUNT ) )   //  0  ok
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_KEYCOUNT ) ) //  0 ,ok
			Assert.Equal(0, (INT)DbOrderInfo( DBOI_NUMBER ) )  //  -1,  but should show 0

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg4AAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAAAABABhZ2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAo"))
			ELSE
				DbCreateIndex( cCdx, "age" )
			END IF
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbSetOrder(1)

			DbGoTop()
			DO WHILE ! Eof()
//				? FieldGet ( 1 )
				DbSkip(1)
			ENDDO

			Assert.True( DbClearIndex(, cCdx) )

			DbGoTop()
			Assert.Equal(1, (INT)RecNo())

			Assert.True( DbSetIndex ( cCdx ) )

			Assert.Equal(4, (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 4, ok
			Assert.Equal(1, (INT) DbOrderInfo( DBOI_NUMBER ) )  // still  -1 , but should show  1
			Assert.Equal("TESTCDX8", (STRING) DbOrderInfo( DBOI_NAME ) )  // ok , "TESTDBF"
			DbCloseArea ()
		RETURN

		[Fact, Trait("Category", "DBF")];
			METHOD DBSetOrderCondition_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")
			aValues := { 1,4,2,3 }
			DbCreate( cDBF , {{"NUM" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbGoTop()

			// DESCENDING = TRUE
			Assert.True( DbSetOrderCondition(,,,,,,,,,,TRUE) )
			Assert.True( DbCreateIndex(cDbf, "NUM" ) )

			DbGoTop()
			aValues := { 4,3,2,1 }
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				nCount ++
				Assert.Equal((INT)aValues[nCount] , (INT)FieldGet(1))
				DbSkip()
			END DO

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Fields_Named_After_Funcs() AS VOID
			LOCAL cDbf AS STRING
			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")

			DbCloseAll() // worakaroudn for previous test crashing

			DbCreate( cDBF , {{"LEFT" , "N" ,5 , 0 } , {"STR" , "C" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()
			FieldPut(1,1)
			FieldPut(2,"A")
			DbAppend()
			FieldPut(1,11)
			FieldPut(2,"B")
			DbGoTop()
			Assert.True( DbCreateIndex(cDbf, "STR" ) )
			Assert.True( DbSetFilter(&("{||LEFT<10}")) )
			DbGoTop()
			DbSkip()
			Assert.True( Eof() )
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Uninitialized_fields() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName()
			FErase(cDbf + ".cdx")
			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbAppend() // no field assigned
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF)
			Assert.True( DbCreateIndex(cDbf, "FIELDN" ) )
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBOrderInfo_DBOI_KEYTYPE() AS VOID
			LOCAL cDbf AS STRING
			DbCloseAll()

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testnewer")
			FErase(cDbf + ".cdx")
			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } , ;
			{"FIELDS" , "C" ,15 , 0 } , ;
			{"FIELDL" , "L" ,1 , 0 } , ;
			{"FIELDD" , "D" ,8 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbCloseArea()

			DbUseArea(,"DBFCDX",cDBF)
			DbCreateIndex(cDbf + ".cdx", "FIELDN" )
			Assert.Equal(3, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 14 (), should be 3 (FLOAT)
			DbCloseArea()
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDS" )
			Assert.Equal(7, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 18 (PTR), should be 7 (STRING)
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDD" )
			Assert.Equal(2, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 16, should be 2 (DATE)
			FErase(cDbf + ".cdx")
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbCreateIndex(cDbf + ".cdx", "FIELDL" )
			Assert.Equal(8, (INT)DbOrderInfo( DBOI_KEYTYPE ) ) // 3 (FLOAT), should be 8

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetOrderCondition_with_FOR() AS VOID
			SELF:DBSetOrderCondition_with_FOR_helper(TRUE)
			SELF:DBSetOrderCondition_with_FOR_helper(FALSE)
		RETURN
		PRIVATE METHOD DBSetOrderCondition_with_FOR_helper(lUseIndexFormVO AS LOGIC) AS VOID
			LOCAL cDbf AS STRING
			DbCloseAll()

			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName("testcdx9")
			FErase(cDbf + ".cdx")

			DbCreate( cDBF , {{"FIELDN" , "N" ,5 , 0 } })
			DbUseArea(,"DBFCDX",cDBF)
			DbAppend()
			FieldPut(1,1)
			DbAppend()
			FieldPut(1,4)
			DbAppend()
			FieldPut(1,2)
			DbAppend()
			FieldPut(1,3)
			DbCloseArea()

			IF lUseIndexFormVO
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQD//////////90B//8AAA8PEAQEAwAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRFU1RDRFg5AAoAAAAAAAAAAAAACABoAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABwAJAAAABwBGSUVMRE4ARklFTEROPjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgD//////////98B//8AAA8PEAQEAwQAYAIAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMAI"))
				DbUseArea(,"DBFCDX",cDBF)
			ELSE
				DbUseArea(,"DBFCDX",cDBF)
				DbSetOrderCondition( "FIELDN>2",{||_FIELD->FIELDN>2},,,,,,,,, TRUE)
				DbCreateIndex(cDbf, "FIELDN" )
			END IF

			// Should show only 4,3, but it shows all records 4,3,2,1
			Assert.True( DbSetOrder(1) )
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .NOT. EoF()
				nCount ++
				IF nCount == 1
					Assert.Equal(4 ,(INT)FieldGet(1))
				ELSEIF nCount == 1
					Assert.Equal(3 ,(INT)FieldGet(1))
				END IF
				DbSkip()
			END DO

			Assert.Equal(2 ,nCount)

			// Should both show true, but both return false
			Assert.True( DbOrderInfo( DBOI_ISCOND ) )
			Assert.True( DbOrderInfo( DBOI_ISDESC ) )

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
			aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()

			Assert.False( Found() )// FALSE, ok
			Assert.True( DbSetFound( FALSE ) )
			Assert.False( Found() ) // TRUE! wrong
			Assert.True( DbSetFound( TRUE ) )
			Assert.True( Found() ) // TRUE correct
			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test2() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
			aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

		    DbCreate( cDBF , aDbf)
		    DbUseArea(,"DBFCDX",cDBF,,FALSE)

		    DbAppend()

		    DbCloseArea()

		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE )
		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE )

		    Assert.True( DbSelectArea ( "AREA1" ) )
		    Assert.Equal("AREA1", Alias() )
		    Assert.False( Found() )
		    Assert.True( DbSetFound ( TRUE ) )
		    Assert.True( Found() )

		    Assert.True( DbSelectArea ( "AREA2" ) )
		    Assert.Equal( "AREA2" , Alias() )
		    Assert.False( Found() )
		    Assert.True( DbSetFound  ( FALSE ) )
		    Assert.False( Found() )

		    Assert.True( DbCloseArea() )
		    Assert.True( DbSelectArea ( "AREA1" ) )
		    Assert.True( DbCloseArea() )
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD DBSetFound_test3() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := GetTempFileName("testcdx1")
			FErase(cDbf + ".cdx")
		    aDbf := {{ "AGE" , "N" , 2 , 0 }}
		    DbCreate( cDBF , aDbf)
		    DbUseArea(,,cDBF,,FALSE)

		    DbAppend()
		    FieldPut(1,1)
		    DbCloseArea()

		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE )
		    DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE )

		    DbSelectArea ( "AREA1" )
		    Assert.True( DbLocate({||_FIELD->AGE == 1}) )
		    Assert.True( Found() )

		    DbSelectArea ( "AREA2" )
		    Assert.False( Found() )

		    DbCloseAll()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD FLock_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := __FUNCTION__
			FErase(cDbf + ".cdx")

		    aDbf := {{ "AGE" , "N" , 2 , 0 }}
			DbCreate( cDBF , aDbf)

			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			DbAppend()
			DbAppend()
			DbAppend()
			DbCloseArea()

			Assert.True( DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA1" ,TRUE ) )// open shared
			DbGoTop()
			Assert.True( DbRLock ( RecNo() ) ) // lock first record
			Assert.Equal( 1 , (INT) ALen ( DbRLockList() ) )

			Assert.True( DbUseArea( TRUE ,"DBFCDX",cDBF,"AREA2" ,TRUE ) ) // open shared
			DbGoBottom()
			Assert.True( DbRLock ( RecNo() ) ) // lock last record
			Assert.Equal( 1 , (INT) ALen ( DbRLockList() ) )

			Assert.False( Flock() )
			// what's the correct return value here??
			// Assert.Equal( 0 , (INT) ALen ( DBRLockList() ) )
			DbCloseAll()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD IndexExt_test() AS VOID
			LOCAL aDbf AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			DbCloseAll()

			cDBF := __FUNCTION__
			FErase(cDbf + ".cdx")

			RddSetDefault("DBFCDX")
			Assert.True( IndexKey() == "")
			Assert.True( IndexOrd() == 0)
			Assert.True( IndexCount() == 0)
			Assert.True( Upper(IndexExt()) ==  ".CDX")
			Assert.True( DbOrderInfo(DBOI_INDEXEXT) == NIL )

			aValues := { 44 , 12, 34 , 21 }
			aDbf := {{ "AGE" , "N" , 2 , 0 }}

			DbCreate( cDBF , aDbf)
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i])
			NEXT
			DbCreateIndex( cDbf, "age" )

			Assert.Equal( "age" , (STRING) IndexKey() )
			Assert.True( IndexOrd() == 1 )
			Assert.True( IndexCount() == 1 )
			Assert.True( Upper(IndexExt()) == ".CDX")
			Assert.True( DbOrderInfo(DBOI_INDEXEXT) == ".CDX")

			DbCloseArea()
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD Cdx_Multi_Order() AS VOID
			SELF:Cdx_Multi_Order_helper(1)
			SELF:Cdx_Multi_Order_helper(2)
			SELF:Cdx_Multi_Order_helper(3)
		RETURN
		PRIVATE METHOD Cdx_Multi_Order_helper(nTestType AS INT) AS VOID
			LOCAL aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING
			LOCAL d AS DATE
			d := ConDate(2019,02,22)

			cDBF := GetTempFileName("testcdx")
			aValues := { {44,d} , {12,d-1}, {34,NULL_DATE} , {21,d+1} }

			RddSetDefault("DBFCDX")
			cCdx := cDbf + ".cdx"
			FErase(cCdx)
			DbCreate( cDbf , {{"FIELDN" , "N" , 3 , 0 } , {"FIELDD" , "D" , 8 , 0 } })
			DbUseArea(,"DBFCDX",cDBF,,FALSE)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut(1,aValues [i,1])
				FieldPut(2,aValues [i,2])
			NEXT
			DbCloseArea()

			IF nTestType == 1
				System.IO.File.WriteAllBytes(cDbf + ".cdx" , Convert.FromBase64String("AAQAAAAAAAAAAAAACgDgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAwD//////////88B//8AAA8PEAQEAwASQAAMNQAGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABURVNUQ0RYOE4yRklFTEREAAoAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBGSUVMRE4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9cB//8AAA8PEAQEAwIAYAQAYQMAYQEAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZBNcAoABAAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAABAAAACAAtRklFTEROAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////78B//8AAA8PEAQEAwEAAAMAAQQAAQIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANf////////K////////vv///////z+5////////ABYAAAAAAAAAAAAACABgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwABAAAABwBGSUVMREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMABAD//////////9UB//8AAA8PEAQEAwMAcAIAQAEANAQAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVgMFCwdSA"))
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
			ELSEIF nTestType == 2
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
				DbCreateIndex( cCdx, "FIELDN" )
				DbCreateOrder("FIELDN2", cCdx, "-FIELDN" )
				DbCreateOrder("FIELDD", cCdx, "FIELDD" )
                DbSetOrder(1)
			ELSE
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
				DbCreateIndex( cCdx, "FIELDN" )
				DbCreateOrder("FIELDN2", cCdx, "-FIELDN" )
				DbCreateOrder("FIELDD", cCdx, "FIELDD" )

				DbCloseArea()
				DbUseArea(,"DBFCDX",cDBF,,FALSE)
			END IF

			LOCAL nCount := 0 AS INT

			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 2)
				CASE nCount == 2
					Assert.True(RecNo() == 4)
				CASE nCount == 3
					Assert.True(RecNo() == 3)
				CASE nCount == 4
					Assert.True(RecNo() == 1)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(1)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 2)
				CASE nCount == 2
					Assert.True(RecNo() == 4)
				CASE nCount == 3
					Assert.True(RecNo() == 3)
				CASE nCount == 4
					Assert.True(RecNo() == 1)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(2)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 1)
				CASE nCount == 2
					Assert.True(RecNo() == 3)
				CASE nCount == 3
					Assert.True(RecNo() == 4)
				CASE nCount == 4
					Assert.True(RecNo() == 2)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			nCount := 0
			DbSetOrder(3)
			DbGoTop()
			DO WHILE .NOT. EOF()
				nCount ++
				DO CASE
				CASE nCount == 1
					Assert.True(RecNo() == 3)
				CASE nCount == 2
					Assert.True(RecNo() == 2)
				CASE nCount == 3
					Assert.True(RecNo() == 1)
				CASE nCount == 4
					Assert.True(RecNo() == 4)
				END CASE
//				? FieldGet(1), FieldGet(2) , RecNo()
				DbSkip()
			ENDDO

			DbCloseArea()
		RETURN

		// TECH-5YYVPE1A8T, DBFCDX StackOverflow with Shared mode, DBSelete() and DBUnlock()
		[Fact, Trait("Category", "DBF")];
		METHOD DBFCDX_StackOverflow() AS VOID
			LOCAL cDBF AS STRING

            TRY
			RddSetDefault("DBFCDX")
			SetExclusive( FALSE )

			cDBF := GetTempFileName()
			FErase(cDBF)
			FErase(cDBF + ".cdx")

			DbfTests.CreateDatabase(cDBF , { { "CFIELD" , "C" , 5 , 0 }} , { "AAA" , "CCC" , "BBB" } )
			DbCreateIndex(cDbf , "CFIELD")
			DbCloseAll()

			DbUseArea(,"DBFCDX",cDBF )
			DbGoTop()
			DbSkip()

			Assert.Equal( 3, (INT) RecNo() )
			Assert.Equal( "BBB  ", FieldGet(1) )

			Assert.True( DbRLock()  )
			Assert.True( DbDelete() )
			Assert.True( DbUnLock() ) // StackOverflow here

            FINALLY
			DbCloseAll()
            SetExclusive ( TRUE )
            END TRY
		RETURN

		// TECH-545T6VKW27, Problems with OrdScope() and DBSeek()
		[Fact, Trait("Category", "DBF")];
		METHOD OrdScope_and_DBSeek_test() AS VOID
			LOCAL cDBF AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")

			cDbf := GetTempFileName()
			FErase(cDbf + ".cdx")

			aValues := {"Gas" , "Abc", "Golden" , "Guru" , "Ddd" , "Aaa" , "Ggg"}
			aFields := { {"CFIELD" , "C" , 10 , 0} }

			DbCreate(cDbf , aFields)
			DbUseArea(,,cDBF )
			DbCreateIndex(cDbf , "Upper(CFIELD)")
			FOR i := 1 UPTO ALen(aValues)
				IF DbAppend()
				    FieldPut(1, aValues[i])
                ENDIF
			NEXT

			DbGoTop()
            DbCommit()
			Assert.Equal(7 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) ) // 7, correct

			// Setting order scope
			OrdScope(TOPSCOPE, "G")
			OrdScope(BOTTOMSCOPE, "G")
			DbGoTop()

			// VO: -2 with NTX, 4 with CDX
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )

			Assert.True( DbSeek("G")    ) // TRUE, correct
			Assert.True( DbSeek("GOLD") ) // TRUE with NTX, FALSE with CDX. VO TRUE in both

			// Clearing order scope
			OrdScope(TOPSCOPE, NIL)
			OrdScope(BOTTOMSCOPE, NIL)
			Assert.Equal( 7 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True( DbSeek("G") )
			Assert.True( DbSeek("GOLD") )

			// Setting order scope again
			OrdScope(TOPSCOPE, "G")
			OrdScope(BOTTOMSCOPE, "G")
			DbGoTop()
			// VO: -2 with NTX, 4 with CDX
			Assert.Equal(4 , (INT) DbOrderInfo( DBOI_KEYCOUNT ) )

			Assert.True( DbSeek("G")    ) // TRUE, correct
			Assert.True( DbSeek("GOLD") ) // TRUE with NTX, FALSE with CDX. VO TRUE in both

			DbCloseArea()
		RETURN

		// TECH-6010F6ZSY9, DBFCDX OrdDescend() not working
		[Fact, Trait("Category", "DBF")];
		METHOD DBFCDX_OrdDescend_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )
			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "b" , "d" , "c", "e" , "a" }
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )
			cIndex := cDbf + "x"
			FErase ( cIndex + IndexExt() )
//			 -----------------
			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			DbCreateOrder ( "ORDER1" , cIndex , "upper(LAST)" , { || Upper(_FIELD->LAST) } )
			DbSetOrder ( 1 )

			Assert.False( DbOrderInfo(DBOI_ISDESC) ) // false, correct
			Assert.False( OrdDescend() ) // true, incorrect

			DbGoTop()
			LOCAL aResult AS ARRAY
			LOCAL nIndex AS INT
			aResult := {5,1,3,2,4}
			nIndex := 0
			DO WHILE ! Eof()
//				5,1,3,2,4 correct
				nIndex ++
				Assert.Equal((INT) aResult[nIndex] , (INT) RecNo() )
				DbSkip(1)
			ENDDO

			Assert.False( OrdDescend ( ,, TRUE ) )
			Assert.True( DbOrderInfo(DBOI_ISDESC) ) // false, wrong
			Assert.True( OrdDescend() )

			DbGoTop()
			aResult := {4,2,3,1,5}
			nIndex := 0
			DO WHILE ! Eof()
//				5,1,3,2,4 again, wrong, should be 4,2,3,1,5
				nIndex ++
				Assert.Equal((INT) aResult[nIndex] , (INT) RecNo() )
				DbSkip(1)
			ENDDO

			DbCloseAll()
		RETURN

		// TECH-8H9WL71978, OrdIsUnique() always returns TRUE
		[Fact, Trait("Category", "DBF")];
		METHOD OrdIsUnique_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL lUnique AS LOGIC

			lUnique := SetUnique()
			RddSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "a" , "d" , "f", "c" }

			cDBF := GetTempFileName()
			cIndex := cDbf

			FErase ( cIndex + IndexExt() )
//			 -----------------
			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			Assert.True( OrdCondSet() )
			Assert.True( OrdCreate(cIndex, "ORDER1", "upper(LAST)", { || Upper ( _FIELD-> LAST) } ) )
			DbSetOrder ( 1 )
			Assert.Equal( "ORDER1" , OrdName() ) // "ORDER1"
			Assert.False( OrdIsUnique() ) // always returns true !
			Assert.False( DbOrderInfo(DBOI_UNIQUE ) ) // ok
			Assert.False( DbOrderInfo(DBOI_ISDESC ) ) // ok

			Assert.True( OrdCondSet() )
//			 create a descend and unique order
			Assert.True( OrdCondSet(,,,,,,,,,,TRUE) )
			SetUnique ( TRUE )
			OrdCreate(cIndex, "ORDER2", "upper(LAST)", { || Upper ( _FIELD-> LAST) } )

			DbSetOrder ( 2 )
			Assert.Equal( "ORDER2" , OrdName() ) // "ORDER2"
			Assert.True( OrdIsUnique() ) // always returns true !
			Assert.True( DbOrderInfo(DBOI_UNIQUE ) ) // ok
			Assert.True( DbOrderInfo(DBOI_ISDESC ) ) // ok
			DbCloseAll()
			Assert.True( SetUnique ( lUnique ) )
		RETURN

		// TECH-679F75W648, Cannot create custom DBFCDX index
		[Fact, Trait("Category", "DBF")];
		METHOD Custom_DBFCDX_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}

			aValues := { "Goethe" , "Goldmann" , "Ober",;
			"Osterreich" , "Gothe" , "Gotz" , "Gobel" ,;
			"Otter" , "Anfang" , "Art" , "Arger" }

			cDBF := __FUNCTION__
			cIndex := cDbf
			FErase ( cIndex + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,"DBFCDX",cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT

			FOR i := 1 UPTO 2
				DbSetOrderCondition()
				IF i == 2
//					 second order should be a custom order.
					DbSetOrderCondition(,,,,,,,,,,,,, TRUE)
				ENDIF
				DbCreateOrder ( "ORDER"+ NTrim(i) , cIndex , "upper(LAST)" , { ||Upper ( _FIELD->LAST) } )
//				? OrdCreate(cIndex, "ORDER"+NTrim(i), "upper(LAST)", { || Upper ( _Field->LAST) } ) // ok
			NEXT

			DbSetOrder ( 1 )
			Assert.Equal( "ORDER1", OrdName() ) // "ORDER1" ok
			Assert.Equal( 1 , (INT) OrdNumber() ) // 1 ok
			Assert.Equal( "upper(LAST)" ,  OrdKey(1) ) // "UPPER(LAST)" ok
			Assert.False( (LOGIC) DbOrderInfo ( DBOI_CUSTOM ) ) // returns FALSE ok
			Assert.Equal( 11 , (INT) DbOrderInfo ( DBOI_KEYCOUNT ) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( 1 , cIndex ) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( "ORDER1" , cIndex) ) // ok, shows 11
			Assert.Equal( 11 , (INT) OrdKeyCount( 1 ) )
			Assert.Equal( 11 , (INT) OrdKeyCount() )

			DbSetOrder ( 2 )
			Assert.Equal( "ORDER2", OrdName() ) // "ORDER2" ok
			Assert.Equal( 2 , (INT) OrdNumber() ) // 2 ok
			Assert.Equal( "upper(LAST)" ,  OrdKey(2) ) // "UPPER(LAST)" ok
			Assert.True( (LOGIC) DbOrderInfo ( DBOI_CUSTOM ) ) // NOTE: returns FALSE instead of TRUE
			Assert.Equal( 0 , (INT) DbOrderInfo ( DBOI_KEYCOUNT ) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( 2 , cIndex ) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( "ORDER2" , cIndex) ) // NOTE: shows 11 instead of 0
			Assert.Equal( 0 , (INT) OrdKeyCount( 2 ) )
			Assert.Equal( 0 , (INT) OrdKeyCount() )

			Assert.Equal( 2 , (INT) IndexCount() ) // 2 ok

//			 NOTE: ORDDESTROY() problem. if the order doesnt exist the func returns TRUE and
//			 seems to do nothing. VO throws an error if a order doesnexist.
			LOCAL lException := FALSE AS LOGIC
			TRY
				OrdDestroy("ORDER4") // NOTE: "ORDER4" does not exist
			CATCH
				lException := TRUE
				Assert.Equal( 2 , (INT) IndexCount() )
				Assert.Equal( 2 , (INT) IndexOrd() )
			END TRY
			Assert.True( lException )
			DbCloseAll()
		RETURN

		// TECH-679F75W648, Cannot create custom DBFCDX index
		[Fact, Trait("Category", "DBF")];
		METHOD Custom_DBFCDX_test2() AS VOID
			#warning Custom order test not added, feature is not supported yet
/*
			LOCAL cDBF, cPfad, cIndex, cDriver AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD
			LOCAL aRecnos AS ARRAY

			cDriver := RDDSetDefault ( "DBFCDX" )

			aFields := { { "LAST" , "C" , 20 , 0 }}

			aValues := { "Goethe" , "Goldmann" , "Ober",;
			"Osterreich" , "Gothe" , "Gotz" , "Gobel" ,;
			"Otter" , "Anfang" , "Art" , "Arger" }

			cPfad := "" // "c:\xide\projects\project1\bin\debug\"
			cDBF := cPfad + "Foo"
			cIndex := cPfad + "Foox"

			FErase ( cIndex + IndexExt() )
//			 -----------------
			? DBCreate( cDBF , AFields)
			? DBUseArea(,"DBFCDX",cDBF )

			FOR i := 1 UPTO ALen ( aValues )
			DBAppend()
			FieldPut ( 1 , aValues [ i ] )
			NEXT

			FOR i := 1 UPTO 2
			DBSetOrderCondition()
			IF i == 2
			DBSetOrderCondition(,,,,,,,,,,,,, TRUE)
			ENDIF

//			 ? DBCREATEORDER ( "ORDER"+ NTrim(i) , cIndex ,"upper(LAST)" , { || Upper ( _Field->LAST) } )
			? OrdCreate(cIndex, "ORDER"+ NTrim(i), "upper(LAST)", { || Upper (_Field->LAST) } )
			NEXT

//			 -------------
			?
			? IndexCount() // ok 2
			? OrdName() // ok current order is "ORDER2"
			? OrdKeyCount() // 0 before OrdKeyAdd()
			?

//			 add 4 records to the custom order
			aRecnos := { 1 , 11 , 4 , 9 }
			FOR i := 1 UPTO ALen ( aRecnos )
			DBGoTo ( aRecnos [ i ] )
			OrdKeyAdd ()
			NEXT
			? OrdKeyCount() // 4 after OrdKeyAdd()
			?

			DBGoTop()

//			 "Last" names shown are:
//			 Anfang
//			 Arger
//			 Gothe
//			 Osterreich

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO
			?
//
			? "Delete the entry 'Arger'"
			DBSeek( Upper ( "Arger" ))
			OrdKeyDel () // delete the entry
			? OrdKeyCount() // 3
			?
			DBGoTop()

//			 "Last" names shown are now:
//			 Anfang
//			 Gothe
//			 Osterreich

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO
			?
			? "Delete all entries"

			DBGoTop()
			DO WHILE OrdKeyCount() > 0
			OrdKeyDel()
			DBGoTop()
			ENDDO

			? "Entries now:" , OrdKeyCount()
			?
//			 "ORDER2" order is no longer needed
			? OrdDestroy("ORDER2")
			? IndexCount() // 1
			?
//			 --- switch to the first order ---
			? DBSetOrder ( 1 )
			? OrdName() // ok "ORDER1"
			?
//			 List all "Last" names
			DBGoTop()

			DO WHILE ! EOF()
			? FieldGet ( 1 ) , RecNo()
			DBSkip(1)
			ENDDO

			DBCloseAll()
			RDDSetDefault ( cDriver )*/
		RETURN

		// TECH-5OD246EMC4, VODBOrdListAdd() fails when index filename passed without extension
		[Fact, Trait("Category", "DBF")];
		METHOD VODBOrdListAdd_test() AS VOID
			LOCAL cDBF, cIndex AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL i AS DWORD

			RddSetDefault("DBFCDX")
			aFields := { { "LAST" , "C" , 20 , 0 }}
			aValues := { "b" , "c" , "d", "e" , "a" }

			cDBF := __FUNCTION__
			cIndex := cDbf
			FErase ( cIndex + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,,cDBF)
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
			NEXT
			DbCreateOrder ( "ORDER1" , cIndex , "upper(LAST)" , { || Upper (_FIELD->LAST) } )
			DbCloseAll()

//			 When ".cdx" is added SetIndex() returns true
//			 cIndex := cIndex + IndexExt()
			DbUseArea(,,cDBF)
			Assert.True( VoDbOrdListAdd(cIndex , NIL) ) // Returns FALSE, error
			DbCloseAll()
		RETURN

		// TECH-0YI914Z4I2, Problem opening dbf with dbt via SetDefault()
		[Fact, Trait("Category", "DBF")];
		METHOD SetDefault_test() AS VOID
			LOCAL cPath, cDbf AS STRING
			LOCAL cDefault AS STRING
			RddSetDefault("DBFCDX")

			cPath := System.IO.Path.GetTempPath()
			IF .NOT. cPath:EndsWith("\")
				cPath += "\"
			END IF
			cDbf := "fpttest"
			FErase(cPath + cDBF + ".dbf")
			FErase(cPath + cDBF + ".ntx")
			FErase(cPath + cDBF + ".cdx")
			FErase(cPath + cDBF + ".dbt")
			FErase(cPath + cDBF + ".fpt")

			cDefault := GetDefault()
			SetDefault(cPath)

			Assert.True( DbCreate( cPath + cDbf , { { "ID" , "C" , 5 , 0 } , {"MEM" , "M" , 10 , 0}} ) )
//			 System.IO.FileNotFoundException
//			 Could not find file '<path_of_exe>\mydbf.DBT'.
			Assert.True( DbUseArea(,,cDbf ) )
			Assert.True( DbCloseArea()      )

			SetDefault(cDefault)
		RETURN

		// TECH-ZW8D1S87CH, Problem updating cdx
		[Fact, Trait("Category", "DBF")];
		METHOD CdxUpdating() AS VOID
			LOCAL cDBF AS STRING
			LOCAL aFields, aValues AS ARRAY
			LOCAL cPrev AS STRING
			LOCAL nCount AS INT
			LOCAL i AS DWORD

			RddSetDefault ( "DBFCDX" )

			aFields := { { "NUM" , "N" , 8 , 0 },{ "LAST" , "C" , 100 , 0 }}
			aValues := { "b" , "c" , "d", "e" , "a" , "r" , "t" , "g" , "m" , "n" , "t" , "b" , "h" , "f" , "y", "r", "t", "y", "z", "v", "e", "r", "b", "z", "b", "m", "w", "e" }

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , AFields)
			DbUseArea(,,cDBF )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , i )
				FieldPut ( 2 , Replicate( aValues [ i ] , 50) )
			NEXT
			DbCreateIndex ( cDBF , "NUM" , {||_FIELD->NUM})
			DbCreateOrder ( "LAST" , cDBF , "LAST" , {||_FIELD->LAST})
			DbCloseAll()

			DbUseArea(,,cDBF )
			DbSetOrder(2)       // Last
			DbGoBottom()

			FieldPut(2, "a")    // Change Z to "a"  Note that at this moment the DeleteKey fails

			DbSkip(-5)
			FieldPut(2, "d")
			DbSkip(5)
			FieldPut(2, "z")

			cPrev := NULL
			nCount := 0
			DbGoTop()
			DO WHILE .NOT. EoF()
				nCount ++
                VAR cCurrent := FieldGet(2)
				IF cPrev != NULL

					Assert.True( cPrev <=  cCurrent)
				END IF
				cPrev := cCurrent
				DbSkip()
			END DO
			Assert.Equal( nCount, (INT) ALen(aValues) )

			DbCloseArea()
		RETURN

		// TECH-78PAZ508AE, Problems with creating/opening DBFCDX memo files
		[Fact, Trait("Category", "DBF")];
		METHOD MemoCreateAndOpen() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := System.IO.Path.GetTempPath() + "cdxtest"

			aFields := { { "LAST" , "C" , 20 , 0 } , { "COMMENTS" , "M" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)
//			DBCreate( cDBF , AFields , "DBFCDX") // same

			Assert.False( (LOGIC) File(cDBF + ".dbt") )
			Assert.True( (LOGIC) File(cDBF + ".fpt") )

			IF File(cDBF + ".dbt")
				FRename(cDBF + ".dbt",cDBF + ".fpt")
			END IF

			TRY
				DbUseArea(,,cDBF)
			FINALLY
				DbCloseAll()
			END TRY

			RddSetDefault("DBFNTX")
			cDBF := System.IO.Path.GetTempPath() + "ntxtest"

			aFields := { { "LAST" , "C" , 20 , 0 } , { "COMMENTS" , "M" , 10 , 0 }}
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			Assert.True( (LOGIC) File(cDBF + ".dbt") )
			Assert.False( (LOGIC) File(cDBF + ".fpt") )

			IF File(cDBF + ".fpt")
				FRename(cDBF + ".fpt",cDBF + ".dbt")
			END IF

			TRY
				DbUseArea(,,cDBF)
			FINALLY
				DbCloseAll()
			END TRY
		RETURN

		[Fact, Trait("Category", "DBF")];
		METHOD CDX_DBGoTop() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := System.IO.Path.GetTempPath() + "cdxtest1"

			aFields := { { "LAST" , "C" , 20 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)

			DbUseArea(,"DBFCDX" , cDbf)
			FOR LOCAL n := 1 AS INT UPTO 1000
				DbAppend()
				FieldPut(1,"A"+AsString(n % 77))
			NEXT
			DbCreateOrder( "ORDER1" , cDbf + ".cdx" , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )
			DbCloseArea()

			LOCAL nCount AS INT
			DbUseArea(,"DBFCDX" , cDbf)

			DbGoTop()
			DbGoTop()
			nCount := 0
			DO WHILE .NOT. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal( nCount, 1000 )

			DbGoBottom()
			DbGoBottom()
			nCount := 0
			DO WHILE .NOT. Bof()
				nCount ++
				DbSkip(-1)
			END DO
			Assert.Equal( nCount, 1000 )
			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_SeekEmptyDbf() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 20 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , AFields)

			DbUseArea(,"DBFCDX" , cDbf)
			DbCreateOrder( "ORDER1" , cDbf + ".cdx" , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )

			DbGoTop()
            DbSeek("A")
			DbCloseArea()

		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdKeyCount() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL dwCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			DbUseArea( ,"DBFCDX",cDBF , , TRUE )
			FOR LOCAL n := 1 AS DWORD UPTO 1000
				DbAppend()
				FieldPut(1, Chr(65 + (n % 5)) )
			NEXT
			DbAppend()
			FieldPut(1, "D" )
			DbAppend()
			FieldPut(1, "E" )
			DbAppend()
			FieldPut(1, "D" )
			DbAppend()
			FieldPut(1, "F" )

			DbGoTop()

			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )
			DbGoTop()

			OrdScope( TOPSCOPE, "C" )
			OrdScope( BOTTOMSCOPE, "C" )

			DbGoTop()

			Assert.Equal(200, (INT) OrdKeyCount() )

			DbGoTop()
			DO WHILE ! Eof()
				dwCount += 1
				DbSkip(1)
			ENDDO
			Assert.Equal(200, dwCount)

			DbGoTop()
			DbSkip(2)
			Assert.False( Eof() )

			OrdScope( TOPSCOPE, "D" )
			OrdScope( BOTTOMSCOPE, "D" )
			DbGoTop()
			Assert.Equal(202, (INT) OrdKeyCount() )

			OrdScope( TOPSCOPE, "E" )
			OrdScope( BOTTOMSCOPE, "E" )
			DbGoTop()
			Assert.Equal(201, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(5)
			Assert.False( Eof() )

			OrdScope( TOPSCOPE, "F" )
			OrdScope( BOTTOMSCOPE, "F" )
			DbGoTop()
			Assert.Equal(1, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(2)
			Assert.True( Eof() )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_DbSetOrderCondition() AS VOID
			LOCAL aFields AS ARRAY
			LOCAL dwCount AS INT
			LOCAL cDBF AS STRING
			LOCAL n AS DWORD

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aFields := { { "LAST" , "C" , 10 , 0 }}
			FErase(cDBF + ".cdx")
			FErase(cDBF + ".dbt")
			FErase(cDBF + ".fpt")

			DbCreate( cDBF , aFields)

			DbUseArea( ,"DBFCDX",cDBF , , TRUE )
			FOR n := 1 UPTO 600
				DbAppend()
				FieldPut(1, Chr(65 + (n % 3)) )
			NEXT

			DbSetOrderCondition (,,,,,,,600,,,,,,,)
			DbGoTop()
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			Assert.Equal(600, (INT) OrdKeyCount() )

			DbGoTop()
			dwCount := 0
			DO WHILE .NOT. eof()
				dwCount ++
				DbSkip()
			END DO
			Assert.Equal(600, dwCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdDescend() AS VOID
			LOCAL cResult AS STRING
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "b" , "d" , "c", "e" , "g1" , "g3" , "g45" , "a" , "o" , "p" , "r"})

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) }  )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE,  "C")
			OrdScope(BOTTOMSCOPE, "O")
			DbGoTop()
			Assert.Equal(7, (INT) OrdKeyCount())

			cResult := ""
			DO WHILE ! Eof()
				cResult += AllTrim(FieldGet(1)) + " "
				DbSkip ( 1)
			ENDDO
			Assert.Equal( "c d e g1 g3 g45 o" , AllTrim(cResult) )

			OrdDescend( , , TRUE)
			DbGoTop()
			Assert.Equal(7, (INT) OrdKeyCount())

			cResult := ""
			DO WHILE ! Eof()
				cResult += AllTrim(FieldGet(1)) + " "
				DbSkip ( 1)
			ENDDO
			Assert.Equal( "o g45 g3 g1 e d c" , AllTrim(cResult) )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_Deleted() AS VOID
			LOCAL cDBF AS STRING
			LOCAL nCount := 0 AS INT

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "e" , "o" , "g" })

		  	DbSetOrderCondition ( "! DELETED()" , { || ! Deleted()  } )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbSetOrder(1)

			DbGoTop()
			Assert.Equal(3, (INT) OrdKeyCount())
			DbGoBottom()
			Assert.True( DbDelete() )
			DbGoTop()
			Assert.Equal(2, (INT) OrdKeyCount())

			DO WHILE ! Eof()
				nCount ++
				DbSkip(1)
			ENDDO
			Assert.Equal( 2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_DeletedScope() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			SetDeleted(TRUE)

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "d" , "c",  "o" , "r" , "go1" , "g" , "go2" , "g2" , "go3" } )

			DbGoBottom()
			DbDelete()

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "GO" )
			OrdScope ( BOTTOMSCOPE, "GO" )

			DbGoTop()
			DO WHILE ! Eof()
				Assert.Equal( "go" , (STRING) Left(FieldGet(1) , 2) )
				nCount ++
				DbSkip (1)
		 	ENDDO

		 	Assert.Equal(2 , nCount )       // go3 is deleted and should not be counted
		 	Assert.Equal(2 , (INT) OrdKeyCount() ) // go3 is deleted and should not be counted

		 	LOCAL nOrdKey AS INT
		 	nOrdKey := OrdKeyCount()
		 	Assert.True(nOrdKey == 2 ) // returns 0 when the test was added

		 	// make sure it still always gives the same result
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoTop()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip(-1)
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoBottom()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )

            SetDeleted(FALSE)
            // When SetDeleted = FALSE then go3 will be included in the count
		 	nOrdKey := OrdKeyCount()
		 	Assert.True(nOrdKey == 3 ) // returns 0 when the test was added

		 	// make sure it still always gives the same result
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoTop()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip(-1)
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbGoBottom()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )
			DbSkip()
		 	Assert.Equal(nOrdKey , (INT) OrdKeyCount() )

			DbCloseArea()

		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdKeyCount_at_EOF() AS VOID
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			SetDeleted(TRUE)

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "d" , "c",  "o" , "r" } )

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )

			DbGoBottom()
			Assert.Equal(4, (INT) OrdKeyCount() )
			DbSkip()
			Assert.Equal(4, (INT) OrdKeyCount() )
			DbGoTop()
			DbSkip(-1)
			Assert.Equal(4, (INT) OrdKeyCount() )

			DbCloseArea()

			SetDeleted(FALSE)
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdScope_and_SetFilter() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "C" , 20 , 0 }} , ;
							{ "A1" ,"A3" , "A2",  "Go1" , "G1" , "g2" , "g3", "go2"  , "h2" , "h4" } )

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "A" )
			OrdScope ( BOTTOMSCOPE, "G" )

			Assert.Equal(8 , (INT) OrdKeyCount() )

			LOCAL cFilter AS STRING
			cFilter := "GO"

			Assert.True( DbSetFilter ( { || Upper ( _Field->LAST ) = cFilter  } )  )
			DbGoTop()
			Assert.False( Eof() )
			Assert.Equal(2 , (INT) OrdKeyCount() )
			Assert.False( Eof() )
			DbGoTop()
			Assert.False( Eof() )

			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1 )
			ENDDO
			Assert.Equal(2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD CDX_OrdScope_and_SetFilter_numerics() AS VOID
			LOCAL nCount := 0 AS INT
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , ;
							{ { "LAST" , "N" , 20 , 0 }} , ;
							{ 1,2,3,4,5,6,3,4 } )

			DbCreateOrder ( "ORDER1" , cDbf , "LAST" , { || _Field->LAST } )
			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, 2 )
			OrdScope ( BOTTOMSCOPE, 5 )

			Assert.Equal(6 , (INT) OrdKeyCount() )

			Assert.True( DbSetFilter ( { || _Field->LAST == 3  } )  )
			DbGoTop()
			Assert.False( Eof() )
			Assert.Equal(2 , (INT) OrdKeyCount() )
			Assert.False( Eof() )
			DbGoTop()
			Assert.False( Eof() )

			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1 )
			ENDDO
			Assert.Equal(2 , nCount )

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_and_SetDeleted() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					Assert.True( DbDelete() )
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )

			SetDeleted ( TRUE )

			OrdScope ( TOPSCOPE, "G" )
			OrdScope ( BOTTOMSCOPE, "G" )
		 	DbGoTop()

			Assert.Equal(3, (INT) OrdKeyCount() ) // 3 ok

			SetDeleted ( FALSE )
			DbGoTop()

			Assert.Equal(5, (INT) OrdKeyCount() ) // 3 ok

			OrdScope ( TOPSCOPE, NIL )
			OrdScope ( BOTTOMSCOPE, NIL )

			// If TOPSCOPE and BOTTOMSCOPE is not equal
			// OrdKeyCount() seems to ignore a SetDeleted( TRUE ) ?

			OrdScope ( TOPSCOPE, "A" )
			OrdScope ( BOTTOMSCOPE, "G" )

            // We are now VO compatible and return the same number that VO does
			SetDeleted( TRUE )
			Assert.Equal(11, (INT) OrdKeyCount() ) // 11 ok

			SetDeleted( FALSE )
			Assert.Equal(11, (INT) OrdKeyCount() ) // 11 ok

			DbCloseArea()
		RETURN

		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands
		[Fact, Trait("Category", "DBFCDX")];
		METHOD Cdx_SoftSeek_Test_Numeric() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := __FUNCTION__
			cCdx := cDbf + ".cdx"

			DbCreate( cDbf , {{"NFIELD" , "N" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,123)
			DbAppend()
			FieldPut(1,456)
			DbCreateIndex(cCdx, "NFIELD")
			DbCloseArea()
			DbUseArea(,,cDbf,,FALSE)
			DbSetIndex(cCdx)
           SET(_SET_SOFTSEEK, "on")
            DbSeek(100)
            Assert.Equal(123, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek(200)
            Assert.Equal(456, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(FALSE)
            DbSeek(200)
            Assert.Equal(0, (INT)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(TRUE)
            DbSeek(100)
            Assert.Equal(123, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek(200)
            Assert.Equal(456, (INT)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
           SET(_SET_SOFTSEEK, "off")
            DbSeek(200)
            Assert.Equal(0, (INT)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())
            RETURN

   		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands
		[Fact, Trait("Category", "DBFCDX")];
		METHOD CDX_SoftSeek_Test_String() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cCdx AS STRING

			RddSetDefault("DBFCDX")

			cDbf := __FUNCTION__
			cCdx := cDbf + ".cdx"

			DbCreate( cDbf , {{"CFIELD" , "C" , 5 , 0 }})
			DbUseArea(,,cDbf,,FALSE)
			DbAppend()
			FieldPut(1,"bbbbb")
			DbAppend()
			FieldPut(1,"kkkkk")
			DbCreateIndex(cCdx, "CFIELD")
			DbCloseArea()
			DbUseArea(,,cDbf,,FALSE)
			DbSetIndex(cCdx)
            SetSoftSeek(TRUE)
            DbSeek("aaaaa")
            Assert.Equal("bbbbb", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek("ccccc")
            Assert.Equal("kkkkk", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            SetSoftSeek(FALSE)
            DbSeek("ccccc")
            Assert.Equal("     ", (STRING)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())

           SET(_SET_SOFTSEEK, "on")
            DbSeek("aaaaa")
            Assert.Equal("bbbbb", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
            DbSeek("ccccc")
            Assert.Equal("kkkkk", (STRING)FieldGet(1))
            Assert.Equal(FALSE, Eof())
            Assert.Equal(FALSE, Found())
           SET(_SET_SOFTSEEK, "off")
            DbSeek("ccccc")
            Assert.Equal("     ", (STRING)FieldGet(1))
            Assert.Equal(TRUE, Eof())
            Assert.Equal(FALSE, Found())

RETURN

		// TECH-9JPUGAOV3L , NTX problem with EoF after sequence of commands

        [Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_SetDeleted_and_OrdScope1() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			TRY

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )

			OrdScope ( TOPSCOPE, "G" )
			OrdScope ( BOTTOMSCOPE, "G" )
//			OrdScope ( TOPSCOPE, "A" )
//			OrdScope ( BOTTOMSCOPE, "G" )

			Assert.Equal(5, (INT) OrdKeyCount() )

			SetDeleted ( TRUE )  // no problem if set to FALSE

			OrdDescend ( , , TRUE )
			DbGoTop()

			// SetDeleted(TRUE) causes a endless loop ...
			LOCAL nCount := 0 AS INT
			DO WHILE ! Eof()
//				? AllTrim(FieldGet ( 1 ) ) , RecNo(), Eof(), Bof()
				DbSkip ( 1 )
				nCount ++
				IF nCount > 100
					THROW Exception{"Skip() loop never ends"}
				END IF
			ENDDO

			Assert.Equal(3, (INT) OrdKeyCount() )

			DbCloseAll()

			CATCH

				THROW

			FINALLY

			SetDeleted(FALSE)

			END TRY
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD SetDeleted_SetDeleted_and_OrdScope2() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING

			TRY

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			// create a descending order

			DbSetOrderCondition( , , , , , , , , , ,TRUE )
			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )
			DbGoTop()

			DO WHILE ! Eof()
				FieldGet ( 1 )
				DbSkip ( 1 )
			ENDDO

			SetDeleted ( FALSE )

			Assert.Equal(20 , (INT) OrdKeyCount() ) // 20  ok

			SetDeleted ( TRUE  )

//			#warning disabled following test because it makes tests stop responding
			//  Here it hangs because SetDeleted() is true
			// We are now VO compatible and return 20 instead of 17
            Assert.Equal(20 , (INT) OrdKeyCount() ) // 20  ok
			DbCloseAll()

			FINALLY

				SetDeleted(FALSE)

			END TRY
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD Filter_Descending_and_OrdKeyCount1() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL cFilter AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )

			FOR LOCAL i := 1 AS INT UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbSetOrder ( 1 )

			cFilter := "G"  // result does include deleted records  !

			SetDeleted ( FALSE )
			DbSetFilter ( { || Upper ( _Field->LAST ) = cFilter  }  )
			DbGoTop()

			Assert.Equal(5, (INT) OrdKeyCount() ) //  5 ok

			SetDeleted ( TRUE  )

			Assert.Equal(3, (INT) OrdKeyCount() ) //  3 ok

			// now change the filter to descend sort on the fly

			OrdDescend ( , , TRUE )
			SetDeleted ( FALSE )
			DbSetFilter ( { || Upper ( _FIELD->LAST ) = cFilter  }  )

			Assert.Equal(5, (INT) OrdKeyCount() ) //  shows 0  ...

			SetDeleted ( TRUE  )

			Assert.Equal(3, (INT) OrdKeyCount() ) // 	shows 0  ...

		   // switch back to ascending sort

			OrdDescend ( , , FALSE )
			SetDeleted ( FALSE )
			Assert.Equal(5, (INT) OrdKeyCount() ) //  5, ok

			SetDeleted ( TRUE )

			Assert.Equal(3, (INT) OrdKeyCount() ) // 	3, ok

			DbCloseAll()

			SetDeleted ( FALSE )
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD Filter_Descending_and_OrdKeyCount2() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDBF AS STRING
			LOCAL cFilter AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "a2", "a3" , "a4" , "a5" , "a6" ,"g1", "g2" , "g3" , "g4" , "g5" , "o1" , "o2" , "o3" , "o4" , "o5" , "u1", "u2","u3" , "u4" }

			DbUseArea( ,,cDBF , , TRUE )
			FOR LOCAL i := 1 AS DWORD UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [ i ] ) , "G1" , "G2" , "O5" )
					DbDelete()
				ENDIF
			NEXT

			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbSetOrder ( 1 )

			cFilter := "A"  // result does include *no* deleted records  !

			DbSetFilter ( { || Upper ( _FIELD->LAST ) = cFilter  }  )
			Assert.Equal(6, (INT) OrdKeyCount() ) // 6 , ok

			OrdDescend ( , , TRUE )

//			SetDeleted ( FALSE )
//			SetDeleted ( TRUE )

			// OrdKeyCount() hangs no matter how the SetDeleted() setting is.
//			#warning disabled following test because it makes tests stop responding
			Assert.Equal(6, (INT) OrdKeyCount() ) // 6 , ok

			DbCloseAll()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyNo_with_no_condition() AS VOID
			LOCAL cDBF AS STRING
			LOCAL lDeleted AS LOGIC
			LOCAL nCounter AS INT

			lDeleted := SetDeleted()

			TRY
				RddSetDefault("DBFCDX")
				cDBF := GetTempFileName()

				DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "a1" , "g1", "g2" , "o5"  } )

				DbUseArea( ,,cDBF , , TRUE )
				DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
				DbSetOrder ( 1 )

				lDeleted := SetDeleted ( FALSE  )
				DbGoTop()
				nCounter := 1
				DO WHILE ! Eof()
			       // ordKeyNo() returns zero based values if no condition is set,
			       // e.g. if no filter, no scope or the setting setdeleted (false) is used.
	//				? FieldGet ( 1 ) , OrdKeyNo()
					Assert.Equal(nCounter , (INT)OrdKeyNo())
					DbSkip(1)
					nCounter ++
				ENDDO

				SetDeleted ( TRUE  ) // Now the ordkeyno() values are correctly one based.

				DbGoTop()
				nCounter := 1
				DO WHILE ! Eof()
	//				? FieldGet ( 1 ) , OrdKeyNo()
					Assert.Equal(nCounter , (INT)OrdKeyNo())
					DbSkip(1)
					nCounter ++
				ENDDO

				DbCloseAll()
			FINALLY

				SetDeleted( lDeleted )

			END TRY
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest() AS VOID
			FOR LOCAL i := 0 AS INT UPTO 5
				SELF:ZapTest_helper(i)
			NEXT
		END METHOD

		METHOD ZapTest_helper(nType AS INT) AS VOID
			LOCAL cDBF AS STRING
			LOCAL nCount AS INT

			cDBF := GetTempFileName()
			FErase(cDbf + ".dbf")
			FErase(cDbf + ".cdx")
			FErase(cDbf + ".ntx")

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "a1" , "g1", "g2" , "o5"  } )

			DO CASE
			CASE  nType % 3 == 0
				? "testing with no index:"
			CASE nType % 3 == 1
				? "testing with NTX:"
				RddSetDefault ( "DBFNTX" )
			CASE nType % 3 == 2
				? "testing with CDX:"
				RddSetDefault ( "DBFCDX" )
			END CASE

			IF nType % 3 != 0
				DbUseArea( ,,cDBF , , TRUE )
				DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
				DbCloseAll()
			END IF

			DbUseArea( ,,cDBF , , FALSE )
			IF nType >= 3
				DbAppend()
				FieldPut(1,"testing")
				DbAppend()
				FieldPut(1,"some")
				DbAppend()
				FieldPut(1,"values")
				DbAppend()
				FieldPut(1,"last one")
			END IF
			IF nType % 3 != 0
				DbSetIndex ( cDBF )
			ENDIF
			Assert.True( DbZap() )
			DbCloseAll()

			DbUseArea( ,,cDBF , , TRUE )
			IF nType % 3 != 0
				DbSetIndex ( cDBF )
				DbSetOrder ( 1 )
			ENDIF

			DbGoTop()
			Assert.True( Eof() )
			Assert.Equal( 0 , (INT) RecCount() )
			Assert.False( IsNil( OrdKeyCount() ) )
			Assert.Equal( 0 , (INT) OrdKeyCount() )
			nCount := 0
			DO WHILE ! Eof()
				nCount ++
				DbSkip ( 1)
			ENDDO
			Assert.Equal( 0 , nCount )
			DbCloseArea()

		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD PackTest() AS VOID
			LOCAL aValues AS ARRAY
			LOCAL cDbf AS STRING
			LOCAL cRet AS STRING
			LOCAL i AS INT

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } )
			aValues := { "a1" , "g1", "g2" , "o5"  }

			DbUseArea( ,,cDBF , , TRUE )
			FOR i := 1 UPTO ALen ( aValues )
				DbAppend()
				FieldPut ( 1 , aValues [ i ] )
				IF InList ( Upper ( aValues [i] ) , "G1" )
					? "DBDelete()" , DbDelete()
				ENDIF
			NEXT
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )
			DbCloseAll()

			DbUseArea( ,,cDBF , , FALSE )
			DbSetIndex ( cDbf )
			Assert.True( DbPack() ) //   NOTE:   returns TRUE  , though a DBFCDX DBPack() creates garbage.
			DbCloseAll()

			Assert.True( DbUseArea( ,,cDBF , , TRUE ) )
			Assert.True( DbSetIndex ( cDbf ) )
			Assert.True( DbSetOrder ( 1 ) )

			DbGoTop()

			Assert.False( Eof() )
			Assert.False( IsNil( OrdKeyCount() ) )
			Assert.Equal(3 , (INT) OrdKeyCount() )
			// should print a1 g2 o5
			cRet := ""
			DO WHILE ! Eof()
				? FieldGet ( 1 )
				cRet += AllTrim(FieldGet ( 1 ))
				DbSkip ( 1)
			ENDDO
			Assert.Equal("a1g2o5" , cRet )
			DbCloseArea()

		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD DBSeek_test() AS VOID
			LOCAL cDbf AS STRING
			LOCAL cRet AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "u1" , "u2", "o2" , "o1"  } )

			DbUseArea( ,,cDBF , , TRUE )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbSetOrder ( 1 )
			DbGoTop()
			cRet := ""
			DO WHILE ! Eof()
				cRet += AllTrim( FieldGet ( 1 ) )
				DbSkip ( 1 )
			ENDDO
			Assert.Equal( "o1o2u1u2" , cRet )
			Assert.False( DbSeek ( "P" , FALSE , TRUE ) ) // seek for last occurence

			OrdDescend ( , , TRUE )
			DbGoTop()
			cRet := ""
			DO WHILE ! Eof()
				cRet += AllTrim( FieldGet ( 1 ) )
				DbSkip ( 1 )
			ENDDO
			Assert.Equal( "u2u1o2o1" , cRet )
			Assert.False( DbSeek ( "P" , FALSE , TRUE ) ) // seek for last occurence

			DbCloseAll()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD Update_from_two_workareas() AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "CFIELD" , "C" , 10 , 0 } , { "MFILED" , "M" , 10 , 0 } } )

			DbUseArea(TRUE,  , cDbf)
			DbCreateIndex(cDbf , "CFIELD")
			DbAppend()
			FieldPut(1,"z-ALIAS1")
			FieldPut(2,"z-ALIAS1_memo")
			DbAppend()
			FieldPut(1,"a-ALIAS1")
			FieldPut(2,"a-ALIAS1_memo")

			DbCloseArea()

			DbUseArea(TRUE, , cDbf , "alias1" , TRUE)
			DbGoTop()
			alias1->RLock()
			alias1->FieldPut(1 , "c-ALIAS1")
			alias1->FieldPut(2 , "c-ALIAS1_memo")
			Assert.Equal(2 , (INT)alias1->RecCount() )

				DbUseArea(TRUE, , cDbf , "alias2" , TRUE)
				Assert.Equal(2 , (INT)alias2->RecCount() )
				alias2->DbAppend()
				alias2->FieldPut(1,"b-ALIAS2")
				alias2->FieldPut(2,"b-ALIAS2_memo")
				Assert.Equal(3 , (INT)alias2->RecCount() )
				alias2->DbCloseArea()

			alias1->DbCloseArea()

			DbUseArea(TRUE, , cDbf , , TRUE)
			Assert.Equal(3 , (INT) RecCount() )

			DbGoTop()
			Assert.Equal("b-ALIAS2" , AllTrim(FieldGet(1)) )
			Assert.Equal("b-ALIAS2_memo" , AllTrim(FieldGet(2)) )
			DbGoBottom()
			Assert.Equal("z-ALIAS1" , AllTrim(FieldGet(1)) )
			Assert.Equal("z-ALIAS1_memo" , AllTrim(FieldGet(2)) )
			DbSkip(-1)
			Assert.Equal("c-ALIAS1" , AllTrim(FieldGet(1)) )
			Assert.Equal("c-ALIAS1_memo" , AllTrim(FieldGet(2)) )
			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD Check_numeric_values() AS VOID
			LOCAL cDbf AS STRING
			LOCAL aValues AS ARRAY
			RddSetDefault("DBFCDX")
			cDBF := GetTempFileName()

			aValues := {123.45, 894837823.0, -323212, 564342.99, -54323.11, 0, 0.00, -0.02, -442, -42523423.7, 12345678, 4324, -6653342.16,;
						-5563423.44, 64346542.11, 566666.1, -1, -1.5, -5555, 1000000, -432423, 53453, 111, 9999999.99, -999999.99}

			DbfTests.CreateDatabase(cDbf , { { "NFIELD" , "N" , 12 , 0 } , { "NFIELDDEC" , "N" , 12 , 2 } } )
			DbUseArea(TRUE,  , cDbf)
			DbCreateIndex(cDbf , "NFIELDDEC")
			FOR LOCAL n := 1 AS INT UPTO ALen(aValues)
				DbAppend()
				FieldPut(1, aValues[n])
				FieldPut(2, aValues[n])
			NEXT

			aValues := ASort(aValues , , , {|a,b| a < b})
			DbGoTop()
			LOCAL nCount := 0 AS INT
			DO WHILE .not. EOF()
				nCount ++
				Assert.True(FieldGet(1) == Round(aValues[nCount] , 0))
				Assert.True(FieldGet(2) == aValues[nCount])
				DbSkip()
			END DO
			Assert.Equal(nCount, (INT)ALen(aValues))

			DbCloseArea()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest2() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , { { "LAST" , "C" , 20 , 0 } } )
			DbUseArea( ,,cDBF )
			DbAppend()
			FieldPut ( 1 , "BC" )
			DbCreateOrder ( "ORDER1"  , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

			DbCloseArea()
			DbUseArea( ,,cDBF)
//			DbOrderInfo(DBOI_KEYCOUNT)

			? DbZap()

			? DbGoTop()	 // <-----------  ArgumentNullException

			Assert.True( Eof() )
			Assert.True( Bof() )
			Assert.True( DbOrderInfo(DBOI_KEYCOUNT) == 0 )

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD ZapTest3() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			DbCreate( cDBF , { { "LAST" , "C" , 20 , 0 } } )
			DbUseArea( ,,cDBF )
			DbAppend()
			FieldPut ( 1 , "here" )
			DbAppend()
			FieldPut ( 1 , "are" )
			DbAppend()
			FieldPut ( 1 , "some" )
			DbAppend()
			FieldPut ( 1 , "values" )
			DbCreateOrder ( "ORDER1"  , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } )

//			DbCloseArea()
//			DbUseArea( ,,cDBF)
			Assert.Equal( 4, (INT) DbOrderInfo(DBOI_KEYCOUNT) )

			Assert.True( DbZap() )

			? DbGoTop()	 // <-----------  ArgumentNullException

			Assert.True( Eof() )
			Assert.True( Bof() )
			Assert.True( DbOrderInfo(DBOI_KEYCOUNT) == 0 )

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD LongIndexTest() AS VOID
			LOCAL cPrev, cCurrent AS USUAL
			LOCAL nRecords AS INT
			LOCAL nCount AS INT
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()
			FErase ( cDbf + IndexExt() )

			nRecords := 500

			DbCreate( cDBF , { { "LAST" , "C" , 200 , 0 } })
			DbUseArea( ,,cDBF , , FALSE )  // open shared
			FOR LOCAL n := 1 AS DWORD UPTO nRecords
				DbAppend()
				FieldPut ( 1 , Replicate( Chr(50 + n % 50) , 50 + n % 80) )
			NEXT
			DbCreateIndex ( cDBF , "LAST" , {||_FIELD->LAST})
			DbGoBottom()

			FOR LOCAL n := 1 AS DWORD UPTO 500
				DbGoto((n * 17) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))
				DbGoto((n * 37) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))
				DbGoto((n * 97) % (nRecords - 10) + 2)
				FieldPut(1, Replicate( Chr((n * 6) % 50 + 40) , n % 80 + 10 ))

				cPrev := NIL
				nCount := 0
				DbGoTop()
				DO WHILE .NOT. EoF()
					nCount ++
					cCurrent := FieldGet(1)
					IF cPrev != NIL
						Assert.True(cPrev <=  cCurrent)
						IF .not. cPrev <=  cCurrent
							? "Failed at values:" , n
							? Left(cPrev,10)
							? Left(cCurrent,10)
						END IF
					END IF
					cPrev := cCurrent
					DbSkip()
				END DO
				Assert.Equal(500, nCount)
			NEXT

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD UniqeTest() AS VOID
			LOCAL cDbf AS STRING
			LOCAL nCount AS INT

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "g1" , "o5" , "g2", "g1" , "g8" , "g1"} )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } , TRUE) // Unique

			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))

			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				? RecNo(), FieldGet(1)
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(4 , nCount)
			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE )    // open not shared
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))

			DbPack()
//			DBZap()
//			DbReindex()

			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(4 , nCount)
			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE ) // FALSE, wrong
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			nCount := 0
			DbGoTop()
			DO WHILE .not. Eof()
				nCount ++
				DbSkip()
			END DO
			Assert.Equal(TRUE , (LOGIC)DbOrderInfo(DBOI_UNIQUE))
			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD PackZapReindexTest() AS VOID
			SELF:PackZapReindexTest_helper(1)
			SELF:PackZapReindexTest_helper(2)
			SELF:PackZapReindexTest_helper(3)
		END METHOD

		METHOD PackZapReindexTest_helper(nWitch AS INT) AS VOID
			LOCAL cDbf AS STRING

			RddSetDefault("DBFCDX")
			SetCollation(#CLIPPER)

			cDBF := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , { "g1" , "o5" , "g2", "g1" , "g8" , "g1"} )
			DbGoto(2)
			DbDelete()
			DbGoto(4)
			DbDelete()

			DBClearOrderCondition () // descend + condition + unique       order
			DbSetOrderCondition( "Upper(LAST) = 'G'", {||Upper(_Field->LAST) = "G" } ,,,,,,,,, TRUE)
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } , TRUE)

			DBClearOrderCondition ()
			DbSetOrderCondition(,,,,,,,,,,,,, TRUE) // custom + unique    order
			DbCreateOrder ( "ORDER2" , cDbf , "upper(LAST)" , { || Upper ( _FIELD->LAST) } , TRUE )

			DbCloseArea()

			DbUseArea( ,,cDBF , , FALSE )    // open not shared
			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			SWITCH nWitch
			CASE 1
				DbPack()
			CASE 2
				DbZap()
			CASE 3
				DbReindex()
			END SWITCH

			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			DbCloseArea()
			DbUseArea( ,,cDBF , , FALSE )    // open shared

			DbSetOrder ( 1 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISDESC))
			Assert.True((LOGIC) DbOrderInfo(DBOI_ISCOND))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))
			DbSetOrder ( 2 )
			Assert.True((LOGIC) DbOrderInfo(DBOI_CUSTOM))
			Assert.True((LOGIC) DbOrderInfo(DBOI_UNIQUE))

			DbCloseArea()
		END METHOD

        [Fact, Trait("Category", "DBF")];
		METHOD OrdSetFocus_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := "ORDSETFOCUS"
			DbfTests.CreateDatabase(cDbf , { { "NUMFIELD" , "N" , 5 , 0 } } , { 2,1,3} )
			DbCreateOrder("ORDER1", cDbf, "NUMFIELD")
			DbCreateOrder("ORDER2", , "-NUMFIELD")
			DbCloseArea()
			DbUseArea(TRUE, "DBFCDX", cDbf)

			Assert.Equal("ORDER1", (STRING)OrdSetFocus(0))
			Assert.Equal("", (STRING)OrdSetFocus(0))
			DbGoTop()
			Assert.Equal(2, (INT)FieldGet(1))

			Assert.Equal("", (STRING)OrdSetFocus(1))
			Assert.Equal("ORDER1", (STRING)OrdSetFocus(1))
			DbGoTop()
			Assert.Equal(1, (INT)FieldGet(1))

			Assert.Equal("ORDER1", (STRING)OrdSetFocus(2))
			Assert.Equal("ORDER2", (STRING)OrdSetFocus(2))
			DbGoTop()
			Assert.Equal(3, (INT)FieldGet(1))

			Assert.Equal("ORDER2", (STRING)OrdSetFocus(3))
			Assert.Equal("", (STRING)OrdSetFocus(3))
			DbGoTop()
			Assert.Equal(2, (INT)FieldGet(1))

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD VoDbOrdSetFocus_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := "VODBORD"
			DbfTests.CreateDatabase(cDbf , { { "NUMFIELD" , "N" , 5 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf)
			DbCreateOrder("ORDER1", cDbf, "NUMFIELD")
			DbCloseArea()
			DbUseArea(TRUE, "DBFCDX", cDbf)

			LOCAL cPrevious := "" AS STRING
			Assert.False(VoDbOrdSetFocus("",123,REF cPrevious))
			Assert.False(VoDbOrdSetFocus("","abc",REF cPrevious))
			Assert.False(VoDbOrdSetFocus("abc","",REF cPrevious))
			Assert.True(VoDbOrdSetFocus("",1,REF cPrevious))
			Assert.True(VoDbOrdSetFocus("",1,REF cPrevious))
			Assert.Equal("ORDER1", cPrevious)
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_BoF_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } } , ;
									{ "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "A1" , "a2" , "p", "q" , "r" , "s" } )
			DbCreateOrder ( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			OrdScope(BOTTOMSCOPE, "G")
			OrdScope(TOPSCOPE, "G")

			Assert.Equal(5, (INT)OrdKeyCount() )

			DbGoTop()

			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )
			DbSkip( -1 )
			Assert.True( Bof() )

			DbGoBottom()

			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )
			DbSkip ( 1 )
			Assert.True( Eof() )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			LOCAL cbExpression AS USUAL
			LOCAL u1,u2 AS USUAL
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild  , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parent" , TRUE)
			parent->DbAppend()
			parent->FieldPut(1,3)

			DbUseArea(TRUE,"DBFCDX", cChild, "child" , TRUE)
			child->DbCreateIndex(cChild,"FLD")
			FOR LOCAL n := 1 AS INT UPTO 5
			child->DbAppend()
			child->FieldPut(1,n)
			NEXT

			cbExpression := &( "{ || FLD }")
			child->DbGoBottom()
			? "evaluate in bottom, must be 5:", child->Eval( cbExpression ) // 3
			Assert.Equal(5 , (INT)child->Eval( cbExpression ))

			Assert.True( parent->VoDbSetRelation("child" , cbExpression ,"FLD") )
			parent->DbGoTop()

			child->DbSkip(0) // this throws a runtime error in __FieldGet()

			? "Recno must be 3:",child->RecNo()
			Assert.Equal(3U , child->RecNo() )
			?
			? "evaluate after SetRelation(), must be 3:", child->Eval( cbExpression )
			Assert.Equal(3 , (INT) child->Eval( cbExpression ))
			? "Recno should be 3:", child->RecNo()
			Assert.Equal(3U , child->RecNo() )

			u1 := u2 := 3
			Assert.True( child->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 ) )
			Assert.True( child->VoDbOrderInfo( DBOI_SCOPEBottom, "", NIL, REF u2 ) )
			parent->DbGoTop()

			child->DbGoTop()
			? "recno after set scope, must be 3:", child->RecNo()
			Assert.Equal(3U , child->RecNo() )

			? "Skipping forward, all must be 6 , FALSE, TRUE"
			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U ,  child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			child->DbSkip(+1)
			? child->RecNo() , child->Bof() , child->Eof()
			Assert.Equal(6U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.True(child->Eof())

			? "Skipping backward"
			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, false, false
			Assert.Equal(3U , child->RecNo() )
			Assert.False(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbSkip(-1)
			? child->RecNo() , child->Bof() , child->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child->RecNo() )
			Assert.True(child->Bof())
			Assert.False(child->Eof())

			child->DbCloseArea()
			parent->DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test_larger() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			LOCAL cbExpression AS USUAL
			LOCAL u1,u2 AS USUAL
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild  , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parent2" , TRUE)
			parent2->DbAppend()
			parent2->FieldPut(1,3)

			DbUseArea(TRUE,"DBFCDX", cChild, "child2" , TRUE)
			child2->DbCreateIndex(cChild,"FLD")
			FOR LOCAL n := 1 AS INT UPTO 15
			child2->DbAppend()
			child2->FieldPut(1,n)
			NEXT

			cbExpression := &( "{ || FLD }")
			child2->DbGoBottom()
			? "evaluate in bottom, must be 5:", child2->Eval( cbExpression ) // 3
			Assert.Equal(15 , (INT)child2->Eval( cbExpression ))

			Assert.True( parent2->VoDbSetRelation("child2" , cbExpression ,"FLD") )
			parent2->DbGoTop()

//			child2->DbSkip(0) // this throws a runtime error in __FieldGet()

			? "Recno must be 3:",child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )
			?
			? "evaluate after SetRelation(), must be 3:", child2->Eval( cbExpression )
//			Assert.Equal(3 , (INT)child2->Eval( cbExpression ))
			? "Recno should be 3:", child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )

			u1 := u2 := 3
			Assert.True( child2->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 ) )
			Assert.True( child2->VoDbOrderInfo( DBOI_SCOPEBottom, "", NIL, REF u2 ) )
			parent2->DbGoTop()

			child2->DbGoTop()
			? "recno after set scope, must be 3:", child2->RecNo()
			Assert.Equal(3U , child2->RecNo() )

			? "Skipping forward, all must be 16 , FALSE, TRUE"
			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			child2->DbSkip(+1)
			? child2->RecNo() , child2->Bof() , child2->Eof()
			Assert.Equal(16U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.True(child2->Eof())

			? "Skipping backward"
			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, false, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.False(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbSkip(-1)
			? child2->RecNo() , child2->Bof() , child2->Eof() // must be 3, TRUE, false
			Assert.Equal(3U , child2->RecNo() )
			Assert.True(child2->Bof())
			Assert.False(child2->Eof())

			child2->DbCloseArea()
			parent2->DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD SetRelation_test_for_526() AS VOID
			LOCAL cParent,cChild,cTemp AS STRING
			RddSetDefault("DBFCDX")
			cTemp := GetTempFileName()
			cParent := cTemp + "_parent"
			cChild := cTemp + "_child"

			DbCreate(cParent , {{"FLD" , "N" , 3 , 0}})
			DbCreate(cChild , {{"FLD" , "N" , 3 , 0}})

			DbUseArea(TRUE,"DBFCDX", cParent, "parentnew" , TRUE)
			parentnew->DbAppend()
			parentnew->FieldPut(1,1)
			parentnew->DbAppend()
			parentnew->FieldPut(1,2)

			DbUseArea(TRUE,"DBFCDX", cChild, "childnew" , TRUE)
			childnew->DbCreateIndex(cChild,"FLD")
			childnew->DbAppend()
			childnew->FieldPut(1,1)
			childnew->DbAppend()
			childnew->FieldPut(1,2)

			DbCloseAll()

			DbUseArea(TRUE,"DBFCDX", cChild, "childnew" , TRUE)
			DbUseArea(TRUE,"DBFCDX", cParent, "parentnew" , TRUE)
			parentnew->VoDbSetRelation("childnew" , &( "{ ||FLD}") ,"FLD")

			FOR LOCAL nMode := 0 AS INT UPTO 2

//			In the next two, childnew EoF() is false as expected
			// ? "move parent to first record"
			parentnew->DbGoTop()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(1U , childnew->RecNo() )

			// ? "move parent to second record"
			parentnew->DbSkip(+1)
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

//			Here, childnew EoF() becomes true, correct
			// ? "move parent to EoF"
			parentnew->DbSkip(+1)
			DoRelation(nMode)
			Assert.True(childnew->Eof())
			Assert.Equal(3U , childnew->RecNo() )

//			In all the below, childnew EoF() remains TRUE, should had turned to false. Also RecNo remains at 3 (above the last rec)
			// ? "move parent back to last record"
			parentnew->DbSkip(-1)
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

			// ? "move parent to top"
			parentnew->DbGoTop()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(1U , childnew->RecNo() )

			// ? "move parent to bottom"
			parentnew->DbGoBottom()
			DoRelation(nMode)
			Assert.False(childnew->Eof())
			Assert.Equal(2U , childnew->RecNo() )

			NEXT

			DbCloseAll()

		INTERNAL STATIC METHOD DoRelation(nMode := 0 AS INT) AS VOID
			LOCAL u1,u2 AS USUAL
			? "Parent value:", u1 := u2 := parentnew->FieldGet(1)
			childnew->VoDbOrderInfo( DBOI_SCOPETOP	 , "", NIL, REF u1 )
			childnew->VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF u2 )
			IF nMode == 1
				childnew->DbGoBottom() // no problem with this instead
			ELSEIF nMode == 2
				childnew->DbGoTop() // <---------- this is what makes the problem manifest itself
			END IF
			? "Child Eof, RecNo:", childnew->Eof(), childnew->RecNo()
		RETURN

        [Fact, Trait("Category", "DBF")];
		METHOD SetScope_test() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "FLD" , "N" , 4 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf)

			DbAppend()
			FieldPut(1,101)
			DbAppend()
			FieldPut(1,202)
			DbAppend()
			FieldPut(1,301)
			DbAppend()
			FieldPut(1,402)

			DbCreateIndex(cDbf,"FLD")

			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 1 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 1 , TestScope(401,410,FALSE) )
			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(501,510,TRUE)  )
			Assert.Equal( 1 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbAppend()
			FieldPut(1,103)
			DbAppend()
			FieldPut(1,201)
			DbAppend()
			FieldPut(1,501)
			DbAppend()
			FieldPut(1,403)

			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 2 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 2 , TestScope(401,410,FALSE) )
			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 1 , TestScope(501,510,FALSE) )
			Assert.Equal( 2 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbAppend()
			FieldPut(1,110)
			DbAppend()
			FieldPut(1,205)
			DbAppend()
			FieldPut(1,321)
			DbAppend()
			FieldPut(1,503)

			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 3 , TestScope(201,210,FALSE) )
			Assert.Equal( 1 , TestScope(301,310,FALSE) )
			Assert.Equal( 2 , TestScope(401,410,FALSE) )
			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 2 , TestScope(501,510,FALSE) )
			Assert.Equal( 3 , TestScope(101,110,FALSE) )
			Assert.Equal( 0 , TestScope(601,610,TRUE)  )

			DbCloseArea()

		INTERNAL STATIC METHOD TestScope(first AS INT,last AS INT,expected AS LOGIC) AS INT
			LOCAL uValue1,uValue2 AS USUAL
			LOCAL nRecords AS INT
			uValue1 := first
			uValue2 := last
			VoDbOrderInfo( DBOI_SCOPETOP,    "", NIL, REF uValue1 )
			DbGoTop() // without this, the problem does not happen
			VoDbOrderInfo( DBOI_SCOPEBOTTOM, "", NIL, REF uValue2 )
			DbGoTop()
			Assert.Equal(expected , Eof() )
			nRecords := 0
			DO WHILE .not. EoF()
				nRecords ++
				DbSkip()
			END DO
		RETURN nRecords

        [Fact, Trait("Category", "DBF")];
		METHOD CreateOrder_fieldname_conflict() AS VOID
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "DEFINE_FLD" , "C" , 10 , 0 } , { "GLOBAL_FLD" , "D" , 8 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf, , FALSE)
			Assert.True( DbCreateOrder("TEST1" , cDbf , "Left(DEFINE_FLD,5)") )
			Assert.True( DbCreateOrder("TEST2" , cDbf , "DToS(GLOBAL_FLD)")   )
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD Empty_Filter_test() AS VOID
			LOCAL cDbf AS STRING
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "TESTFLD" , "C" , 10 , 0 } } )
			DbUseArea(TRUE, "DBFCDX", cDbf, , FALSE)
			LOCAL uInfo := NIL AS USUAL
			VoDbInfo(DBI_DBFILTER, REF uInfo)
			Assert.False( IsNil(uInfo) )
			Assert.True( uInfo == "" )
			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/578
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE, "X")     // "A"
			OrdScope(BOTTOMSCOPE, "X")  // "A"

			Assert.Equal(0, (INT)OrdKeyCount())

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdScope_OrdDescend_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/579
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdDescend ( , , TRUE )  // switch to descend view
			OrdScope(TOPSCOPE, "B")     // Note: must be "R" !
			OrdScope(BOTTOMSCOPE, "R")  // Note: must be "B" !

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyCount())
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyNo())
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()

            SetDeleted(TRUE)
			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			OrdDescend ( , , TRUE )  // switch to descend view
			OrdScope(TOPSCOPE, "B")     // Note: must be "R" !
			OrdScope(BOTTOMSCOPE, "R")  // Note: must be "B" !

			DbGoTop()
			Assert.True(Bof())
			Assert.True(Eof())
			Assert.Equal(13, (INT)RecNo())

		    DbGoBottom()
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyCount())
			Assert.True(Bof())
			Assert.True(Eof())

			Assert.Equal(0, (INT)OrdKeyNo())
			Assert.True(Bof())
			Assert.True(Eof())

			DbCloseArea()
            SetDeleted(FALSE)

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyCount_OrdKeyNo_BoF_EoF_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/583
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 9
				DbSkip()
				Assert.False(Eof())
			NEXT
			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Eof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Eof())

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 2
				DbSkip(-1)
				Assert.False(Bof())
			NEXT
			DbSkip(-1)
			Assert.True(Bof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Bof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Bof())

			DbCloseArea()

			SetDeleted(TRUE)
			DbUseArea( ,,cDBF )
			DbSetOrder ( 1 )

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 9
				DbSkip()
				Assert.False(Eof())
			NEXT
			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Eof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Eof())

			DbSeek ( "G" )
			FOR LOCAL i := 1 AS INT UPTO 2
				DbSkip(-1)
				Assert.False(Bof())
			NEXT
			DbSkip(-1)
			Assert.True(Bof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )
			Assert.True(Bof())
			Assert.Equal(12 , (INT)DbOrderInfo( DBOI_KEYCOUNT ) )
			Assert.True(Bof())

			DbCloseArea()
			SetDeleted(FALSE)

        [Fact, Trait("Category", "DBF")];
		METHOD DbOrderInfo_DBOI_POSITION_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/593
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "a" , "b", "c" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )

			DbGoTop()
			Assert.False(Eof())
			Assert.Equal(1 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.False(Eof())
			Assert.Equal(2 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.False(Eof())
			Assert.Equal(3 ,  (INT)DbOrderInfo( DBOI_POSITION ) )

			DbSkip()
			Assert.True(Eof())
			Assert.Equal(0 , (INT)DbOrderInfo( DBOI_POSITION ) )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD Found_test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/582
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "a" , "b", "c" } )
			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )

			DbSeek ( "B" )
			Assert.True( Found() )

			DbSeek ( "D" )
			Assert.False( Found() )

			DbSeek ( "B" )
			DbSkip()
			Assert.False( Found() )

			DbSeek ( "B" )
			DbSkip(-1)
			Assert.False( Found() )

			DbSeek ( "B" )
			DbGoTop()
			Assert.False( Found() )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD OrdKeyCount_SetDeleted() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/599
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()

			DbfTests.CreateDatabase(cDbf , { { "LAST" , "C" , 20 , 0 } 	} , { "g6" , "o2", "g2" , "g1" , "g3" , "g5" , "B1" , "b2" , "p", "q" , "r" , "s" } )

			DbGoto(5)
			DbDelete()
			DbGoto(8)
			DbDelete()
			DbGoto(9)
			DbDelete()

			DbCreateOrder( "ORDER1" , cDbf , "upper(LAST)" , { || Upper ( _Field->LAST) } )
			DbCloseArea()

			DbUseArea( TRUE,,cDBF )
			DbSetOrder ( 1 )

			OrdScope(TOPSCOPE, "A")    // "A"  "A"
			OrdScope(BOTTOMSCOPE, "S") // "Z"  "S"

			DbGoTop()
			Assert.Equal( 12, (INT)RecCount() )

			SetDeleted ( TRUE )
			Assert.Equal( 12, (INT)OrdKeyCount() )

			SetDeleted ( FALSE )
			Assert.Equal( 12, (INT)OrdKeyCount() )

			DbCloseArea()
			SetDeleted( FALSE )

        [Fact, Trait("Category", "DBF")];
		METHOD FPT_OpenShared() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/592
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"MEMOFLD","M",10,0}} )
			DbUseArea( TRUE,,cDBF,,FALSE )
			FOR LOCAL n := 1 AS INT UPTO 10
				DbAppend()
			NEXT
			DbCloseArea()

			DbUseArea( TRUE,,cDBF,,TRUE )

			FOR LOCAL n := 1 AS INT UPTO 200
				Assert.True( DbUseArea(TRUE,"DBFCDX",cDbf,"alias" + AsString(n),TRUE) )
				Assert.True( DbCloseArea() )
			NEXT

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD DBClose_tests() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/611
			Assert.False( DbCloseArea() )
			Assert.True( DbCloseAll() )
			Assert.False( DbCloseArea() )
			Assert.True( DbCloseAll() )

        [Fact, Trait("Category", "DBF")];
		METHOD ReadOnly_Test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/610
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","C",10,0}} , {"a","b"} )
			DbCloseArea()

			Assert.True( DbUseArea( TRUE,,cDBF,,FALSE,TRUE ) )
			Assert.True( DbCreateIndex(cDbf,"FLD") )
			Assert.True( DbCloseArea() )

			Assert.True( DbUseArea(TRUE,"DBFCDX", cDbf , , TRUE) )
			Assert.True( DbCloseArea() )

        [Fact, Trait("Category", "DBF")];
		METHOD DbOrderInfo_withnoindex_Test() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/627
			// https://github.com/X-Sharp/XSharpPublic/issues/666
			// https://github.com/X-Sharp/XSharpPublic/issues/684

			// Insane inconsistent VO behavior...
			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","C",10,0}} , {"a","b"} )
			DbCloseArea()

			LOCAL uRet AS USUAL

			uRet := DbOrderInfo(DBOI_NAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_FULLPATH)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_EXPRESSION)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_CONDITION)
			Assert.True( IsNil(uRet) )

			uRet := DbOrderInfo(DBOI_POSITION)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYTYPE)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYSIZE)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ISCOND)
			Assert.True( IsNil(uRet) )

			DbUseArea(TRUE, "DBFNTX", cDbf)

			uRet := DbOrderInfo(DBOI_NAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_BAGNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_INDEXNAME)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_FULLPATH)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_EXPRESSION) // NIL in VO, empty string in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_CONDITION)  // NIL in VO, empty string in X#
			Assert.True( IsNil(uRet) )

			uRet := DbOrderInfo(DBOI_POSITION)   // 0 in VO, 1 in X#
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )

			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".NTX" )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".NTX" )
			uRet := DbOrderInfo(DBOI_KEYTYPE)    // NIL in VO, 0 in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_KEYSIZE)    // NIL in VO, 0 in X#
			Assert.True( IsNil(uRet) )
			uRet := DbOrderInfo(DBOI_ISCOND)     // NIL in VO, .F. in X#
			Assert.True( IsNil(uRet) )

			DbCloseArea()

			DbUseArea(TRUE, "DBFCDX", cDbf)

			uRet := DbOrderInfo(DBOI_NAME)       // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_BAGNAME)    // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_INDEXNAME)  // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_FULLPATH)   // empty string in VO, NIL ,in X#
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_EXPRESSION)
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )
			uRet := DbOrderInfo(DBOI_CONDITION)
			Assert.True( IsString(uRet) )
			Assert.True( uRet = "" )

			uRet := DbOrderInfo(DBOI_POSITION)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 1 )
			uRet := DbOrderInfo(DBOI_RECNO)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 1 )
			uRet := DbOrderInfo(DBOI_ORDERCOUNT)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )

			uRet := DbOrderInfo(DBOI_BAGEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".CDX" )
			uRet := DbOrderInfo(DBOI_INDEXEXT)
			Assert.True( IsString(uRet) )
			Assert.True( uRet == ".CDX" )
			uRet := DbOrderInfo(DBOI_KEYTYPE)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_KEYSIZE)
			Assert.True( IsNumeric(uRet) )
			Assert.True( uRet == 0 )
			uRet := DbOrderInfo(DBOI_ISCOND)
			Assert.True( IsLogic(uRet) )
			Assert.True( uRet == FALSE )

			DbCloseArea()

        [Fact, Trait("Category", "DBF")];
		METHOD FieldGet_After_Skip_zero() AS VOID
			// https://github.com/X-Sharp/XSharpPublic/issues/698

			LOCAL cDbf AS STRING
			RddSetDefault("DBFCDX")
			cDbf := GetTempFileName()
			DbfTests.CreateDatabase(cDbf , {{"FLD","N",5,0}} , {1,2} )
			DbCreateOrder("ORDER1", cDbf, "FLD")

			DbGoTop()
			DbSkip(-1)
			Assert.True( Bof() )
			Assert.True( FieldGet(1) == 1 )
			Assert.Equal( 1U , RecNo() )

			DbSkip(0)
			Assert.True( Bof() )
			Assert.True( FieldGet(1) == 1 )
			Assert.Equal( 1U , RecNo() )

			DbGoBottom()
			Assert.False( Eof() )
			Assert.True( FieldGet(1) == 2 )
			Assert.Equal( 2U , RecNo() )

			DbSkip(+1)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			DbSkip(0)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			DbSkip(+1)
			Assert.True( Eof() )
			Assert.True( FieldGet(1) == 0 )
			Assert.Equal( 3U , RecNo() )

			Assert.True( Eof() )

			DbCloseArea()

		STATIC PRIVATE METHOD GetTempFileName() AS STRING
           STATIC nCounter AS LONG
            ++nCounter
		    RETURN GetTempFileName("testcdx"+NTrim(nCounter))

		STATIC PRIVATE METHOD GetTempFileName(cFileName AS STRING) AS STRING
			// we may want to put them to a specific folder etc
		RETURN cFileName

	END CLASS
END NAMESPACE