int getListItemReferences_v1(int _iDatasetId, hobj_ref_t ** _piItemRef)
{
    int iItem = 0;
    herr_t status = 0;

    getListDims_v1(_iDatasetId, &iItem);

    *_piItemRef = (hobj_ref_t *) MALLOC(iItem * sizeof(hobj_ref_t));

    status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, *_piItemRef);
    if (status < 0)
    {
        return -1;
    }

    return 0;
}
static bool read_list_v1(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
{
    int iRet = 0;
    int iItems = 0;
    int *piListAddr = NULL;
    hobj_ref_t *piItemRef = NULL;

    iRet = getListDims_v1(_iDatasetId, &iItems);
    if (iRet)
    {
        return false;
    }

    if (iItems == 0)
    {
        //special case for empty list
    }
    else
    {
        iRet = getListItemReferences_v1(_iDatasetId, &piItemRef);
        if (iRet)
        {
            return false;
        }
    }
    //_pInfo = (VarInfo_v1*)MALLOC(sizeof(VarInfo));
    _pInfo->iDims = 1;
    _pInfo->piDims[0] = iItems;
    _pInfo->iSize = (2 + iItems + 1) * 4;

    for (int i = 0; i < iItems; i++)
    {
        int iItemDataset = 0;

        iRet = getListItemDataset_v1(_iDatasetId, piItemRef, i, &iItemDataset);
        if (iRet || iItemDataset == 0)
        {
            return false;
        }
        VarInfo_v1 info;
        bool bRet = read_data_v1(pvCtx, iItemDataset, i + 1, piListAddr, &info);
        if (bRet == false)
        {
            return false;
        }

        _pInfo->iSize += info.iSize;
    }

    if (_iVarType == sci_list)
    {
        generateInfo_v1(_pInfo, "list");
    }
    else if (_iVarType == sci_tlist)
    {
        generateInfo_v1(_pInfo, "tlist");
    }
    else if (_iVarType == sci_mlist)
    {
        generateInfo_v1(_pInfo, "mlist");
    }

    return true;
}
static bool import_hypermat_v1(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
{
    int iRet = 0;
    int iRows = 0;
    int iCols = 0;
    int iItems = 0;
    hobj_ref_t *piItemRef = NULL;

    // an hypermatrix is stored in an mlist
    if (_iVarType != sci_mlist)
    {
        return false;
    }

    iRet = getListDims_v1(_iDatasetId, &iItems);
    if (iRet)
    {
        return false;
    }

    if (iItems != 3)
    {
        // hypermatrix have 3 elements
        return false;
    }

    iRet = getListItemReferences_v1(_iDatasetId, &piItemRef);
    if (iRet)
    {
        return false;
    }

    // get first item
    int iItemDataset = 0;
    iRet = getListItemDataset_v1(_iDatasetId, piItemRef, 0, &iItemDataset);
    if (iRet || iItemDataset == 0)
    {
        return false;
    }

    // get first item type
    int iItemType = getScilabTypeFromDataSet_v1(iItemDataset);
    if (iItemType != sci_strings)
    {
        return false;
    }

    // get size of first item
    iRet = getDatasetDims_v1(iItemDataset, &iRows, &iCols);
    if (iRet < 0)
    {
        return false;
    }

    if (iRows * iCols != 3)
    {
        return false;
    }

    // get data of first item for check the type of mlist
    char** pstData = new char*[iRows * iCols];
    iRet = readStringMatrix_v1(iItemDataset, iRows, iCols, pstData);
    if (iRet || strcmp(pstData[0], "hm") != 0)
    {
        FREE(piItemRef);
        for (int i = 0; i < iRows * iCols; i++)
        {
            FREE(pstData[i]);
        }
        delete[] pstData;
        return false;
    }

    for (int i = 0; i < iRows * iCols; i++)
    {
        FREE(pstData[i]);
    }
    delete[] pstData;
    pstData = NULL;

    // get second item, the Size of hypermatrix
    iRet = getListItemDataset_v1(_iDatasetId, piItemRef, 1, &iItemDataset);
    if (iRet)
    {
        return false;
    }

    iRet = getDatasetDims_v1(iItemDataset, &iRows, &iCols);
    if (iRet < 0)
    {
        return false;
    }

    if (iRows != 1)
    {
        return false;
    }

    int* piDimsArray = new int[iCols];
    iRet = readInteger32Matrix_v1(iItemDataset, iRows, iCols, piDimsArray);
    if (iRet)
    {
        delete[] piDimsArray;
        return false;
    }

    // get third item, the Data of hypermatrix
    // import data like a "type" (Double, Int, ...) instead of mlist
    iRet = getListItemDataset_v1(_iDatasetId, piItemRef, 2, &iItemDataset);
    bool bRet = import_data_v1(pvCtx, iItemDataset, _iItemPos, _piAddress, _pstVarname);
    if (bRet == false)
    {
        delete[] piDimsArray;
        return false;
    }

    // get imported hypermatrix from List or Context
    types::GenericType* pGT = NULL;
    types::InternalType* pIT = NULL;
    if (_piAddress)
    {
        types::List* pL = (types::List*)_piAddress;
        pIT = pL->get(_iItemPos - 1);
    }
    else
    {
        wchar_t* pwcsName = to_wide_string(_pstVarname);
        pIT = symbol::Context::getInstance()->getCurrentLevel(symbol::Symbol(pwcsName));
        FREE(pwcsName);
    }

    // reshape data with size of hypermatrix
    pGT = pIT->getAs<types::GenericType>();
    pGT->reshape(piDimsArray, iCols);

    delete[] piDimsArray;


    iRet = deleteListItemReferences_v1(_iDatasetId, piItemRef);
    if (iRet)
    {
        return false;
    }

    return true;
}
static bool import_list_v1(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
{
    int iRet = 0;
    int i = 0;
    int iItems = 0;
    int *piListAddr = NULL;
    hobj_ref_t *piItemRef = NULL;
    SciErr sciErr;

    iRet = getListDims_v1(_iDatasetId, &iItems);
    if (iRet)
    {
        return false;
    }

    if (iItems == 0)
    {
        //special case for empty list
    }
    else
    {
        iRet = getListItemReferences_v1(_iDatasetId, &piItemRef);
        if (iRet)
        {
            return false;
        }
    }

#ifdef PRINT_DEBUG
    char pstMsg[512];

    sprintf(pstMsg, "list_%d (%d)", _iItemPos, iItems);
    print_tree(pstMsg);
#endif

    if (_piAddress == 0)
    {
        switch (_iVarType)
        {
            case sci_list:
                sciErr = createNamedList(pvCtx, _pstVarname, iItems, &piListAddr);
                break;
            case sci_tlist:
                sciErr = createNamedTList(pvCtx, _pstVarname, iItems, &piListAddr);
                break;
            case sci_mlist:
                sciErr = createNamedMList(pvCtx, _pstVarname, iItems, &piListAddr);
                break;
            default:
                return false;
        }
    }
    else                        //if not null this variable is in a list
    {
        switch (_iVarType)
        {
            case sci_list:
                sciErr = createListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
                break;
            case sci_tlist:
                sciErr = createTListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
                break;
            case sci_mlist:
                sciErr = createMListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
                break;
            default:
                return false;
        }
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return false;
    }

    iTab++;
    for (i = 0; i < iItems; i++)
    {
        int iItemDataset = 0;

        iRet = getListItemDataset_v1(_iDatasetId, piItemRef, i, &iItemDataset);
        if (iRet || iItemDataset == 0)
        {
            return false;
        }

        bool bRet = import_data_v1(pvCtx, iItemDataset, i + 1, piListAddr, _pstVarname);

        if (bRet == false)
        {
            return false;
        }
    }
    iTab--;

    iRet = deleteListItemReferences_v1(_iDatasetId, piItemRef);
    if (iRet)
    {
        return false;
    }

#ifdef TIME_DEBUG
    printf("Close List %d\n\n", iCloseList++);
#endif

#ifdef PRINT_DEBUG
    char pstMsg1[512];

    sprintf(pstMsg1, "ListEnd_%d", _iItemPos);
    print_tree(pstMsg1);
#endif
    return true;
}