Last-Modified: Wed, 17 Jul 2024 00:59:37 GMT Expires: Sat, 15 Jul 2034 00:59:37 GMT hdf5.git - Mirror from: https://github.com/HDFGroup/hdf5.git
summaryrefslogtreecommitdiffstats
path: root/test/unlink.c
blob: f5754f8b67c67be32388d659763c7ce4f199f219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 * Programmer:  Robb Matzke <matzke@llnl.gov>
 *              Friday, September 25, 1998
 *
 * Purpose:	Test unlinking operations.
 */

#define H5G_FRIEND		/*suppress error about including H5Gpkg	  */

/* Define this macro to indicate that the testing APIs should be available */
#define H5G_TESTING

#include "h5test.h"
#include "H5Gpkg.h"		/* Groups				*/

const char *FILENAME[] = {
    "unlink",
    "new_move_a",
    "new_move_b",
    "lunlink",
    "filespace",
    "slashes",
    "resurrect_set",
    "resurrect_type",
    "resurrect_group",
    "unlink_chunked",
    "full_group",
    NULL
};

/* Macros for test_create_unlink() & test_filespace */
#define GROUPNAME       "group"
#define GROUP2NAME      "group2"
#define UNLINK_NGROUPS         1000
#define DATASETNAME     "dataset"
#define DATASET2NAME    "dataset2"
#define ATTRNAME        "attribute"
#define TYPENAME        "datatype"
#define TYPE2NAME       "datatype2"
#define FILESPACE_NDIMS 3
#define FILESPACE_DIM0  20
#define FILESPACE_DIM1  20
#define FILESPACE_DIM2  20
#define FILESPACE_CHUNK0  10
#define FILESPACE_CHUNK1  10
#define FILESPACE_CHUNK2  10
#define FILESPACE_DEFLATE_LEVEL 6
#define FILESPACE_REWRITE       10
#define FILESPACE_NATTR 100
#define FILESPACE_ATTR_NDIMS    2
#define FILESPACE_ATTR_DIM0     5
#define FILESPACE_ATTR_DIM1     5
#define FILESPACE_TOP_GROUPS    10
#define FILESPACE_NESTED_GROUPS 50
#define FILESPACE_NDATASETS     50
#define SLASHES_GROUP_NAME      "Group///"
#define SLASHES_HARDLINK_NAME   "Hard///"
#define SLASHES_SOFTLINK_NAME   "Soft///"
#define SLASHES_SOFTLINK2_NAME  "Soft2///"
#define SLASHES_ROOTLINK_NAME   "Root///"
#define FULL_GROUP_NUM_KEEP     2
#define FULL_GROUP_NUM_DELETE_COMPACT   2
#define FULL_GROUP_NUM_DELETE_DENSE     16
#define FULL_GROUP_EST_NUM_ENTRIES      8
#define FULL_GROUP_EST_ENTRY_LEN        9


/*-------------------------------------------------------------------------
 * Function:	test_one
 *
 * Purpose:	Creates a group that has just one entry and then unlinks that
 *		entry.
 *
 * Return:	Success:	0
 *
 *		Failure:	number of errors
 *
 * Programmer:	Robb Matzke
 *              Friday, September 25, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_one(hid_t file)
{
    hid_t	work = -1, grp = -1;
    herr_t	status;

    /* Create a test group */
    if((work = H5Gcreate2(file, "/test_one", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Delete by absolute name */
    TESTING("unlink by absolute name");
    if((grp = H5Gcreate2(work, "foo", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(grp) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(file, "/test_one/foo", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    PASSED();

    /* Delete by local name */
    TESTING("unlink by local name");
    if((grp = H5Gcreate2(work, "foo", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(grp) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(work, "foo", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    PASSED();

    /* Delete directly - should fail */
    TESTING("unlink without a name");
    if((grp = H5Gcreate2(work, "foo", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    H5E_BEGIN_TRY {
	status = H5Ldelete(grp, ".", H5P_DEFAULT);
    } H5E_END_TRY;
    if(status>=0)
	FAIL_PUTS_ERROR("    Unlinking object w/o a name should have failed.")
    if(H5Gclose(grp) < 0) FAIL_STACK_ERROR

    /* Cleanup */
    if(H5Gclose(work) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose(work);
	H5Gclose(grp);
    } H5E_END_TRY;
    return 1;
} /* end test_one() */


/*-------------------------------------------------------------------------
 * Function:	test_many
 *
 * Purpose:	Tests many unlinks in a single directory.
 *
 * Return:	Success:	0
 *
 *		Failure:	number of errors
 *
 * Programmer:	Robb Matzke
 *              Friday, September 25, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_many(hid_t file)
{
    hid_t	work=-1, grp=-1;
    int		i;
    const int	how_many=500;
    char	name[32];

    /* Create a test group */
    if((work = H5Gcreate2(file, "/test_many", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
    if((grp = H5Gcreate2(work, "/test_many_foo", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
    if(H5Gclose(grp) < 0) goto error;

    /* Create a bunch of names and unlink them in order */
    TESTING("forward unlink");
    for(i = 0; i < how_many; i++) {
	sprintf(name, "obj_%05d", i);
	if(H5Lcreate_hard(work, "/test_many_foo", H5L_SAME_LOC, name, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    for(i = 0; i < how_many; i++) {
	sprintf(name, "obj_%05d", i);
	if(H5Ldelete(work, name, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    PASSED();

    /* Create a bunch of names and unlink them in reverse order */
    TESTING("backward unlink");
    for(i = 0; i < how_many; i++) {
	sprintf(name, "obj_%05d", i);
	if(H5Lcreate_hard(work, "/test_many_foo", H5L_SAME_LOC, name, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    for(i = (how_many - 1); i >= 0; --i) {
	sprintf(name, "obj_%05d", i);
	if(H5Ldelete(work, name, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    PASSED();

    /* Create a bunch of names and unlink them from both directions */
    TESTING("inward unlink");
    for(i = 0; i < how_many; i++) {
	sprintf(name, "obj_%05d", i);
	if(H5Lcreate_hard(work, "/test_many_foo", H5L_SAME_LOC, name, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    for(i = 0; i < how_many; i++) {
	if(i % 2)
	    sprintf(name, "obj_%05d", how_many - (1 + i / 2));
	else
	    sprintf(name, "obj_%05d", i / 2);
	if(H5Ldelete(work, name, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    PASSED();

    /* Create a bunch of names and unlink them from the midle */
    TESTING("outward unlink");
    for(i = 0; i < how_many; i++) {
	sprintf(name, "obj_%05d", i);
	if(H5Lcreate_hard(work, "/test_many_foo", H5L_SAME_LOC, name, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    for(i = (how_many - 1); i >= 0; --i) {
	if(i % 2)
	    sprintf(name, "obj_%05d", how_many - (1 + i / 2));
	else
	    sprintf(name, "obj_%05d", i / 2);
	if(H5Ldelete(work, name, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */
    PASSED();


    /* Cleanup */
    if (H5Gclose(work) < 0) goto error;
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose(work);
	H5Gclose(grp);
    } H5E_END_TRY;
    return 1;
}


/*-------------------------------------------------------------------------
 * Function:	test_symlink
 *
 * Purpose:	Tests removal of symbolic links.
 *
 * Return:	Success:	0
 *
 *		Failure:	number of errors
 *
 * Programmer:	Robb Matzke
 *              Friday, September 25, 1998
 *
 *-------------------------------------------------------------------------
 */
static int
test_symlink(hid_t file)
{
    hid_t	work=-1;

    TESTING("symlink removal");

    /* Create a test group and symlink */
    if((work = H5Gcreate2(file, "/test_symlink", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("link_value", work, "link", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(work, "link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Cleanup */
    if(H5Gclose(work) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Gclose(work);
    } H5E_END_TRY;
    return 1;
} /* end test_symlink() */


/*-------------------------------------------------------------------------
 * Function:	test_rename
 *
 * Purpose:	Tests H5Lmove()
 *
 * Return:	Success:	0
 *
 *		Failure:	number of errors
 *
 * Programmer:	Robb Matzke
 *              Friday, September 25, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_rename(hid_t file)
{
    hid_t	work=-1, foo=-1, inner=-1;

    /* Create a test group and rename something */
    TESTING("object renaming");
    if((work = H5Gcreate2(file, "/test_rename", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((foo = H5Gcreate2(work, "foo", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Lmove(work, "foo", H5L_SAME_LOC, "bar", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if((inner = H5Gcreate2(foo, "inner", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(inner) < 0) FAIL_STACK_ERROR
    if(H5Gclose(foo) < 0) FAIL_STACK_ERROR
    if((inner = H5Gopen2(work, "bar/inner", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(inner) < 0) FAIL_STACK_ERROR
    PASSED();

    /* Try renaming a symlink */
    TESTING("symlink renaming");
    if(H5Lcreate_soft("link_value", work, "link_one", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lmove(work, "link_one", H5L_SAME_LOC, "link_two", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Cleanup */
    if (H5Gclose(work) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Gclose(work);
	H5Gclose(foo);
	H5Gclose(inner);
    } H5E_END_TRY;
    return 1;
} /* end test_rename() */


/*-------------------------------------------------------------------------
 * Function:    test_new_move
 *
 * Purpose:     Tests H5Lmove() with different locations
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  Raymond Lu
 *              Thursday, April 25, 2002
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_new_move(hid_t fapl)
{
    hid_t 	file_a, file_b=(-1);
    hid_t	grp_1=(-1), grp_2=(-1), grp_move=(-1), moved_grp=(-1);
    char 	filename[1024];

    TESTING("new move");

    /* Create a second file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file_a = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR
    h5_fixname(FILENAME[2], fapl, filename, sizeof filename);
    if((file_b = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create groups in first file */
    if((grp_1 = H5Gcreate2(file_a, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((grp_2 = H5Gcreate2(file_a, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((grp_move = H5Gcreate2(grp_1, "group_move", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create hard and soft links. */
    if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Move a group within the file.  Both of source and destination use
     * H5L_SAME_LOC.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) != FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Move a group across files.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) != FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Move a group across groups in the same file. */
    if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Open the group just moved to the new location. */
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    if(H5Gclose(grp_1) < 0) FAIL_STACK_ERROR
    if(H5Gclose(grp_2) < 0) FAIL_STACK_ERROR
    if(H5Gclose(grp_move) < 0) FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file_a) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file_b) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

  error:
    H5E_BEGIN_TRY {
 	H5Gclose(grp_1);
	H5Gclose(grp_2);
	H5Gclose(grp_move);
        H5Gclose(moved_grp);
	H5Fclose(file_a);
	H5Fclose(file_b);
    } H5E_END_TRY;
    return 1;
}


/*-------------------------------------------------------------------------
 * Function:    check_new_move
 *
 * Purpose:     Checks result of H5Lmove() with different locations
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  Raymond Lu
 *              Thursday, April 25, 2002
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
check_new_move(hid_t fapl)
{
    hid_t 	file;
    H5O_info_t	oi_hard1, oi_hard2;
    char 	filename[1024];
    char 	linkval[1024];

    TESTING("check new move function");

    /* Open file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
        FAIL_STACK_ERROR

    /* Get hard link info */
    if(H5Oget_info_by_name(file, "/group2/group_new_name", &oi_hard1, H5P_DEFAULT) < 0)
        FAIL_STACK_ERROR
    if(H5Oget_info_by_name(file, "/group1/hard", &oi_hard2, H5P_DEFAULT) < 0)
        FAIL_STACK_ERROR

    /* Check hard links */
    if(H5O_TYPE_GROUP != oi_hard1.type || H5O_TYPE_GROUP != oi_hard2.type)
        FAIL_PUTS_ERROR("    Unexpected object type, should have been a group")
    if(H5F_addr_ne(oi_hard1.addr, oi_hard2.addr))
        FAIL_PUTS_ERROR("    Hard link test failed.  Link seems not to point to the expected file location.")

    /* Check soft links */
    if(H5Lget_val(file, "group2/soft", linkval, sizeof linkval, H5P_DEFAULT) < 0)
        FAIL_STACK_ERROR
    if(HDstrcmp(linkval, "/group1/group_move"))
        FAIL_PUTS_ERROR("    Soft link test failed. Wrong link value")

    /* Cleanup */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    return 1;
} /* end check_new_move() */


/*-------------------------------------------------------------------------
 * Function:    test_filespace
 *
 * Purpose:     Test proper reuse of space in the file when objects are unlinked
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Saturday, March 22, 2003
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_filespace(hid_t fapl)
{
    hid_t 	fapl_nocache;   /* File access property list with raw data cache turned off */
    hid_t 	contig_dcpl;    /* Dataset creation property list for contiguous dataset */
    hid_t 	early_chunk_dcpl; /* Dataset creation property list for chunked dataset & early allocation */
    hid_t 	late_chunk_dcpl; /* Dataset creation property list for chunked dataset & late allocation */
    hid_t 	comp_dcpl;      /* Dataset creation property list for compressed, chunked dataset */
    hid_t 	compact_dcpl;   /* Dataset creation property list for compact dataset */
    hid_t 	file;           /* File ID */
    hid_t 	group, group2;  /* Group IDs */
    hid_t 	dataset, dataset2;      /* Dataset IDs */
    hid_t 	space;          /* Dataspace ID */
    hid_t 	type;           /* Datatype ID */
    hid_t 	attr_space;     /* Dataspace ID for attributes */
    hid_t 	attr;           /* Attribute ID */
    char 	filename[1024]; /* Name of file to create */
    char 	objname[128];   /* Name of object to create */
    hsize_t     dims[FILESPACE_NDIMS]= {FILESPACE_DIM0, FILESPACE_DIM1, FILESPACE_DIM2};        /* Dataset dimensions */
    hsize_t     chunk_dims[FILESPACE_NDIMS]= {FILESPACE_CHUNK0, FILESPACE_CHUNK1, FILESPACE_CHUNK2};        /* Chunk dimensions */
    hsize_t     attr_dims[FILESPACE_ATTR_NDIMS]= {FILESPACE_ATTR_DIM0, FILESPACE_ATTR_DIM1};        /* Attribute dimensions */
    int        *data = NULL;    /* Pointer to dataset buffer */
    int        *tmp_data;       /* Temporary pointer to dataset buffer */
    h5_stat_size_t       empty_size;     /* Size of an empty file */
    h5_stat_size_t       file_size;      /* Size of each file created */
    herr_t	status;         /* Function status return value */
    unsigned u,v,w;             /* Local index variables */

    /* Metadata cache parameters */
    int mdc_nelmts;
    size_t rdcc_nelmts;
    size_t rdcc_nbytes;
    double rdcc_w0;

    puts("Testing file space gets reused:");

    /* Open file */
    h5_fixname(FILENAME[4], fapl, filename, sizeof filename);

/* Create FAPL with raw data cache disabled */
    /* Create file access property list with raw data cache disabled */
    if ((fapl_nocache=H5Pcopy(fapl)) < 0) TEST_ERROR

    /* Get the cache settings */
    if(H5Pget_cache(fapl_nocache,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0) < 0) TEST_ERROR

    /* Disable the raw data cache */
    rdcc_nelmts=0;
    rdcc_nbytes=0;
    if(H5Pset_cache(fapl_nocache,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0) < 0) TEST_ERROR

/* Create empty file for size comparisons later */

    /* Create file */
    if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) TEST_ERROR

    /* Get the size of an empty file */
    if((empty_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

/* Create common objects for datasets */

    /* Create dataset creation property list for contigous storage */
    if ((contig_dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR

    /* Make certain that space is allocated early */
    if(H5Pset_alloc_time(contig_dcpl, H5D_ALLOC_TIME_EARLY) < 0) TEST_ERROR

    /* Create dataset creation property list for chunked storage & early allocation */
    if ((early_chunk_dcpl=H5Pcopy(contig_dcpl)) < 0) TEST_ERROR

    /* Set chunk dimensions */
    if(H5Pset_chunk(early_chunk_dcpl, FILESPACE_NDIMS, chunk_dims) < 0) TEST_ERROR

    /* Create dataset creation property list for chunked storage & late allocation */
    if ((late_chunk_dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR

    /* Set chunk dimensions */
    if(H5Pset_chunk(late_chunk_dcpl, FILESPACE_NDIMS, chunk_dims) < 0) TEST_ERROR

    /* Create dataset creation property list for compressed, chunked storage & early allocation */
    if ((comp_dcpl=H5Pcopy(early_chunk_dcpl)) < 0) TEST_ERROR

    /* Enable compression & set level */
    if(H5Pset_deflate(comp_dcpl, FILESPACE_DEFLATE_LEVEL) < 0) TEST_ERROR

    /* Create dataset creation property list for compact storage */
    if ((compact_dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR

    /* Set to compact storage */
    if(H5Pset_layout(compact_dcpl, H5D_COMPACT) < 0) TEST_ERROR

    /* Create dataspace for datasets */
    if((space = H5Screate_simple(FILESPACE_NDIMS, dims, NULL)) < 0) TEST_ERROR

    /* Create buffer for writing dataset */
    if(NULL == (data = (int *)HDmalloc(sizeof(int) * FILESPACE_DIM0 * FILESPACE_DIM1 * FILESPACE_DIM2))) TEST_ERROR


/* Create single dataset (with contiguous storage & late allocation), remove it & verify file size */
    TESTING("    contiguous dataset with late allocation");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with contiguous storage & early allocation), remove it & verify file size */
    TESTING("    contiguous dataset with early allocation");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, contig_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with chunked storage & late allocation), remove it & verify file size */
    TESTING("    chunked dataset with late allocation");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, late_chunk_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with chunked storage & early allocation), remove it & verify file size */
    TESTING("    chunked dataset with early allocation");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, early_chunk_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with compressed storage & early allocation), remove it & verify file size */
    TESTING("    compressed, chunked dataset");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, comp_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with compressed storage & early allocation), re-write it a bunch of
 * times (which should re-allocate blocks many times) and remove it & verify
 * file size.
 */
    TESTING("    re-writing compressed, chunked dataset");

    /* Create file (using FAPL with disabled raw data cache) */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_nocache)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, comp_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Alternate re-writing dataset with compressible & random data */
    for(u = 0; u < FILESPACE_REWRITE; u++) {
        /* Set buffer to some compressible values */
        for(v = 0, tmp_data = data; v < (FILESPACE_DIM0 * FILESPACE_DIM1 * FILESPACE_DIM2); v++)
            *tmp_data++ = (int)(v * u);

        /* Write the buffer to the dataset */
        if(H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0) FAIL_STACK_ERROR

        /* Set buffer to different random numbers each time */
        for(v = 0, tmp_data = data; v < (FILESPACE_DIM0 * FILESPACE_DIM1 * FILESPACE_DIM2); v++)
            *tmp_data++ = (int)HDrandom();

        /* Write the buffer to the dataset */
        if(H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close dataset */
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl_nocache)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single dataset (with compact storage), remove it & verify file size */
    TESTING("    compact dataset");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, compact_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create two datasets (with contiguous storage), alternate adding attributes
 * to each one (which creates many object header continuations),
 * remove both & verify file size.
 */
    TESTING("    object header continuations");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create datasets to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, contig_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((dataset2 = H5Dcreate2(file, DATASET2NAME, H5T_NATIVE_INT, space, H5P_DEFAULT, contig_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create a dataspace for the attributes */
    if((attr_space = H5Screate_simple(FILESPACE_ATTR_NDIMS, attr_dims, NULL)) < 0) FAIL_STACK_ERROR

    /* Alternate adding attributes to each one */
    for(u = 0; u < FILESPACE_NATTR; u++) {
        /* Set the name of the attribute to create */
        sprintf(objname,"%s %u",ATTRNAME,u);

        /* Create an attribute on the first dataset */
        if((attr = H5Acreate2(dataset, objname, H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Don't worry about writing the attribute - it will have a fill value */

        /* Close the attribute on the first dataset */
        if(H5Aclose(attr) < 0) FAIL_STACK_ERROR

        /* Create an attribute on the second dataset */
        if((attr = H5Acreate2(dataset2, objname, H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Don't worry about writing the attribute - it will have a fill value */

        /* Close the attribute on the second dataset */
        if(H5Aclose(attr) < 0) FAIL_STACK_ERROR

        /* Flush the file (to fix the sizes of object header buffers, etc) */
        if(H5Fflush(file,H5F_SCOPE_GLOBAL) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close the dataspace for the attributes */
    if(H5Sclose(attr_space) < 0) FAIL_STACK_ERROR

    /* Close datasets */
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset2) < 0) FAIL_STACK_ERROR

    /* Remove the datasets */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(file, DATASET2NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single named datatype, remove it & verify file size */
    TESTING("    named datatype");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create datatype to commit */
    if((type = H5Tcopy(H5T_NATIVE_INT)) < 0) FAIL_STACK_ERROR

    /* Create a single named datatype to remove */
    if(H5Tcommit2(file, TYPENAME, type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Tclose(type) < 0) FAIL_STACK_ERROR

    /* Remove the named datatype */
    if(H5Ldelete(file, TYPENAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create single group, remove it & verify file size */
    TESTING("    single group");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single group to remove */
    if((group = H5Gcreate2(file, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group) < 0) FAIL_STACK_ERROR

    /* Remove the group */
    if(H5Ldelete(file, GROUPNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create many groups, remove them & verify file size */
    TESTING("    multiple groups");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a many groups to remove */
    for(u = 0; u < UNLINK_NGROUPS; u++) {
        sprintf(objname, "%s %u", GROUPNAME, u);
        if((group = H5Gcreate2(file, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(group) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Remove the all the groups */
    /* (Remove them in reverse order just to make file size calculation easier -QAK) */
    for(u = UNLINK_NGROUPS; u > 0; u--) {
        sprintf(objname, "%s %u", GROUPNAME, (u - 1));
        if(H5Ldelete(file, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create simple group hiearchy, remove it & verify file size */
    TESTING("    simple group hierarchy");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a small group hierarchy to remove */
    if((group = H5Gcreate2(file, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((group2 = H5Gcreate2(group, GROUP2NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group2) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group) < 0) FAIL_STACK_ERROR

    /* Remove the second group */
    if(H5Ldelete(file, GROUPNAME "/" GROUP2NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Remove the first group */
    if(H5Ldelete(file, GROUPNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create complex group hiearchy, remove it & verify file size */
    TESTING("    complex group hierarchy");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a complex group hierarchy to remove */
    for(u = 0; u < FILESPACE_TOP_GROUPS; u++) {
        /* Create group */
        sprintf(objname,"%s %u",GROUPNAME,u);
        if((group = H5Gcreate2(file, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Create nested groups inside top groups */
        for(v = 0; v < FILESPACE_NESTED_GROUPS; v++) {
            /* Create group */
            sprintf(objname, "%s %u", GROUP2NAME, v);
            if((group2 = H5Gcreate2(group, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

            /* Create datasets inside nested groups */
            for(w = 0; w < FILESPACE_NDATASETS; w++) {
                /* Create & close a dataset */
                sprintf(objname, "%s %u", DATASETNAME, w);
                if((dataset = H5Dcreate2(group2, objname, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
                if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR
            } /* end for */

            /* Close nested group */
            if(H5Gclose(group2) < 0) FAIL_STACK_ERROR
        } /* end for */

        /* Close top group */
        if(H5Gclose(group) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Remove complex group hierarchy */
    /* (Remove them in reverse order just to make file size calculation easier -QAK) */
    for(u = FILESPACE_TOP_GROUPS; u > 0; u--) {
        /* Open group */
        sprintf(objname, "%s %u", GROUPNAME, (u - 1));
        if((group = H5Gopen2(file, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Open nested groups inside top groups */
        for(v = 0; v < FILESPACE_NESTED_GROUPS; v++) {
            /* Create group */
            sprintf(objname, "%s %u", GROUP2NAME, v);
            if((group2 = H5Gopen2(group, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

            /* Remove datasets inside nested groups */
            for(w = 0; w < FILESPACE_NDATASETS; w++) {
                /* Remove dataset */
                sprintf(objname, "%s %u", DATASETNAME, w);
                if(H5Ldelete(group2, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
            } /* end for */

            /* Close nested group */
            if(H5Gclose(group2) < 0) FAIL_STACK_ERROR

            /* Remove nested group */
            sprintf(objname, "%s %u",GROUP2NAME, v);
            if(H5Ldelete(group, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
        } /* end for */

        /* Close top group */
        if(H5Gclose(group) < 0) FAIL_STACK_ERROR

        /* Remove top group */
        sprintf(objname, "%s %u", GROUPNAME, (u - 1));
        if(H5Ldelete(file, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create dataset and duplicate dataset, remove original & verify file size */
    TESTING("    duplicate dataset");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single dataset to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Create another dataset with same name */
    H5E_BEGIN_TRY {
        dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    } H5E_END_TRY;
    if(dataset >= 0) {
        H5Dclose(dataset);
        TEST_ERROR
    } /* end if */

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create group and duplicate group, remove original & verify file size */
    TESTING("    duplicate group");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a single group to remove */
    if((group = H5Gcreate2(file, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group) < 0) FAIL_STACK_ERROR

    /* Create another group with same name */
    H5E_BEGIN_TRY {
        group = H5Gcreate2(file, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    } H5E_END_TRY;
    if(group >= 0) {
        H5Gclose(group);
        TEST_ERROR
    } /* end if */

    /* Remove the group */
    if(H5Ldelete(file, GROUPNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create named datatype and duplicate named datatype, remove original & verify file size */
    TESTING("    duplicate named datatype");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create datatype to commit */
    if((type = H5Tcopy(H5T_NATIVE_INT)) < 0) FAIL_STACK_ERROR

    /* Create a single named datatype to remove */
    if(H5Tcommit2(file, TYPENAME, type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Tclose(type) < 0) FAIL_STACK_ERROR

    /* Create datatype to commit */
    if((type = H5Tcopy(H5T_NATIVE_INT)) < 0) FAIL_STACK_ERROR

    /* Create another named datatype with same name */
    H5E_BEGIN_TRY {
        status = H5Tcommit2(file, TYPENAME, type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    } H5E_END_TRY;
    if(status >= 0) TEST_ERROR
    if(H5Tclose(type) < 0) FAIL_STACK_ERROR

    /* Remove the named datatype */
    if(H5Ldelete(file, TYPENAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Create named datatype and duplicate named datatype, remove original & verify file size */
    TESTING("    duplicate attribute");

    /* Create file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create datasets to remove */
    if((dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, contig_dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create a dataspace for the attributes */
    if((attr_space = H5Screate_simple(FILESPACE_ATTR_NDIMS, attr_dims, NULL)) < 0) FAIL_STACK_ERROR

    /* Create an attribute on the dataset */
    if((attr = H5Acreate2(dataset, ATTRNAME, H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Don't worry about writing the attribute - it will have a fill value */

    /* Close the attribute on the dataset */
    if(H5Aclose(attr) < 0) FAIL_STACK_ERROR

    /* Create another attribute with same name */
    H5E_BEGIN_TRY {
        attr = H5Acreate2(dataset, ATTRNAME, H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT);
    } H5E_END_TRY;
    if(attr >= 0) {
        H5Aclose(attr);
        TEST_ERROR
    } /* end if */

    /* Close the dataspace for the attributes */
    if(H5Sclose(attr_space) < 0) FAIL_STACK_ERROR

    /* Close dataset */
    if(H5Dclose(dataset) < 0) FAIL_STACK_ERROR

    /* Remove the dataset */
    if(H5Ldelete(file, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != empty_size) TEST_ERROR

    PASSED();


/* Cleanup common objects */

    /* Release dataset buffer */
    HDfree(data);

    /* Close property lists */
    if(H5Pclose(fapl_nocache) < 0) FAIL_STACK_ERROR
    if(H5Pclose(contig_dcpl) < 0) FAIL_STACK_ERROR
    if(H5Pclose(early_chunk_dcpl) < 0) FAIL_STACK_ERROR
    if(H5Pclose(late_chunk_dcpl) < 0) FAIL_STACK_ERROR
    if(H5Pclose(comp_dcpl) < 0) FAIL_STACK_ERROR
    if(H5Pclose(compact_dcpl) < 0) FAIL_STACK_ERROR

    /* Close dataspace */
    if(H5Sclose(space) < 0) FAIL_STACK_ERROR

    /* Indicate success */
    /* Don't print final "PASSED", since we aren't on the correct line anymore */
    return 0;

error:
    /* Release dataset buffer */
    if(data)
        HDfree(data);

    return 1;
} /* end test_filespace() */


/*-------------------------------------------------------------------------
 * Function:    test_create_unlink
 *
 * Purpose:     Creates and then unlinks a large number of objects
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Friday, April 11, 2003
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_create_unlink(const char *msg, hid_t fapl)
{
    hid_t 	file, group;
    unsigned u;
    char 	groupname[1024];
    char	filename[1024];

    TESTING(msg);

    /* Create file */
    h5_fixname(FILENAME[3], fapl, filename, sizeof filename);
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        FAIL_PUTS_ERROR("    Creating file failed")

    /* Create a many groups to remove */
    for(u = 0; u < UNLINK_NGROUPS; u++) {
        sprintf(groupname, "%s %u", GROUPNAME, u);
        if((group = H5Gcreate2(file, groupname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("group %s creation failed\n", groupname);
            goto error;
        } /* end if */
        if(H5Gclose (group) < 0) {
            H5_FAILED();
            printf("closing group %s failed\n", groupname);
            goto error;
        } /* end if */
    } /* end for */

    /* Remove the all the groups */
    for(u = 0; u < UNLINK_NGROUPS; u++) {
        sprintf(groupname, "%s %u", GROUPNAME, u);
        if(H5Ldelete(file, groupname, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("Unlinking group %s failed\n", groupname);
            goto error;
        } /* end if */
    } /* end for */

    /* Close file */
    if(H5Fclose(file) < 0)
        FAIL_PUTS_ERROR("Closing file failed")

    PASSED();
    return 0;

error:
    return 1;
} /* end test_create_unlink() */


/*-------------------------------------------------------------------------
 * Function:    test_link_slashes
 *
 * Purpose:     Tests creating links with various multiple & trailing slashes
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Saturday, August 16, 2003
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_link_slashes(hid_t fapl)
{
    hid_t fid;          /* File ID */
    hid_t gid, gid2;     /* Group ID */
    char	filename[1024];

    TESTING("creating links with multiple slashes");

    /* Create file */
    h5_fixname(FILENAME[5], fapl, filename, sizeof filename);

    /* Create a file */
    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create a group in the root group */
    if((gid = H5Gcreate2(fid, SLASHES_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create a nested group in the root group */
    if((gid2 = H5Gcreate2(gid, SLASHES_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close the nested group */
    if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR

    /* Create a hard link to the nested group */
    if(H5Lcreate_hard(gid, SLASHES_GROUP_NAME, H5L_SAME_LOC, SLASHES_HARDLINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create a soft link with a relative path to the nested group */
    if(H5Lcreate_soft(SLASHES_GROUP_NAME, gid, SLASHES_SOFTLINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create a soft link with the full path to the nested group */
    if(H5Lcreate_soft("////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, gid, SLASHES_SOFTLINK2_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create a soft link to the root group */
    if(H5Lcreate_soft("////", gid, SLASHES_ROOTLINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Create a hard link to the existing group */
    if(H5Lcreate_hard(fid, SLASHES_GROUP_NAME, H5L_SAME_LOC, SLASHES_HARDLINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    return 1;
} /* end test_link_slashes() */


/*-------------------------------------------------------------------------
 * Function:    test_unlink_slashes
 *
 * Purpose:     Tests deleting links with various multiple & trailing slashes
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Saturday, August 16, 2003
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_unlink_slashes(hid_t fapl)
{
    hid_t fid;          /* File ID */
    hid_t gid;          /* Group ID */
    char	filename[1024];

    TESTING("deleting links with multiple slashes");

    /* Create file */
    h5_fixname(FILENAME[5], fapl, filename, sizeof filename);

    /* Open the file */
    if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Open the top level group */
    if((gid = H5Gopen2(fid, SLASHES_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Delete the root link */
    if(H5Ldelete(gid,SLASHES_ROOTLINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete the soft link with the full path */
    if(H5Ldelete(gid,SLASHES_SOFTLINK2_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete the soft link with the relative path */
    if(H5Ldelete(gid,SLASHES_SOFTLINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete the hard link */
    if(H5Ldelete(gid,SLASHES_HARDLINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete the group itself */
    if(H5Ldelete(gid,SLASHES_GROUP_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Delete the hard link */
    if(H5Ldelete(fid,SLASHES_HARDLINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete the group itself */
    if(H5Ldelete(fid,SLASHES_GROUP_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    return 1;
} /* end test_unlink_slashes() */

/*
 * Helper routine for test_unlink_rightleaf()
 */
static int
delete_node(hid_t pid, hid_t id)
{
    char name[256];     /* Name of object to close */

    /* Get the name of the object to delete */
    if(H5Iget_name(id, name, sizeof(name)) < 0) return (-1);

    /* Close the object */
    if(H5Gclose(id) < 0) return(-1);

    /* Unlink the object */
    if(H5Ldelete(pid, name, H5P_DEFAULT) < 0) return(-1);

    /* If this object is the right-most child, try opening the previous object */
    if(HDstrcmp(name,"/Zone81") == 0) {
        hid_t gid;

        if((gid = H5Gopen2(pid, "/Zone80", H5P_DEFAULT)) < 0) return(-1);
        if(H5Gclose(gid) < 0) return(-1);
    } /* end if */

    /* Indicate success */
    return(0);
}


/*-------------------------------------------------------------------------
 * Function:    test_unlink_rightleaf
 *
 * Purpose:     Tests deleting objects in a way that triggers deletion of the
 *              right child in the leaf of a non-leaf B-tree node
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Monday, January 19, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_unlink_rightleaf(hid_t fid)
{
    hid_t rootid = -1,  /* Group ID for root group */
        *gids = NULL;   /* Array of IDs for groups created */
    int n,              /* Local index variable */
        ngroups = 150;  /* Number of groups to create */
    char name[256];     /* Name of object to create */

    TESTING("deleting right-most child in non-leaf B-tree node");

    /* Allocate space for the group IDs */
    if(NULL == (gids = (hid_t *)HDcalloc((size_t)ngroups, sizeof(hid_t)))) TEST_ERROR

    if((rootid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create all the groups */
    for (n = 0; n < ngroups; n++) {
        sprintf(name, "Zone%d", n + 1);
        if((gids[n] = H5Gcreate2(rootid, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    } /* end for */

    /* Unlink & re-create each group */
    for (n = 0; n < ngroups; n++) {
        if(delete_node (rootid, gids[n]) < 0) TEST_ERROR
        sprintf(name, "Zone%d", n + 1);
        if((gids[n] = H5Gcreate2(rootid, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    } /* end for */

    /* Close all the groups */
    for (n = 0; n < ngroups; n++) {
        if(H5Gclose(gids[n]) < 0) TEST_ERROR
        gids[n] = 0;
    } /* end for */

    /* Close root group ID */
    if(H5Gclose(rootid) < 0) TEST_ERROR

    /* Free memory */
    HDfree(gids);

    PASSED();
    return 0;

error:
    if(gids) {
        /* Close any open groups */
        for (n = 0; n < ngroups; n++)
            if(gids[n]) {
                H5E_BEGIN_TRY {
                    H5Gclose(gids[n]);
                } H5E_END_TRY;
            } /* end if */
        HDfree(gids);
    } /* end if */
    H5E_BEGIN_TRY {
        H5Gclose(rootid);
    } H5E_END_TRY;

    return 1;
} /* end test_unlink_rightleaf() */


/*-------------------------------------------------------------------------
 * Function:    test_unlink_rightnode
 *
 * Purpose:     Tests deleting objects in a way that triggers deletion of the
 *              entire right child leaf of a non-leaf B-tree node
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Monday, January 19, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_unlink_rightnode(hid_t fid)
{
    hid_t rootid = -1,       /* Group ID for root group */
        *gids = NULL;   /* Array of IDs for groups created */
    int n,              /* Local index variable */
        ngroups = 150;  /* Number of groups to create */
    char name[256];     /* Name of object to create */

    TESTING("deleting right-most child in non-leaf B-tree node");

    /* Allocate space for the group IDs */
    if(NULL == (gids = (hid_t *)HDcalloc((size_t)ngroups, sizeof(hid_t)))) TEST_ERROR

    if((rootid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create all the groups */
    for (n = 0; n < ngroups; n++) {
        sprintf(name, "ZoneB%d", n + 1);
        if((gids[n] = H5Gcreate2(rootid, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close all the groups */
    for (n = 0; n < ngroups; n++) {
        if(H5Gclose(gids[n]) < 0) FAIL_STACK_ERROR
        gids[n] = 0;
    } /* end for */

    /* Unlink specific objects to trigger deletion of right leaf in non-leaf node */
    if(H5Ldelete(fid, "/ZoneB77", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneB78", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneB79", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneB8", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneB80", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close root group ID */
    if(H5Gclose(rootid) < 0) FAIL_STACK_ERROR

    /* Free memory */
    HDfree(gids);

    PASSED();
    return 0;

error:
    if(gids) {
        /* Close any open groups */
        for (n = 0; n < ngroups; n++)
            if(gids[n]) {
                H5E_BEGIN_TRY {
                    H5Gclose(gids[n]);
                } H5E_END_TRY;
            } /* end if */
        HDfree(gids);
    } /* end if */
    H5E_BEGIN_TRY {
        H5Gclose(rootid);
    } H5E_END_TRY;

    return 1;
} /* end test_unlink_rightnode() */


/*-------------------------------------------------------------------------
 * Function:    test_unlink_middlenode
 *
 * Purpose:     Tests deleting objects in a way that triggers deletion of all
 *              the leafs of a "middle" non-leaf B-tree node
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Monday, January 19, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_unlink_middlenode(hid_t fid)
{
    hid_t rootid = -1,  /* Group ID for root group */
        *gids = NULL;   /* Array of IDs for groups created */
    int n,              /* Local index variable */
        ngroups = 250;  /* Number of groups to create */
    char name[256];     /* Name of object to create */

    TESTING("deleting right-most child in non-leaf B-tree node");

    /* Allocate space for the group IDs */
    if(NULL == (gids = (hid_t *)HDcalloc((size_t)ngroups, sizeof(hid_t)))) TEST_ERROR

    if((rootid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create all the groups */
    for (n = 0; n < ngroups; n++) {
        sprintf(name, "ZoneC%d", n + 1);
        if((gids[n] = H5Gcreate2(rootid, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close all the groups */
    for (n = 0; n < ngroups; n++) {
        if(H5Gclose(gids[n]) < 0) FAIL_STACK_ERROR
        gids[n] = 0;
    } /* end for */

    /* Unlink specific objects to trigger deletion of all leafs in "interior" non-leaf node */
    if(H5Ldelete(fid, "/ZoneC11", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC110", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC111", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC112", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC113", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC114", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC115", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC116", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC117", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC118", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC119", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC12", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC120", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC121", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC122", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC123", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC124", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC125", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC126", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC127", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC128", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC129", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC13", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC130", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC131", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC132", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC133", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC134", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC135", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC136", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC137", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC138", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC139", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC14", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC140", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC141", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC142", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC143", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC144", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC145", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC146", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC147", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC148", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC149", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC15", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC150", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC151", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC152", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC153", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC154", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC155", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC156", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC157", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC158", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC159", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC16", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC160", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC161", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC162", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC163", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC164", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC165", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC166", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC167", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC168", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC169", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC17", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC170", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC171", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC172", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC173", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC174", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC175", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC176", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC177", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC178", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC179", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC18", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC180", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC19", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC2", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC20", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC21", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC22", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC23", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC24", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC25", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC26", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC27", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC28", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC29", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC3", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC30", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC31", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC32", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC33", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC34", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC35", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC36", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC37", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC38", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC39", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC4", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC40", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC41", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC42", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC43", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC44", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC45", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC46", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC47", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC48", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC49", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC5", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC50", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC51", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC52", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC53", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC54", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC55", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC56", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC57", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC58", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC59", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC6", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC60", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC61", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC62", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC63", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC64", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC65", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC66", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC67", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC68", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC69", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC7", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC70", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC71", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC72", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC73", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC74", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC75", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC76", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC77", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC78", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC79", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC8", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, "/ZoneC80", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close root group ID */
    if(H5Gclose(rootid) < 0) FAIL_STACK_ERROR

    /* Free memory */
    HDfree(gids);

    PASSED();
    return 0;

error:
    if(gids) {
        /* Close any open groups */
        for (n = 0; n < ngroups; n++)
            if(gids[n]) {
                H5E_BEGIN_TRY {
                    H5Gclose(gids[n]);
                } H5E_END_TRY;
            } /* end if */
        HDfree(gids);
    } /* end if */
    H5E_BEGIN_TRY {
        H5Gclose(rootid);
    } H5E_END_TRY;

    return 1;
} /* end test_unlink_middlenode() */


/*-------------------------------------------------------------------------
 * Function:    test_resurrect_dataset
 *
 * Purpose:     Tests deleting a dataset while its still open and then
 *              "resurrecting" it by creating a link to it again.
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, July 14, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_resurrect_dataset(hid_t fapl)
{
    hid_t       f = -1, s = -1, d = -1;
    char	filename[1024];

    TESTING("resurrecting dataset after deletion");

    /* Create file */
    h5_fixname(FILENAME[6], fapl, filename, sizeof filename);

    /* Create the file */
    if((f = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a dataset in the file */
    if((s = H5Screate(H5S_SCALAR)) < 0) FAIL_STACK_ERROR
    if((d = H5Dcreate2(f, DATASETNAME, H5T_NATIVE_INT, s, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Sclose(s) < 0) FAIL_STACK_ERROR

    /* Unlink the dataset while it's open (will mark it for deletion when closed) */
    if(H5Ldelete(f, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check that dataset name is NULL */
    if(H5Iget_name(d, NULL, (size_t)0) != 0) FAIL_STACK_ERROR

    /* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */
    if(H5Lcreate_hard(d, ".", f, DATASET2NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Dclose(d) < 0) FAIL_STACK_ERROR
    if(H5Fclose(f) < 0) FAIL_STACK_ERROR

    /* Re-open the file */
    if((f = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Attempt to open the dataset under the new name */
    if((d = H5Dopen2(f, DATASET2NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Dclose(d) < 0) FAIL_STACK_ERROR
    if(H5Fclose(f) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Sclose(s);
	H5Dclose(d);
	H5Fclose(f);
    } H5E_END_TRY;
    return 1;
} /* end test_resurrect_dataset() */


/*-------------------------------------------------------------------------
 * Function:    test_resurrect_datatype
 *
 * Purpose:     Tests deleting a datatype while it's still open and then
 *              "resurrecting" it by creating a link to it again.
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Wednesday, July 28, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_resurrect_datatype(hid_t fapl)
{
    hid_t       file = -1, type = -1;
    char        filename[1024];

    TESTING("resurrecting datatype after deletion");

    /* Create file */
    h5_fixname(FILENAME[7], fapl, filename, sizeof filename);

    /* Create the file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a named datatype in the file */
    if((type = H5Tcopy (H5T_NATIVE_INT)) < 0) FAIL_STACK_ERROR
    if(H5Tcommit2(file, TYPENAME, type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Unlink the datatype while it's open (will mark it for deletion when closed) */
    if(H5Ldelete(file, TYPENAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check that datatype name is NULL */
    if(H5Iget_name(type, NULL, (size_t)0) != 0) FAIL_STACK_ERROR

    /* Re-link the datatype to the group hierarchy (shouldn't get deleted now) */
    if(H5Lcreate_hard(type, ".", file, TYPE2NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Tclose(type) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Re-open the file */
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Attempt to open the datatype under the new name */
    if((type = H5Topen2(file,TYPE2NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Tclose(type) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Tclose(type);
	H5Fclose(file);
    } H5E_END_TRY;
    return 1;
} /* end test_resurrect_datatype() */


/*-------------------------------------------------------------------------
 * Function:    test_resurrect_group
 *
 * Purpose:     Tests deleting a group while it's still open and then
 *              "resurrecting" it by creating a link to it again.
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Wednesday, July 28, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_resurrect_group(hid_t fapl)
{
    hid_t       file = -1, group = -1;
    char        filename[1024];

    TESTING("resurrecting group after deletion");

    /* Create file */
    h5_fixname(FILENAME[8], fapl, filename, sizeof filename);

    /* Create the file */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create a group in the file */
    if((group = H5Gcreate2(file, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Unlink the group while it's open (will mark it for deletion when closed) */
    if(H5Ldelete(file, GROUPNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check that group's name is NULL */
    if(H5Iget_name(group, NULL, (size_t)0) != 0) FAIL_STACK_ERROR

    /* Re-link the group into the group hierarchy (shouldn't get deleted now) */
    if(H5Lcreate_hard(group, ".", file, GROUP2NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Gclose(group) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    /* Re-open the file */
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Attempt to open the datatype under the new name */
    if((group = H5Gopen2(file, GROUP2NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close things */
    if(H5Gclose(group) < 0) FAIL_STACK_ERROR
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Gclose(group);
	H5Fclose(file);
    } H5E_END_TRY;
    return 1;
} /* end test_resurrect_group() */


/*-------------------------------------------------------------------------
 * Function:    test_unlink_chunked_dataset
 *
 * Purpose:     Tests deleting a chunked dataset
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Monday, September 27, 2004
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_unlink_chunked_dataset(hid_t fapl)
{
    hid_t file_id = -1;
    hid_t dset_id = -1;
    hid_t space_id = -1;
    hid_t dcpl_id = -1;
    hsize_t dims[FILESPACE_NDIMS] = {FILESPACE_DIM0, FILESPACE_DIM1, FILESPACE_DIM2};
    hsize_t max_dims[FILESPACE_NDIMS] = {H5S_UNLIMITED, H5S_UNLIMITED, H5S_UNLIMITED};
    hsize_t chunk_dims[FILESPACE_NDIMS] = {FILESPACE_CHUNK0, FILESPACE_CHUNK1, FILESPACE_CHUNK2};
    char filename[1024];

    TESTING("unlinking chunked dataset");

    /* Create file */
    h5_fixname(FILENAME[9], fapl, filename, sizeof filename);

    /* Create the file */
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create the dataspace */
    if((space_id = H5Screate_simple(FILESPACE_NDIMS, dims, max_dims)) < 0) FAIL_STACK_ERROR

    /* Create the dataset creation filter */
    if((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR

    /* Set to chunked storage */
    if(H5Pset_chunk(dcpl_id, FILESPACE_NDIMS, chunk_dims) < 0) FAIL_STACK_ERROR

    /* Set to early space allocation */
    if(H5Pset_alloc_time(dcpl_id, H5D_ALLOC_TIME_EARLY) < 0) FAIL_STACK_ERROR

    /* Create the dataset */
    if((dset_id = H5Dcreate2(file_id, DATASETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close the dataspace */
    if(H5Sclose(space_id) < 0) FAIL_STACK_ERROR

    /* Close the dataset creation property list */
    if(H5Pclose(dcpl_id) < 0) FAIL_STACK_ERROR

    /* Close the dataset */
    if(H5Dclose(dset_id) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Delete the dataset */
    if(H5Ldelete(file_id, DATASETNAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Pclose(dcpl_id);
	H5Sclose(space_id);
	H5Dclose(dset_id);
	H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_unlink_chunked_dataset() */


/*-------------------------------------------------------------------------
 * Function:    test_full_group_compact
 *
 * Purpose:     Test deleting a compact group which still has valid objects in it
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, January 18, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
test_full_group_compact(hid_t fapl)
{
    hid_t file_id = -1;
    hid_t gid = -1, gid2 = -1;  /* Group IDs */
    H5O_info_t	oi;             /* Stat buffer for object */
    char objname[128];          /* Buffer for name of objects to create */
    char objname2[128];         /* Buffer for name of objects to create */
    char filename[1024];        /* Buffer for filename */
    h5_stat_size_t       keep_size;      /* Size of the file with objects to keep */
    h5_stat_size_t       file_size;      /* Size of each file created */
    unsigned u;                 /* Local index variable */

    TESTING("unlinking non-empty compact group");

    /* Create filename */
    h5_fixname(FILENAME[10], fapl, filename, sizeof filename);

    /* Create the file */
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create group to link objects to */
    if((gid = H5Gcreate2(file_id, "/keep", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create several objects to link to */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "keep %u\n", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close group with objects to keep */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Get the size of the file with only the objects to keep */
    if((keep_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Create group to delete */
    if((gid = H5Gcreate2(file_id, "/delete", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create external link (doesn't matter if it dangles) */
    if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create soft link (doesn't matter if it dangles) */
    if(H5Lcreate_soft("/foo", gid, "soft", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create hard links to objects in group to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        sprintf(objname2, "keep %u\n", u);
        if(H5Lcreate_hard(file_id, objname, gid, objname2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Create several objects to delete */
    for(u = 0; u < FULL_GROUP_NUM_DELETE_COMPACT; u++) {
        sprintf(objname, "delete %u\n", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Check on group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, NULL) != TRUE) TEST_ERROR
    if(H5G__has_stab_test(gid) == TRUE) TEST_ERROR

    /* Close group with objects to delete */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Check reference count on objects to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        if(H5Oget_info_by_name(file_id, objname, &oi, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
        if(oi.rc != 2) TEST_ERROR
    } /* end for */

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Delete the full group */
    if(H5Ldelete(file_id, "/delete", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check reference count on objects to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        if(H5Oget_info_by_name(file_id, objname, &oi, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
        if(oi.rc != 1) TEST_ERROR
    } /* end for */

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != keep_size) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Gclose(gid2);
	H5Gclose(gid);
	H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_full_group_compact() */


/*-------------------------------------------------------------------------
 * Function:    test_full_group_dense
 *
 * Purpose:     Test deleting a dense group which still has valid objects in it
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, January 18, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
test_full_group_dense(hid_t fapl)
{
    hid_t file_id = -1;
    hid_t gcpl = (-1);          /* Group creation property list ID */
    hid_t gid = -1, gid2 = -1;  /* Group IDs */
    H5O_info_t	oi;             /* Stat buffer for object */
    char objname[128];          /* Buffer for name of objects to create */
    char objname2[128];         /* Buffer for name of objects to create */
    char filename[1024];        /* Buffer for filename */
    h5_stat_size_t       keep_size;      /* Size of the file with objects to keep */
    h5_stat_size_t       file_size;      /* Size of each file created */
    unsigned u;                 /* Local index variable */

    TESTING("unlinking non-empty dense group");

    /* Create filename */
    h5_fixname(FILENAME[10], fapl, filename, sizeof filename);

    /* Create the file */
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

    /* Create group to link objects to */
    if((gid = H5Gcreate2(file_id, "/keep", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create several objects to link to */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "keep %u\n", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Close group with objects to keep */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Get the size of the file with only the objects to keep */
    if((keep_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Set group creation "est. link info" closer to what will actually occur */
    if((gcpl = H5Pcreate(H5P_GROUP_CREATE)) < 0) FAIL_STACK_ERROR
    if(H5Pset_est_link_info(gcpl, FULL_GROUP_EST_NUM_ENTRIES, FULL_GROUP_EST_ENTRY_LEN) < 0) FAIL_STACK_ERROR

    /* Create group to delete */
    /* (use non-default GCPL, in order to make certain that the group's object
     *  header is large enough to hold the links inserted without allocating
     *  another object header message chunk - in order to make the file size
     *  computation below easier/correct - QAK)
     */
    if((gid = H5Gcreate2(file_id, "/delete", H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close GCPL */
    if(H5Pclose(gcpl) < 0) FAIL_STACK_ERROR

    /* Create external link (doesn't matter if it dangles) */
    if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create soft link (doesn't matter if it dangles) */
    if(H5Lcreate_soft("/foo", gid, "soft", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Create hard links to objects in group to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        sprintf(objname2, "keep %u\n", u);
        if(H5Lcreate_hard(file_id, objname, gid, objname2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Create several objects to delete */
    for(u = 0; u < FULL_GROUP_NUM_DELETE_DENSE; u++) {
        sprintf(objname, "delete %u\n", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Check on group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, NULL) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(gid) != TRUE) TEST_ERROR

    /* Close group with objects to delete */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Check reference count on objects to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        if(H5Oget_info_by_name(file_id, objname, &oi, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
        if(oi.rc != 2) TEST_ERROR
    } /* end for */

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Delete the full group */
    if(H5Ldelete(file_id, "/delete", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check reference count on objects to keep */
    for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
        sprintf(objname, "/keep/keep %u\n", u);
        if(H5Oget_info_by_name(file_id, objname, &oi, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
        if(oi.rc != 1) TEST_ERROR
    } /* end for */

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Get the size of the file */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

    /* Verify the file is correct size */
    if(file_size != keep_size) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Gclose(gid2);
	H5Gclose(gid);
    	H5Pclose(gcpl);
	H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_full_group_dense() */


/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Test unlinking operations
 *
 * Return:	Success:	zero
 *
 *		Failure:	non-zero
 *
 * Programmer:	Robb Matzke
 *              Friday, September 25, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
int
main(void)
{
    hid_t	fapl, fapl2, file;
    int		nerrors = 0;
    char	filename[1024];
    unsigned	new_format;

    /* Metadata cache parameters */
    int mdc_nelmts;
    size_t rdcc_nelmts;
    size_t rdcc_nbytes;
    double rdcc_w0;

    /* Set the random # seed */
    HDsrandom((unsigned)HDtime(NULL));

    /* Open */
    h5_reset();
    fapl = h5_fileaccess();

    /* Copy the file access property list */
    if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR

    /* Set the "use the latest version of the format" bounds for creating objects in the file */
    if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR

    /* Test with old & new format groups */
    for(new_format = FALSE; new_format <= TRUE; new_format++) {
        hid_t my_fapl;

        /* Set the FAPL for the type of format */
        if(new_format) {
            puts("\nTesting with new group format:");
            my_fapl = fapl2;
        } /* end if */
        else {
            puts("Testing with old group format:");
            my_fapl = fapl;
        } /* end else */

        h5_fixname(FILENAME[0], my_fapl, filename, sizeof filename);
        if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0) TEST_ERROR

        /* Tests */
        nerrors += test_one(file);
        nerrors += test_many(file);
        nerrors += test_symlink(file);
        nerrors += test_rename(file);

        nerrors += test_new_move(my_fapl);
        nerrors += check_new_move(my_fapl);
        nerrors += test_filespace(my_fapl);

        /* Test creating & unlinking lots of objects with default FAPL */
        nerrors += test_create_unlink("create and unlink large number of objects", my_fapl);

        {
            hid_t fapl_small_mdc;

            /* Make copy of regular fapl, to turn down the elements in the metadata cache */
            if((fapl_small_mdc = H5Pcopy(my_fapl)) < 0)
                goto error;

            /* Get FAPL cache settings */
            if(H5Pget_cache(fapl_small_mdc, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0) < 0)
                printf("H5Pget_cache failed\n");

            /* Change FAPL cache settings */
            mdc_nelmts=1;
            if(H5Pset_cache(fapl_small_mdc, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0) < 0)
                printf("H5Pset_cache failed\n");

            /* Test creating & unlinking lots of objects with a 1-element metadata cache FAPL */
            nerrors += test_create_unlink("create and unlink large number of objects with small cache", fapl_small_mdc);

            if(H5Pclose(fapl_small_mdc) < 0) TEST_ERROR
        } /* end block */

        nerrors += test_link_slashes(my_fapl);
        nerrors += test_unlink_slashes(my_fapl);

        /* Test specific B-tree removal issues */
        /* (only for old format groups) */
        if(!new_format) {
            nerrors += test_unlink_rightleaf(file);
            nerrors += test_unlink_rightnode(file);
            nerrors += test_unlink_middlenode(file);
        } /* end if */

        /* Test "resurrecting" objects */
        nerrors += test_resurrect_dataset(my_fapl);
        nerrors += test_resurrect_datatype(my_fapl);
        nerrors += test_resurrect_group(my_fapl);

        /* Test unlinking chunked datasets */
        nerrors += test_unlink_chunked_dataset(my_fapl);

        /* Test unlinked groups which still have objects in them */
        /* (only for new format groups) */
        if(new_format) {
            nerrors += test_full_group_compact(my_fapl);
            nerrors += test_full_group_dense(my_fapl);
        } /* end if */

        /* Close */
        if(H5Fclose(file) < 0) TEST_ERROR
    } /* end for */

    /* Close 2nd FAPL */
    H5Pclose(fapl2);

    /* Verify symbol table messages are cached */
    nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);

    if (nerrors) {
        printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S");
        exit(EXIT_FAILURE);
    }

    puts("All unlink tests passed.");

    h5_cleanup(FILENAME, fapl);

    return 0;

error:
    return 1;
}

' href='#n11534'>11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975 11976 11977 11978 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 12113 12114 12115 12116 12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 12163 12164 12165 12166 12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029 13030 13031 13032 13033 13034 13035 13036 13037 13038 13039 13040 13041 13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307 13308 13309 13310 13311 13312 13313 13314 13315 13316 13317 13318 13319 13320 13321 13322 13323 13324 13325 13326 13327 13328 13329 13330 13331 13332 13333 13334 13335 13336 13337 13338 13339 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356 13357 13358 13359 13360 13361 13362 13363 13364 13365 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 13384 13385 13386 13387 13388 13389 13390 13391 13392 13393 13394 13395 13396 13397 13398 13399 13400 13401 13402 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423 13424 13425 13426 13427 13428 13429 13430 13431 13432 13433 13434 13435 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500 13501 13502 13503 13504 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 13558 13559 13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 13634 13635 13636 13637 13638 13639 13640 13641 13642 13643 13644 13645 13646 13647 13648 13649 13650 13651 13652 13653 13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 13824 13825 13826 13827 13828 13829 13830 13831 13832 13833 13834 13835 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 13898 13899 13900 13901 13902 13903 13904 13905 13906 13907 13908 13909 13910 13911 13912 13913 13914 13915 13916 13917 13918 13919 13920 13921 13922 13923 13924 13925 13926 13927 13928 13929 13930 13931 13932 13933 13934 13935 13936 13937 13938 13939 13940 13941 13942 13943 13944 13945 13946 13947 13948 13949 13950 13951 13952 13953 13954 13955 13956 13957 13958 13959 13960 13961 13962 13963 13964 13965 13966 13967 13968 13969 13970 13971 13972 13973 13974 13975 13976 13977 13978 13979 13980 13981 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 13993 13994 13995 13996 13997 13998 13999 14000 14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 14019 14020 14021 14022 14023 14024 14025 14026 14027 14028 14029 14030 14031 14032 14033 14034 14035 14036 14037 14038 14039 14040 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 14058 14059 14060 14061 14062 14063 14064 14065 14066 14067 14068 14069 14070 14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 14111 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 14138 14139 14140 14141 14142 14143 14144 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266 14267 14268 14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294 14295 14296 14297 14298 14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352 14353 14354 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 14431 14432 14433 14434 14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 14454 14455 14456 14457 14458 14459 14460 14461 14462 14463 14464 14465 14466 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 14482 14483 14484 14485 14486 14487 14488 14489 14490 14491 14492 14493 14494 14495 14496 14497 14498 14499 14500 14501 14502 14503 14504 14505 14506 14507 14508 14509 14510 14511 14512 14513 14514 14515 14516 14517 14518 14519 14520 14521 14522 14523 14524 14525 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 14550 14551 14552 14553 14554 14555 14556 14557 14558 14559 14560 14561 14562 14563 14564 14565 14566 14567 14568 14569 14570 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 14610 14611 14612 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 14633 14634 14635 14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 14660 14661 14662 14663 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 14807 14808 14809 14810 14811 14812 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 14829 14830 14831 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867 14868 14869 14870 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 14886 14887 14888 14889 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954 14955 14956 14957 14958 14959 14960 14961 14962 14963 14964 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000 15001 15002 15003 15004 15005 15006 15007 15008 15009 15010 15011 15012 15013 15014 15015 15016 15017 15018 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 15041 15042 15043 15044 15045 15046 15047 15048 15049 15050 15051 15052 15053 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063 15064 15065 15066 15067 15068 15069 15070 15071 15072 15073 15074 15075 15076 15077 15078 15079 15080 15081 15082 15083 15084 15085 15086 15087 15088 15089 15090 15091 15092 15093 15094
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 * Programmer:  Robb Matzke <matzke@llnl.gov>
 *              Friday, April 10, 1998
 *
 * Purpose:	Tests hard, soft (symbolic) & external links.
 */

/*
 * This file needs to access private information from the H5FD package.
 * This file also needs to access the file driver testing code.
 */
#define H5FD_FRIEND		/*suppress error about including H5FDpkg	  */
#define H5FD_TESTING

/*
 * This file needs to access private information from the H5G package.
 * This file also needs to access the group testing code.
 */
#define H5G_FRIEND		/*suppress error about including H5Gpkg	  */
#define H5G_TESTING

#include "h5test.h"
#include "H5srcdir.h"
#include "H5FDpkg.h"            /* File drivers                         */
#include "H5Gpkg.h"		/* Groups 				*/
#include "H5Iprivate.h"		/* IDs			  		*/
#include "H5Lprivate.h"         /* Links                                */

/* File for external link test.  Created with gen_udlinks.c */
#define LINKED_FILE  "be_extlink2.h5"

#define TMPDIR          "tmp/"
#define TMPDIR2         "tmp2/"

/* Symlinks for external link symlink test */
#define SYMLINK1  TMPDIR "sym1.h5"
#define SYMLINK2  TMPDIR2 "sym2.h5"

const char *FILENAME[] = {
    "links0",
    "links1",
    "links2",
    "links3",
    "links4a", /* 4 */
    "links4b", /* 5 */
    "links4c", /* 6 */
    "links4d", /* 7 */
    "links5",  /* 8 */
    "links6",  /* 9 */
    "links7",  /* 10 */
    "links8",  /* 11 */
    "extlinks0",	/* 12: main files */
    TMPDIR "extlinks0",	/* 13: */
    "extlinks1",	/* 14: target files */
    TMPDIR "extlinks1",	/* 15: */
    "extlinks2",	/* 16: */
    TMPDIR "extlinks2",	/* 17: */
    "extlinks3",	/* 18: */
    TMPDIR "extlinks3",	/* 19: */
    "extlinks4",	/* 20: */
    TMPDIR "extlinks4",	/* 21: */
    "extlinks5",	/* 22: */
    TMPDIR "extlinks6",	/* 23: */
    "extlinks7",	/* 24: */
    TMPDIR "extlinks7",	/* 25: */
    TMPDIR "extlinks8",	/* 26: */
    "extlinks9",	/* 27: */
    TMPDIR "extlinks9",	/* 28: */
    "extlinks10",	/* 29: */ /* TESTS for windows */
    TMPDIR "extlinks10",/* 30: */
    TMPDIR "extlinks11",/* 31: */
    TMPDIR "extlinks12",/* 32: */
    "extlinks13",	/* 33: */
    TMPDIR "extlinks13",/* 34: */
    TMPDIR "extlinks14",/* 35: */
    TMPDIR "extlinks15",/* 36: */
    "extlinks16A",	/* 37: */ /* TESTS for H5P_set_elink_fapl */
    "extlinks16B",	/* 38: */
    "extlinks17",	/* 39: */
    "extlinks18A",	/* 40: */
    "extlinks18B",	/* 41: */
    "extlinks19A",	/* 42: */
    "extlinks19B",	/* 43: */
    "extlinks20",	/* 44: */
    "extlinks21A",	/* 45: Files for symlink() tests*/
    TMPDIR2 "extlinks21B",/* 46: */
    TMPDIR2 "extlinks21C",/* 47: */
    "extlinks21C",	/* 48: (same as #47, only without the TMPDIR2 prefix) */
    TMPDIR "extlinks21D",/* 49: */
    TMPDIR "extlinks21E",/* 50: */
    "extlinks21E",	/* 51: (same as #50, only without the TMPDIR prefix) */
    NULL
};

#define FAMILY_SIZE	1024
#define CORE_INCREMENT  1024
#define NUM40		40

/* do not do check_all_closed() for "ext*" files and "tmp/ext*" */
#define EXTSTOP		12

#define LINK_BUF_SIZE   1024
#define NAME_BUF_SIZE   1024
#define MAX_NAME_LEN    ((64*1024)+1024)

/* Link type IDs */
#define UD_HARD_TYPE 201
#define UD_CB_TYPE H5L_TYPE_MAX
#define UD_PLIST_TYPE 128
#define UD_CBFAIL_TYPE UD_PLIST_TYPE
#define UD_ERROR_TYPE 189
#define UD_BAD_TYPE1 H5L_TYPE_HARD
#define UD_BAD_TYPE2 (H5L_TYPE_UD_MIN - 5)
#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1)

#define DEST_PROP_NAME "destination_group"
#define REREG_TARGET_NAME "rereg_target"

#define UD_CB_LINK_NAME "ud_callback_link"
#define NEW_UD_CB_LINK_NAME "ud_callback_link2"
#define UD_CB_TARGET "ud_target"
#define UD_CB_TARGET_LEN 10

#define LE_FILENAME "le_extlink1.h5"
#define BE_FILENAME "be_extlink1.h5"

#define ELINK_CB_FAM_SIZE (hsize_t) 100

#define H5L_DIM1 100
#define H5L_DIM2 100

#define FILTER_FILESIZE_MAX_FRACTION (double)0.9F

/* Creation order macros */
#define CORDER_GROUP_NAME       "corder_group"
#define CORDER_SOFT_GROUP_NAME  "corder_soft_group"
#define CORDER_NLINKS               18
#define CORDER_ITER_STOP            3
#define CORDER_EST_ENTRY_LEN        9

/* Timestamp macros */
#define TIMESTAMP_GROUP_1       "timestamp1"
#define TIMESTAMP_GROUP_2       "timestamp2"

/* Link iteration struct */
typedef struct {
    H5_iter_order_t order;      /* Direction of iteration */
    unsigned ncalled;           /* # of times callback is entered */
    unsigned nskipped;          /* # of links skipped */
    int stop;                   /* # of iterations to stop after */
    int64_t curr;               /* Current creation order value */
    size_t max_visit;           /* Size of "visited link" flag array */
    hbool_t *visited;           /* Pointer to array of "visited link" flags */
} link_iter_info_t;

/* Link visit structs */
typedef struct {
    const char *path;           /* Path to link */
    H5L_type_t type;            /* Type of link */
} link_visit_t;
static const link_visit_t lvisit0[] = {
    {"Dataset_zero", H5L_TYPE_HARD},
    {"Group1", H5L_TYPE_HARD},
    {"Group1/Dataset_one", H5L_TYPE_HARD},
    {"Group1/Group2", H5L_TYPE_HARD},
    {"Group1/Group2/Dataset_two", H5L_TYPE_HARD},
    {"Group1/Group2/Type_two", H5L_TYPE_HARD},
    {"Group1/Group2/hard_zero", H5L_TYPE_HARD},
    {"Group1/Type_one", H5L_TYPE_HARD},
    {"Group1/hard_one", H5L_TYPE_HARD},
    {"Type_zero", H5L_TYPE_HARD},
    {"ext_dangle", H5L_TYPE_EXTERNAL},
    {"ext_one", H5L_TYPE_EXTERNAL},
    {"hard_one", H5L_TYPE_HARD},
    {"hard_two", H5L_TYPE_HARD},
    {"hard_zero", H5L_TYPE_HARD},
    {"soft_dangle", H5L_TYPE_SOFT},
    {"soft_one", H5L_TYPE_SOFT},
    {"soft_two", H5L_TYPE_SOFT}
};
static const link_visit_t lvisit1[] = {
    {"Dataset_one", H5L_TYPE_HARD},
    {"Group2", H5L_TYPE_HARD},
    {"Group2/Dataset_two", H5L_TYPE_HARD},
    {"Group2/Type_two", H5L_TYPE_HARD},
    {"Group2/hard_zero", H5L_TYPE_HARD},
    {"Group2/hard_zero/Dataset_zero", H5L_TYPE_HARD},
    {"Group2/hard_zero/Group1", H5L_TYPE_HARD},
    {"Group2/hard_zero/Type_zero", H5L_TYPE_HARD},
    {"Group2/hard_zero/ext_dangle", H5L_TYPE_EXTERNAL},
    {"Group2/hard_zero/ext_one", H5L_TYPE_EXTERNAL},
    {"Group2/hard_zero/hard_one", H5L_TYPE_HARD},
    {"Group2/hard_zero/hard_two", H5L_TYPE_HARD},
    {"Group2/hard_zero/hard_zero", H5L_TYPE_HARD},
    {"Group2/hard_zero/soft_dangle", H5L_TYPE_SOFT},
    {"Group2/hard_zero/soft_one", H5L_TYPE_SOFT},
    {"Group2/hard_zero/soft_two", H5L_TYPE_SOFT},
    {"Type_one", H5L_TYPE_HARD},
    {"hard_one", H5L_TYPE_HARD}
};
static const link_visit_t lvisit2[] = {
    {"Dataset_two", H5L_TYPE_HARD},
    {"Type_two", H5L_TYPE_HARD},
    {"hard_zero", H5L_TYPE_HARD},
    {"hard_zero/Dataset_zero", H5L_TYPE_HARD},
    {"hard_zero/Group1", H5L_TYPE_HARD},
    {"hard_zero/Group1/Dataset_one", H5L_TYPE_HARD},
    {"hard_zero/Group1/Group2", H5L_TYPE_HARD},
    {"hard_zero/Group1/Type_one", H5L_TYPE_HARD},
    {"hard_zero/Group1/hard_one", H5L_TYPE_HARD},
    {"hard_zero/Type_zero", H5L_TYPE_HARD},
    {"hard_zero/ext_dangle", H5L_TYPE_EXTERNAL},
    {"hard_zero/ext_one", H5L_TYPE_EXTERNAL},
    {"hard_zero/hard_one", H5L_TYPE_HARD},
    {"hard_zero/hard_two", H5L_TYPE_HARD},
    {"hard_zero/hard_zero", H5L_TYPE_HARD},
    {"hard_zero/soft_dangle", H5L_TYPE_SOFT},
    {"hard_zero/soft_one", H5L_TYPE_SOFT},
    {"hard_zero/soft_two", H5L_TYPE_SOFT}
};

typedef struct {
    unsigned idx;               /* Index in link visit structure */
    const link_visit_t *info;   /* Pointer to the link visit structure to use */
} lvisit_ud_t;


/* Object visit structs */
typedef struct {
    const char *path;           /* Path to object */
    H5O_type_t type;            /* Type of object */
} obj_visit_t;
static const obj_visit_t ovisit0_old[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_zero", H5O_TYPE_DATASET},
    {"Group1", H5O_TYPE_GROUP},
    {"Group1/Dataset_one", H5O_TYPE_DATASET},
    {"Group1/Group2", H5O_TYPE_GROUP},
    {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET},
    {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE},
    {"Type_zero", H5O_TYPE_NAMED_DATATYPE}
};
static const obj_visit_t ovisit0_new[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_zero", H5O_TYPE_DATASET},
    {"Group1", H5O_TYPE_GROUP},
    {"Group1/Dataset_one", H5O_TYPE_DATASET},
    {"Group1/Group2", H5O_TYPE_GROUP},
    {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET},
    {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE},
    {"Type_zero", H5O_TYPE_NAMED_DATATYPE}
};
static const obj_visit_t ovisit1_old[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_one", H5O_TYPE_DATASET},
    {"Group2", H5O_TYPE_GROUP},
    {"Group2/Dataset_two", H5O_TYPE_DATASET},
    {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"Group2/hard_zero", H5O_TYPE_GROUP},
    {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET},
    {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE},
    {"Type_one", H5O_TYPE_NAMED_DATATYPE}
};
static const obj_visit_t ovisit1_new[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_one", H5O_TYPE_DATASET},
    {"Group2", H5O_TYPE_GROUP},
    {"Group2/Dataset_two", H5O_TYPE_DATASET},
    {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"Group2/hard_zero", H5O_TYPE_GROUP},
    {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET},
    {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE},
    {"Type_one", H5O_TYPE_NAMED_DATATYPE}
};
static const obj_visit_t ovisit2_old[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_two", H5O_TYPE_DATASET},
    {"Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"hard_zero", H5O_TYPE_GROUP},
    {"hard_zero/Dataset_zero", H5O_TYPE_DATASET},
    {"hard_zero/Group1", H5O_TYPE_GROUP},
    {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET},
    {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE},
    {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}
};
static const obj_visit_t ovisit2_new[] = {
    {".", H5O_TYPE_GROUP},
    {"Dataset_two", H5O_TYPE_DATASET},
    {"Type_two", H5O_TYPE_NAMED_DATATYPE},
    {"hard_zero", H5O_TYPE_GROUP},
    {"hard_zero/Dataset_zero", H5O_TYPE_DATASET},
    {"hard_zero/Group1", H5O_TYPE_GROUP},
    {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET},
    {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE},
    {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}
};

typedef struct {
    unsigned idx;               /* Index in object visit structure */
    const obj_visit_t *info;    /* Pointer to the object visit structure to use */
} ovisit_ud_t;



/*-------------------------------------------------------------------------
 * Function:    fix_ext_filename
 *
 * Purpose:     Internal function to append path to file name.  It handles
 *              path name of Unix and Windows.
 *
 * Return:      void
 *
 * Programmer:  Raymond Lu
 *              14 Jan. 2009
 *-------------------------------------------------------------------------
 */
static void
fix_ext_filename(char *path_name, char *cwd, const char *file_name)
{
    HDstrcpy(path_name, cwd);

    HDstrcat(path_name, "/");
    HDstrcat(path_name, file_name);
}


/*-------------------------------------------------------------------------
 * Function:	mklinks
 *
 * Purpose:	Build a file with assorted links.
 *
 * Return:	Success:	0
 *
 *		Failure:	-1
 *
 * Programmer:	Robb Matzke
 *              Friday, August 14, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
mklinks(hid_t fapl, hbool_t new_format)
{
    hid_t		file, scalar, grp, d1;
    hsize_t	        size[1] = {1};
    char		filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("link creation (w/new group format)")
    else
        TESTING("link creation")

    /* Create a file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((scalar = H5Screate_simple(1, size, size)) < 0) TEST_ERROR

    /* Create a group */
    if((grp = H5Gcreate2(file, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(grp) < 0) TEST_ERROR

    /* Create a dataset */
    if((d1 = H5Dcreate2(file, "d1", H5T_NATIVE_INT, scalar, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(d1) < 0) TEST_ERROR

    /* Create a hard link */
    if(H5Lcreate_hard(file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create a symbolic link */
    if(H5Lcreate_soft("/d1", file, "grp1/soft", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create a symbolic link to something that doesn't exist */
    if(H5Lcreate_soft("foobar", file, "grp1/dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create a recursive symbolic link */
    if(H5Lcreate_soft("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close */
    if(H5Sclose(scalar) < 0) TEST_ERROR
    if(H5Fclose(file) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:    new_links
 *
 * Purpose:     Build a file with assorted links for different locations.
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Raymond Lu
 *              Friday, April 19, 2002
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
new_links(hid_t fapl, hbool_t new_format)
{
    hid_t		file_a, file_b=(-1);
    hid_t		grp1_a=(-1), grp1_b=(-1), grp2_a=(-1), grp2_b=(-1);
    hid_t		scalar=(-1);
    hid_t		dset1=(-1), dset2=(-1);
    char		filename[NAME_BUF_SIZE];
    hsize_t             size[1] = {1};

    if(new_format)
        TESTING("H5Lcreate functions (w/new group format)")
    else
        TESTING("H5Lcreate functions")

    /* Create two files */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file_a = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    h5_fixname(FILENAME[2], fapl, filename, sizeof filename);
    if((file_b = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    if((scalar = H5Screate_simple (1, size, size)) < 0) TEST_ERROR

    /* Create two groups in each file */
    if((grp1_a = H5Gcreate2(file_a, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp2_a = H5Gcreate2(file_a, "grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp1_b = H5Gcreate2(file_b, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp2_b = H5Gcreate2(file_b, "grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create datasets */
    if((dset1 = H5Dcreate2(file_a, "dataset1", H5T_NATIVE_INT, scalar, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((dset2 = H5Dcreate2(grp1_a, "dataset2", H5T_NATIVE_INT, scalar, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create links within a file.  Both of source and destination use
     * H5L_SAME_LOC.  Both hard and soft links should fail. */
    H5E_BEGIN_TRY {
        if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR
    } H5E_END_TRY;
    H5E_BEGIN_TRY {
        if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Create links across files with hard link.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Create hard link to test H5L_SAME_LOC */
    if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create links to test hard links across different locations */
    if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close dataspace and files */
    if(H5Sclose(scalar) < 0) TEST_ERROR
    if(H5Dclose(dset1) < 0) TEST_ERROR
    if(H5Dclose(dset2) < 0) TEST_ERROR
    if(H5Gclose(grp1_a) < 0) TEST_ERROR
    if(H5Gclose(grp2_a) < 0) TEST_ERROR
    if(H5Gclose(grp1_b) < 0) TEST_ERROR
    if(H5Gclose(grp2_b) < 0) TEST_ERROR
    if(H5Fclose(file_a) < 0) TEST_ERROR
    if(H5Fclose(file_b) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Sclose(scalar);
    	H5Dclose(dset1);
    	H5Dclose(dset2);
    	H5Gclose(grp1_a);
    	H5Gclose(grp2_a);
    	H5Gclose(grp1_b);
    	H5Gclose(grp2_b);
    	H5Fclose(file_a);
    	H5Fclose(file_b);
    } H5E_END_TRY;
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:	cklinks
 *
 * Purpose:	Open the file created in the first step and check that the
 *		links look correct.
 *
 * Return:	Success:	0
 *
 *		Failure:	-1
 *
 * Programmer:	Robb Matzke
 *              Friday, August 14, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
cklinks(hid_t fapl, hbool_t new_format)
{
    hid_t		file;
    H5O_info_t		oinfo1, oinfo2;
    H5L_info_t		linfo2;
    char		linkval[LINK_BUF_SIZE];
    char		filename[NAME_BUF_SIZE];
    herr_t		status;

    if(new_format)
        TESTING("link queries (w/new group format)")
    else
        TESTING("link queries")

    /* Open the file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Hard link */
    if(H5Oget_info_by_name(file, "d1", &oinfo1, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Oget_info_by_name(file, "grp1/hard", &oinfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5O_TYPE_DATASET != oinfo2.type) {
	H5_FAILED();
	printf("    %d: Unexpected object type should have been a dataset\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) {
	H5_FAILED();
	HDputs("    Hard link test failed. Link seems not to point to the ");
	HDputs("    expected file location.");
	TEST_ERROR
    } /* end if */
    if(H5Lexists(file, "/", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR
    if(H5Lexists(file, "d1", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR
    if(H5Lexists(file, "grp1/hard", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR
    if(H5Lexists(file, "/grp1", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR
    if(H5Lexists(file, "/grp1/hard", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR
    H5E_BEGIN_TRY {
        status = H5Lexists(file, "no_grp1/hard", H5P_DEFAULT);
    } H5E_END_TRY;
    if(status >= 0) {
	H5_FAILED();
	HDputs("    H5Lexists() should have failed for a path with missing components.");
	TEST_ERROR
    } /* end if */
    H5E_BEGIN_TRY {
        status = H5Lexists(file, "/no_grp1/hard", H5P_DEFAULT);
    } H5E_END_TRY;
    if(status >= 0) {
	H5_FAILED();
	HDputs("    H5Lexists() should have failed for a path with missing components.");
	TEST_ERROR
    } /* end if */

    /* Symbolic link */
    if(H5Oget_info_by_name(file, "grp1/soft", &oinfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5O_TYPE_DATASET != oinfo2.type) {
	H5_FAILED();
	printf("    %d: Unexpected object type should have been a dataset\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(H5F_addr_ne(oinfo1.addr, oinfo2.addr)) {
	H5_FAILED();
	HDputs("    Soft link test failed. Link seems not to point to the ");
	HDputs("    expected file location.");
	TEST_ERROR
    } /* end if */
    if(H5Lget_val(file, "grp1/soft", linkval, sizeof linkval, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(linkval, "/d1")) {
	H5_FAILED();
	HDputs("    Soft link test failed. Wrong link value");
	TEST_ERROR
    } /* end if */
    if(H5Lexists(file, "grp1/soft", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR

    /* Dangling link */
    H5E_BEGIN_TRY {
	status = H5Oget_info_by_name(file, "grp1/dangle", &oinfo2, H5P_DEFAULT);
    } H5E_END_TRY;
    if(status >= 0) {
	H5_FAILED();
	HDputs("    H5Oget_info_by_name() should have failed for a dangling link.");
	TEST_ERROR
    } /* end if */
    if(H5Lget_info(file, "grp1/dangle", &linfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5L_TYPE_SOFT != linfo2.type) {
	H5_FAILED();
	printf("    %d: Unexpected object type should have been a symbolic link\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(H5Lget_val(file, "grp1/dangle", linkval, sizeof linkval, H5P_DEFAULT) < 0) {
	H5_FAILED();
	printf("    %d: Can't retrieve link value\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(HDstrcmp(linkval, "foobar")) {
	H5_FAILED();
	HDputs("    Dangling link test failed. Wrong link value");
	TEST_ERROR
    } /* end if */
    if(H5Lexists(file, "grp1/dangle", H5P_DEFAULT) != TRUE) FAIL_STACK_ERROR

    /* Recursive link */
    H5E_BEGIN_TRY {
	status = H5Oget_info_by_name(file, "grp1/recursive", &oinfo2, H5P_DEFAULT);
    } H5E_END_TRY;
    if(status >= 0) {
	H5_FAILED();
	HDputs("    H5Oget_info_by_name() should have failed for a recursive link.");
	TEST_ERROR
    } /* end if */
    if(H5Lget_info(file, "grp1/recursive", &linfo2, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5L_TYPE_SOFT != linfo2.type) {
	H5_FAILED();
	printf("    %d: Unexpected object type should have been a symbolic link\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(H5Lget_val(file, "grp1/recursive", linkval, sizeof linkval, H5P_DEFAULT) < 0) {
	H5_FAILED();
	printf("    %d: Can't retrieve link value\n", __LINE__);
	TEST_ERROR
    } /* end if */
    if(HDstrcmp(linkval, "/grp1/recursive")) {
	H5_FAILED();
	HDputs("   Recursive link test failed. Wrong link value");
	TEST_ERROR
    } /* end if */

    /* Non-existent link */
    if(H5Lexists(file, "foobar", H5P_DEFAULT) == TRUE) FAIL_STACK_ERROR

    /* Cleanup */
    if(H5Fclose(file) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:    ck_new_links
 *
 * Purpose:     Open the file created in the first step and check that the
 *              links look correct.
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Raymond Lu
 *              Thursday, April 25, 2002
 *
 *-------------------------------------------------------------------------
 */
static int
ck_new_links(hid_t fapl, hbool_t new_format)
{
    hid_t 		file;
    H5O_info_t		oi_dset, oi_hard1, oi_hard2;
    char 		filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("new link queries (w/new group format)")
    else
        TESTING("new link queries")

    /* Open the file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Get hard link info */
    if(H5Oget_info_by_name(file, "/grp1/dataset2", &oi_dset, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Oget_info_by_name(file, "/grp1/hard1", &oi_hard1, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Oget_info_by_name(file, "/grp2/hard2", &oi_hard2, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Check hard links */
    if(H5O_TYPE_DATASET != oi_hard1.type || H5O_TYPE_DATASET != oi_hard2.type) {
	H5_FAILED();
	printf("    %d: Unexpected object type should have been a dataset\n", __LINE__);
	TEST_ERROR
    }
    if(H5F_addr_ne(oi_dset.addr, oi_hard1.addr) || H5F_addr_ne(oi_dset.addr, oi_hard2.addr)) {
	H5_FAILED();
	HDputs("    Hard link test failed.  Link seems not to point to the ");
	HDputs("    expected file location.");
	TEST_ERROR
    }

    /* Cleanup */
    if(H5Fclose(file) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:    long_links
 *
 * Purpose:     Build a file with long names
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, April 16, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
long_links(hid_t fapl, hbool_t new_format)
{
    hid_t		fid = (-1);     /* File ID */
    hid_t		gid = (-1);     /* Group ID */
    hid_t		gid2 = (-1);    /* Datatype ID */
    char               *objname = NULL; /* Name of object [Long] */
    size_t              u;              /* Local index variable */
    char		filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("long names for objects & links (w/new group format)")
    else
        TESTING("long names for objects & links")

    /* Create files */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group with short name in file (used as target for hard links) */
    if((gid = H5Gcreate2(fid, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Construct very long file name */
    if((objname = (char *)HDmalloc((size_t)(MAX_NAME_LEN + 1))) == NULL) TEST_ERROR
    for(u = 0; u < MAX_NAME_LEN; u++)
        objname[u] = 'a';
    objname[MAX_NAME_LEN] = '\0';

    /* Create hard link to existing object */
    if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create soft link to existing object */
    objname[0] = 'b';
    if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create group with long name in existing group */
    if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close objects */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Release memory */
    HDfree(objname);

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid2);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    HDfree(objname);
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:    toomany
 *
 * Purpose:     Build a file with too many symbolic links
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, August 9, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
toomany(hid_t fapl, hbool_t new_format)
{
    hid_t		fid = (-1);     	/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char                objname[NAME_BUF_SIZE];         /* Object name */
    char		filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("too many links (w/new group format)")
    else
        TESTING("too many links")

    /* Make certain test is valid */
    /* XXX: should probably make a "generic" test that creates the proper
     *          # of links based on this value - QAK
     */
    HDassert(H5L_NUM_LINKS == 16);

    /* Create file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group with short name in file (used as target for hard links) */
    if((gid = H5Gcreate2(fid, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create chain of hard links to existing object (no limit on #) */
    if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create chain of soft links to existing object (limited) */
    if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close objects */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Open file */
    if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open object through last hard link */
    if((gid = H5Gopen2(fid, "hard21", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/hard21")) TEST_ERROR

    /* Create object in hard-linked group */
    if((gid2 = H5Gcreate2(gid, "new_hard", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in hard-linked group */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close hard-linked object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Open object through too deep soft link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "soft17", H5P_DEFAULT);
    } H5E_END_TRY;
    if(gid >= 0) {
	H5_FAILED();
	HDputs("    Should have failed for sequence of too many nested links.");
	TEST_ERROR
    } /* end if */

    /* Open object through lesser soft link */
    if((gid = H5Gopen2(fid, "soft16", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/soft16")) TEST_ERROR

    /* Create object using soft links */
    if((gid2 = H5Gcreate2(gid, "new_soft", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close groups */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end toomany() */


/*-------------------------------------------------------------------------
 * Function:    test_lcpl
 *
 * Purpose:     Tests Link Creation Property Lists
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Monday, January 30, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_lcpl(hid_t fapl, hbool_t new_format)
{
    hid_t file_id=-1;
    hid_t group_id=-1;
    hid_t space_id=-1;
    hid_t dset_id=-1;
    hid_t type_id=-1;
    hid_t lcpl_id=-1;
    H5L_info_t linfo;
    char filename[1024];
    hsize_t dims[2];

    if(new_format)
        TESTING("link creation property lists (w/new group format)")
    else
        TESTING("link creation property lists")

    /* Actually, intermediate group creation is tested elsewhere (tmisc).
     * Here we only need to test the character encoding property */

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create and link a group with the default LCPL */
    if((group_id = H5Gcreate2(file_id, "/group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Check that its character encoding is the default */
    if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR

    /* Create and commit a datatype with the default LCPL */
    if((type_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(file_id, "/type", type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(type_id) < 0) TEST_ERROR

    /* Check that its character encoding is the default */
    if(H5Lget_info(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR

    /* Create a dataspace */
    dims[0] = H5L_DIM1;
    dims[1] = H5L_DIM2;
    if((space_id=H5Screate_simple(2 ,dims, NULL)) < 0) TEST_ERROR

    /* Create a dataset using the default LCPL */
    if((dset_id = H5Dcreate2(file_id, "/dataset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(dset_id) < 0) TEST_ERROR

    /* Check that its character encoding is the default */
    if(H5Lget_info(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5F_DEFAULT_CSET) TEST_ERROR

    /* Create a link creation property list with the UTF-8 character encoding */
    if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR

    /* Create and link a group with the new LCPL */
    if((group_id = H5Gcreate2(file_id, "/group2", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Check that its character encoding is UTF-8 */
    if(H5Lget_info(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Create and commit a datatype with the new LCPL */
    if((type_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(file_id, "/type2", type_id, lcpl_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(type_id) < 0) TEST_ERROR

    /* Check that its character encoding is UTF-8 */
    if(H5Lget_info(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Create a dataset using the new LCPL */
    if((dset_id = H5Dcreate2(file_id, "/dataset2", H5T_NATIVE_INT, space_id, lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(dset_id) < 0) TEST_ERROR

    /* Check that its character encoding is UTF-8 */
    if(H5Lget_info(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Create a new link to the dataset with a different character encoding. */
    if(H5Pclose(lcpl_id) < 0) TEST_ERROR
    if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR

    if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR

    /* Check that its character encoding is ASCII */
    if(H5Lget_info(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR

    /* Check that the first link's encoding hasn't changed */
    if(H5Lget_info(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Make sure that LCPLs work properly for other API calls: */
    /* H5Lcreate_soft */
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR
    if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* H5Lmove */
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR
    if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR

    /* H5Lcopy */
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR
    if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* H5Lcreate_external */
    if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Close open IDs */
    if(H5Pclose(lcpl_id) < 0) TEST_ERROR
    if(H5Sclose(space_id) < 0) TEST_ERROR
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Dclose(dset_id);
        H5Tclose(type_id);
        H5Pclose(lcpl_id);
        H5Sclose(space_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_lcpl() */


/*-------------------------------------------------------------------------
 * Function:    test_move
 *
 * Purpose:     Tests H5Lmove()
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Friday, March 30, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_move(hid_t fapl, hbool_t new_format)
{
    hid_t 	file_a, file_b=(-1);
    hid_t	grp_1=(-1), grp_2=(-1), grp_move=(-1), moved_grp=(-1);
    char 	filename[1024];

    if(new_format)
        TESTING("H5Lmove (w/new group format)")
    else
        TESTING("H5Lmove")

    /* Create two new files */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create groups in first file */
    if((grp_1 = H5Gcreate2(file_a, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp_2 = H5Gcreate2(file_a, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp_move = H5Gcreate2(grp_1, "group_move", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create hard, soft and external links. */
    if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Lcreate_external("filename", "pathname", grp_2, "ext", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Move a group within the file.  Both of source and destination use
     * H5L_SAME_LOC.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
                !=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Move a group across files.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
                !=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Move a soft link across files.  Should succeed. */
    if(H5Lmove(grp_2, "soft", file_b, "soft_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lexists(file_b, "soft_new_name", H5P_DEFAULT) != TRUE)
        TEST_ERROR

    /* Move an external link across files.  Should succeed. */
    if(H5Lmove(grp_2, "ext", file_b, "ext_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lexists(file_b, "ext_new_name", H5P_DEFAULT) != TRUE)
        TEST_ERROR

    /* Move a group across groups in the same file while renaming it. */
    if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group just moved to the new location. */
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if( H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Verify that the group is no longer in the original location */
    H5E_BEGIN_TRY {
        moved_grp = H5Gopen2(grp_1, "group_move", H5P_DEFAULT);
    } H5E_END_TRY;
    if(moved_grp >= 0) {
	H5_FAILED();
	HDputs("    Group still in original location?");
	TEST_ERROR
    } /* end if */

    /* Use H5Lmove to rename a group without moving it. */
    if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group. */
    if((moved_grp = H5Gopen2(grp_2, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Use H5Lmove to move a group without renaming it. */
    if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group . */
    if((moved_grp = H5Gopen2(grp_1, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Move the group while giving long paths. */
    if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group just moved to the new location. */
    if((moved_grp = H5Gopen2(grp_2, "group_newest_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR

    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Verify that the group is in no previous locations */
    H5E_BEGIN_TRY {
        if((moved_grp = H5Gopen2(grp_1, "group_newer_name", H5P_DEFAULT)) >= 0)
            FAIL_STACK_ERROR
        if((moved_grp = H5Gopen2(grp_2, "group_newer_name", H5P_DEFAULT)) >= 0)
            FAIL_STACK_ERROR
        if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) >= 0)
            FAIL_STACK_ERROR
        if((moved_grp = H5Gopen2(grp_1, "group_copy", H5P_DEFAULT)) >= 0)
            FAIL_STACK_ERROR
    } H5E_END_TRY;

    H5Gclose(grp_1);
    H5Gclose(grp_2);
    H5Gclose(grp_move);
    H5Fclose(file_a);
    H5Fclose(file_b);

    PASSED();
    return 0;

  error:
    H5_FAILED();
    H5E_BEGIN_TRY {
 	H5Gclose(grp_1);
	H5Gclose(grp_2);
	H5Gclose(grp_move);
        H5Gclose(moved_grp);
	H5Fclose(file_a);
	H5Fclose(file_b);
    } H5E_END_TRY;
    return 1;
}


/*-------------------------------------------------------------------------
 * Function:    test_copy
 *
 * Purpose:     Tests H5Lcopy()
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Friday, March 30, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_copy(hid_t fapl, hbool_t new_format)
{
    hid_t 	file_a, file_b=(-1);
    hid_t	grp_1=(-1), grp_2=(-1), grp_move=(-1), moved_grp=(-1);
    char 	filename[1024];

    if(new_format)
        TESTING("H5Lcopy (w/new group format)")
    else
        TESTING("H5Lcopy")

    /* Create two new files */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create groups in first file */
    if((grp_1 = H5Gcreate2(file_a, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp_2 = H5Gcreate2(file_a, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if((grp_move = H5Gcreate2(grp_1, "group_copy", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create hard, soft and external links. */
    if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR
    if(H5Lcreate_external("filename", "pathname", grp_2, "ext", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Copy a group within the file.  Both of source and destination use
     * H5L_SAME_LOC.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
                !=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Copy a group across files.  Should fail. */
    H5E_BEGIN_TRY {
        if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
                !=FAIL) TEST_ERROR
    } H5E_END_TRY;

    /* Copy a soft link across files.  Should succeed. */
    if(H5Lcopy(grp_2, "soft", file_b, "soft_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lexists(file_b, "soft_new_name", H5P_DEFAULT) != TRUE)
        TEST_ERROR

    /* Copy an external link across files.  Should succeed. */
    if(H5Lcopy(grp_2, "ext", file_b, "ext_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lexists(file_b, "ext_new_name", H5P_DEFAULT) != TRUE)
        TEST_ERROR

    /* Move a group across groups in the same file while renaming it. */
    if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group just moved to the new location. */
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Verify that the group is also in the original location */
    if((moved_grp = H5Gopen2(grp_1, "group_copy", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Use H5Lcopy to create a group in the same location with a different name. */
    if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group. */
    if((moved_grp = H5Gopen2(grp_2, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR
    /* Verify that the group is also in the original location */
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Use H5Lcopy to copy to a different location with the same name. */
    if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group . */
    if((moved_grp = H5Gopen2(grp_1, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR
    /* Verify that the group is still in the previous location */
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Copy the group while giving long paths. */
    if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Open the group just moved to the new location. */
    if((moved_grp = H5Gopen2(grp_2, "group_newest_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    /* Verify that the group is still in all previous original locations */
    if((moved_grp = H5Gopen2(grp_1, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR
    if((moved_grp = H5Gopen2(grp_2, "group_newer_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR
    if((moved_grp = H5Gopen2(grp_2, "group_new_name", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR
    if((moved_grp = H5Gopen2(grp_1, "group_copy", H5P_DEFAULT)) < 0)
	FAIL_STACK_ERROR
    if(H5Gclose(moved_grp) < 0)
        TEST_ERROR

    H5Gclose(grp_1);
    H5Gclose(grp_2);
    H5Gclose(grp_move);
    H5Fclose(file_a);
    H5Fclose(file_b);

    PASSED();
    return 0;

  error:
    H5_FAILED();
    H5E_BEGIN_TRY {
 	H5Gclose(grp_1);
	H5Gclose(grp_2);
	H5Gclose(grp_move);
        H5Gclose(moved_grp);
	H5Fclose(file_a);
	H5Fclose(file_b);
    } H5E_END_TRY;
    return 1;
}


/*-------------------------------------------------------------------------
 * Function:    test_move_preserves
 *
 * Purpose:     Tests that moving and renaming links preserves their
 *              properties.
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Monday, January 30, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_move_preserves(hid_t fapl_id, hbool_t new_format)
{
    hid_t file_id=-1;
    hid_t group_id=-1;
    hid_t fcpl_id=-1;           /* Group creation property list ID */
    hid_t lcpl_id=-1;
    hid_t lcpl2_id=-1;
    H5O_info_t oinfo;
    H5L_info_t linfo;
    H5T_cset_t old_cset;
    int64_t old_corder;         /* Creation order value of link */
    time_t old_modification_time;
    time_t curr_time;
    unsigned crt_order_flags;   /* Status of creation order info for GCPL */
    char filename[1024];

    if(new_format)
        TESTING("moving and copying links preserves their properties (w/new group format)")
    else
        TESTING("moving and copying links preserves their properties")

    /* Create a file creation property list with creation order stored for links
     * in the root group
     */
    if((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR
    if(H5Pget_link_creation_order(fcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != 0) TEST_ERROR
    if(H5Pset_link_creation_order(fcpl_id, H5P_CRT_ORDER_TRACKED) < 0) TEST_ERROR
    if(H5Pget_link_creation_order(fcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != H5P_CRT_ORDER_TRACKED) TEST_ERROR

    /* Create file */
    /* (with creation order tracking for the root group) */
    h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) TEST_ERROR

    /* Create a link creation property list with the UTF-8 character encoding */
    if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR

    /* Create a group with that lcpl */
    if((group_id = H5Gcreate2(file_id, "group", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Get the group's link's information */
    if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    old_cset = linfo.cset;
    if(old_cset != H5T_CSET_UTF8) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    old_corder = linfo.corder;
    if(old_corder != 0) TEST_ERROR
    old_modification_time = oinfo.mtime;

    /* If this test happens too quickly, the times will all be the same.  Make sure the time changes. */
    curr_time = HDtime(NULL);
    while(HDtime(NULL) <= curr_time)
        ;

    /* Close the file and reopen it */
    if(H5Fclose(file_id) < 0) TEST_ERROR
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR

    /* Get the link's character set & modification time .  They should be unchanged */
    if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(old_cset != linfo.cset) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(old_corder != linfo.corder) TEST_ERROR

    /* Create a new link to the group.  It should have a different creation order value but the same modification time */
    if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group2", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_corder == linfo.corder) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(linfo.corder != 1) TEST_ERROR
    if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR

    /* Copy the first link to a UTF-8 name.
     *  Its creation order value should be different, but modification time
     * should not change.
     */
    if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group_copied", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group_copied", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(linfo.corder != 2) TEST_ERROR

    /* Check that its character encoding is UTF-8 */
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Move the link with the default property list. */
    if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group_copied2", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group_copied2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(linfo.corder != 3) TEST_ERROR

    /* Check that its character encoding is not UTF-8 */
    if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR

    /* Check that the original link is unchanged */
    if(H5Oget_info_by_name(file_id, "group", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(old_corder != linfo.corder) TEST_ERROR
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Move the first link to a UTF-8 name.
     *  Its creation order value will change, but modification time should not
     *  change. */
    if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group_moved", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group_moved", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(linfo.corder != 4) TEST_ERROR

    /* Check that its character encoding is UTF-8 */
    if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Move the link again using the default property list. */
    if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(file_id, "group_moved_again", &oinfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(old_modification_time != oinfo.mtime) TEST_ERROR
    if(H5Lget_info(file_id, "group_moved_again", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder_valid != TRUE) TEST_ERROR
    if(linfo.corder != 5) TEST_ERROR

    /* Check that its character encoding is not UTF-8 */
    if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR

    /* Close open IDs */
    if(H5Pclose(fcpl_id) < 0) TEST_ERROR
    if(H5Pclose(lcpl_id) < 0) TEST_ERROR
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
	H5Pclose(fcpl_id);
	H5Pclose(lcpl_id);
	H5Pclose(lcpl2_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_move_preserves() */


/*-------------------------------------------------------------------------
 * Function:    test_deprec
 *
 * Purpose:     Tests deprecated functions for backward compatibility.
 *
 * Return:      Success:        0
 *              Failure:        number of errors
 *
 * Programmer:  James Laird
 *              Wednesday, April 26 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
#ifndef H5_NO_DEPRECATED_SYMBOLS
static int
test_deprec(hid_t fapl, hbool_t new_format)
{
    hid_t file_id = -1;
    hid_t group1_id = -1;
    hid_t group2_id = -1;
    H5G_stat_t	sb_hard1, sb_hard2, sb_soft1, sb_soft2;
    H5G_obj_t obj_type;         /* Object type */
    hsize_t num_objs;           /* Number of objects in a group */
    char filename[1024];
    char tmpstr[1024];

    if(new_format)
        TESTING("backwards compatibility (w/new group format)")
    else
        TESTING("backwards compatibility")

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create two groups in the file */
    if((group1_id = H5Gcreate2(file_id, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((group2_id = H5Gcreate2(file_id, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Test H5Gset and get comment */
    if(H5Gset_comment(file_id, "group1", "comment") < 0) FAIL_STACK_ERROR
    if(H5Gget_comment(file_id, "group1", sizeof(tmpstr), tmpstr) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(tmpstr, "comment")) TEST_ERROR

    /* Create links using H5Glink and H5Glink2 */
    if(H5Glink(file_id, H5G_LINK_HARD, "group2", "group1/link_to_group2") < 0) FAIL_STACK_ERROR
    if(H5Glink2(file_id, "group1", H5G_LINK_HARD, group2_id, "link_to_group1") < 0) FAIL_STACK_ERROR
    if(H5Glink2(file_id, "link_to_group1", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/soft_link_to_group1") < 0) FAIL_STACK_ERROR
    if(H5Glink2(file_id, "dangle", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/dangle_soft_link") < 0) FAIL_STACK_ERROR

    /* Test getting the names for objects */
    if(H5Gget_objname_by_idx(group1_id, (hsize_t)0, tmpstr, sizeof(tmpstr)) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(tmpstr, "link_to_group2")) TEST_ERROR
    H5E_BEGIN_TRY {
        if(H5Gget_objname_by_idx(group1_id, (hsize_t)1, tmpstr, sizeof(tmpstr)) >= 0) TEST_ERROR
    } H5E_END_TRY;

    /* Test getting the type for objects */
    if((obj_type = H5Gget_objtype_by_idx(group1_id, (hsize_t)0)) < 0) FAIL_STACK_ERROR
    if(obj_type != H5G_GROUP) TEST_ERROR
    H5E_BEGIN_TRY {
        if(H5Gget_objtype_by_idx(group1_id, (hsize_t)1) >= 0) TEST_ERROR
    } H5E_END_TRY;

    /* Test getting the number of objects in a group */
    if(H5Gget_num_objs(file_id, &num_objs) < 0) FAIL_STACK_ERROR
    if(num_objs != 2) TEST_ERROR
    if(H5Gget_num_objs(group1_id, &num_objs) < 0) FAIL_STACK_ERROR
    if(num_objs != 1) TEST_ERROR

    /* Test that H5Glink created hard links properly */
    if(H5Gget_objinfo(file_id, "/group2", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR
    if(H5Gget_objinfo(file_id, "/group1/link_to_group2", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR

    if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) {
        H5_FAILED();
        HDputs("    Hard link test failed.  Link seems not to point to the ");
        HDputs("    expected file location.");
        TEST_ERROR
    } /* end if */

    /* Test for the other hard link created */
    if(H5Gget_objinfo(file_id, "/group1", TRUE, &sb_hard1) < 0) FAIL_STACK_ERROR
    if(H5Gget_objinfo(file_id, "/group2/link_to_group1", TRUE, &sb_hard2) < 0) FAIL_STACK_ERROR

    if(HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) {
        H5_FAILED();
        HDputs("    Hard link test failed.  Link seems not to point to the ");
        HDputs("    expected file location.");
        TEST_ERROR
    } /* end if */

    /* Test the soft link */
    if(H5Gget_objinfo(file_id, "/group2/soft_link_to_group1", FALSE, &sb_soft1) < 0) FAIL_STACK_ERROR
    if(sb_soft1.type != H5G_LINK) TEST_ERROR
    if(sb_soft1.linklen != HDstrlen("link_to_group1") + 1) TEST_ERROR

    if(H5Gget_linkval(group2_id, "soft_link_to_group1", sb_soft1.linklen, tmpstr) < 0) FAIL_STACK_ERROR
    if(HDstrcmp("link_to_group1", tmpstr)) TEST_ERROR


    /* Test the dangling soft link */
    if(H5Gget_objinfo(file_id, "/group2/dangle_soft_link", FALSE, &sb_soft2) < 0) FAIL_STACK_ERROR
    if(sb_soft2.type != H5G_LINK) TEST_ERROR
    if(sb_soft2.linklen != HDstrlen("dangle") + 1) TEST_ERROR

    if(H5Gget_linkval(group2_id, "dangle_soft_link", sb_soft2.linklen, tmpstr) < 0) FAIL_STACK_ERROR
    if(HDstrcmp("dangle", tmpstr)) TEST_ERROR


    /* Test H5Gmove and H5Gmove2 */
    if(H5Gmove(file_id, "group1", "moved_group1") < 0) FAIL_STACK_ERROR
    if(H5Gmove2(file_id, "group2", group1_id, "moved_group2") < 0) FAIL_STACK_ERROR

    /* Ensure that both groups can be opened */
    if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR

    if((group1_id = H5Gopen2(file_id, "moved_group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((group2_id = H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close open IDs */
    if(H5Gclose(group2_id) < 0) FAIL_STACK_ERROR
    if(H5Gclose(group1_id) < 0) FAIL_STACK_ERROR

    /* Test H5Gunlink */
    if(H5Gunlink(file_id, "moved_group1/moved_group2") < 0) FAIL_STACK_ERROR

    H5E_BEGIN_TRY {
        if(H5Gopen2(file_id, "moved_group1/moved_group2", H5P_DEFAULT) >=0) TEST_ERROR
    } H5E_END_TRY;

    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(group2_id);
        H5Gclose(group1_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return 1;
} /* end test_deprec() */
#endif /* H5_NO_DEPRECATED_SYMBOLS */


/*-------------------------------------------------------------------------
 * Function:    external_link_root
 *
 * Purpose:     Build a file with external link to root group in external file
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, May 25, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_root(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    H5L_info_t	linfo;                          /* Link information */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE];
    char	filename2[NAME_BUF_SIZE];
    const char  *file;				/* File from external link */
    const char  *path;				/* Path from external link */

    if(new_format)
        TESTING("external link to root (w/new group format)")
    else
        TESTING("external link to root")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create file to point to */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Check that external links are registered with the library */
    if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR

    /* Create file with link to first file */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to object in first file */
    if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Check information for external link */
    if(H5Lget_info(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error;
    if(H5L_TYPE_EXTERNAL != linfo.type) {
	H5_FAILED();
	HDputs("    Unexpected object type - should have been an external link");
	goto error;
    }
    if(H5Lget_val(fid, "ext_link", objname, sizeof(objname), H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lunpack_elink_val(objname, linfo.u.val_size, NULL, &file, &path) < 0) TEST_ERROR
    if(HDstrcmp(file, filename1)) {
	H5_FAILED();
	HDputs("    External link file name incorrect");
	goto error;
    }
    if(HDstrcmp(path, "/")) {
	H5_FAILED();
	HDputs("    External link path incorrect");
	goto error;
    }

    /* Create external link to object in first file */
    /* (add a few extra '/'s to make certain library normalizes external link object names) */
    if(H5Lcreate_external(filename1, "///", fid, "ext_link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Check information for external link */
    if(H5Lget_info(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error;
    if(H5L_TYPE_EXTERNAL != linfo.type) {
	H5_FAILED();
	HDputs("    Unexpected object type - should have been an external link");
	goto error;
    }
    if(H5Lget_val(fid, "ext_link", objname, sizeof(objname), H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lunpack_elink_val(objname, linfo.u.val_size, NULL, &file, &path) < 0) TEST_ERROR
    if(HDstrcmp(file, filename1)) {
	H5_FAILED();
	HDputs("    External link file name incorrect");
	goto error;
    }
    if(HDstrcmp(path, "/")) {
	H5_FAILED();
	HDputs("    External link path incorrect");
	goto error;
    }

    /* Close and re-open file to ensure that data is written to disk */
    if(H5Fclose(fid) < 0) TEST_ERROR
    if((fid = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR


    /* Open object through external link */
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object (lets first file close) */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Create a new object using H5Gcreate2 through the external link
     * directly
     */
    if((gid = H5Gcreate2(fid, "ext_link/newer_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close file and group */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Check that all file IDs have been closed */
    if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR
    H5F_sfile_assert_num(0);

    /* Open first file again with read-only access and check on objects created */
    if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open objects created through external link */
    if((gid = H5Gopen2(fid, "new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((gid2 = H5Gopen2(fid, "newer_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check names */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/new_group")) TEST_ERROR
    if(H5Iget_name(gid2, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/newer_group")) TEST_ERROR

    /* Close opened objects */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Check that all file IDs have been closed */
    if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR
    H5F_sfile_assert_num(0);

    /* Verify that new objects can't be created through a read-only external
     * link.
     */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    H5E_BEGIN_TRY {
        gid = H5Gcreate2(fid, "ext_link/readonly_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    } H5E_END_TRY
    if(gid >= 0) TEST_ERROR

    /* Close second file again */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Check that all file IDs have been closed */
    if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR
    H5F_sfile_assert_num(0);

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid2);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_root() */


/*-------------------------------------------------------------------------
 * Function:    external_link_path
 *
 * Purpose:     Build a file with external link to object down a path in the
 *              external file
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, July 26, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_path(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE];
    char	filename2[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external link to object on path (w/new group format)")
    else
        TESTING("external link to object on path")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create file to point to */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object down a path */
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "A/B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create file with link to first file */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to object in first file */
    if(H5Lcreate_external(filename1, "/A/B/C", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/A/B/C")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object (lets first file close) */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close second file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file again and check on object created */
    if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open object created through external link */
    if((gid = H5Gopen2(fid, "/A/B/C/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid2);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_path() */


/*-------------------------------------------------------------------------
 * Function:    external_link_mult
 *
 * Purpose:     Build a file with external link to object that crossed several
 *              external file links
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, July 26, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_mult(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1), fid2 = (-1); 	/* File IDs */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
    		filename4[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("external links across multiple files (w/new group format)")
    else
        TESTING("external links across multiple files")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
    h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3);
    h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4);

    /* Create first file to point to */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object down a path */
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "A/B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link down a path */
    if((gid = H5Gcreate2(fid, "D", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "D/E", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create external link to object in first file */
    if(H5Lcreate_external(filename1, "/A/B/C", gid, "F", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create third file to point to */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link down a path */
    if((gid = H5Gcreate2(fid, "G", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if((gid = H5Gcreate2(fid, "G/H", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create external link to object in second file */
    if(H5Lcreate_external(filename2, "/D/E/F", gid, "I", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create file with link to third file */
    if((fid=H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to object in first file */
    if(H5Lcreate_external(filename3, "/G/H/I", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/A/B/C")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object (lets first file close) */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close second file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file again and check on object created */
    if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open object created through external link */
    if((gid = H5Gopen2(fid, "/A/B/C/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open an object through external links */
    if((fid = H5Fopen(filename4, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* The intermediate files should not stay open. Replace one of them with a new file. */
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Open the other with write access and delete the external link in it */
    if((fid2 = H5Fopen(filename3, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
    if(H5Ldelete(fid2, "G/H/I", H5P_DEFAULT) < 0) TEST_ERROR

    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Cleanup */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid2);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_mult() */


/*-------------------------------------------------------------------------
 * Function:    external_link_self
 *
 * Purpose:     Build a file with external link to itself
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Wednesday, July 12, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_self(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    hid_t	lcpl_id = (-1);     		/* Link Creation Property List ID */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE];
    char	filename2[NAME_BUF_SIZE];
    char	filename3[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external link to self (w/new group format)")
    else
        TESTING("external link to self")

    /* Set up filename */
    h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[2], fapl, filename2, sizeof filename1);
    h5_fixname(FILENAME[3], fapl, filename3, sizeof filename1);

    /* Create file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create an lcpl with intermediate group creation set */
    if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR

    /* Create a series of groups within the file: /A/B and /X/Y/Z */
    if((gid = H5Gcreate2(fid, "A/B", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "X/Y", lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if(H5Pclose (lcpl_id) < 0) TEST_ERROR

    /* Create external link to own root group*/
    if(H5Lcreate_external(filename1, "/X", fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "A/B/C/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/X")) TEST_ERROR

    /* Create object through external link */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close created group */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close object opened through external link */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Check on object created */
    if((gid = H5Gopen2(fid, "X/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/X/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Complicate things. Use this file as an intermediate file in a chain
        * of external links that will go: file2 -> file1 -> file1 -> file3
        */

    /* Create file2 with an external link to file1  */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    if(H5Lcreate_external(filename1, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file2 */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create file3 as a target */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "end", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Open file1 and create an extlink pointing to file3 */
    if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    if(H5Lcreate_external(filename3, "/", fid, "/X/Y/Z", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file1 */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Re-open file2 and traverse through file1 (with its recursive extlink) to file3 */
    if((fid=H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    if((gid = H5Gopen2(fid, "ext_link/B/C/Y/Z/end", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create object through external link */
    if((gid2 = H5Gcreate2(gid, "newer_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Cleanup */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Open up file3 and make sure the object was created successfully */
    if((fid = H5Fopen(filename3, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "end/newer_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Cleanup */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();

    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Pclose(lcpl_id);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_self() */


/*-------------------------------------------------------------------------
 * Function:    external_link_pingpong
 *
 * Purpose:     Build a file with external link to object that goes back and
 *              force between two files a couple of times:
 *
 *                      file1:/link1    -> file2: /link2
 *                      file2:/link2    -> file1: /link3
 *                      file1:/link3    -> file2: /link4
 *                      file2:/link4    -> file1: /link5
 *                      file1:/link5    -> file2: /link6
 *                      file2:/link6    -> file1: /final
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, July 26, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_pingpong(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("external links back and forth (w/new group format)")
    else
        TESTING("external links back and forth")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external links for chain */
    if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create final object */
    if((gid = H5Gcreate2(fid, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external links for chain */
    if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/final", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file */
    if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "link1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/final")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object (lets first file close) */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file again and check on object created */
    if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open object created through external link */
    if((gid = H5Gopen2(fid, "/final/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/final/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();

    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_pingpong() */


/*-------------------------------------------------------------------------
 * Function:    external_link_toomany
 *
 * Purpose:     Build a file with too many external links to objects (i.e.
 *              more than H5L_NLINKS_DEF.  Use a "back & forth" style of
 *              linking (like the "ping pong" test above) to minimize the
 *              number of files involved:
 *
 *                      file1:/link1    -> file2: /link2
 *                      file2:/link2    -> file1: /link3
 *                      file1:/link3    -> file2: /link4
 *                      file2:/link4    -> file1: /link5
 *                      file1:/link5    -> file2: /link6
 *                      file2:/link6    -> file1: /link7
 *                      file1:/link7    -> file2: /link8
 *                      file2:/link8    -> file1: /link9
 *                      file1:/link9    -> file2: /link10
 *                      file2:/link10   -> file1: /link11
 *                      file1:/link11   -> file2: /link12
 *                      file2:/link12   -> file1: /link13
 *                      file1:/link13   -> file2: /link14
 *                      file2:/link14   -> file1: /link15
 *                      file1:/link15   -> file2: /link16
 *                      file2:/link16   -> file1: /link17
 *                      file1:/link17   -> file2: /final
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, August 8, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_toomany(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("too many external links (w/new group format)")
    else
        TESTING("too many external links")

    /* Make certain test is valid */
    /* XXX: should probably make a "generic" test that creates the proper
     *          # of links based on this value - QAK
     */
    HDassert(H5L_NUM_LINKS == 16);

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external links for chain */
    if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link8", fid, "link7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link10", fid, "link9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link12", fid, "link11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link14", fid, "link13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/link16", fid, "link15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/final", fid, "link17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external links for chain */
    if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link7", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link9", fid, "link8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link11", fid, "link10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link13", fid, "link12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link15", fid, "link14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/link17", fid, "link16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create final object */
    if((gid = H5Gcreate2(fid, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file */
    if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "link1", H5P_DEFAULT);
    } H5E_END_TRY;
    if (gid >= 0) {
	H5_FAILED();
	printf("%d:    Should have failed for sequence of too many nested links.", __LINE__);
	goto error;
    }

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "link3", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/final")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid2);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_toomany() */


/*-------------------------------------------------------------------------
 * Function:    external_link_dangling
 *
 * Purpose:     Build a file with "dangling" external links: with both
 *              missing files and missing objects.
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, August 9, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_dangling(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    hid_t   rid = (-1);             /* Root Group ID */
    hid_t   status = (-1);          /* Status */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("dangling external links (w/new group format)")
    else
        TESTING("dangling external links")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create dangling external links */
    if(H5Lcreate_external("missing", "/missing", fid, "no_file", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/missing", fid, "no_object", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file (for dangling object test) */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file */
    if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Get root group ID */
    if((rid=H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) TEST_ERROR;

    /* Open object through dangling file external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "no_file", H5P_DEFAULT);
    } H5E_END_TRY;
    if (gid >= 0) {
	H5_FAILED();
	HDputs("    Should have failed for sequence of too many nested links.");
	goto error;
    }

    /* Open object through dangling object external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "no_object", H5P_DEFAULT);
    } H5E_END_TRY;
    if (gid >= 0) {
	H5_FAILED();
	HDputs("    Should have failed for sequence of too many nested links.");
	goto error;
    }

    /* Try to get name of object by index through dangling file external link */
    H5E_BEGIN_TRY {
        status = H5Lget_name_by_idx(rid, "no_file", H5_INDEX_NAME, H5_ITER_INC, 0, NULL, 0, H5P_DEFAULT);
    } H5E_END_TRY;
    if (status >= 0) {
        H5_FAILED();
        HDputs("    Retreiving name of object by index through dangling file external link should have failed.");
    } /* end if */

    /* Close root group */
    if(H5Gclose(rid) < 0) TEST_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_dangling() */


/*-------------------------------------------------------------------------
 * Function:    external_link_prefix
 *
 * Purpose:     1. target link: "extlinks2"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks2"
 * 		4. Set up external link prefix via H5Pset_elink_prefix() to be "tmp"
 *		Should be able to access the target file in tmp directory via the prefix set
 *		by H5Pset_elink_prefix()
 *
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb 19, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_prefix(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    hid_t	gapl_id = (-1);
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via H5Pset_elink_prefix()(w/new group format)")
    else
        TESTING("external links via H5Pset_elink_prefix()")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);
    /* set up name for external linked target file: "extlinks2" */
    h5_fixname(FILENAME[16], fapl, filename2, sizeof filename2);

    /* create tmp directory and get current working directory path */
    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
	TEST_ERROR

    /* set up name for target file: "tmp/extlinks2" */
    h5_fixname(FILENAME[17], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file (without the absolute path) */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* set up prefix for external link */
    if((gapl_id = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_prefix(gapl_id, TMPDIR) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", gapl_id);
    } H5E_END_TRY;

    /* should be able to find the target file from pathnames set via H5Pset_elink_prefix() */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp directory.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_prefix() */


/*-------------------------------------------------------------------------
 * Function:    external_link_abs_mainpath: test 3
 *
 * Purpose:     1. target link: "extlinks3"
 *		2. main file: Linux:"/CWD/tmp/extlinks0"; Windows: "<cur drive>:/CWD/tmp/extlinks0"
 *		3. target file: "tmp/extlinks3"
 *		Should be able to access the target file via the main file's absolute path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb 19, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_abs_mainpath(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
    		tmpname[NAME_BUF_SIZE],
    		cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's absolute path (w/new group format)")
    else
        TESTING("external links via main file's absolute path")

    /* set up name for external linked target file: "extlinks3" */
    h5_fixname(FILENAME[18], fapl, filename2, sizeof filename2);
    /* set up name for target file: "tmp/extlinks3" */
    h5_fixname(FILENAME[19], fapl, filename3, sizeof filename3);

    /* create tmp directory and get current working directory path */
    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

    /*
     * set up name for main file:
     *	Linux: "/CWD/tmp/extlinks0"
     *  Window: "<cur drive>:/CWD/tmp/extlinks0"
     */
    fix_ext_filename(tmpname, cwdpath, FILENAME[13]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file from absolute path set for main file */
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp directory.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_abs_mainpath() */


/*-------------------------------------------------------------------------
 * Function:    external_link_rel_mainpath: test 4
 *
 * Purpose: 	1. target link: "extlinks4"
 *		2. main file: "tmp/extlinks0"
 *		3. target file: "tmp/extlinks4"
 *		Should be able to access the target file via the main file's CWD+relative path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb 19, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_rel_mainpath(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's CWD + relative path(w/new group format)")
    else
        TESTING("external links via main file's CWD + relative path")

    /* set up name for external linked target file: "extlinks4" */
    h5_fixname(FILENAME[20], fapl, filename2, sizeof filename2);

    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR

     /* set up name for main file: "tmp/extlinks0" */
    h5_fixname(FILENAME[13], fapl, filename1, sizeof filename1);
    /* set up name for target file: "tmp/extlinks4" */
    h5_fixname(FILENAME[21], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file from the main file's relative pathname */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in current working directory");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_rel_mainpath() */

/*-------------------------------------------------------------------------
 * Function:    external_link_cwd: test 5
 *
 * Purpose:     1. target link: "extlinks5"
 *		2. main file: Linux:"/CWD/tmp/extlinks0"; Window: "<cur drive>:/CWD/tmp/extlinks0"
 * 		2. target file: "extlinks5"
 *		Should be able to access the target file in the current working directory
 *
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb 19, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_cwd(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];


    if(new_format)
        TESTING("external links via current working directory(w/new group format)")
    else
        TESTING("external links via current working directory")

    /* set up name for external linked target file: "extlinks5"  */
    /* set up name for target file: "extlinks5" */
    h5_fixname(FILENAME[22], fapl, filename2, sizeof filename2);

    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

    /*
     * set up name for main file:
     *	 Linux: "/CWD/tmp/extlinks0"
     *   Windows: "<cur drive>:/CWD/tmp/extlinks0"
     */
    fix_ext_filename(tmpname, cwdpath, FILENAME[13]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* Create the target file */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file from the current working directory */
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in current working directory");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_cwd() */



/*-------------------------------------------------------------------------
 * Function:    external_link_abstar: test 6
 *
 * Purpose:     1. target link: Linux:"/CWD/tmp/extlinks6"; Windows:"<cur drive>:/CWD/tmp/extlinks6"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks6"
 *		Should be able to access the target file's absolute path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb. 20, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_abstar(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via target's absolute path (w/new group format)")
    else
        TESTING("external links via target's absolute path")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

     /* create tmp directory and get current working directory path */
    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

    /*
     * set up name for external linked target file:
     *   Linux: "/CWD/tmp/extlinks6"
     *	 Windows: "<cur drive>:/CWD/tmp/extlinks6"
     */
    fix_ext_filename(tmpname, cwdpath, FILENAME[23]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks6" */
    h5_fixname(FILENAME[23], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file with abolute path */
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp directory.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_abstar() */

/*-------------------------------------------------------------------------
 * Function:    external_link_abstar_cur: test 7
 *
 * Purpose:     1. target link: Linux: "/CWD/tmp/extlinks7"; Windows: "<cur drive>:/CWD/tmp/extlinks7"
 *		2. main file: "extlinks0"
 *		3. target file: "extlinks7"
 *		Should be able to access the target file via the main file's CWD.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb. 20, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_abstar_cur(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
    		tmpname[NAME_BUF_SIZE],
    		cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's CWD (w/new group format)")
    else
        TESTING("external links via main file's CWD")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    /* set up name for target file name: "extlinks7" */
    h5_fixname(FILENAME[24], fapl, filename3, sizeof filename3);

    /* create tmp directory and get current working directory path */
    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

     /*
      * set up name for external linked target file:
      *   Linux: "/CWD/tmp/extlinks7"
      *	  Windows: "<cur drive>:/CWD/tmp/extlinks7"
      */
    fix_ext_filename(tmpname, cwdpath, FILENAME[25]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file from main file's current working directory */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in current working directory.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_abstar_cur() */


/*-------------------------------------------------------------------------
 * Function:    external_link_reltar: test 8
 *
 * Purpose:     1. target link: Linux:"tmp/extlinks8"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks8"
 *		Should be able to access the target file via the main file's CWD+ target's relative path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb. 20, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_reltar(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's CWD + target's relative path(w/new group format)")
    else
        TESTING("external links via main file's CWD + target's relative path")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    /* create tmp directory */
    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR

    /* set up name for target file name: "tmp/extlinks8" */
    /* set up name for external linked target file: "tmp/extlinks8" */
    h5_fixname(FILENAME[26], fapl, filename2, sizeof filename2);

    /* Create the target file */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "///A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp directory.");
	goto error;
    } /* end if */

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_reltar() */


/*-------------------------------------------------------------------------
 * Function:    external_link_chdir: test 9
 *
 * Purpose:
 *		1. target link: "extlinks9"
 *		2. main file: "extlinks0"
 *		3. target file" "tmp/extlinks9"
 *		3. chdir "tmp"
 *		Should be able to access the target file in current working directory
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Feb. 20, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_chdir(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via chdir and found in current working directory (w/new group format)")
    else
        TESTING("external links via chdir and found in current working directory")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);
    /* set up name for external linked target file ("extlinks9") */
    h5_fixname(FILENAME[27], fapl, filename2, sizeof filename2);

    /* create tmp directory */
    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR

    /* set up name for target file name ("tmp/extlinks9") */
    h5_fixname(FILENAME[28], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR


    if (HDchdir(TMPDIR) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    if (HDchdir("..") < 0) TEST_ERROR

    /*
     * Should be able to find the target file from:
     * main file's current working directory + pathname of external linked targetfile
     */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp directory.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_chdir() */


/*-------------------------------------------------------------------------
 * Function:    external_set_elink_fapl1: test 10
 *
 * Purpose:     To verify that the external linked target file with physical layout
 *		different from the parent can be successfully opened.
 *
 *		1. target link: "extlinks16"
 * 		2. target file: "extlinks16"
 *		3. main file: Linux:"/CWD/tmp/extlinks0"; Window: "<cur drive>:/CWD/tmp/extlinks0"
 *		4. Create target file A to be a "family" file: extlinks16A
 *		4. Create target file B to be a "multi" file: extlinks16B
 *		5. Create external link from main file to target file A: ext_linkA->extlinks16A:/A
 *		5. Create external link from main file to target file B: ext_linkB->extlinks16B:/B
 *		6. Should succeed in opening the target object: ext_extA
 *		6. Should succeed in opening the target object: ext_extB
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Sept. 12, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_set_elink_fapl1(hid_t fapl, hbool_t new_format)
{
    hid_t	fid=(-1);
    hid_t	fidA=(-1), fidB=(-1);
    hid_t	gidA=(-1), gidB=(-1);
    hid_t	oidA=(-1), oidB=(-1);
    char	filename1[NAME_BUF_SIZE],
    		filename2A[NAME_BUF_SIZE],
    		filename2B[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];
    hid_t 	fam_fapl=-1, multi_fapl=-1;
    hid_t	lapl_idA=-1, lapl_idB=-1;
    H5FD_mem_t	mt, memb_map[H5FD_MEM_NTYPES];
    hid_t	memb_fapl[H5FD_MEM_NTYPES];
    char        sv[H5FD_MEM_NTYPES][500];
    const	char *memb_name[H5FD_MEM_NTYPES];
    haddr_t	memb_addr[H5FD_MEM_NTYPES];

    if(new_format)
        TESTING("H5Pset/get_elink_fapl() with different physical layouts (w/new group format)")
    else
        TESTING("H5Pset/get_elink_fapl() with different physical layouts")

    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
	TEST_ERROR

    /*
     * set up name for main file:
     *	 Linux: "/CWD/tmp/extlinks0"
     *   Windows: "<cur drive>:/CWD/tmp/extlinks0"
     */
    fix_ext_filename(tmpname, cwdpath, FILENAME[13]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* create "family" fapl */
    fam_fapl = h5_fileaccess();
    if(H5Pset_fapl_family(fam_fapl, (hsize_t)FAMILY_SIZE, H5P_DEFAULT) < 0)
        TEST_ERROR;

    /* set up name for external linked target file A: "extlinks16A"  */
    /* set up name for target file A: "extlinks16A" */
    h5_fixname(FILENAME[37], fam_fapl, filename2A, sizeof filename2A);

    /* settings for multi file */
    HDmemset(memb_map, 0,  sizeof memb_map);
    HDmemset(memb_fapl, 0, sizeof memb_fapl);
    HDmemset(memb_name, 0, sizeof memb_name);
    HDmemset(memb_addr, 0, sizeof memb_addr);
    HDmemset(sv, 0, sizeof sv);

    for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) {
	memb_map[mt] = H5FD_MEM_SUPER;
	memb_fapl[mt] = H5P_DEFAULT;
    } /* end for */

    memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW;
    memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE;
    memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP;
    memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP;

    sprintf(sv[H5FD_MEM_SUPER], "%%s-%c.h5", 's');
    memb_name[H5FD_MEM_SUPER] = sv[H5FD_MEM_SUPER];
    memb_addr[H5FD_MEM_SUPER] = 0;

    sprintf(sv[H5FD_MEM_BTREE], "%%s-%c.h5", 'b');
    memb_name[H5FD_MEM_BTREE] = sv[H5FD_MEM_BTREE];
    memb_addr[H5FD_MEM_BTREE] = HADDR_MAX/6;

    sprintf(sv[H5FD_MEM_DRAW], "%%s-%c.h5", 'r');
    memb_name[H5FD_MEM_DRAW] = sv[H5FD_MEM_DRAW];
    memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/3;

    sprintf(sv[H5FD_MEM_GHEAP], "%%s-%c.h5", 'g');
    memb_name[H5FD_MEM_GHEAP] = sv[H5FD_MEM_GHEAP];
    memb_addr[H5FD_MEM_GHEAP] = HADDR_MAX/2;

    sprintf(sv[H5FD_MEM_LHEAP], "%%s-%c.h5", 'l');
    memb_name[H5FD_MEM_LHEAP] = sv[H5FD_MEM_LHEAP];
    memb_addr[H5FD_MEM_LHEAP] = (HADDR_MAX/3)*2;

    sprintf(sv[H5FD_MEM_OHDR], "%%s-%c.h5", 'o');
    memb_name[H5FD_MEM_OHDR] = sv[H5FD_MEM_OHDR];
    memb_addr[H5FD_MEM_OHDR] = (HADDR_MAX/6)*5;

    /* create "multi" fapl */
    multi_fapl = h5_fileaccess();
    if(H5Pset_fapl_multi(multi_fapl, memb_map, memb_fapl, memb_name, memb_addr, TRUE) < 0)
        TEST_ERROR;

    /* set up name for external linked target file B: "extlinks16B"  */
    /* set up name for target file B: "extlinks16B" */
    h5_fixname(FILENAME[38], multi_fapl, filename2B, sizeof filename2B);

    /* Create target file A to be a "family" file */
    if((fidA=H5Fcreate(filename2A, H5F_ACC_TRUNC, H5P_DEFAULT, fam_fapl)) < 0) TEST_ERROR
    if((gidA=H5Gcreate2(fidA, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create target file B to be a "multi" file */
    if((fidB=H5Fcreate(filename2B, H5F_ACC_TRUNC, H5P_DEFAULT, multi_fapl)) < 0) TEST_ERROR
    if((gidB=H5Gcreate2(fidB, "B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target files */
    if(H5Gclose(gidA) < 0) TEST_ERROR
    if(H5Gclose(gidB) < 0) TEST_ERROR
    if(H5Fclose(fidA) < 0) TEST_ERROR
    if(H5Fclose(fidB) < 0) TEST_ERROR

    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file A:/A */
    if(H5Lcreate_external(filename2A, "/A", fid, "ext_linkA", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR
    /* Create external link to target file B:/B */
    if(H5Lcreate_external(filename2B, "/B", fid, "ext_linkB", H5P_DEFAULT, H5P_DEFAULT) < 0)
	TEST_ERROR

    /* Set file access property list for link access to use the family driver */
    if((lapl_idA = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_fapl(lapl_idA, fam_fapl) < 0) TEST_ERROR

    /* open target object A */
    oidA = H5Oopen(fid, "ext_linkA", lapl_idA);

    /* should succeed in opening the target object A in the current working directory */
    if (oidA < 0) {
	H5_FAILED();
	HDputs("    Should succeed in opening family target file A in current working directory");
	goto error;
    }

    /* Set file access property list for link access to use the multi driver */
    if((lapl_idB = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_fapl(lapl_idB, multi_fapl) < 0) TEST_ERROR

    /* open target object B */
    oidB = H5Oopen(fid, "ext_linkB", lapl_idB);

    /* should succeed in opening the target object B in the current working directory */
    if (oidB < 0) {
	H5_FAILED();
	HDputs("    Should succeed in opening multi target file B in current working directory");
	goto error;
    }

    /* closing */
    if(H5Pclose(lapl_idA) < 0) TEST_ERROR
    if(H5Pclose(lapl_idB) < 0) TEST_ERROR
    if(H5Pclose(fam_fapl) < 0) TEST_ERROR
    if(H5Pclose(multi_fapl) < 0) TEST_ERROR
    if(H5Oclose(oidA) < 0) TEST_ERROR
    if(H5Oclose(oidB) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Pclose (lapl_idA);
	H5Pclose (lapl_idB);
	H5Pclose (fam_fapl);
	H5Pclose (multi_fapl);
	H5Gclose (gidA);
	H5Gclose (gidB);
	H5Oclose (oidA);
	H5Oclose (oidB);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_set_elink_fapl1() */


/*-------------------------------------------------------------------------
 * Function:    external_set_elink_fapl2: test 11
 *
 * Purpose:     To verify that processing done to the external linked target object is
 *		correctly handled when the parent and target files have the same
 *		physical layout but different access methods.
 *
 * 		1. target link: "extlinks17"
 * 		2. target file: "extlinks17"
 *		3. main file: Linux:"/CWD/tmp/extlinks0"; Window: "<cur drive>:/CWD/tmp/extlinks0"
 *		4. Create target file to be a "core" file:/A/Dataset
 *		5. Create external link from main file to target file:ext_link->target file:/A/Dataset
 *		6. Set the file access property list of the link access to use "core" file without
 *		   backing store
 *		6. Should succeed in opening the target dataset: ext_link
 *		7. Write data to the target dataset
 *		8. On closing, the file size of target should be the same as before since
 *		   it is opened without backing store.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Sept. 12, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_set_elink_fapl2(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    hid_t       core_fapl = -1, space = -1, dset = -1, did = -1, dapl_id = -1, dcpl = -1;
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];
    hsize_t     dims[2];
    int		points[NUM40][NUM40];
    h5_stat_size_t	filesize, new_filesize;
    int		i, j, n;

    if(new_format)
        TESTING("H5Pset/get_elink_fapl() with same physical layout (w/new group format)")
    else
        TESTING("H5Pset/get_elink_fapl() with same physical layout")

    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

    /*
     * set up name for main file:
     *	 Linux: "/CWD/tmp/extlinks0"
     *   Windows: "<cur drive>:/CWD/tmp/extlinks0"
     */
    fix_ext_filename(tmpname, cwdpath, FILENAME[13]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* create fapl for the target file to be a "core" file */
    core_fapl = h5_fileaccess();
    if(H5Pset_fapl_core(core_fapl, (size_t)CORE_INCREMENT, TRUE) < 0)
        TEST_ERROR

    /* set up name for external linked target file: "extlinks17"  */
    /* set up name for target file: "extlinks17" */
    h5_fixname(FILENAME[39], core_fapl, filename2, sizeof filename2);

    /* Create the target file to be a "core" file */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, core_fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    dims[0] = NUM40;
    dims[1] = NUM40;
    if((space = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR

    /* Create dataset creation property list */
    if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
    if(H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_LATE) < 0) TEST_ERROR;

    /* create "Dataset" in group "A" of target file */
    if((dset = H5Dcreate2(gid, "Dataset", H5T_NATIVE_INT, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
	TEST_ERROR

    /* closing for target file */
    if(H5Pclose(dcpl) < 0) TEST_ERROR
    if(H5Sclose(space) < 0) TEST_ERROR
    if(H5Dclose(dset) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* get size of target file */
    filesize = h5_get_file_size(filename2, core_fapl);

    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file: ext_link->extlinks17:/A/Dataset */
    if(H5Lcreate_external(filename2, "/A/Dataset", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* create fapl to be a "core" file without backing store */
    if(H5Pset_fapl_core(core_fapl, (size_t)CORE_INCREMENT, FALSE) < 0)
        TEST_ERROR

    /* Set file access property list for link access to use the "core" driver */
    if((dapl_id = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_fapl(dapl_id, core_fapl) < 0) TEST_ERROR

    /* try to open the external linked target dataset */
    did = H5Dopen2(fid, "ext_link", dapl_id);
    if(did < 0) {
        H5_FAILED();
        HDputs("    Should succeed in opening the target dataset");
        goto error;
    }

    /* Initialize the dataset */
    for(i = n = 0; i < NUM40; i++)
        for(j = 0; j < NUM40; j++)
            points[i][j] = n++;

    /* Write the data to the dataset */
    if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points) < 0)
        TEST_ERROR

    if(H5Pclose(dapl_id) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    new_filesize = h5_get_file_size(filename2, core_fapl);

    /* the file size should remain the same since there is no backing store */
    if(new_filesize != filesize) TEST_ERROR

    if(H5Pclose(core_fapl) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Pclose(dcpl);
	H5Sclose(space);
	H5Dclose(dset);
	H5Pclose(core_fapl);
	H5Pclose(dapl_id);
	H5Dclose(did);
	H5Gclose(gid);
	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_set_elink_fapl2() */


/*-------------------------------------------------------------------------
 * Function:    external_set_elink_fapl3: test 12
 *
 * Purpose:     To verify that the file access property list for link access is
 *		set and closed correctly.
 *
 *		1. Create fapl for core driver
 *		2. Create fapl for stdio driver
 *		3. Set link access's fapl to use stdio driver
 *		4. Verify that link access's fapl is the stdio driver
 *		5. Reset the link access' fapl to use core driver
 *		6. H5Pcopy() the link access
 *		7. Get the fapl property value of the original link access
 *		8. Close the original link access
 *		9. H5Pclose() fapl should fail since closing in step #8 should also close its fapl
 *	       10. Verify that the copied link access's fapl is the core driver
 *	       11. Get the fapl property value of the copied link access
 *	       12. H5Premove() the fapl property from the copied link access
 *	       13. H5Pclose() fapl set in the copied link access should fail since the
 *		   removal in #12 should also close its fapl
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              Sept. 12, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_set_elink_fapl3(hbool_t new_format)
{
    hid_t       core_fapl = -1, stdio_fapl = -1;
    hid_t	lapl_id = -1, new_lapl_id = -1, l_fapl = -1, out_fapl;

    if(new_format)
        TESTING("H5Pset/get_fapl() (w/new group format)")
    else
        TESTING("H5Pset/get_fapl()")

    /* create fapl for the target file to be a "core" file */
    core_fapl = h5_fileaccess();
    if(H5Pset_fapl_core(core_fapl, (size_t)CORE_INCREMENT, TRUE) < 0)
        TEST_ERROR

    stdio_fapl = h5_fileaccess();
    if(H5Pset_fapl_stdio(stdio_fapl) < 0)
        TEST_ERROR

    /* Set file access property list for link access to use the "stdio" driver */
    if((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_fapl(lapl_id, stdio_fapl) < 0) TEST_ERROR

    /* Verify that the driver for the link's fapl is the "stdio" driver */
    if((l_fapl = H5Pget_elink_fapl(lapl_id)) < 0) TEST_ERROR
    if(H5Pget_driver(l_fapl) != H5FD_STDIO) TEST_ERROR
    if(H5Pclose(l_fapl) < 0) TEST_ERROR

    /* Set file access property list for link access to use the "core" driver */
    if(H5Pset_elink_fapl(lapl_id, core_fapl) < 0) TEST_ERROR

    /* Make a copy of the link access property */
    if((new_lapl_id = H5Pcopy(lapl_id)) < 0) TEST_ERROR

    /* get the fapl set in lapl_id */
    if(H5Pget(lapl_id, "external link fapl", &out_fapl) < 0) TEST_ERROR
    if(H5Pclose(lapl_id) < 0) TEST_ERROR

    /* Try closing out_fapl, should succeed since H5Pget() should clone its fapl */
    if(H5Pclose(out_fapl) < 0) TEST_ERROR

    /* Verify that the driver for the copied link's fapl is the "core" driver */
    if((l_fapl = H5Pget_elink_fapl(new_lapl_id)) < 0) TEST_ERROR
    if(H5Pget_driver(l_fapl) != H5FD_CORE) TEST_ERROR

    /* get the fapl set in new_lapl_id */
    if(H5Pget(new_lapl_id, "external link fapl", &out_fapl) < 0) TEST_ERROR
    if(H5Premove(new_lapl_id, "external link fapl") < 0) TEST_ERROR

    /* Try closing out_fapl, should succeed since H5Pget() should clone its fapl */
    if(H5Pclose(out_fapl) < 0) TEST_ERROR

    if(H5Pclose(l_fapl) < 0) TEST_ERROR
    if(H5Pclose(new_lapl_id) < 0) TEST_ERROR
    if(H5Pclose(core_fapl) < 0) TEST_ERROR
    if(H5Pclose(stdio_fapl) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Pclose(l_fapl);
        H5Pclose(lapl_id);
        H5Pclose(new_lapl_id);
        H5Pclose(core_fapl);
        H5Pclose(stdio_fapl);
    } H5E_END_TRY;
    return -1;
} /* end external_set_elink_fapl3() */


/*-------------------------------------------------------------------------
 * Function:    external_set_elink_acc_flags
 *
 * Purpose:     Verify functionality of H5P_set/get_elink_acc_flags
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Jan. 5, 2009
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_set_elink_acc_flags(const char *env_h5_drvr, hid_t fapl, hbool_t new_format)
{
    hid_t       file1 = -1, file2 = -1, group = -1, subgroup = -1, gapl = -1;
    char        filename1[NAME_BUF_SIZE],
                filename2[NAME_BUF_SIZE];
    herr_t      ret;
    unsigned    flags;

    if(new_format)
        TESTING("H5Pset/get_elink_acc_flags() (w/new group format)")
    else
        TESTING("H5Pset/get_elink_acc_flags()")

    /* Create parent and target files, and external link */
    h5_fixname(FILENAME[40], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[41], fapl, filename2, sizeof filename2);
    if((file1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((file2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/", file1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file2, leave file1 open (should be read-write) */
    if(H5Fclose(file2) < 0) TEST_ERROR

    /* Create new gapl, and set elink access flags to be H5F_ACC_RDONLY */
    if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDONLY) < 0) TEST_ERROR

    /* Verify "get" routine functionality */
    if(H5Pget_elink_acc_flags(gapl, &flags) < 0) TEST_ERROR
    if(flags != H5F_ACC_RDONLY) TEST_ERROR

    /* Attempt to create a group through the external link using gapl (should fail) */
    H5E_BEGIN_TRY {
        group = H5Gcreate2(file1, "/ext_link/group", H5P_DEFAULT, H5P_DEFAULT, gapl);
    } H5E_END_TRY;
    if(group != FAIL) TEST_ERROR

    /* Close file1 and reopen with read only access */
    if(H5Fclose(file1) < 0) TEST_ERROR
    if((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Set elink access flags on gapl to be H5F_ACC_RDWR */
    if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDWR) < 0) TEST_ERROR

    /* Create a group through the external link using gapl (should succeed) */
    if((group = H5Gcreate2(file1, "/ext_link/group", H5P_DEFAULT, H5P_DEFAULT, gapl)) < 0) TEST_ERROR

    /* Close group */
    if(H5Gclose(group) < 0) TEST_ERROR

    /* Unset elink access flags on gapl */
    if(H5Pset_elink_acc_flags(gapl, H5F_ACC_DEFAULT) < 0) TEST_ERROR

    /* Attempt to create a group through the external link using gapl (should fail) */
    H5E_BEGIN_TRY {
        subgroup = H5Gcreate2(file1, "/ext_link/group/subgroup", H5P_DEFAULT, H5P_DEFAULT, gapl);
    } H5E_END_TRY;
    if(subgroup != FAIL) TEST_ERROR

    /* Attempt to set SWMR flags on gapl.
     * This is just a smoke check of the flags. The actual external link
     * functionality is tested in the SWMR tests.
     */
    /* Set SWMR reader flags on gapl */
    if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ) < 0) TEST_ERROR
    /* Set SWMR writer flags on gapl */
    if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE) < 0) TEST_ERROR

    /* Attempt to set invalid flags on gapl */
    H5E_BEGIN_TRY {
        ret = H5Pset_elink_acc_flags(gapl, H5F_ACC_TRUNC);
    } H5E_END_TRY;
    if(ret != FAIL) TEST_ERROR
    H5E_BEGIN_TRY {
        ret = H5Pset_elink_acc_flags(gapl, H5F_ACC_EXCL);
    } H5E_END_TRY;
    if(ret != FAIL) TEST_ERROR
    H5E_BEGIN_TRY {
        ret = H5Pset_elink_acc_flags(gapl, H5F_ACC_CREAT);
    } H5E_END_TRY;
    if(ret != FAIL) TEST_ERROR
    /* SWMR reader with write access */
    H5E_BEGIN_TRY {
        ret = H5Pset_elink_acc_flags(gapl, H5F_ACC_RDWR | H5F_ACC_SWMR_READ);
    } H5E_END_TRY;
    if(ret != FAIL) TEST_ERROR
    /* SWMR writer with read-only access */
    H5E_BEGIN_TRY {
        ret = H5Pset_elink_acc_flags(gapl, H5F_ACC_RDONLY | H5F_ACC_SWMR_WRITE);
    } H5E_END_TRY;
    if(ret != FAIL) TEST_ERROR

    /* Close file1 */
    if(H5Fclose(file1) < 0) TEST_ERROR

    /* Only run this part with VFDs that support SWMR */
    if(H5FD_supports_swmr_test(env_h5_drvr)) {

        /* Reopen file1, with read-write and SWMR-write access */
        /* Only supported under the latest file format */
        if(new_format) {
            if((file1 = H5Fopen(filename1, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0) FAIL_STACK_ERROR

            /* Open a group through the external link using default gapl */
            if((group = H5Gopen2(file1, "/ext_link/group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

            /* Verify that the correct parameters have been set on file2 */
            if((file2 = H5Iget_file_id(group)) < 0) FAIL_STACK_ERROR
            if(H5Fget_intent(file2, &flags) < 0) FAIL_STACK_ERROR
            if(flags != (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE)) TEST_ERROR

            /* Close file2 and group */
            if(H5Gclose(group) < 0) FAIL_STACK_ERROR
            if(H5Fclose(file2) < 0) FAIL_STACK_ERROR

            /* Set elink access flags on gapl to be H5F_ACC_RDWR (dropping SWMR_WRITE) */
            if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDWR) < 0) FAIL_STACK_ERROR

            /* Open a group through the external link using gapl */
            if((group = H5Gopen2(file1, "/ext_link/group", gapl)) < 0) FAIL_STACK_ERROR

            /* Verify that the correct parameters have been set on file2 */
            if((file2 = H5Iget_file_id(group)) < 0) FAIL_STACK_ERROR
            if(H5Fget_intent(file2, &flags) < 0) FAIL_STACK_ERROR
            if(flags != H5F_ACC_RDWR) TEST_ERROR

            /* Close file2 and group */
            if(H5Gclose(group) < 0) FAIL_STACK_ERROR
            if(H5Fclose(file2) < 0) FAIL_STACK_ERROR

            /* Close file1 */
            if(H5Fclose(file1) < 0) TEST_ERROR
        }

        /* Reopen file1, with read-only and SWMR-read access */
        if((file1 = H5Fopen(filename1, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) FAIL_STACK_ERROR

        /* Open a group through the external link using default gapl */
        if((group = H5Gopen2(file1, "/ext_link/group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Verify that the correct parameters have been set on file2 */
        if((file2 = H5Iget_file_id(group)) < 0) FAIL_STACK_ERROR
        if(H5Fget_intent(file2, &flags) < 0) FAIL_STACK_ERROR
        if(flags != (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ)) TEST_ERROR

        /* Close file2 and group */
        if(H5Gclose(group) < 0) FAIL_STACK_ERROR
        if(H5Fclose(file2) < 0) FAIL_STACK_ERROR

        /* Set elink access flags on gapl to be H5F_ACC_RDWR (dropping SWMR_WRITE) */
        if(H5Pset_elink_acc_flags(gapl, H5F_ACC_RDONLY) < 0) FAIL_STACK_ERROR

        /* Open a group through the external link using gapl */
        if((group = H5Gopen2(file1, "/ext_link/group", gapl)) < 0) FAIL_STACK_ERROR

        /* Verify that the correct parameters have been set on file2 */
        if((file2 = H5Iget_file_id(group)) < 0) FAIL_STACK_ERROR
        if(H5Fget_intent(file2, &flags) < 0) FAIL_STACK_ERROR
        if(flags != H5F_ACC_RDONLY) TEST_ERROR

        /* Close file2 and group */
        if(H5Gclose(group) < 0) FAIL_STACK_ERROR
        if(H5Fclose(file2) < 0) FAIL_STACK_ERROR

        /* Close file1 */
        if(H5Fclose(file1) < 0) TEST_ERROR
    } /* end if */


    /* Verify that H5Fcreate and H5Fopen reject H5F_ACC_DEFAULT */
    H5E_BEGIN_TRY {
        file1 = H5Fcreate(filename1, H5F_ACC_DEFAULT, H5P_DEFAULT, fapl);
    } H5E_END_TRY;
    if(file1 != FAIL) TEST_ERROR
    H5E_BEGIN_TRY {
        file1 = H5Fcreate(filename1, H5F_ACC_TRUNC | H5F_ACC_DEFAULT, H5P_DEFAULT, fapl);
    } H5E_END_TRY;
    if(file1 != FAIL) TEST_ERROR
    H5E_BEGIN_TRY {
        file1 = H5Fopen(filename1, H5F_ACC_DEFAULT, fapl);
    } H5E_END_TRY;
    if(file1 != FAIL) TEST_ERROR
    H5E_BEGIN_TRY {
        file1 = H5Fopen(filename1, H5F_ACC_RDWR | H5F_ACC_DEFAULT, fapl);
    } H5E_END_TRY;
    if(file1 != FAIL) TEST_ERROR

    /* Close gapl */
    if(H5Pclose(gapl) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Gclose(group);
        H5Gclose(subgroup);
        H5Fclose(file1);
        H5Fclose(file2);
        H5Pclose(gapl);
    } H5E_END_TRY;
    return -1;
} /* end external_set_elink_acc_flags() */


/*-------------------------------------------------------------------------
 * Function:    external_set_elink_cb
 *
 * Purpose:     Verify functionality of H5P_set/get_elink_cb
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Jan. 5, 2009
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
 /* User data structure for callback function */
typedef struct {
    const char  *parent_file;   /* Expected parent file name */
    const char  *target_file;   /* Expected target file name */
    hid_t       base_fapl;      /* Base fapl for family driver */
    hsize_t     fam_size;       /* Size of family files */
    int         code;           /* Code to control the actions taken by the callback */
} set_elink_cb_t;

/* Callback function */
static herr_t
external_set_elink_cb_cb(const char *parent_file, const char *parent_group,
    const char *target_file, const char *target_obj, unsigned *flags,
    hid_t fapl, void *_op_data)
{
    set_elink_cb_t  *op_data = (set_elink_cb_t *)_op_data;

    /* Verify file and object names are correct */
    if (HDstrcmp(parent_file, op_data->parent_file)) return FAIL;
    if (HDstrcmp(parent_group, "/group1")) return FAIL;
    if (HDstrcmp(target_file, op_data->target_file)) return FAIL;
    if (HDstrcmp(target_obj, "/")) return FAIL;

    /* Set flags to be read-write */
    *flags = (*flags & ~H5F_ACC_RDONLY) | H5F_ACC_RDWR;

    /* Set family file driver on fapl */
    if (H5Pset_fapl_family(fapl, op_data->fam_size, op_data->base_fapl) < 0) return FAIL;

    /* Codes to cause an invalid condition (and verify that an error is issued */
    if (op_data->code == 1)
        return FAIL;
    if (op_data->code == 2)
        *flags = H5F_ACC_DEFAULT;

    return 0;
}

/* Main test function */
static int
external_set_elink_cb(hid_t fapl, hbool_t new_format)
{
    hid_t       file1 = -1, file2 = -1, group = -1, gapl = -1, fam_fapl = -1, ret_fapl = -1, base_driver;
    set_elink_cb_t op_data,
                *op_data_p;
    H5L_elink_traverse_t cb;
    char        filename1[NAME_BUF_SIZE],
                filename2[NAME_BUF_SIZE];
    unsigned    flags;

    if(new_format)
        TESTING("H5Pset/get_elink_cb() (w/new group format)")
    else
        TESTING("H5Pset/get_elink_cb()")

    /* Build user data for callback */
    op_data.parent_file = filename1;
    op_data.target_file = filename2;
    /* Core file driver has issues when used as the member file driver for a family file */
    /* Family file driver cannot be used with family or multi drivers for member files */
    /* Also disable parallel member drivers, because H5F_HAS_FEATURE(H5FD_FEAT_HAS_MPI) 
       would report FALSE, causing problems */
    base_driver = H5Pget_driver(fapl);
    op_data.base_fapl = (base_driver == H5FD_FAMILY || base_driver ==  H5FD_MULTI
            || base_driver == H5FD_MPIO || base_driver == H5FD_CORE) ? H5P_DEFAULT : fapl;
    op_data.fam_size = ELINK_CB_FAM_SIZE;
    op_data.code = 0;

    /* Create family fapl */
    if ((fam_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR
    if (H5Pset_fapl_family(fam_fapl, op_data.fam_size, op_data.base_fapl) < 0) TEST_ERROR

    /* Create parent and target files, group, and external link */
    h5_fixname(FILENAME[42], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[43], fam_fapl, filename2, sizeof filename2);
    if((file1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((file2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fam_fapl)) < 0) TEST_ERROR
    if((group = H5Gcreate2(file1, "group1",H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Lcreate_external(filename2, "/", group, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close files and group */
    if(H5Fclose(file1) < 0) TEST_ERROR
    if(H5Fclose(file2) < 0) TEST_ERROR
    if(H5Gclose(group) < 0) TEST_ERROR

    /* Create new gapl, and set elink callback */
    if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_cb(gapl, external_set_elink_cb_cb, &op_data) < 0) TEST_ERROR

    /* Verify "get" routine functionality */
    if(H5Pget_elink_cb(gapl, &cb, (void **) &op_data_p) < 0) TEST_ERROR
    if(cb != external_set_elink_cb_cb) TEST_ERROR
    if(op_data_p != &op_data) TEST_ERROR

    /* Open file1 with read only access */
    if((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Create a group through the external link using gapl */
    if((group = H5Gcreate2(file1, "/group1/ext_link/group2", H5P_DEFAULT, H5P_DEFAULT, gapl)) < 0) TEST_ERROR

    /* Verify that the correct parameters have been set on file2 (somewhat
     * redundant as the library would be unable to create the group otherwise)
     */
    if((file2 = H5Iget_file_id(group)) < 0) TEST_ERROR
    if(H5Fget_intent(file2, &flags) < 0) TEST_ERROR
    if(!(flags & H5F_ACC_RDWR)) TEST_ERROR
    if((ret_fapl = H5Fget_access_plist(file2)) < 0) TEST_ERROR
    if(H5FD_FAMILY != H5Pget_driver(ret_fapl)) TEST_ERROR

    if(H5Gclose(group) < 0) TEST_ERROR
    if(H5Fclose(file2) < 0) TEST_ERROR
    if(H5Pclose(ret_fapl) < 0) TEST_ERROR
    if(H5Pclose(fam_fapl) < 0) TEST_ERROR

    /* Modify the user data structure to cause the callback to fail next time */
    op_data.code = 1;

    /* Attempt to reopen group2 (should fail) */
    H5E_BEGIN_TRY {
        group = H5Gopen2(file1, "/group1/ext_link/group2", gapl);
    } H5E_END_TRY;
    if(group != FAIL) TEST_ERROR

    /* Modify the user data structure to cause the callback to return invalid flags */
    op_data.code = 2;

    /* Attempt to reopen group2 (should fail) */
    H5E_BEGIN_TRY {
        group = H5Gopen2(file1, "/group1/ext_link/group2", gapl);
    } H5E_END_TRY;
    if(group != FAIL) TEST_ERROR

    /* Close */
    if(H5Fclose(file1) < 0) TEST_ERROR
    if(H5Pclose(gapl) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Gclose(group);
        H5Fclose(file1);
        H5Fclose(file2);
        H5Pclose(gapl);
        H5Pclose(ret_fapl);
        H5Pclose(fam_fapl);
    } H5E_END_TRY;
    return -1;
} /* end external_set_elink_cb() */


/*-------------------------------------------------------------------------
 * Function:    external_reset_register
 *
 * Purpose:     Check that external links are registered after the library
 *              is reset.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Apr. 9, 2009
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_reset_register(void)
{
    hid_t       file;
    char        filename[NAME_BUF_SIZE];

    TESTING("external links are registered after reset")

    /* Create and close file */
    h5_fixname(FILENAME[44], H5P_DEFAULT, filename, sizeof filename);
    if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if (H5Fclose(file) < 0) TEST_ERROR

    /* Reset the library */
    H5close();

    /* Re open file */
    if ((file = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create an external link */
    if (H5Lcreate_external("some_file", "some_obj", file, "ext_link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if (H5Fclose(file) < 0) TEST_ERROR

    /* Try again to make sure the previous H5Lcreate_external call does not
     * affect the ability to reset */
    H5close();
    if ((file = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
    if (H5Lcreate_external("another_file", "another_obj", file, "ext_link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if (H5Fclose(file) < 0) TEST_ERROR

    if(HDremove(filename) != 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Fclose(file);
    } H5E_END_TRY;
    return -1;
} /* end external_reset_register() */


#ifdef H5_HAVE_WINDOW_PATH

/*-------------------------------------------------------------------------
 * Function:    external_link_win1
 *
 * Purpose:
 *   		1. target link: "/CWD/tmp/extlinks10"
 *		2. main file: "extlinks0"
 *		3. target file: "extlinks10"
 *		Should be able to find the target file via main file's current drive/rel path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April 15, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win1(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's current drive/rel path(windows)(w/new group format)")
    else
        TESTING("external links via main file's current drive/rel path(windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
        TEST_ERROR

    /* set up name for target link: "/CWD/tmp/extlinks10" */
    HDstrcpy(tmpname, &cwdpath[2]); /* stripped the drive letter to make it rel drive but absolute path */
    HDstrcat(tmpname, "/");
    HDstrcat(tmpname, FILENAME[30]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "extlinks10" */
    h5_fixname(FILENAME[29], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via main file's CWD*/
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in CWD.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win1() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win2
 *
 * Purpose:
 *   		1. target link: "/CWD/tmp/extlinks11"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks11"
 *		Should be able to access the target file directly (rel drive/abs path)
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April 15, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win2(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via target's rel drive/abs path directly(windows)(w/new group format)")
    else
        TESTING("external links via target's rel drive/abs path directly(windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

     /* create tmp directory and get current working directory path */
    if((HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST) || (NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE)))
        TEST_ERROR

    /* set up name for target link: "/CWD/tmp/extlinks11" */
    HDstrcpy(tmpname, &cwdpath[2]); /* stripped the drive letter to make it relative drive but absolute path */
    HDstrcat(tmpname, "/");
    HDstrcat(tmpname, FILENAME[31]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks11" */
    h5_fixname(FILENAME[31], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file directly */
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win2() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win3
 *
 * Purpose:
 *   		1. target link: "<cur drive>:tmp/extlinks12"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks12"
 *		Should be able to access the target file directly (abs drive/rel path)
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April i15 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win3(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    int		drive=0;
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via target's abs drive/rel path directly (windows)(w/new group format)")
    else
        TESTING("external links via target's abs drive/rel path directly (windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    /* create tmp directory */
    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR

    /* set up name for target link: "<drive-letter>:tmp/extlinks12" */
    drive = HDgetdrive();
    sprintf(tmpname, "%c:%s", (drive+'A'-1), FILENAME[32]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks12" */
    h5_fixname(FILENAME[32], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file directly */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win3() */

/*-------------------------------------------------------------------------
 * Function:    external_link_win4
 *
 * Purpose:
 *   		1. target link: "<cur drive>:extlinks13"
 *		2. main file: "<cur-drive>:tmp/extlinks0"
 *		3. target file: tmp/extlinks13
 *		Should be able to access the target file via main file's abs drive/rel path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April 15, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win4(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    int		drive=0;
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's abs drive/rel path (windows)(w/new group format)")
    else
        TESTING("external links via main file's abs drive/rel path (windows)")

    /* set up name for main file: "<drive-letter>:tmp/extlinks0" */
    drive = HDgetdrive();
    sprintf(tmpname, "%c:%s", (drive+'A'-1), FILENAME[13]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* set up name for target link: "<drive-letter>:extlinks13" */
    sprintf(tmpname, "%c:%s", (drive+'A'-1), FILENAME[33]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks13" */
    h5_fixname(FILENAME[34], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via main file's absolute drive/relative path */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in CWD.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win4() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win5
 *
 * Purpose:
 *   		1. target link: "<cur drive+1>:tmp/extlinks14"
 *		2. main file: "/CWD/extlinks0"
 *		3. target file: "tmp/extlinks14"
 *		Should be able to access the target file via main file's relative drive/absolute path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April 15, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win5(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    int		drive=0;
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's rel drive/abs path (windows)(w/new group format)")
    else
        TESTING("external links via main file's rel drive/abs path (windows)")

    if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
        TEST_ERROR
    drive = HDgetdrive();

    /* set up name for main file: "/CWD/extlinks0" */
    HDstrcpy(tmpname, &cwdpath[2]); /* stripped the drive letter to make it rel drive but absolute path */
    HDstrcat(tmpname, "/");
    HDstrcat(tmpname, FILENAME[12]);
    h5_fixname(tmpname, fapl, filename1, sizeof filename1);

    /* set up name for target link: "<drive-letter+1>:tmp/extlinks14" */
    sprintf(tmpname, "%c:%s", ((drive+1)+'A'-1), FILENAME[35]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks14" */
    h5_fixname(FILENAME[35], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via main file's rel drive/abs path */
    if(gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in CWD.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win5() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win6
 *
 * Purpose:
 *   		1. target link: "<cur drive+1>:tmp/extlinks15"
 *		2. main file: "extlinks0"
 *		3. target file: "tmp/extlinks15"
 *		Should be able to access the target file via target's current drive/rel path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Vailin Choi
 *              April 15, 2008
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win6(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    int		drive=0;
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
		tmpname[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via target's current drive/rel path (windows)(w/new group format)")
    else
        TESTING("external links via target's current drive/rel path (windows)")

    /* create tmp directory */
    if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR
    drive = HDgetdrive();

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    /* set up name for target link: "<drive-letter+1>:tmp/extlinks15" */
    sprintf(tmpname, "%c:%s", ((drive+1)+'A'-1), FILENAME[36]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "tmp/extlinks15" */
    h5_fixname(FILENAME[36], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via target file's rel path in current drive */
    if (gid < 0) {
	H5_FAILED();
	HDputs("    Should have found the file in tmp.");
	goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
	H5Gclose (gid);
	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win6() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win7
 *
 * Purpose:
 *      1. UNC target link: "\\127.0.01\c$/tmp/extlinks10"
 *      2. main file: "extlinks0"
 *      3. target file: "extlinks15"
 *      Should be able to find the target file via main file's local host/main drive/rel path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *-------------------------------------------------------------------------
 */
static int
external_link_win7(hid_t fapl, hbool_t new_format)
{
    hid_t   fid = (-1);             /* File ID */
    hid_t   gid = (-1);                 /* Group IDs */
    char    filename1[NAME_BUF_SIZE],
            filename2[NAME_BUF_SIZE],
            filename3[NAME_BUF_SIZE],
            tmpname[NAME_BUF_SIZE],
            cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's UNC local host/main drive/rel path(windows)(w/new group format)")
    else
        TESTING("external links via main file's UNC local host/main drive/rel path(windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
        TEST_ERROR

    /* set up name for target link: "\\127.0.0.1\c$/tmp/extlinks10" */
    HDstrcpy(tmpname, "\\\\127.0.0.1\\c$"); /* absolute path */
    HDstrcat(tmpname, "/");
    HDstrcat(tmpname, FILENAME[30]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "extlinks15" */
    h5_fixname(FILENAME[29], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via main file's local host/main drive*/
    if(gid < 0) {
        H5_FAILED();
        HDputs("    Should have found the file in local host/main drive.");
        goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    H5Gclose (gid);
    H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win7() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win8
 *
 * Purpose:
 *      1. Long UNC target link: "\\?\<cur drive>:\CWD\extlinks10"
 *      2. main file: "extlinks0"
 *      3. target file: "extlinks10"
 *      Should be able to access the target file directly (abs drive/abs path)
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_win8(hid_t fapl, hbool_t new_format)
{
    hid_t   fid = (-1);             /* File ID */
    hid_t   gid = (-1);                 /* Group IDs */
    int     drive=0;
    char    filename1[NAME_BUF_SIZE],
            filename2[NAME_BUF_SIZE],
            filename3[NAME_BUF_SIZE],
            tmpname[NAME_BUF_SIZE],
            cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via target's Long UNC abs drive/abs path directly (windows)(w/new group format)")
    else
        TESTING("external links via target's Long UNC abs drive/abs path directly (windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
        TEST_ERROR

    /* create tmp directory */
    if(HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
        TEST_ERROR

    /* set up name for target link: "<drive-letter>:\CWD\extlinks10" */
    drive = HDgetdrive();
    sprintf(tmpname, "\\\\?\\%c:%s\\%s", (drive+'A'-1), &cwdpath[2], FILENAME[30]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "extlinks10" */
    h5_fixname(FILENAME[30], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file directly */
    if(gid < 0) {
        H5_FAILED();
        HDputs("    Should have found the file in tmp.");
        goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    H5Gclose (gid);
    H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win8() */


/*-------------------------------------------------------------------------
 * Function:    external_link_win9
 *
 * Purpose:
 *      1. Long UNC target link: "\\?\UNC\127.0.01\c$/tmp/extlinks10"
 *      2. main file: "extlinks0"
 *      3. target file: "extlinks15"
 *      Should be able to find the target file via main file's local host/main drive/rel path
 *
 * Return:      Success:        0
 *              Failure:        -1
 *-------------------------------------------------------------------------
 */
static int
external_link_win9(hid_t fapl, hbool_t new_format)
{
    hid_t   fid = (-1);             /* File ID */
    hid_t   gid = (-1);                 /* Group IDs */
    char    filename1[NAME_BUF_SIZE],
            filename2[NAME_BUF_SIZE],
            filename3[NAME_BUF_SIZE],
        tmpname[NAME_BUF_SIZE],
                cwdpath[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external links via main file's Long UNC local host/main drive/rel path(windows)(w/new group format)")
    else
        TESTING("external links via main file's Long UNC local host/main drive/rel path(windows)")

    /* set up name for main file: "extlinks0" */
    h5_fixname(FILENAME[12], fapl, filename1, sizeof filename1);

    if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
        TEST_ERROR

    /* set up name for target link: "\\?\UNC\127.0.0.1\c$/tmp/extlinks10" */
    HDstrcpy(tmpname, "\\\\?\\UNC\127.0.0.1\\c$"); /* absolute path */
    HDstrcat(tmpname, "/");
    HDstrcat(tmpname, FILENAME[30]);
    h5_fixname(tmpname, fapl, filename2, sizeof filename2);

    /* set up name for target file: "extlinks15" */
    h5_fixname(FILENAME[29], fapl, filename3, sizeof filename3);

    /* Create the target file */
    if((fid = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* closing for target file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Create the main file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link to target file */
    if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open object through external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
    } H5E_END_TRY;

    /* should be able to find the target file via main file's local host/main drive*/
    if(gid < 0) {
        H5_FAILED();
        HDputs("    Should have found the file in local host/main drive.");
        goto error;
    }

    /* closing for main file */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    H5Gclose (gid);
    H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_win9() */

#endif /* H5_HAVE_WINDOW_PATH */


/*-------------------------------------------------------------------------
 * Function:    external_link_recursive
 *
 * Purpose:     Build a file with "recursive" external link
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, August 15, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_recursive(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    char	filename1[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("recursive external links (w/new group format)")
    else
        TESTING("recursive external links")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);

    /* Create first file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create recursive external links */
    if(H5Lcreate_external(filename1, "/recursive", fid, "recursive", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open file */
    if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open object through dangling file external link */
    H5E_BEGIN_TRY {
        gid = H5Gopen2(fid, "recursive", H5P_DEFAULT);
    } H5E_END_TRY;
    if (gid >= 0) {
	H5_FAILED();
	HDputs("    Should have failed for recursive external links.");
	goto error;
    }

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_recursive() */


/*-------------------------------------------------------------------------
 * Function:    external_link_query
 *
 * Purpose:     Query file & object names for external links, as well as
 *              information from H5Gget_obj_info
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, August 15, 2005
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_query(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group IDs */
    const char *file_name;                      /* Name of the file the external link points to */
    const char *object_name;                    /* Name of the object the external link points to */
    H5O_info_t	oi;                             /* Object information */
    H5L_info_t  li;                             /* Link information */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE],       /* Names of files to externally link across */
                query_buf[NAME_BUF_SIZE];       /* Buffer to hold query result */

    if(new_format)
        TESTING("query aspects of external link (w/new group format)")
    else
        TESTING("query aspects of external link")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file, with external link to object in second file */
    if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link */
    /* (add a few extra '/'s to make certain library normalizes external link object names) */
    if(H5Lcreate_external(filename2, "///dst//", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Get size of buffer for external link */
    if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR
    if (H5L_TYPE_EXTERNAL != li.type) {
	H5_FAILED();
	HDputs("    Unexpected link class - should have been an external link");
	goto error;
    }

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object to link to */
    if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Get size of buffer for external link */
    if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.u.val_size != (1 + (HDstrlen(filename2) + 1) + (HDstrlen("/dst") + 1))) TEST_ERROR
    if(H5L_TYPE_EXTERNAL != li.type) {
	H5_FAILED();
	HDputs("    Unexpected link class - should have been an external link");
	goto error;
    }

    /* Get information for external link.  It should be two strings right after each other */
    if(H5Lget_val(fid, "src", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR

    /* Extract the file and object names from the buffer */
    if(H5Lunpack_elink_val(query_buf, li.u.val_size, NULL, &file_name, &object_name) < 0) TEST_ERROR

    /* Compare the file and object names */
    if(HDstrcmp(file_name, filename2)) TEST_ERROR
    if(HDstrcmp(object_name, "/dst")) TEST_ERROR

    /* Query information about object that external link points to */
    if(H5Oget_info_by_name(fid, "src", &oi, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5O_TYPE_GROUP != oi.type) {
	H5_FAILED();
	HDputs("    Unexpected object type - should have been a group");
	goto error;
    }

    /* Close first file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Make sure that passing in NULLs to H5Lunpack_elink_val works */
    if(H5Lunpack_elink_val(query_buf, li.u.val_size, NULL, NULL, NULL) < 0) TEST_ERROR

    /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */
    H5E_BEGIN_TRY {
      if(H5Lunpack_elink_val(query_buf, li.u.val_size - 1, NULL, NULL, NULL) >= 0) TEST_ERROR
    } H5E_END_TRY
    H5E_BEGIN_TRY {
      if(H5Lunpack_elink_val(query_buf, (size_t)0, NULL, NULL, NULL) >= 0) TEST_ERROR
    } H5E_END_TRY
    H5E_BEGIN_TRY {
      if(H5Lunpack_elink_val(NULL, (size_t)0, NULL, NULL, NULL) >= 0) TEST_ERROR
    } H5E_END_TRY
    H5E_BEGIN_TRY {
      if(H5Lunpack_elink_val(NULL, (size_t)1000, NULL, NULL, NULL) >= 0) TEST_ERROR
    } H5E_END_TRY

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_query() */


/*-------------------------------------------------------------------------
 * Function:    external_link_unlink_compact
 *
 * Purpose:     Remove an external link (from a compact group)
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, January 18, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_unlink_compact(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("unlinking external link in compact group (w/new group format)")
    else
        TESTING("unlinking external link in compact group")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file, with external link to object in second file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link */
    if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object to link to */
    if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


/* Unlink external link */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Unlink external link */
    if(H5Ldelete(fid, "src", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group for external link */
    if((gid = H5Gopen2(fid, "dst", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_unlink_compact() */


/*-------------------------------------------------------------------------
 * Function:    external_link_unlink_dense
 *
 * Purpose:     Remove an external link (from a dense group)
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, January 18, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_unlink_dense(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t       gcpl = (-1);                    /* Group creation property list ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */
    unsigned	nmsgs;		                /* Number of messages in group's header */
    unsigned    max_compact;                    /* Maximum # of links to store in group compactly */
    unsigned    min_dense;                      /* Minimum # of links to store in group "densely" */
    unsigned    u;                              /* Local index variable */

    if(new_format)
        TESTING("unlinking external link in dense group (w/new group format)")
    else
        TESTING("unlinking external link in dense group")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file, with external link to object in second file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Open root group */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) != TRUE) TEST_ERROR

    /* Query the group creation properties */
    if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
    if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Create external link */
    /* (This also covers the case of having an external link in a compact group that's converted to a dense group) */
    if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR
    if(nmsgs != 1) TEST_ERROR
    if(H5G__has_stab_test(gid) == TRUE) TEST_ERROR

    /* Create enough objects in the root group to change it into a "dense" group */
    for(u = 0; u < max_compact; u++) {
        sprintf(objname, "filler %u", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(gid2) < 0) TEST_ERROR
    } /* end for */

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, NULL) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(gid) != TRUE) TEST_ERROR

    /* Close group creation property list */
    if(H5Pclose(gcpl) < 0) TEST_ERROR

    /* Close root group */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object to link to */
    if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


/* Unlink external link */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Open root group */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Unlink external link */
    if(H5Ldelete(fid, "src", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Remove enough objects in the root group to change it into a "compact" group */
    for(u = 0; u < ((max_compact - min_dense) + 1); u++) {
        sprintf(objname, "filler %u", u);
        if(H5Ldelete(gid, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR
    if(nmsgs != (min_dense - 1)) TEST_ERROR
    if(H5G__is_new_dense_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(gid) == TRUE) TEST_ERROR

    /* Close root group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group for external link (should be unaffected) */
    if((gid = H5Gopen2(fid, "dst", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_unlink_dense() */


/*-------------------------------------------------------------------------
 * Function:    external_link_move
 *
 * Purpose:     Move/rename external link
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, December  5, 2005
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_move(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */

    if(new_format)
        TESTING("move external link (w/new group format)")
    else
        TESTING("move external link")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file, with external link to object in second file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create external link */
    if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object to link to */
    if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


/* Move external link to different name within same group */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Move external link within same group */
    if(H5Lmove(fid, "src", H5L_SAME_LOC, "src2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "src2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group created through external link */
    if((gid = H5Gopen2(fid, "dst/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

/* Move external link to different group */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Create another group, to move the external link into */
    if((gid = H5Gcreate2(fid, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Move external link to different group */
    if(H5Lmove(fid, "src2", gid, "src3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close new group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "/group2/src3", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group created through external link */
    if((gid = H5Gopen2(fid, "dst/new_group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

/* Move external link back to original group */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "/group2/src3", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Move external link back to original location */
    if(H5Lmove(fid, "/group2/src3", H5L_SAME_LOC, "/src", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group created through external link */
    if((gid = H5Gopen2(fid, "dst/new_group3", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_move() */


/*-------------------------------------------------------------------------
 * Function:    external_link_ride
 *
 * Purpose:     Let an external link "come along for the ride" when a group is
 *              converted between compact & dense forms.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, January 18, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_ride(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t       gcpl = (-1);                    /* Group creation property list ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
    		filename2[NAME_BUF_SIZE];       /* Names of files to externally link across */
    unsigned	nmsgs;		                /* Number of messages in group's header */
    unsigned    max_compact;                    /* Maximum # of links to store in group compactly */
    unsigned    min_dense;                      /* Minimum # of links to store in group "densely" */
    unsigned    u;                              /* Local index variable */

    if(new_format)
        TESTING("external link along for the ride (w/new group format)")
    else
        TESTING("external link along for the ride")

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);

    /* Create first file, with external link to object in second file */
    if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Open root group */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) != TRUE) TEST_ERROR

    /* Query the group creation properties */
    if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
    if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Create enough objects in the root group to change it into a "dense" group */
    for(u = 0; u < (max_compact + 1); u++) {
        sprintf(objname, "filler %u", u);
        if((gid2 = H5Gcreate2(gid, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(gid2) < 0) TEST_ERROR
    } /* end for */

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, NULL) == TRUE) TEST_ERROR
    if(new_format) {
        if(H5G__is_new_dense_test(gid) != TRUE) TEST_ERROR
    } /* end if */
    else {
        if(H5G__has_stab_test(gid) != TRUE) TEST_ERROR
    } /* end else */

    /* Create external link */
    /* (This also covers the case of adding an external link to a dense group) */
    if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, NULL) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(gid) != TRUE) TEST_ERROR

    /* Close group creation property list */
    if(H5Pclose(gcpl) < 0) TEST_ERROR

    /* Close root group */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Create second file to point to */
    if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create object to link to */
    if((gid = H5Gcreate2(fid, "dst", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

/* Remove enough objects to convert group containing external link back into compact form */

    /* Open first file */
    if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "src", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Open root group */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Remove enough objects in the root group to change it into a "compact" group */
    for(u = 0; u < ((max_compact - min_dense) + 3); u++) {
        sprintf(objname, "filler %u", u);
        if(H5Ldelete(gid, objname, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    } /* end for */

    /* Check on root group's status */
    if(H5G__is_empty_test(gid) == TRUE) TEST_ERROR
    if(H5G__has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR
    if(nmsgs != (min_dense - 1)) TEST_ERROR
    if(H5G__has_stab_test(gid) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(gid) == TRUE) TEST_ERROR

    /* Close root group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Open object through external link */
    if((gid = H5Gopen2(fid, "src", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/dst")) TEST_ERROR

    /* Create object in external file */
    if((gid2 = H5Gcreate2(gid, "new_group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group in external file */
    if(H5Gclose(gid2) < 0) FAIL_STACK_ERROR

    /* Close external object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close first file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* Open second file */
    if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group created through external link */
    if((gid = H5Gopen2(fid, "dst/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Open group created through external link */
    if((gid = H5Gopen2(fid, "dst/new_group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl);
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end external_link_ride() */


/*-------------------------------------------------------------------------
 * Function:    external_link_closing
 *
 * Purpose:     Test that files are closed correctly when traversing
 *              external links.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Wednesday, August 16, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_closing(hid_t fapl, hbool_t new_format)
{
    hid_t       fid1 = (-1), fid2 = (-1), fid3 = (-1), fid4=(-1);
    hid_t       gid=(-1), tid=(-1), tid2=(-1), sid=(-1), did=(-1);
    hid_t       lcpl_id=(-1);
    hsize_t     dims[2];
    char	filename1[NAME_BUF_SIZE],
                filename2[NAME_BUF_SIZE],
    		filename3[NAME_BUF_SIZE],
    		filename4[NAME_BUF_SIZE],       /* Names of files to externally link across */
    		buf[NAME_BUF_SIZE];             /* misc. buffer */
    H5L_info_t  li;
    H5O_info_t  oi;
    hobj_ref_t  obj_ref;

    if(new_format)
        TESTING("that external files are closed during traversal (w/new group format)")
    else
        TESTING("that external files are closed during traversal")

    /* In this test, external links will go from file1 to file2 and from
     * file2 to file3.
     * Test that all functions that can traverse external files close
     * the files they open.
     * Test that providing unusual paths containing external links can't
     * make HDF5 forget to close a file it opened.
     */

    /* Set up filenames */
    h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
    h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3);
    h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4);

    /* Create four files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create a dataspace and a datatype so we can create/commit a dataset/datatype in the files */
    dims[0] = 2;
    dims[1] = 2;
    if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if((tid2 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR

    /* Create external links from each file to the next */
    if(H5Lcreate_external(filename2, "/", fid1, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename3, "/", fid2, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external(filename4, "/", fid3, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close all files but the first */
    if(H5Fclose(fid4) < 0) TEST_ERROR
    if(H5Fclose(fid3) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Test creating each kind of object */
    if((gid = H5Gcreate2(fid1, "elink/elink/elink/group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Tcommit2(fid1, "elink/elink/elink/type1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if((did = H5Dcreate2(fid1, "elink/elink/elink/dataset1", tid2, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close objects */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    /* Test that getting info works */
    if(H5Lget_info(fid1, "elink/elink/elink/type1", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(fid1, "elink/elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(fid1, "elink/elink/elink/type1", &oi, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Oget_info_by_name(fid1, "elink/elink/elink", &oi, H5P_DEFAULT) < 0) TEST_ERROR

    /* Test move */
    if(H5Lmove(fid1, "elink/elink/elink/group1", fid1,
        "elink/elink/elink/group1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open file 4 so we can do some fancy things */
    if((fid4 = H5Fopen(filename4, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR
    if(H5Lmove(fid1, "elink/elink/elink/type1", fid4,
        "type1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lmove(fid4, "dataset1", fid1,
        "elink/elink/elink/dataset1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file 4 again */
    if(H5Fclose(fid4) < 0) FAIL_STACK_ERROR

    /* Test copy (as of this test, it uses the same code as move) */
    if(H5Lcopy(fid1, "elink/elink/elink", fid1,
        "elink/elink/elink_copied", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcopy(fid1, "elink/elink/elink", fid1,
        "elink/elink/elink/elink_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Test H5Gset and get comment */
    if(H5Oset_comment_by_name(fid1, "elink/elink/elink/group1_moved", "comment", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Oget_comment_by_name(fid1, "elink/elink/elink/group1_moved", buf, sizeof(buf), H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(buf, "comment")) TEST_ERROR

    /* Test H5*open */
    if((gid = H5Gopen2(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((tid = H5Topen2(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((did = H5Dopen2(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    /* Close objects */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
    if(H5Tclose(tid) < 0) FAIL_STACK_ERROR
    if(H5Dclose(did) < 0) FAIL_STACK_ERROR

    /* Test H5*open2 */
    if((gid = H5Gopen2(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((tid = H5Topen2(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((did = H5Dopen2(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    /* Close objects */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
    if(H5Tclose(tid) < 0) FAIL_STACK_ERROR
    if(H5Dclose(did) < 0) FAIL_STACK_ERROR

    /* Test H5Oopen */
    if((did = H5Oopen(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    /* Test H5Fmount */
    if((gid = H5Gcreate2(fid1, "elink/elink/elink/mnt", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    H5E_BEGIN_TRY {
        if(H5Fmount(fid1, "elink/elink/elink/mnt", fid1, H5P_DEFAULT) >= 0) TEST_ERROR
        if(H5Funmount(fid1, "elink/elink/elink/mnt") >= 0) TEST_ERROR
    } H5E_END_TRY

    /* Test H5Rcreate */
    if(H5Rcreate(&obj_ref, fid1, "elink/elink/elink/type1_moved", H5R_OBJECT, (hid_t)(-1)) < 0) TEST_ERROR

    /* Test unlink */
    if(H5Ldelete(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(fid1, "elink/elink/elink_copied", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(fid1, "elink/elink/elink/elink_copied2", H5P_DEFAULT) < 0) TEST_ERROR

    /* We've tested that the various functions above don't leave files open.
        * Now test that we can't confuse HDF5 by giving unusual paths with external links
        */
    /* Create an external link that points to another external link */
    if((fid2 = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
    if(H5Lcreate_external(filename3, "/elink", fid2, "elink2",
            H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Do an external link traversal that recursively calls another external link. */
    if((gid = H5Gcreate2(fid1, "elink/elink2/group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Create two more groups so that the last three elements in the path are
        * all within the same external file
        */
    if((gid = H5Gcreate2(fid1, "elink/elink2/group2/group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid1, "elink/elink2/group2/group3/group4", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Oget_info_by_name(fid1, "elink/elink2/group2/group3/group4", &oi, H5P_DEFAULT) < 0) TEST_ERROR

    /* Add a few regular groups and a soft link in file2 using intermediate group creation */
    if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR
    if(H5Lcreate_soft("/elink2", fid1, "elink/file2group1/file2group2/slink",
                lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR

    /* Try to traverse this path.  There are three soft traversals in a row;
     * slink points to (file2)/elink2, which points to (file3)/elink, which
     * points to file 4.
     */
    if((gid = H5Gcreate2(fid1, "elink/file2group1/file2group2/slink/group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Lget_info(fid1, "elink/file2group1/file2group2/slink/group3", &li, H5P_DEFAULT) < 0) TEST_ERROR

    /* Some simpler tests */
    if((gid = H5Gcreate2(fid1, "elink/file2group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Lget_info(fid1, "elink/file2group3", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lget_info(fid1, "elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR


    /* Close file1, the only file that should still be open */
    if(H5Fclose(fid1) < 0) TEST_ERROR

    /* Re-create each file. If they are hanging open, these creates will fail */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Cleanup */
    if(H5Sclose(sid) < 0) TEST_ERROR
    if(H5Tclose(tid2) < 0) TEST_ERROR
    if(H5Fclose(fid4) < 0) TEST_ERROR
    if(H5Fclose(fid3) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR
    if(H5Fclose(fid1) < 0) TEST_ERROR

    PASSED();

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Tclose(tid);
        H5Dclose(did);
        H5Sclose(sid);
        H5Tclose(tid2);
        H5Fclose(fid4);
        H5Fclose(fid3);
        H5Fclose(fid2);
        H5Fclose(fid1);
    } H5E_END_TRY;
    return -1;
} /* external_link_closing() */


/*-------------------------------------------------------------------------
 * Function:    ext_link_endian
 *
 * Purpose:     Check that external links work properly when they are
 *              moved from big-endian to little-endian systems and
 *              vice versa.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_endian(hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    hid_t       lapl_id = (-1);                 /* Prop List ID */
    const char  *pathbuf = H5_get_srcdir();     /* Path to the files */
    const char  *namebuf;

    if(new_format)
        TESTING("endianness of external links (w/new group format)")
    else
        TESTING("endianness of external links")

    /* Create a link access property list with the path to the srcdir */
    if((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    if(H5Pset_elink_prefix(lapl_id, pathbuf) < 0) TEST_ERROR

    namebuf = H5_get_srcdir_filename(LE_FILENAME); /* Corrected test file name */

    /* Test LE file; try to open a group through the external link */
    if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
    if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR

    /* Open a group in the external file using that group ID */
    if((gid2 = H5Gopen2(gid, "subgroup", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close the IDs */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    namebuf = H5_get_srcdir_filename(BE_FILENAME); /* Corrected test file name */

    /* Test BE file; try to open a group through the external link */
    if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
    if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR

    /* Open a group in the external file using that group ID */
    if((gid2 = H5Gopen2(gid, "subgroup", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close the IDs */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();

    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
}


/*-------------------------------------------------------------------------
 * Function:    external_link_strong
 *
 * Purpose:     Check that external links work properly when they opened in
 *              a file with "strong" file close degree.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, March 5, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_strong(hid_t fapl, hbool_t new_format)
{
    hid_t       my_fapl = (-1);                 /* File access property list */
    hid_t       fid1 = (-1), fid2 = (-1);       /* File ID */
    hid_t       gid1 = (-1), gid2 = (-1);       /* Group IDs */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename1[NAME_BUF_SIZE],
                filename2[NAME_BUF_SIZE];

    if(new_format)
        TESTING("that external files work with strong file close degree (w/new group format)")
    else
        TESTING("that external files work with strong file close degree")

    /* Set up filenames */
    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);

    /* Copy file access property list */
    if((my_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR

    /* Set strong file close degree */
    if(H5Pset_fclose_degree(my_fapl, H5F_CLOSE_STRONG) < 0) TEST_ERROR

    /* Create a group at /A/B/C in first file */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0) TEST_ERROR
    if((gid1 = H5Gcreate2(fid1, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if((gid1 = H5Gcreate2(fid1, "A/B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if((gid1 = H5Gcreate2(fid1, "A/B/C", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if(H5Fclose(fid1) < 0) TEST_ERROR

    /* Create an external link /W/X/DLINK in second file to <filename1>:/A/B/C */
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid2 = H5Gcreate2(fid2, "/W", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if((gid2 = H5Gcreate2(fid2, "/W/X", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Lcreate_external(filename1, "/A/B/C", gid2, "DLINK", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Access external link from file #1 */
    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
    if((gid2 = H5Gopen2(fid2, "/W/X/DLINK", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Iget_name(gid2, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/A/B/C")) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Fclose(fid2) < 0) TEST_ERROR

    /* Close fapl */
    if(H5Pclose(my_fapl) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(my_fapl);
        H5Gclose(fapl);
        H5Gclose(gid2);
        H5Gclose(gid1);
        H5Fclose(fid2);
        H5Fclose(fid1);
    } H5E_END_TRY;
    return -1;
} /* end external_link_strong() */


/*-------------------------------------------------------------------------
 * Function:    external_symlink
 *
 * Purpose:     Verify functionality of external links when symlinks are
 *              used for parent/child files
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Nov. 23, 2009
 *
 *-------------------------------------------------------------------------
 */
static int
external_symlink(const char *env_h5_drvr, hid_t fapl, hbool_t new_format)
{
#ifdef H5_HAVE_SYMLINK
    hid_t       file1 = -1, file2 = -1, file3 = -1, file4 = -1, file5 = -1;
    hid_t       group2 = -1, group3 = -1, group4 = -1, group5 = -1;
    char	filename1[NAME_BUF_SIZE],
    		filename2a[NAME_BUF_SIZE],
    		filename2b[NAME_BUF_SIZE],
    		filename3a[NAME_BUF_SIZE],
    		filename3b[NAME_BUF_SIZE],
    		filename4a[NAME_BUF_SIZE],
    		filename4b[NAME_BUF_SIZE],
    		filename5a[NAME_BUF_SIZE],
    		filename5b[NAME_BUF_SIZE],
    		tmpname[NAME_BUF_SIZE],
    		cwdpath[NAME_BUF_SIZE];
    hbool_t     have_posix_compat_vfd;   /* Whether VFD used is compatible w/POSIX I/O calls */
#endif /* H5_HAVE_SYMLINK */

    if(new_format)
        TESTING("external links w/symlink files (w/new group format)")
    else
        TESTING("external links w/symlink files")

#ifdef H5_HAVE_SYMLINK
    /* Skip test when using VFDs that can't provide a POSIX compatible file
     *  descriptor.
     */
    have_posix_compat_vfd = (hbool_t)(!HDstrcmp(env_h5_drvr, "sec2")
            || !HDstrcmp(env_h5_drvr, "core")
            || !HDstrcmp(env_h5_drvr, "nomatch"));
    if(have_posix_compat_vfd) {
        /* set up name for main file: "extlinks21A" */
        h5_fixname(FILENAME[45], fapl, filename1, sizeof(filename1));

        /* create tmp directory and get current working directory path */
        if(HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
            TEST_ERROR
        if(HDmkdir(TMPDIR2, (mode_t)0755) < 0 && errno != EEXIST)
            TEST_ERROR
        if(NULL == HDgetcwd(cwdpath, (size_t)NAME_BUF_SIZE))
            TEST_ERROR

        /* Set up names for files in the subdirectories */

        /* set up names for file #2 in temporary directory #2: "tmp2/extlinks21B" */
        h5_fixname(FILENAME[46], fapl, filename2a, sizeof(filename2a));
        fix_ext_filename(tmpname, cwdpath, FILENAME[46]);
        h5_fixname(tmpname, fapl, filename2b, sizeof(filename2b));

        /* Create symbolic link #1 in temporary directory #1 to file #2 in temporary directory #2 */
        /* (i.e. tmp/sym1.h5 -> <full path to>/tmp2/extlinks21B.h5) */
        if(HDsymlink(filename2b, SYMLINK1) < 0 && errno != EEXIST) TEST_ERROR

        /* set up name for file #3 in temporary directory #2: "tmp2/extlinks21C" */
        h5_fixname(FILENAME[47], fapl, filename3a, sizeof(filename3a));
        h5_fixname(FILENAME[48], fapl, filename3b, sizeof(filename3b));

        /* set up name for file #4 in temporary directory #1: "tmp/extlinks21D" */
        h5_fixname(FILENAME[49], fapl, filename4a, sizeof(filename4a));
        fix_ext_filename(tmpname, cwdpath, FILENAME[49]);
        h5_fixname(tmpname, fapl, filename4b, sizeof(filename4b));

        /* Create symbolic link #2 in temporary directory #2 to file #4 in temporary directory #1 */
        /* (i.e. tmp2/sym2.h5 -> <full path to>/tmp/extlinks21D.h5) */
        if(HDsymlink(filename4b, SYMLINK2) < 0 && errno != EEXIST) TEST_ERROR

        /* set up name for file #5 in temporary directory #1: "tmp/extlinks21E" */
        h5_fixname(FILENAME[50], fapl, filename5a, sizeof(filename5a));
        h5_fixname(FILENAME[51], fapl, filename5b, sizeof(filename5b));


        /* Create file #1 in current directory */
        if((file1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create external link to file & object in temporary directory #2, using symlink #1 name */
        if(H5Lcreate_external(SYMLINK1, "group2", file1, "extlink2-sym", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

        /* Close file #1 */
        if(H5Fclose(file1) < 0) TEST_ERROR


        /* Create file #2 in tmp directory #2 */
        if((file2 = H5Fcreate(filename2a, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
        if(H5Fclose(file2) < 0) TEST_ERROR

        /* Re-open file #2 in tmp directory through symlink */
        if((file2 = H5Fopen(SYMLINK1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

        /* Create group in file #2 in temporary directory */
        if((group2 = H5Gcreate2(file2, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create external link to file #3 & object in temporary directory #2 */
        if(H5Lcreate_external(filename3b, "group3", group2, "extlink3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

        /* Close group in file #2 */
        if(H5Gclose(group2) < 0) TEST_ERROR

        /* Close file #2 */
        if(H5Fclose(file2) < 0) TEST_ERROR


        /* Create file #3 in temp. directory #2 */
        if((file3 = H5Fcreate(filename3a, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group in file #3 */
        if((group3 = H5Gcreate2(file3, "group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create external link to file & object in temporary directory #1, using symlink #2 name */
        if(H5Lcreate_external(SYMLINK2, "group4", group3, "extlink4-sym", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

        /* Close group in file #3 */
        if(H5Gclose(group3) < 0) TEST_ERROR

        /* Close file #3 */
        if(H5Fclose(file3) < 0) TEST_ERROR


        /* Create file #4 in temporary directory #1 */
        if((file4 = H5Fcreate(filename4b, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group in file #4 in 'temporary' directory */
        if((group4 = H5Gcreate2(file4, "group4", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create external link to file #5 & object in temporary directory #1 */
        if(H5Lcreate_external(filename5b, "group5", group4, "extlink5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

        /* Close group in file #4 */
        if(H5Gclose(group4) < 0) TEST_ERROR

        /* Close file #4 */
        if(H5Fclose(file4) < 0) TEST_ERROR


        /* Create file #5 in temporary directory #1 */
        if((file5 = H5Fcreate(filename5a, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group in file #5 in 'temporary' directory #1 */
        if((group5 = H5Gcreate2(file5, "group5", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group5) < 0) TEST_ERROR

        /* Close file #5 */
        if(H5Fclose(file5) < 0) TEST_ERROR


        /* Actual tests... */

        /* Reopen file #1 */
        if((file1 = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

        /* Open group in file #2, through external link w/symlink */
        if((group2 = H5Gopen2(file1, "extlink2-sym", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(group2) < 0) TEST_ERROR

        /* Open group in file #3, through external link w/symlink to external link */
        if((group3 = H5Gopen2(file1, "extlink2-sym/extlink3", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(group3) < 0) TEST_ERROR

        /* Open group in file #4, through external link w/symlink to external link w/symlink */
        if((group4 = H5Gopen2(file1, "extlink2-sym/extlink3/extlink4-sym", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(group4) < 0) TEST_ERROR

        /* Open group in file #5, through external link w/symlink to external link w/symlink to external link */
        if((group5 = H5Gopen2(file1, "extlink2-sym/extlink3/extlink4-sym/extlink5", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
        if(H5Gclose(group5) < 0) TEST_ERROR

        /* Close file #1 */
        if(H5Fclose(file1) < 0) TEST_ERROR


        PASSED();
    } /* end if */
    else {
	SKIPPED();
	HDputs("    Current VFD doesn't support POSIX I/O calls");
    } /* end else */

    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Gclose(group5);
        H5Gclose(group4);
        H5Gclose(group3);
        H5Gclose(group2);
        H5Fclose(file5);
        H5Fclose(file4);
        H5Fclose(file3);
        H5Fclose(file2);
        H5Fclose(file1);
    } H5E_END_TRY;
    return -1;
#else /* H5_HAVE_SYMLINK */
    SKIPPED();
    HDputs("    Current file system or operating system doesn't support symbolic links");

    return 0;
#endif /* H5_HAVE_SYMLINK */
} /* end external_symlink() */


/*-------------------------------------------------------------------------
 * Function:    external_copy_invalid_object
 *
 * Purpose:     Check that attempting to copy an object through an
 *              external link to the source file but with an invalid
 *              object name fails gracefully, and does not leave lingering
 *              file ids.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Wednesday, March 3, 2010
 *
 *-------------------------------------------------------------------------
 */
static int
external_copy_invalid_object(hid_t fapl, hbool_t new_format)
{
    hid_t       fid = (-1);                     /* File ID */
    hid_t       gid = (-1);                     /* Group ID */
    hid_t       ocpyplid = (-1);                /* Object copy plist ID */
    char        filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("copying invalid external links to the source file (w/new group format)")
    else
        TESTING("copying invalid external links to the source file")

    /* Set up filename */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    /* Create object copy plist, set expand external flag */
    if((ocpyplid = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
    if(H5Pset_copy_object(ocpyplid, H5O_COPY_EXPAND_EXT_LINK_FLAG) < 0) TEST_ERROR

    /* Create file and group */
    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Create an external link in the group to the source file with an invalid
     * object name */
    if(H5Lcreate_external(filename, "no_object", fid, "/group1/link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Copy the group containing the external link */
    if(H5Ocopy(fid, "group1", fid, "group2", ocpyplid, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Attempt to truncate the file again.  If there is a lingering id for this
     * file this will fail */
    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Close */
    if(H5Fclose(fid) < 0) TEST_ERROR
    if(H5Pclose(ocpyplid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
        H5Pclose(ocpyplid);
    } H5E_END_TRY

    return -1;
} /* end external_copy_invalid_object */


/*-------------------------------------------------------------------------
 * Function:    external_dont_fail_to_source
 *
 * Purpose:     Check that external links with invalid target file names
 *              work properly and do not attempt to (re)open the source
 *              file.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Wednesday, March 3, 2010
 *
 *-------------------------------------------------------------------------
 */
static int
external_dont_fail_to_source(hid_t fapl, hbool_t new_format)
{
    hid_t       fid = (-1);                     /* File ID */
    hid_t       gid = (-1);                     /* Group ID */
    hid_t       oid = (-1);                     /* Object ID */
    char        filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("that invalid external links don't open the source file (w/new group format)")
    else
        TESTING("that invalid external links don't open the source file")

    /* Set up filename */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    /* Create file and group */
    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Create an external link with an invalid file name, but the same object
     * name as the group.  This way, if the external link is interpreted to
     * refer to the source file, it will link to the group */
    if(H5Lcreate_external("no_file", "/group", fid, "link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Attempt to open the object the link points to.  This should fail */
    H5E_BEGIN_TRY {
        oid = H5Oopen(fid, "link", H5P_DEFAULT);
    } H5E_END_TRY
    if(oid >= 0) FAIL_PUTS_ERROR("Succeeded in opening target of invalid external link")

    /* Close */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Oclose(oid);
        H5Fclose(fid);
    } H5E_END_TRY

    return -1;
} /* end external_dont_fail_to_source */


/*-------------------------------------------------------------------------
 * Function:    external_file_cache
 *
 * Purpose:     Tests that the external file cache works with external
 *              links in a few basic cases.  More complicated cases are
 *              tested by interfacing directly with the cache in efc.c.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Thursday, January 13, 2011
 *
 *-------------------------------------------------------------------------
 */
static int
external_file_cache(hid_t fapl, hbool_t new_format)
{
    hid_t       my_fapl = (-1);                 /* Temporary FAPL */
    hid_t       fid1 = (-1);                    /* File ID */
    hid_t       fid2 = (-1);                    /* File ID */
    hid_t       fid3 = (-1);                    /* File ID */
    hid_t       fid4 = (-1);                    /* File ID */
    hid_t       oid = (-1);                     /* Object ID */
    unsigned    efc_size;
    char        filename1[NAME_BUF_SIZE];
    char        filename2[NAME_BUF_SIZE];
    char        filename3[NAME_BUF_SIZE];
    char        filename4[NAME_BUF_SIZE];

    if(new_format)
        TESTING("external file cache with external links (w/new group format)")
    else
        TESTING("external file cache with external links")

    /* Set up filenames */
    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
    h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
    h5_fixname(FILENAME[3], fapl, filename4, sizeof filename4);

    /* Verify that the default EFC size is 0 */
    if(H5Pget_elink_file_cache_size(fapl, &efc_size) < 0)
        TEST_ERROR
    if(efc_size != 0)
        FAIL_PUTS_ERROR("default external file cache size is not 0")

    /* Copy FAPL and enable external file caching */
    if((my_fapl = H5Pcopy(fapl)) < 0)
        TEST_ERROR
    if(H5Pset_elink_file_cache_size(my_fapl, 8) < 0)
        TEST_ERROR

    /* Verify that the external file cache size has been set */
    if(H5Pget_elink_file_cache_size(my_fapl, &efc_size) < 0)
        TEST_ERROR
    if(efc_size != 8)
        FAIL_PUTS_ERROR("external file cache size different from expected")


    /*
     * Test 1: One file caches another
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close the target of the external link */
    if((oid = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that both files are now open */
    H5F_sfile_assert_num(2);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 2: One file caches another, release parent's EFC
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close the target of the external link */
    if((oid = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that both files are now open */
    H5F_sfile_assert_num(2);

    /* Release file 1's EFC */
    if(H5Fclear_elink_file_cache(fid1) < 0)
        TEST_ERROR

    /* Verify that only the parent file is now open */
    H5F_sfile_assert_num(1);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 3: "Y" shaped tree
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create links */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename3, "/", fid2, "link_to_3", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename4, "/", fid2, "link_to_4", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close files 2-4 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR
    if(H5Fclose(fid3) < 0)
        TEST_ERROR
    if(H5Fclose(fid4) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close one branch of the tree */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_3", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that files 2 and 3 are now open */
    H5F_sfile_assert_num(3);

    /* Open and close the other branch of the tree */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_4", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that all files are now open */
    H5F_sfile_assert_num(4);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that all files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 4: "Y" shaped tree, release parent's EFC
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create links */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename3, "/", fid2, "link_to_3", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename4, "/", fid2, "link_to_4", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close files 2-4 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR
    if(H5Fclose(fid3) < 0)
        TEST_ERROR
    if(H5Fclose(fid4) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close one branch of the tree */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_3", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that files 2 and 3 are now open */
    H5F_sfile_assert_num(3);

    /* Open and close the other branch of the tree */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_4", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that all files are now open */
    H5F_sfile_assert_num(4);

    /* Release file 1's EFC */
    if(H5Fclear_elink_file_cache(fid1) < 0)
        TEST_ERROR

    /* Verify that only file 1 is now open */
    H5F_sfile_assert_num(1);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that all files are now closed */
    H5F_sfile_assert_num(0);

    /*
     * Test 5: 3 file cycle
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create links */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename3, "/", fid2, "link_to_3", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename1, "/", fid3, "link_to_1", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close files 2-3 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR
    if(H5Fclose(fid3) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close one complete cycle */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_3/link_to_1", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that all files are now open */
    H5F_sfile_assert_num(3);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that all files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 6: 3 file cycle, release parent's EFC
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR
    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        TEST_ERROR

    /* Create links */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename3, "/", fid2, "link_to_3", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_external(filename1, "/", fid3, "link_to_1", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close files 2-3 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR
    if(H5Fclose(fid3) < 0)
        TEST_ERROR

    /* Verify that only 1 file is open */
    H5F_sfile_assert_num(1);

    /* Open and close one complete cycle */
    if((oid = H5Oopen(fid1, "link_to_2/link_to_3/link_to_1", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Oclose(oid) < 0)
        TEST_ERROR

    /* Verify that all files are now open */
    H5F_sfile_assert_num(3);

    /* Release file 1's EFC */
    if(H5Fclear_elink_file_cache(fid1) < 0)
        TEST_ERROR

    /* Verify that only file 1 is now open */
    H5F_sfile_assert_num(1);

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that all files are now closed */
    H5F_sfile_assert_num(0);

    /* Close fapl */
    H5Pclose(my_fapl);

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Oclose(oid);
        H5Fclose(fid1);
        H5Fclose(fid2);
        H5Fclose(fid3);
        H5Fclose(fid4);
        H5Pclose(my_fapl);
    } H5E_END_TRY

    return -1;
} /* end external_file_cache */


/*-------------------------------------------------------------------------
 * Function:    external_open_twice
 *
 * Purpose:     Test opening the same object twice, both times through an
 *              external links.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Saturday, April 30, 2011
 *
 *-------------------------------------------------------------------------
 */
static int
external_open_twice(hid_t fapl, hbool_t new_format)
{
    hid_t       fid1 = (-1);                    /* File ID */
    hid_t       fid2 = (-1);                    /* File ID */
    hid_t       oid1 = (-1);                    /* Object ID */
    hid_t       oid2 = (-1);                    /* Object ID */
    hid_t       type = (-1);                    /* Datatype ID */
    hid_t       space = (-1);                   /* Dataspace ID */
    char        filename1[NAME_BUF_SIZE];
    char        filename2[NAME_BUF_SIZE];

    if(new_format)
        TESTING("opening object twice through elink (w/new group format)")
    else
        TESTING("opening object twice through elink")

    /* Set up filenames */
    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);


    /*
     * Test 1: Open root group twice
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Open the target of the external link twice */
    if((oid1 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if((oid2 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR

    /* Close both objects, in the reverse opening order (necessary to duplicate
     * bug */
    if(H5Oclose(oid2) < 0)
        TEST_ERROR
    if(H5Oclose(oid1) < 0)
        TEST_ERROR

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 2: Open group twice
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create target group */
    if((oid1 = H5Gcreate2(fid2, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))
            < 0)
        TEST_ERROR
    if(H5Gclose(oid1) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/group", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Open the target of the external link twice */
    if((oid1 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if((oid2 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR

    /* Close both objects, in the reverse opening order (necessary to duplicate
     * bug */
    if(H5Oclose(oid2) < 0)
        TEST_ERROR
    if(H5Oclose(oid1) < 0)
        TEST_ERROR

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 3: Open dataset twice
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create target dataset */
    if((space = H5Screate(H5S_SCALAR)) < 0)
        TEST_ERROR
    if((oid1 = H5Dcreate2(fid2, "dset", H5T_NATIVE_INT, space, H5P_DEFAULT,
            H5P_DEFAULT, H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Dclose(oid1) < 0)
        TEST_ERROR
    if(H5Sclose(space) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/dset", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Open the target of the external link twice */
    if((oid1 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if((oid2 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR

    /* Close both objects, in the reverse opening order (necessary to duplicate
     * bug */
    if(H5Oclose(oid2) < 0)
        TEST_ERROR
    if(H5Oclose(oid1) < 0)
        TEST_ERROR

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    /*
     * Test 4: Open datatype twice
     */
    /* Create files */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create target datatype */
    if((type = H5Tcopy(H5T_NATIVE_INT)) < 0)
        TEST_ERROR
    if(H5Tcommit2(fid2, "dtype", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)
            < 0)
        TEST_ERROR
    if(H5Tclose(type) < 0)
        TEST_ERROR

    /* Create link */
    if(H5Lcreate_external(filename2, "/dtype", fid1, "link_to_2", H5P_DEFAULT,
            H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file 2 */
    if(H5Fclose(fid2) < 0)
        TEST_ERROR

    /* Open the target of the external link twice */
    if((oid1 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR
    if((oid2 = H5Oopen(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        TEST_ERROR

    /* Close both objects, in the reverse opening order (necessary to duplicate
     * bug */
    if(H5Oclose(oid2) < 0)
        TEST_ERROR
    if(H5Oclose(oid1) < 0)
        TEST_ERROR

    /* Close file 1 */
    if(H5Fclose(fid1) < 0)
        TEST_ERROR

    /* Verify that both files are now closed */
    H5F_sfile_assert_num(0);


    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Oclose(oid1);
        H5Oclose(oid2);
        H5Tclose(type);
        H5Fclose(fid1);
        H5Fclose(fid2);
        H5Sclose(space);
    } H5E_END_TRY

    return -1;
} /* end external_open_twice() */


/*-------------------------------------------------------------------------
 * Function:    external_link_with_committed_datatype
 *
 * Purpose:     Test to verify the problem described in HDFFV-9940 is resolved.
 *              (A) Attach an attribute to an externally linked group in the target file.
 *              The attribute's datatype is a committed datatype to the root group
 *              in the main file.
 *              (B) Create a dataset to an externally group in the target file.
 *              The dataset's datatype is a committed datatype to the root group
 *              in the main file.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  This is copied and modified from the customer's test program that
 *              exposed the problem.
 *
 *-------------------------------------------------------------------------
 */
static int
external_link_with_committed_datatype(hid_t fapl, hbool_t new_format)
{
    hid_t       fid1 = -1, fid2 = -1;		/* File IDs */
    hid_t 	gid1 = -1, gid2 = -1;		/* Group IDs */
    hid_t       tid = -1;                    	/* Datatype ID */
    hid_t       sid = -1;                   	/* Dataspace ID */
    hid_t       sid2 = -1;                   	/* Dataspace ID */
    hid_t       aid = -1;                   	/* Attribute ID */
    hid_t       atid = -1;                   	/* Attribute's datatype ID */
    hid_t       did = -1;                   	/* Dataset ID */
    hid_t       dtid = -1;                   	/* Dataset's datatype ID */
    hid_t	dcpl = -1;			/* Dataset creation property list */
    int		wdata = 99;			/* Attribute data written */
    int		wbuf[60];			/* Data buffer for writing */
    int		rbuf[60];			/* Data buffer for reading */
    int		i;				/* Local index variable */
    char        filename1[NAME_BUF_SIZE];	/* File name for main file */
    char        filename2[NAME_BUF_SIZE];	/* File name for target file */
    hsize_t     dims[2] = {5, 12};		/* Dimension sizes */
    hsize_t     chunks[2] = {3, 7};		/* Chunk sizes */

    if(new_format)
        TESTING("attach committed datatype to external group's attribute/dataset(w/new group format)")
    else
        TESTING("attach committed datatype to external group's attribute/dataset")

    /* Set up filenames */
    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);


    /* Main file */
    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        FAIL_STACK_ERROR

    /* Create external link from main file to target file */
    if(H5Lcreate_external(filename2, "target_group", fid1, "link_to_2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        FAIL_STACK_ERROR


    /* Create target file */
    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        FAIL_STACK_ERROR
    /* Create group in target file */
    if((gid2 = H5Gcreate2(fid2, "target_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(gid2) < 0)
        FAIL_STACK_ERROR
    /* Close the file */
    if(H5Fclose(fid2) < 0)
        FAIL_STACK_ERROR

    /* Open the group which is externally linked to target file */
    if((gid1 = H5Gopen2(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Create a copy of integer datatype */
    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)
        FAIL_STACK_ERROR

    /* Commit the datatype to the main file root group */
    if(H5Tcommit2(fid1, "myDatatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
        FAIL_STACK_ERROR

    /* Create dataspace */
    if((sid = H5Screate(H5S_SCALAR)) < 0)
        FAIL_STACK_ERROR

    /* Attach an attribute with the committed datatype to the group */
    if((aid = H5Acreate2(gid1, "myAttribute", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Write data to the attribute */
    if(H5Awrite(aid, tid, &wdata) < 0)
        FAIL_STACK_ERROR

    /* Get the attribute's datatype */
    if((atid = H5Aget_type(aid)) < 0)
        FAIL_STACK_ERROR

    /* Verify the datatype is not committed */
    if(H5Tcommitted(atid) == TRUE)
        FAIL_STACK_ERROR

    /* Close the attribute */
    if(H5Aclose(aid) < 0)
        FAIL_STACK_ERROR

    /* Create a chunked dataset */
    if((sid2 = H5Screate_simple(2, dims, NULL)) < 0)
        FAIL_STACK_ERROR

    if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
        FAIL_STACK_ERROR
    if(H5Pset_chunk(dcpl, 2, chunks) < 0)
        FAIL_STACK_ERROR

    /* Initialize data buffers */
    for(i = 0; i < 60; i++) {
	wbuf[i] = i;
	rbuf[i] = 0;
    }

    /* Create a dataset with the committed datatype in the group */
    if((did = H5Dcreate2(gid1, "myDataset", tid, sid2, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Write to the dataset */
    if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0)
        FAIL_STACK_ERROR

    /* Get the dataset's datatype */
    if((dtid = H5Dget_type(did)) < 0)
        FAIL_STACK_ERROR

    /* Verify the datatype is not committed */
    if(H5Tcommitted(dtid) == TRUE)
        FAIL_STACK_ERROR

    /* Close the dataset */
    if(H5Dclose(did) < 0)
        FAIL_STACK_ERROR

    /* Close the dataset creation property list */
    if(H5Pclose(dcpl) < 0)
        FAIL_STACK_ERROR

    /* Close the dataspaces */
    if(H5Sclose(sid) < 0)
        FAIL_STACK_ERROR
    if(H5Sclose(sid2) < 0)
        FAIL_STACK_ERROR

    /* Close the datatypes */
    if(H5Tclose(tid) < 0)
        FAIL_STACK_ERROR
    if(H5Tclose(atid) < 0)
        FAIL_STACK_ERROR
    if(H5Tclose(dtid) < 0)
        FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(gid1) < 0)
        FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(fid1) < 0)
        FAIL_STACK_ERROR


    /* Open the mainfile */
    if((fid1 = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0)
        FAIL_STACK_ERROR

    /* Open the committed datatype in the mainfile */
    if((tid = H5Topen2(fid1, "myDatatype", H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Verify the datatype is committed */
    if(H5Tcommitted(tid) == FALSE)
        FAIL_STACK_ERROR

    /* Open the group which is externally linked to target file */
    if((gid1 = H5Gopen2(fid1, "link_to_2", H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Open the attribute attached to the group */
    if((aid = H5Aopen(gid1, "myAttribute", H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Get the attribute's datatype */
    if((atid = H5Aget_type(aid)) < 0)
        FAIL_STACK_ERROR

    /* Verify the attribute's datatype is not committed */
    if(H5Tcommitted(atid) == TRUE)
        FAIL_STACK_ERROR

    /* Close the attribute */
    if(H5Aclose(aid) < 0)
        FAIL_STACK_ERROR

    /* Delete the attribute */
    if(H5Adelete(gid1, "myAttribute") < 0)
        FAIL_STACK_ERROR

    /* Open the dataset in the group */
    if((did = H5Dopen2(gid1, "myDataset", H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Get the dataset's datatype */
    if((dtid = H5Dget_type(did)) < 0)
        FAIL_STACK_ERROR

    /* Verify the dataset's datatype is not committed */
    if(H5Tcommitted(dtid) == TRUE)
        FAIL_STACK_ERROR

    /* Read the dataset */
    if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0)
        FAIL_STACK_ERROR

    /* Compare the data read should be the same as wbuf */
    if(HDmemcmp(wbuf, rbuf, sizeof(wbuf)) != 0)
        FAIL_STACK_ERROR

    /* Close the dataset */
    if(H5Dclose(did) < 0)
        FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(gid1) < 0)
        FAIL_STACK_ERROR

    /* Close the datatypes */
    if(H5Tclose(tid) < 0)
        FAIL_STACK_ERROR
    if(H5Tclose(atid) < 0)
        FAIL_STACK_ERROR
    if(H5Tclose(dtid) < 0)
        FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(fid1) < 0)
        FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Fclose(fid2);
        H5Fclose(fid1);
        H5Gclose(gid1);
        H5Gclose(gid2);

        H5Aclose(aid);
        H5Dclose(did);

        H5Sclose(sid);
        H5Sclose(sid2);

        H5Tclose(tid);
        H5Aclose(atid);
        H5Aclose(dtid);

	H5Pclose(dcpl);
    } H5E_END_TRY

    return -1;
} /* end external_link_with_committed_datatype() */


/*-------------------------------------------------------------------------
 * Function:    ud_hard_links
 *
 * Purpose:     Check that the functionality of hard links can be duplicated
 *              with user-defined links.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
/* Callback functions for UD hard links. */
/* UD_hard_create increments the object's reference count */
static herr_t
UD_hard_create(const char H5_ATTR_UNUSED * link_name, hid_t loc_group, const void *udata,
    size_t udata_size, hid_t H5_ATTR_UNUSED lcpl_id)
{
    haddr_t addr;
    hid_t target_obj = -1;
    herr_t ret_value = 0;

    if(udata_size != sizeof(haddr_t)) {
        ret_value = -1;
        goto done;
    } /* end if */

    addr = *((const haddr_t *)udata);

    /* Open the object this link points to */
    target_obj= H5Oopen_by_addr(loc_group, addr);
    if(target_obj < 0) {
        ret_value = -1;
        goto done;
    } /* end if */

    /* Increment the reference count of the target object */
    if(H5Oincr_refcount(target_obj) < 0) {
        ret_value = -1;
        goto done;
    } /* end if */

done:
    /* Close the target object if we opened it */
    if(target_obj >= 0) {
        switch(H5Iget_type(target_obj)) {
            case H5I_GROUP:
                if(H5Gclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_DATASET:
                if(H5Dclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_DATATYPE:
                if(H5Tclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_UNINIT:
            case H5I_BADID:
            case H5I_FILE:
            case H5I_DATASPACE:
            case H5I_ATTR:
            case H5I_REFERENCE:
            case H5I_VFL:
            case H5I_GENPROP_CLS:
            case H5I_GENPROP_LST:
            case H5I_ERROR_CLASS:
            case H5I_ERROR_MSG:
            case H5I_ERROR_STACK:
            case H5I_NTYPES:
            default:
              return -1;
        } /* end switch */
    } /* end if */

    return ret_value;
} /* end UD_hard_create() */

/* Traverse a hard link by opening the object */
static hid_t
UD_hard_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
    const void *udata, size_t udata_size, hid_t H5_ATTR_UNUSED lapl_id)
{
    haddr_t addr;
    hid_t ret_value = -1;

    if(udata_size != sizeof(haddr_t))
        return -1;

    addr = *((const haddr_t *) udata);

    ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */

    return ret_value;
} /* end UD_hard_traverse() */

/* UD_hard_delete decrements the object's reference count */
static herr_t
UD_hard_delete(const char H5_ATTR_UNUSED * link_name, hid_t file, const void *udata,
    size_t udata_size)
{
    haddr_t addr;
    hid_t target_obj = -1;
    herr_t ret_value = 0;

    if(udata_size != sizeof(haddr_t)) {
        ret_value = -1;
        goto done;
    } /* end if */

    addr = *((const haddr_t *) udata);

    /* Open the object this link points to */
    target_obj= H5Oopen_by_addr(file, addr);
    if(target_obj < 0) {
        ret_value = -1;
        goto done;
    } /* end if */

    /* Decrement the reference count of the target object */
    if(H5Odecr_refcount(target_obj) < 0) {
        ret_value = -1;
        goto done;
    } /* end if */

done:
    /* Close the target object if we opened it */
    if(target_obj >= 0) {
        switch(H5Iget_type(target_obj)) {
            case H5I_GROUP:
                if(H5Gclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_DATASET:
                if(H5Dclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_DATATYPE:
                if(H5Tclose(target_obj) < 0)
                    ret_value = -1;
                break;

            case H5I_UNINIT:
            case H5I_BADID:
            case H5I_FILE:
            case H5I_DATASPACE:
            case H5I_ATTR:
            case H5I_REFERENCE:
            case H5I_VFL:
            case H5I_GENPROP_CLS:
            case H5I_GENPROP_LST:
            case H5I_ERROR_CLASS:
            case H5I_ERROR_MSG:
            case H5I_ERROR_STACK:
            case H5I_NTYPES:
            default:
                return -1;
        } /* end switch */
    } /* end if */

    return ret_value;
} /* end UD_hard_delete() */

const H5L_class_t UD_hard_class[1] = {{
    H5L_LINK_CLASS_T_VERS,      /* H5L_class_t version       */
    (H5L_type_t)UD_HARD_TYPE,   /* Link type id number            */
    "UD_hard_link",             /* Link class name for debugging  */
    UD_hard_create,             /* Creation callback              */
    NULL,                       /* Move/rename callback           */
    NULL,                       /* Copy callback                  */
    UD_hard_traverse,           /* The actual traversal function  */
    UD_hard_delete,             /* Deletion callback              */
    NULL                        /* Query callback                 */
}};

static int
ud_hard_links(hid_t fapl)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    H5L_info_t li;                          /* Link information */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    h5_stat_size_t empty_size;                  /* Size of an empty file */
    char	filename[NAME_BUF_SIZE];

    TESTING("user-defined hard link (w/new group format)")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Get the size of the empty file for reference */
    if(H5Fclose(fid) < 0) TEST_ERROR
    if((empty_size = h5_get_file_size(filename, fapl))<0) TEST_ERROR

    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Check that external links are registered and UD hard links are not */
    if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR

    /* Register "user-defined hard links" with the library */
    if(H5Lregister(UD_hard_class) < 0) TEST_ERROR

    /* Check that UD hard links are now registered */
    if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR

    /* Create a group for the UD hard link to point to */
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Get address for the group to give to the hard link */
    if(H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR

    if(H5Gclose(gid) < 0) TEST_ERROR


    /* Create a user-defined "hard link" to the group using the address we got
     * from H5Lget_info */
    if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address), (size_t)sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close and re-open file to ensure that data is written to disk */
    if(H5Fclose(fid) < 0) TEST_ERROR
    if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open group through UD link */
    if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/group")) TEST_ERROR

    /* Create object in group */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close groups*/
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Re-open group without using ud link to check that it was created properly */
    if((gid = H5Gopen2(fid, "group/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/group/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Check that H5Lget_objinfo works on the hard link */
    if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    /* UD hard links have no query function, thus return a "link length" of 0 */
    if(li.u.val_size != 0) TEST_ERROR
    if(UD_HARD_TYPE != li.type) {
	H5_FAILED();
	HDputs("    Unexpected link class - should have been a UD hard link");
	goto error;
    } /* end if */

    /* Unlink the group pointed to by the UD link.  It shouldn't be
     * deleted because of the UD link. */
    if(H5Ldelete(fid, "/group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Ensure we can open the group through the UD link */
    if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Unlink the group contained within it. */
    if(H5Ldelete(gid, "new_group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Now delete the UD link.  This should cause the group to be
     * deleted, too. */
    if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* The file should be empty again. */
    if(empty_size != h5_get_file_size(filename, fapl)) TEST_ERROR

    if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end ud_hard_links() */


/*-------------------------------------------------------------------------
 * Function:    UD_rereg_traverse
 *
 * Purpose:     Check that user defined link types can be unregistered and
 *              reregistered properly.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
 /* A traversal function that ignores any udata and simply opens an object
 * in the current group named REREG_TARGET_NAME
 */
static hid_t
UD_rereg_traverse(const char H5_ATTR_UNUSED * link_name, hid_t cur_group,
    const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size, hid_t lapl_id)
{
    hid_t ret_value;

    if((ret_value = H5Oopen(cur_group, REREG_TARGET_NAME, lapl_id)) < 0) TEST_ERROR

    return ret_value;

error:
    return -1;
} /* end UD_rereg_traverse() */

/* This link class has the same ID number as the UD hard links but
 * has a very different traversal function */
const H5L_class_t UD_rereg_class[1] = {{
    H5L_LINK_CLASS_T_VERS,      /* H5L_class_t version       */
    (H5L_type_t)UD_HARD_TYPE,   /* Link type id number            */
    "UD_reregistered_type",     /* Link class name for debugging  */
    NULL,                       /* Creation callback              */
    NULL,                       /* Move/rename callback           */
    NULL,                       /* Copy callback                  */
    UD_rereg_traverse,          /* The actual traversal function  */
    NULL,                       /* Deletion callback              */
    NULL                        /* Query callback                 */
}};

static int
ud_link_reregister(hid_t fapl)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    H5L_info_t	li;                     /* Link information */
    char        objname[NAME_BUF_SIZE];         /* Object name */
    char	filename[NAME_BUF_SIZE];
    h5_stat_size_t empty_size;                  /* Size of an empty file */

    TESTING("registering a new class for existing UD links (w/new group format)")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Get the size of the empty file for reference */
    if(H5Fclose(fid) < 0) TEST_ERROR
    if((empty_size=h5_get_file_size(filename, fapl))<0) TEST_ERROR

    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Check that UD hard links are not registered */
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR

    /* Register "user-defined hard links" with the library */
    if(H5Lregister(UD_hard_class) < 0) TEST_ERROR

    /* Check that UD hard links are registered */
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR

    /* Point a UD defined hard link to a group in the same way as the previous test */
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if (H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.address),
                    sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Create a group named REREG_TARGET_NAME in the same group as the ud link */
    if((gid = H5Gcreate2(fid, REREG_TARGET_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Now unregister UD hard links */
    if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) TEST_ERROR

    /* Check that UD hard links are no longer registered */
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR

    /* Verify that we can't traverse the ud link anymore */
    H5E_BEGIN_TRY {
        if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) >= 0) TEST_ERROR
    } H5E_END_TRY

    /* Verify that we can't create any new links of this type */
    H5E_BEGIN_TRY {
      if(H5Lcreate_ud(fid, "ud_link2", (H5L_type_t)UD_HARD_TYPE, &(li.u.address),
                      sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0)
          TEST_ERROR
    } H5E_END_TRY

    /* Register a new kind of link with the same ID number */
    if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR

    /* Check that UD hard links are registered again */
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR

    /* Open a group through the ud link (now a different class of link).
     * It should be a different group
     * than the UD hard link pointed to */
    if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/" REREG_TARGET_NAME)) TEST_ERROR

    /* Create object in group */
    if((gid2 = H5Gcreate2(gid, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close groups*/
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Re-open group without using ud link to check that it was created properly */
    if((gid = H5Gopen2(fid, "rereg_target/new_group", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/rereg_target/new_group")) TEST_ERROR

    /* Close opened object */
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Unlink the group pointed to by the UD hard link.  It shouldn't be
     * deleted because the UD link incremented its reference count. */
    if(H5Ldelete(fid, "/group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* What a mess! Re-register user-defined links to clean up the
     * reference counts.  We shouldn't actually need to unregister the
     * other link type */
    if(H5Lregister(UD_hard_class) < 0) FAIL_STACK_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) FAIL_STACK_ERROR

    /* Ensure we can open the group through the UD link (now that UD hard
     * links have been registered) */
    if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Delete the UD hard link.  This should cause the group to be
     * deleted, too. */
    if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Unlink the other two groups so that we can make sure the file is empty */
    if(H5Ldelete(fid, "/rereg_target/new_group", H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Ldelete(fid, REREG_TARGET_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    /* The file should be empty again. */
    if(empty_size != h5_get_file_size(filename, fapl)) TEST_ERROR

    if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) FAIL_STACK_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end ud_link_reregister() */


/*-------------------------------------------------------------------------
 * Function:    ud_callbacks
 *
 * Purpose:     Check that all callbacks are called and are given the correct
 *              information.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
/* Callback functions for UD "callback" links. */
/* Creation callback.  Called during move as well. */
static herr_t
UD_cb_create(const char * link_name, hid_t loc_group, const void *udata,
    size_t udata_size, hid_t lcpl_id)
{
    if(!link_name) TEST_ERROR
    if(loc_group < 0) TEST_ERROR
    if(udata_size > 0 && !udata) TEST_ERROR
    if(lcpl_id < 0) TEST_ERROR

    if(HDstrcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR
    if(HDstrcmp((const char *)udata, UD_CB_TARGET)) TEST_ERROR
    if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR

    return 0;

error:
    return -1;
} /* end UD_cb_create() */

static hid_t
UD_cb_traverse(const char * link_name, hid_t cur_group, const void *udata,
    size_t udata_size, hid_t lapl_id)
{
    const char *target = (const char *)udata;
    hid_t ret_value;

    if(!link_name) TEST_ERROR
    if(cur_group < 0) TEST_ERROR
    if(udata_size > 0 && !udata) TEST_ERROR

    if(HDstrcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR
    if(HDstrcmp((const char *)udata, UD_CB_TARGET)) TEST_ERROR
    if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR

    if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
        TEST_ERROR

    return ret_value;

error:
    return -1;
} /* end UD_cb_traverse() */

/* Callback for when the link is moved or renamed */
static herr_t
UD_cb_move(const char *new_name, hid_t new_loc, const void *udata,
    size_t udata_size)
{
    if(!new_name) TEST_ERROR
    if(new_loc < 0) TEST_ERROR
    if(udata_size > 0 && !udata) TEST_ERROR

    if(HDstrcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR
    if(HDstrcmp((const char *)udata, UD_CB_TARGET)) TEST_ERROR
    if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR

    return 0;

error:
    return -1;
} /* end UD_cb_move() */

/* Callback for when the link is deleted.  Also called during move */
static herr_t
UD_cb_delete(const char *link_name, hid_t file, const void *udata,
    size_t udata_size)
{
    if(!link_name) TEST_ERROR
    if(file < 0) TEST_ERROR
    if(udata_size > 0 && !udata) TEST_ERROR

    if(HDstrcmp(link_name, UD_CB_LINK_NAME) && HDstrcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR
    if(HDstrcmp((const char *)udata, UD_CB_TARGET)) TEST_ERROR
    if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR

    return 0;

error:
    return -1;
} /* end UD_cb_delete() */

/* Callback for when the link is queried */
static ssize_t
UD_cb_query(const char * link_name, const void *udata, size_t udata_size,
    void *buf, size_t buf_size)
{
    if(!link_name) TEST_ERROR
    if(udata_size > 0 && !udata) TEST_ERROR

    if(HDstrcmp(link_name, UD_CB_LINK_NAME)) TEST_ERROR
    if(HDstrcmp((const char *)udata, UD_CB_TARGET)) TEST_ERROR
    if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR

    if(buf) {
      if(buf_size < 16) TEST_ERROR
      HDstrcpy((char *)buf, "query succeeded");
    } /* end if */

    /* There are 15 characters and a NULL in "query succeeded" */
    return 16;

error:
    return -1;
} /* end UD_cb_query() */

const H5L_class_t UD_cb_class[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_CB_TYPE,   /* Link type id number            */
    NULL,                     /* NULL name (to make sure this doesn't break anything */
    UD_cb_create,             /* Creation callback              */
    UD_cb_move,               /* Move/rename callback           */
    UD_cb_move,               /* Copy callback                  */
    UD_cb_traverse,           /* The actual traversal function  */
    UD_cb_delete,             /* Deletion callback              */
    UD_cb_query               /* Query callback                 */
}};

static int
ud_callbacks(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group ID */
    hid_t       lcpl = (-1);                    /* Link Creation PL */
    H5L_info_t  li;                             /* Link information */
    char        ud_target_name[] = UD_CB_TARGET; /* Link target name */
    char	filename[NAME_BUF_SIZE];
    char        query_buf[NAME_BUF_SIZE];

    if(new_format)
        TESTING("user-defined link callbacks (w/new group format)")
    else
        TESTING("user-defined link callbacks")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Check that registered link classes are, and unregistered ones aren't */
    if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != FALSE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_CB_TYPE) != FALSE) TEST_ERROR

    /* Hit two birds with one stone: register UD hard links from previous
     * test to check that having two UD links registered at once presents
     * no problems. */
    if(H5Lregister(UD_hard_class) < 0) TEST_ERROR

    /* Register user-defined link class.  This is the one we'll actually
     * be using. */
    if(H5Lregister(UD_cb_class) < 0) TEST_ERROR

    /* Check that registered link classes are, and unregistered ones aren't */
    if(H5Lis_registered(H5L_TYPE_EXTERNAL) != TRUE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != TRUE) TEST_ERROR
    if(H5Lis_registered((H5L_type_t)UD_CB_TYPE) != TRUE) TEST_ERROR

    /* Create a group for the UD link to point to */
    if((gid = H5Gcreate2(fid, UD_CB_TARGET, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create a user-defined link to the group.  These UD links behave like soft links. */
    if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Try opening group through UD link */
    if((gid = H5Gopen2(fid, UD_CB_LINK_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Query the link to test its query callback */
    if (H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.u.val_size != 16) TEST_ERROR
    if (UD_CB_TYPE != li.type) {
	H5_FAILED();
	HDputs("    Unexpected link class - should have been a UD hard link");
	goto error;
    }

    /* Fill the query buffer */
    if(H5Lget_val(fid, UD_CB_LINK_NAME, query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(query_buf, "query succeeded") != 0) TEST_ERROR

    /* Move the link */
    if(H5Lmove(fid, UD_CB_LINK_NAME, H5L_SAME_LOC, NEW_UD_CB_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Re-open group to ensure that move worked */
    if((gid = H5Gopen2(fid, NEW_UD_CB_LINK_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Remove UD link */
    if(H5Ldelete(fid, NEW_UD_CB_LINK_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR


    /* Test that the callbacks don't work if the link class is not registered */

    /* Create a new link. Just for fun, give it a non-default character
     * encoding (to test that LAPLs work) */
    if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) FAIL_STACK_ERROR
    if(H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, lcpl, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Pclose(lcpl) < 0) FAIL_STACK_ERROR

    /* Check its character encoding */
    if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(li.cset != H5T_CSET_UTF8) TEST_ERROR

    /* Unregister the link class so the library forgets what its callbacks do */
    if(H5Lunregister((H5L_type_t)UD_CB_TYPE) < 0) FAIL_STACK_ERROR

    /* Now test that each of the callbacks fails */
    H5E_BEGIN_TRY {
        if(H5Lcreate_ud(fid, NEW_UD_CB_LINK_NAME, (H5L_type_t)UD_CB_TYPE, ud_target_name, (size_t)UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR
        if(H5Lmove(fid, UD_CB_LINK_NAME, H5L_SAME_LOC, NEW_UD_CB_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR
        if(H5Ldelete(fid, UD_CB_LINK_NAME, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR
        if((gid = H5Gopen2(gid, UD_CB_LINK_NAME, H5P_DEFAULT)) >= 0) FAIL_STACK_ERROR
        if(H5Ldelete(fid, UD_CB_LINK_NAME, H5P_DEFAULT) >= 0) FAIL_STACK_ERROR
    } H5E_END_TRY

    /* The query callback should NOT fail, but should be unable to give a linklen */
    if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(li.u.val_size != 0) TEST_ERROR
    if(li.type != UD_CB_TYPE) TEST_ERROR

    /* Unregister the UD hard links */
    if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Pclose (lcpl);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end ud_callbacks() */


/*-------------------------------------------------------------------------
 * Function:    lapl_udata
 *
 * Purpose:     Check that information can be passed to UD links using the
 *              Link Access Property List.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
static hid_t
UD_plist_traverse(const char H5_ATTR_UNUSED * link_name, hid_t cur_group,
    const void H5_ATTR_UNUSED *udata, size_t udata_size, hid_t lapl_id)
{
    char target[NAME_BUF_SIZE];
    hid_t ret_value;

    if(udata_size != 0) TEST_ERROR

    /* Get the name of the target from the property list. */
    if(H5Pget(lapl_id, DEST_PROP_NAME, target) < 0) TEST_ERROR

    if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
        TEST_ERROR

    return ret_value;

error:
    return -1;
} /* end UD_plist_traverse() */

const H5L_class_t UD_plist_class[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_PLIST_TYPE, /* Link type id number            */
    "UD_plist_link",          /* Link class name for debugging  */
    NULL,                     /* Creation callback              */
    NULL,                     /* Move/rename callback           */
    NULL,                     /* Copy callback                  */
    UD_plist_traverse,        /* The actual traversal function  */
    NULL,                     /* Deletion callback              */
    NULL                      /* Query callback                 */
}};

static int
lapl_udata(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1), gid2 = (-1);	/* Group IDs */
    hid_t       plist_id = (-1);                /* Property List ID */
    char	group_a_name[NAME_BUF_SIZE];
    char	group_b_name[NAME_BUF_SIZE];
    char	filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("user data passed through lapl (w/new group format)")
    else
        TESTING("user data passed through lapl")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Register UD link types from previous tests to check that having
     * multiple types registered at once presents no problems. */
    if(H5Lregister(UD_cb_class) < 0) TEST_ERROR

    /* Register the link class.  We'll actually be using for this test. */
    if(H5Lregister(UD_plist_class) < 0) TEST_ERROR

    /* Another link class from a previous test */
    if(H5Lregister(UD_hard_class) < 0) TEST_ERROR

    /* Unregister the first link type registered to make sure this doesn't
     * break anything. */
    if(H5Lunregister((H5L_type_t)UD_CB_TYPE) < 0) TEST_ERROR

    /* Create two groups for the UD link to point to */
    if((gid = H5Gcreate2(fid, "group_a", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "group_b", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Create a user-defined link to the group.  These UD links have no udata. */
    if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_PLIST_TYPE, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create a non-default lapl with a new property pointing to group a*/
    if((plist_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    HDstrcpy(group_a_name, "group_a");
    if(H5Pinsert2(plist_id, DEST_PROP_NAME, (size_t)NAME_BUF_SIZE, group_a_name, NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR

    /* Try opening group through UD link */
    if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR
    if((gid2 = H5Gcreate2(gid, "subgroup_a", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Verify that we can open the new group without using the ud link */
    if((gid2 = H5Gopen2(fid, "/group_a/subgroup_a", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Now use the same ud link to access group_b */
    strcpy(group_b_name, "group_b");
    if(H5Pset(plist_id, DEST_PROP_NAME, group_b_name) < 0) TEST_ERROR

    /* Create a subgroup */
    if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR
    if((gid2 = H5Gcreate2(gid, "subgroup_b", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Verify that we can open the new group without using the ud link */
    if((gid2 = H5Gopen2(fid, "/group_b/subgroup_b", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR

    /* Close property list */
    if(H5Pclose(plist_id) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Pclose (plist_id);
    	H5Gclose (gid);
    	H5Gclose (gid2);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end lapl_udata() */


/*-------------------------------------------------------------------------
 * Function:    ud_link_errors
 *
 * Purpose:     Create error conditions in callbacks and ensure that the
 *              errors propagate correctly.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
static herr_t
UD_cbsucc_create(const char H5_ATTR_UNUSED * link_name, hid_t H5_ATTR_UNUSED loc_group,
    const void *udata, size_t udata_size, hid_t H5_ATTR_UNUSED lcpl_id)
{
    /* Check to make sure that this "soft link" has a target */
    if(udata_size < 1 || !udata)
       return -1;

    return 0;
} /* end UD_cbsucc_create() */

static hid_t
UD_cbsucc_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
    const void *udata, size_t H5_ATTR_UNUSED udata_size, hid_t lapl_id)
{
    const char *target = (const char *)udata;
    hid_t ret_value;

    if(!target) goto error;

    if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) goto error;

    return ret_value;

error:
    return -1;
} /* end UD_cbsucc_traverse() */

/* Failure callback for when the link is moved or renamed */
static herr_t
UD_cbfail_move(const char H5_ATTR_UNUSED *new_name, hid_t H5_ATTR_UNUSED new_loc,
    const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size)
{
    /* This traversal function will always fail. */
    return -1;
} /* end UD_cbfail_move() */

/* SuccessCallback for when the link is moved or renamed */
static herr_t
UD_cbsucc_move(const char H5_ATTR_UNUSED *new_name, hid_t H5_ATTR_UNUSED new_loc,
    const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size)
{
    /* This traversal function will always succeed. */
    return 0;
} /* end UD_cbsucc_move() */

/* Callback for when the link is deleted.  Also called during move */
static herr_t
UD_cbsucc_delete(const char H5_ATTR_UNUSED *link_name, hid_t H5_ATTR_UNUSED file,
    const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size)
{
    /* This callback will always succeed */
    return 0;
} /* end UD_cbsucc_delete() */

/* Callback for when the link is deleted.  Also called during move */
static herr_t
UD_cbfail_delete(const char H5_ATTR_UNUSED *link_name, hid_t H5_ATTR_UNUSED file,
    const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size)
{
    /* This traversal function will always fail. */
    /* Note: un-deletable links are in general a very bad idea! */
    return -1;
} /* end UD_cbfail_delete() */

/* Callback for when the link is queried */
static ssize_t
UD_cbfail_query(const char H5_ATTR_UNUSED *link_name, const void H5_ATTR_UNUSED *udata,
    size_t H5_ATTR_UNUSED udata_size, void H5_ATTR_UNUSED *buf, size_t H5_ATTR_UNUSED buf_size)
{
    /* This traversal function will always fail. */
    return -1;
} /* end UD_cbfail_query() */

/* Callback for when the link is queried */
static ssize_t
UD_cbfail_on_write_query(const char H5_ATTR_UNUSED *link_name, const void H5_ATTR_UNUSED *udata,
    size_t H5_ATTR_UNUSED udata_size, void *buf, size_t H5_ATTR_UNUSED buf_size)
{
    /* This traversal function will return a buffer size,
     * but will fail when a buffer is passed in ("writing to the buffer"
     * fails
     */

    if(buf != NULL)
        return -1;

    return 0;
} /* end UD_cbfail_on_write_query() */

/* Callback for when the link is queried */
static ssize_t
UD_cbsucc_query(const char H5_ATTR_UNUSED *link_name, const void H5_ATTR_UNUSED *udata,
    size_t H5_ATTR_UNUSED udata_size, void *buf, size_t buf_size)
{
    /* This traversal function will return a buffer size,
     * but will fail when a buffer is passed in ("writing to the buffer"
     * fails
     */

    if(buf != NULL && buf_size >= 8)
        HDstrcpy((char *)buf, "succeed");

    return 8;
} /* end UD_cbsucc_query() */

/* This class is full of failing callbacks */
const H5L_class_t UD_cbfail_class1[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_CBFAIL_TYPE,   /* Link type id number            */
    "UD_cbfail_link1",            /* Link class name for debugging  */
    UD_cbsucc_create,             /* Creation callback              */
    UD_cbfail_move,               /* Move/rename callback           */
    UD_cbfail_move,               /* Copy callback                  */
    UD_cbsucc_traverse,           /* The actual traversal function  */
    UD_cbfail_delete,             /* Deletion callback              */
    UD_cbfail_query               /* Query callback                 */
}};

/* This class is has two failing callbacks, move and query */
const H5L_class_t UD_cbfail_class2[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_CBFAIL_TYPE,   /* Link type id number            */
    "UD_cbfail_link2",            /* Link class name for debugging  */
    UD_cbsucc_create,             /* Creation callback              */
    UD_cbfail_move,               /* Move/rename callback           */
    UD_cbsucc_move,               /* Copy callback                  */
    UD_cbsucc_traverse,           /* The actual traversal function  */
    UD_cbsucc_delete,             /* Deletion callback              */
    UD_cbfail_on_write_query      /* Query callback                 */
}};

/* All of these callbacks will succeed */
const H5L_class_t UD_cbfail_class3[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_CBFAIL_TYPE,   /* Link type id number            */
    "UD_cbfail_link3",            /* Link class name for debugging  */
    UD_cbsucc_create,             /* Creation callback              */
    UD_cbsucc_move,               /* Move/rename callback           */
    UD_cbsucc_move,               /* Copy callback                  */
    UD_cbsucc_traverse,           /* The actual traversal function  */
    UD_cbsucc_delete,             /* Deletion callback              */
    UD_cbsucc_query               /* Query callback                 */
}};

/* Link classes that are invalid for various reasons */
const H5L_class_t UD_error1_class[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version       */
    (H5L_type_t)UD_ERROR_TYPE, /* Link type id number            */
    "UD_error_link",          /* Link class name for debugging  */
    NULL,                     /* Creation callback              */
    NULL,                     /* Move/rename callback           */
    NULL,                     /* Copy callback                  */
    NULL,                     /* This class has no traversal function */
    NULL,                     /* Deletion callback              */
    NULL                      /* Query callback                 */
}};
const H5L_class_t UD_error2_class[1] = {{
    UD_BAD_VERS,              /* Invalid H5L_class_t version */
    (H5L_type_t)UD_ERROR_TYPE, /* Link type id number            */
    "UD_error_link",          /* Link class name for debugging  */
    NULL,                     /* Creation callback              */
    NULL,                     /* Move/rename callback           */
    NULL,                     /* Copy callback                  */
    UD_cbsucc_traverse,       /* Traversal function             */
    NULL,                     /* Deletion callback              */
    NULL                      /* Query callback                 */
}};
const H5L_class_t UD_error3_class[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version */
    (H5L_type_t)UD_BAD_TYPE1, /* Invalid Link type id number            */
    "UD_error_link",          /* Link class name for debugging  */
    NULL,                     /* Creation callback              */
    NULL,                     /* Move/rename callback           */
    NULL,                     /* Copy callback                  */
    UD_cbsucc_traverse,       /* Traversal function             */
    NULL,                     /* Deletion callback              */
    NULL                      /* Query callback                 */
}};
const H5L_class_t UD_error4_class[1] = {{
    H5L_LINK_CLASS_T_VERS,    /* H5L_class_t version */
    (H5L_type_t)UD_BAD_TYPE2, /* Invalid Link type id number            */
    "UD_error_link",          /* Link class name for debugging  */
    NULL,                     /* Creation callback              */
    NULL,                     /* Move/rename callback           */
    NULL,                     /* Copy callback                  */
    UD_cbsucc_traverse,       /* Traversal function             */
    NULL,                     /* Deletion callback              */
    NULL                      /* Query callback                 */
}};

static int
ud_link_errors(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);                     /* Group IDs */
    char	group_name[NAME_BUF_SIZE];
    char	filename[NAME_BUF_SIZE];
    char        query_buf[NAME_BUF_SIZE];
    H5L_info_t li;                         /* Link information */

    if(new_format)
        TESTING("user-defined link error conditions (w/new group format)")
    else
        TESTING("user-defined link error conditions")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Try to register some invalid link classes */
    H5E_BEGIN_TRY {
      if(H5Lregister(UD_error1_class) >= 0) TEST_ERROR
      if(H5Lregister(UD_error2_class) >= 0) TEST_ERROR
      if(H5Lregister(UD_error3_class) >= 0) TEST_ERROR
      if(H5Lregister(UD_error4_class) >= 0) TEST_ERROR
    } H5E_END_TRY

    /* Register the UD plist class. */
    if(H5Lregister(UD_plist_class) < 0) TEST_ERROR
    /* Now register the first class we'll be using.
     * It has the same ID as the plist class, and should replace it. */
    if(H5Lregister(UD_cbfail_class1) < 0) FAIL_STACK_ERROR

    /* Create a group for the UD link to point to */
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Try to create internally defined links with H5Lcreate_ud */
    H5E_BEGIN_TRY {
        if(H5Lcreate_ud(fid, "/ud_link", H5L_TYPE_HARD, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) >= 0)
            TEST_ERROR
        if(H5Lcreate_ud(fid, "/ud_link", H5L_TYPE_SOFT, "str", (size_t)4, H5P_DEFAULT, H5P_DEFAULT) >= 0)
            TEST_ERROR
    } H5E_END_TRY

    /* Create a user-defined link to the group. */
    strcpy(group_name, "/group");
    if(H5Lcreate_ud(fid, "/ud_link", (H5L_type_t)UD_CBFAIL_TYPE, &group_name, HDstrlen(group_name) + 1, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Open the group through the ud link */
    if((gid = H5Gopen2(fid, "ud_link", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Now test that each of the callbacks will cause a failure if it returns -1 */
    H5E_BEGIN_TRY {
        /* The create callback will fail if we pass in no udata */
        if(H5Lcreate_ud(fid, "fail", (H5L_type_t)UD_CBFAIL_TYPE, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR

        /* The move and copy callbacks will fail */
        if(H5Lmove(fid, "ud_link", H5L_SAME_LOC, "move_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR
        if(H5Lcopy(fid, "ud_link", fid, "copy_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR

        /* The traversal callback will fail if we remove its target */
        if(H5Ldelete(fid, "group", H5P_DEFAULT) < 0) TEST_ERROR
        if((gid = H5Gopen2(gid, "ud_link", H5P_DEFAULT)) >= 0) TEST_ERROR

        /* The deletion callback will always fail */
        if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) >= 0) TEST_ERROR

        /* The query callback will fail */
        if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR
    } H5E_END_TRY

    /* Now use a class with different callback functions */
    if(H5Lregister(UD_cbfail_class2) < 0) FAIL_STACK_ERROR

    /* Moving should still fail, but copying will succeed */
    H5E_BEGIN_TRY {
        if(H5Lmove(fid, "ud_link", H5L_SAME_LOC, "move_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR
    } H5E_END_TRY
    if(H5Lcopy(fid, "ud_link", fid, "copy_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* The query callback will succeed when we only want to get the size of the buffer... */
    if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(li.u.val_size != 0) TEST_ERROR
    /* ...but fail when we try to write data to the buffer itself*/
    H5E_BEGIN_TRY {
        if(H5Lget_val(fid, "ud_link", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) >=0) TEST_ERROR
    } H5E_END_TRY

    /* Register a new class */
    if(H5Lregister(UD_cbfail_class3) < 0) FAIL_STACK_ERROR

    /* Now querying should succeed */
    if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(li.u.val_size != 8) TEST_ERROR
    if(H5Lget_val(fid, "ud_link", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR

    /* Moving and copying should both succeed */
    if(H5Lmove(fid, "copy_succ", H5L_SAME_LOC, "move_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcopy(fid, "ud_link", fid, "copy_succ2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Delete link (this callback should work now) */
    if(H5Ldelete(fid, "ud_link", H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end ud_link_errors() */


/*-------------------------------------------------------------------------
 * Function:    lapl_nlinks
 *
 * Purpose:     Check that the maximum number of soft links can be adjusted
 *              by the user using the Link Access Property List.
 *
 * Return:      Success:        0
 *
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
lapl_nlinks(hid_t fapl, hbool_t new_format)
{
    hid_t		fid = (-1);               /* File ID */
    hid_t	gid = (-1), gid2 = (-1);          /* Group IDs */
    hid_t		plist = (-1);             /* lapl ID */
    hid_t       tid = (-1), sid = (-1), did = (-1); /* Other IDs */
    hid_t gapl = (-1), dapl = (-1), tapl = (-1);   /* Other property lists */
    char                objname[NAME_BUF_SIZE];   /* Object name */
    char		filename[NAME_BUF_SIZE];
    size_t              nlinks;               /* nlinks for H5Pset_nlinks */
    hsize_t     	dims[2];

    if(new_format)
        TESTING("adjusting nlinks with LAPL (w/new group format)")
    else
        TESTING("adjusting nlinks with LAPL")

    /* Make certain test is valid */
    /* XXX: should probably make a "generic" test that creates the proper
     *          # of links based on this value - QAK
     */
    HDassert(H5L_NUM_LINKS == 16);

    /* Create file */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group with short name in file (used as target for links) */
    if((gid = H5Gcreate2(fid, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create chain of soft links to existing object (limited) */
    if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Close objects */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Open file */
    if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Create LAPL with higher-than-usual nlinks value */
    /* Create a non-default lapl with udata set to point to the first group */
    if((plist = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR
    nlinks = 20;
    if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR

    /* Ensure that nlinks was set successfully */
    nlinks = 0;
    if(H5Pget_nlinks(plist, &nlinks) < 0) TEST_ERROR
    if(nlinks != 20) TEST_ERROR

    /* Open object through what is normally too many soft links using
     * new property list */
    if((gid = H5Oopen(fid, "soft17", plist)) < 0) TEST_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/soft17")) TEST_ERROR

    /* Create group using soft link */
    if((gid2 = H5Gcreate2(gid, "new_soft", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close groups */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Set nlinks to a smaller number */
    nlinks = 4;
    if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR

    /* Ensure that nlinks was set successfully */
    nlinks = 0;
    if(H5Pget_nlinks(plist, &nlinks) < 0) TEST_ERROR
    if(nlinks != 4) TEST_ERROR

    /* Try opening through what is now too many soft links */
    H5E_BEGIN_TRY {
        gid = H5Oopen(fid, "soft5", plist);
    } H5E_END_TRY;
    if (gid >= 0) {
	H5_FAILED();
	HDputs("    Should have failed for sequence of too many nested links.");
	goto error;
    }

    /* Open object through lesser soft link */
    if((gid = H5Oopen(fid, "soft4", plist)) < 0) TEST_ERROR

    /* Check name */
    if(H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE) < 0) TEST_ERROR
    if(HDstrcmp(objname, "/soft4")) TEST_ERROR


    /* Test other functions that should use a LAPL */
    nlinks = 20;
    if(H5Pset_nlinks(plist, nlinks) < 0) TEST_ERROR

    /* Try copying and moving when both src and dst contain many soft links
     * using a non-default LAPL
     */
    if(H5Lcopy(fid, "soft17", fid, "soft17/newer_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR
    if(H5Lmove(fid, "soft17/newer_soft", fid, "soft17/newest_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR

    /* H5Olink */
    if(H5Olink(gid, fid, "soft17/link_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR

    /* H5Lcreate_hard  and H5Lcreate_soft */
    if(H5Lcreate_hard(fid, "soft17", fid, "soft17/link2_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR
    if(H5Lcreate_soft("/soft4", fid, "soft17/soft_link", H5P_DEFAULT, plist) < 0) TEST_ERROR

    /* H5Ldelete */
    if(H5Ldelete(fid, "soft17/soft_link", plist) < 0) TEST_ERROR

    /* H5Lget_val and H5Lget_info */
    if(H5Lget_val(fid, "soft17", NULL, (size_t)0, plist) < 0) TEST_ERROR
    if(H5Lget_info(fid, "soft17", NULL, plist) < 0) TEST_ERROR

    /* H5Lcreate_external and H5Lcreate_ud */
    if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) < 0) TEST_ERROR
    if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR
    if(H5Lcreate_ud(fid, "soft17/udlink", (H5L_type_t)UD_HARD_TYPE, NULL, (size_t)0, H5P_DEFAULT, plist) < 0) TEST_ERROR

    /* Close plist */
    if(H5Pclose(plist) < 0) TEST_ERROR


    /* Create a datatype and dataset as targets inside the group */
    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(gid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR

    dims[0] = 2;
    dims[1] = 2;
    if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
    if((did = H5Dcreate2(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    /* Close group */
    if(H5Gclose(gid) < 0) TEST_ERROR

    /* Try to open the objects using too many symlinks with default *APLs */
    H5E_BEGIN_TRY {
        if((gid = H5Gopen2(fid, "soft17", H5P_DEFAULT)) >= 0)
            FAIL_PUTS_ERROR("    Should have failed for too many nested links.")
        if((tid = H5Topen2(fid, "soft17/datatype", H5P_DEFAULT)) >= 0)
            FAIL_PUTS_ERROR("    Should have failed for too many nested links.")
        if((did = H5Dopen2(fid, "soft17/dataset", H5P_DEFAULT)) >= 0)
            FAIL_PUTS_ERROR("    Should have failed for too many nested links.")
    } H5E_END_TRY

    /* Create property lists with nlinks set */
    if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
    if((tapl = H5Pcreate(H5P_DATATYPE_ACCESS)) < 0) TEST_ERROR
    if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR

    nlinks = 20;
    if(H5Pset_nlinks(gapl, nlinks) < 0) TEST_ERROR
    if(H5Pset_nlinks(tapl, nlinks) < 0) TEST_ERROR
    if(H5Pset_nlinks(dapl, nlinks) < 0) TEST_ERROR

    /* We should now be able to use these property lists to open each kind
     * of object.
     */
    if((gid = H5Gopen2(fid, "soft17", gapl)) < 0) FAIL_STACK_ERROR
    if((tid = H5Topen2(fid, "soft17/datatype", tapl)) < 0) TEST_ERROR
    if((did = H5Dopen2(fid, "soft17/dataset", dapl)) < 0) TEST_ERROR

    /* Close objects */
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    /* Close plists */
    if(H5Pclose(gapl) < 0) TEST_ERROR
    if(H5Pclose(tapl) < 0) TEST_ERROR
    if(H5Pclose(dapl) < 0) TEST_ERROR

    /* Unregister UD hard link class */
    if(H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Pclose(gapl);
    	H5Pclose(dapl);
    	H5Pclose(tapl);
    	H5Dclose(did);
    	H5Sclose(sid);
    	H5Tclose(tid);
    	H5Gclose(gid2);
    	H5Gclose(gid);
    	H5Pclose(plist);
    	H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end lapl_nlinks() */


/*-------------------------------------------------------------------------
 * Function:    linkinfo
 *
 * Purpose:     Check that the link class is returned correctly when queried.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Tuesday, June 6, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
linkinfo(hid_t fapl, hbool_t new_format)
{
    hid_t	fid = (-1);     		/* File ID */
    hid_t	gid = (-1);	                /* Group ID */
    hid_t       tid = (-1);                     /* Type ID */
    hid_t       sid = (-1), did = -(1);         /* Dataspace and dataset IDs */
    H5L_info_t li;                          /* Link information */
    char	filename[NAME_BUF_SIZE];

    if(new_format)
        TESTING("link type field in H5Lget_info (w/new group format)")
    else
        TESTING("link type field in H5Lget_info")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Register a couple of user-defined link classes with the library */
    if(H5Lregister(UD_plist_class) < 0) TEST_ERROR

    /* Create an object of each type */
    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(fid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(H5Lcreate_soft("group", fid, "softlink", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR
    if((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    if(H5Lcreate_ud(fid, "ud_link", (H5L_type_t)UD_PLIST_TYPE, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_external("file_name", "obj_path", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close all objects */
    if(H5Tclose(tid) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    /* Make sure that link type is correct when objects are queried */
    if(H5Lget_info(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != H5L_TYPE_HARD) TEST_ERROR
    if(H5Lget_info(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != H5L_TYPE_HARD) TEST_ERROR
    if(H5Lget_info(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != H5L_TYPE_HARD) TEST_ERROR

    if(H5Lget_info(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != H5L_TYPE_EXTERNAL) TEST_ERROR
    if(H5Lget_info(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != H5L_TYPE_SOFT) TEST_ERROR
    if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR
    if(li.type != UD_PLIST_TYPE) TEST_ERROR

    /* Ensure that passing a NULL pointer doesn't cause an error */
    if(H5Lget_info(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR

    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

 error:
    H5E_BEGIN_TRY {
    	H5Tclose (tid);
    	H5Dclose (did);
    	H5Gclose (gid);
    	H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
} /* end linkinfo() */


/*-------------------------------------------------------------------------
 * Function:    check_all_closed
 *
 * Purpose:     External links and some UD links open files.  To make sure
 *              that all such files got closed correctly, try to create
 *              each of them.
 *
 *              If the files are still open, this will fail (indicating that
 *              some other test made a mistake).
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  James Laird
 *              Thursday, August 17, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
check_all_closed(hid_t fapl, hbool_t new_format, int stopat)
{
    hid_t fid=-1;
    char filename[NAME_BUF_SIZE];
    int x;

    if(new_format)
        TESTING("that all files were closed correctly (w/new group format)")
    else
        TESTING("that all files were closed correctly")

    /* Some of the external or UD link tests may have failed to close
     * an external file properly.
     * To check this, try to create every file used in this test.  If
     * a file is already open, creating it will fail.
     */
    for(x=0; FILENAME[x] != NULL && x < stopat; x++)
    {
        h5_fixname(FILENAME[x], fapl, filename, sizeof filename);

        if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
        if(H5Fclose(fid) < 0) TEST_ERROR
    }

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end check_all_closed() */



/*-------------------------------------------------------------------------
 * Function:    build_visit_file
 *
 * Purpose:     Build an "interesting" file to use for visiting links & objects
 *
 * Return:      Success:        >0, File ID for file built
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, November 24, 2007
 *
 *-------------------------------------------------------------------------
 */
static hid_t
build_visit_file(hid_t fapl)
{
    hid_t fid = -1;                     /* File ID */
    hid_t gid = -1, gid2 = -1;          /* Group IDs */
    hid_t sid = (-1);                   /* Dataspace ID */
    hid_t did = (-1);                   /* Dataset ID */
    hid_t tid = (-1);                   /* Datatype ID */
    char filename[NAME_BUF_SIZE];
    const char *pathname = H5_get_srcdir_filename(LINKED_FILE); /* Corrected test file name */

    h5_fixname(FILENAME[9], fapl, filename, sizeof filename);

    /* Create file for visiting */
    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group */
    if((gid = H5Gcreate2(fid, "/Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Create nested group */
    if((gid2 = H5Gcreate2(gid, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close groups */
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Gclose(gid) < 0) TEST_ERROR


    /* Create soft links to groups created */
    if(H5Lcreate_soft("/Group1", fid, "/soft_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_soft("/Group1/Group2", fid, "/soft_two", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create dangling soft link */
    if(H5Lcreate_soft("nowhere", fid, "/soft_dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR


    /* Create hard links to all groups */
    if(H5Lcreate_hard(fid, "/", fid, "hard_zero", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "/Group1", fid, "hard_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "/Group1/Group2", fid, "hard_two", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create loops w/hard links */
    if(H5Lcreate_hard(fid, "/Group1", fid, "/Group1/hard_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Lcreate_hard(fid, "/", fid, "/Group1/Group2/hard_zero", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create external link to existing file */
    if(H5Lcreate_external(pathname, "/group", fid, "/ext_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create dangling external link to non-existent file */
    if(H5Lcreate_external("foo.h5", "/group", fid, "/ext_dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Create dataset in each group */
    if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR

    if((did = H5Dcreate2(fid, "/Dataset_zero", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    if((did = H5Dcreate2(fid, "/Group1/Dataset_one", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    if((did = H5Dcreate2(fid, "/Group1/Group2/Dataset_two", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Dclose(did) < 0) TEST_ERROR

    if(H5Sclose(sid) < 0) TEST_ERROR

    /* Create named datatype in each group */
    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(fid, "/Type_zero", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR

    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(fid, "/Group1/Type_one", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR

    if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
    if(H5Tcommit2(fid, "/Group1/Group2/Type_two", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Tclose(tid) < 0) TEST_ERROR

    return(fid);

error:
    H5E_BEGIN_TRY {
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end build_visit_file() */


/*-------------------------------------------------------------------------
 * Function:    visit_link_cb
 *
 * Purpose:     Callback routine for visiting links in a file
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, November 24, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
visit_link_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5L_info_t *linfo,
    void *_op_data)
{
    lvisit_ud_t *op_data = (lvisit_ud_t *)_op_data;

    /* Check for correct link information */
    if(HDstrcmp(op_data->info[op_data->idx].path, name)) return(H5_ITER_ERROR);
    if(op_data->info[op_data->idx].type != linfo->type) return(H5_ITER_ERROR);

    /* Advance to next location in expected output */
    op_data->idx++;

    return(H5_ITER_CONT);
} /* end visit_link_cb() */


/*-------------------------------------------------------------------------
 * Function:    link_visit
 *
 * Purpose:     Test the link visiting routine
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, November 24, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
link_visit(hid_t fapl, hbool_t new_format)
{
    lvisit_ud_t udata;          /* User-data for visiting */
    hid_t fid = -1;
    hid_t gid = -1;             /* Group ID */

    if(new_format)
        TESTING("link visiting (w/new group format)")
    else
        TESTING("link visiting")

    /* Construct "interesting" file to visit */
    if((fid = build_visit_file(fapl)) < 0) TEST_ERROR

    /* Visit all the links reachable from the root group (with file ID) */
    udata.idx = 0;
    udata.info = lvisit0;
    if(H5Lvisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR

    /* Visit all the links reachable from the root group (with group ID) */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit0;
    if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Visit all the links reachable from each internal group */
    if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit1;
    if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit2;
    if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Close file created */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end link_visit() */


/*-------------------------------------------------------------------------
 * Function:    link_visit_by_name
 *
 * Purpose:     Test the link visiting "by name" routine
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, November 24, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
link_visit_by_name(hid_t fapl, hbool_t new_format)
{
    lvisit_ud_t udata;          /* User-data for visiting */
    hid_t fid = -1;
    hid_t gid = -1;             /* Group ID */

    if(new_format)
        TESTING("link visiting by name (w/new group format)")
    else
        TESTING("link visiting by name")

    /* Construct "interesting" file to visit */
    if((fid = build_visit_file(fapl)) < 0) TEST_ERROR

    /* Visit all the links reachable from the root group (with file ID) */
    udata.idx = 0;
    udata.info = lvisit0;
    if(H5Lvisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Visit all the links reachable from the root group (with group ID) */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit0;
    if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Visit all the links reachable from each internal group */
    udata.idx = 0;
    udata.info = lvisit1;
    if(H5Lvisit_by_name(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit1;
    if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    udata.idx = 0;
    udata.info = lvisit2;
    if(H5Lvisit_by_name(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = lvisit2;
    if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Close file created */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end link_visit_by_name() */


/*-------------------------------------------------------------------------
 * Function:    visit_obj_cb
 *
 * Purpose:     Callback routine for visiting objects in a file
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 25, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
visit_obj_cb(hid_t H5_ATTR_UNUSED group_id, const char *name, const H5O_info_t *oinfo,
    void *_op_data)
{
    ovisit_ud_t *op_data = (ovisit_ud_t *)_op_data;

    /* Check for correct object information */
    if(HDstrcmp(op_data->info[op_data->idx].path, name)) return(H5_ITER_ERROR);
    if(op_data->info[op_data->idx].type != oinfo->type) return(H5_ITER_ERROR);

    /* Advance to next location in expected output */
    op_data->idx++;

    return(H5_ITER_CONT);
} /* end visit_obj_cb() */


/*-------------------------------------------------------------------------
 * Function:    obj_visit
 *
 * Purpose:     Test the object visiting routine
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 25, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
obj_visit(hid_t fapl, hbool_t new_format)
{
    ovisit_ud_t udata;          /* User-data for visiting */
    hid_t fid = -1;
    hid_t gid = -1;             /* Group ID */

    if(new_format)
        TESTING("object visiting (w/new group format)")
    else
        TESTING("object visiting")

    /* Construct "interesting" file to visit */
    if((fid = build_visit_file(fapl)) < 0) TEST_ERROR

    /* Visit all the objects reachable from the root group (with file ID) */
    udata.idx = 0;
    udata.info = new_format ? ovisit0_new : ovisit0_old;
    if(H5Ovisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata) < 0) FAIL_STACK_ERROR

    /* Visit all the objects reachable from the root group (with group ID) */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit0_new : ovisit0_old;
    if(H5Ovisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Visit all the objects reachable from each internal group */
    if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit1_new : ovisit1_old;
    if(H5Ovisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit2_new : ovisit2_old;
    if(H5Ovisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Close file created */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end obj_visit() */


/*-------------------------------------------------------------------------
 * Function:    obj_visit_by_name
 *
 * Purpose:     Test the object visiting "by name" routine
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 25, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
obj_visit_by_name(hid_t fapl, hbool_t new_format)
{
    ovisit_ud_t udata;          /* User-data for visiting */
    hid_t fid = -1;
    hid_t gid = -1;             /* Group ID */

    if(new_format)
        TESTING("object visiting by name (w/new group format)")
    else
        TESTING("object visiting by name")

    /* Construct "interesting" file to visit */
    if((fid = build_visit_file(fapl)) < 0) TEST_ERROR

    /* Visit all the objects reachable from the root group (with file ID) */
    udata.idx = 0;
    udata.info = new_format ? ovisit0_new : ovisit0_old;
    if(H5Ovisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Visit all the objects reachable from the root group (with group ID) */
    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit0_new : ovisit0_old;
    if(H5Ovisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Visit all the objects reachable from each internal group */
    udata.idx = 0;
    udata.info = new_format ? ovisit1_new : ovisit1_old;
    if(H5Ovisit_by_name(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit1_new : ovisit1_old;
    if(H5Ovisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    udata.idx = 0;
    udata.info = new_format ? ovisit2_new : ovisit2_old;
    if(H5Ovisit_by_name(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    udata.idx = 0;
    udata.info = new_format ? ovisit2_new : ovisit2_old;
    if(H5Ovisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR


    /* Close file created */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end obj_visit_by_name() */


/*-------------------------------------------------------------------------
 * Function:    visit_obj_stop_cb
 *
 * Purpose:     Callback routine for visiting objects in a file
 *
 * Return:      1 (H5_ITER_STOP)
 *
 * Programmer:  Neil Fortner
 *              Sunday, November 2, 2008
 *
 *-------------------------------------------------------------------------
 */
static int
visit_obj_stop_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *name, const H5O_info_t H5_ATTR_UNUSED *oinfo,
    void *_op_data)
{
    unsigned *op_data = (unsigned *)_op_data;

    /* Increment the number of visited objects */
    (*op_data)++;

    return(H5_ITER_STOP);
} /* end visit_obj_stop_cb() */


/*-------------------------------------------------------------------------
 * Function:    obj_visit_stop
 *
 * Purpose:     Test that the object visiting routine stops iteration
 *              properly on the starting object.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Sunday, November 2, 2008
 *
 *-------------------------------------------------------------------------
 */
static int
obj_visit_stop(hid_t fapl, hbool_t new_format)
{
    unsigned    nvisited;           /* User-data for visiting */
    hid_t       fid = -1;
    herr_t      ret;                /* Return value */

    if(new_format)
        TESTING("stopping object iteration (w/new group format)")
    else
        TESTING("stopping object iteration")

    /* Construct "interesting" file to visit */
    if((fid = build_visit_file(fapl)) < 0) TEST_ERROR

    /* Start iteration.  The callback should only be called once because it
     * returns H5_ITER_STOP
     */
    nvisited = 0;
    if((ret = H5Ovisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, &nvisited)) < 0)
        FAIL_STACK_ERROR
    if(ret != H5_ITER_STOP) TEST_ERROR
    if(nvisited != 1) TEST_ERROR

    /* Same test with H5Ovisit_by_name */
    nvisited = 0;
    if((ret = H5Ovisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb,
        &nvisited, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if(ret != H5_ITER_STOP) TEST_ERROR
    if(nvisited != 1) TEST_ERROR

    /* Close file created */
    if(H5Fclose(fid) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end obj_visit_stop() */


/*-------------------------------------------------------------------------
 * Function:    link_filters
 *
 * Purpose:     Tests adding filters to group link storage.  Also tests
 *              copying these groups.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Neil Fortner
 *              Tuesday, June 16, 2009
 *
 *-------------------------------------------------------------------------
 */
static enum {
    LFS_INIT,
    LFS_CAN_APPLY_CALLED,
    LFS_SET_LOCAL_CALLED,
    LFS_ENCODED,
    LFS_DECODED
} link_filter_state;

static htri_t link_filter_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id)
{
    if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0)
        return -1;

    if(link_filter_state >= LFS_ENCODED)
        return 1;

    if(link_filter_state != LFS_INIT)
        return -1;

    link_filter_state = LFS_CAN_APPLY_CALLED;

    return 1;
} /* end link_fitler_can_apply */

static herr_t link_filter_set_local(hid_t dcpl_id, hid_t type_id, hid_t space_id)
{
    if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0)
        return -1;

    if(link_filter_state >= LFS_ENCODED)
        return 0;

    if(link_filter_state != LFS_CAN_APPLY_CALLED)
        return -1;

    link_filter_state = LFS_SET_LOCAL_CALLED;

    return 0;
} /* end link_filter_set_local */

static size_t link_filter_filter(unsigned int flags, size_t cd_nelmts,
    const unsigned int cd_values[], size_t nbytes, size_t H5_ATTR_UNUSED *buf_size,
    void H5_ATTR_UNUSED **buf)
{
    if(flags & H5Z_FLAG_OPTIONAL || cd_nelmts != 1 || cd_values[0] != 2112)
        return 0;

    if(link_filter_state == LFS_DECODED)
        return nbytes;

    if(flags & H5Z_FLAG_REVERSE) {
        if(link_filter_state != LFS_ENCODED)
            return 0;
        link_filter_state = LFS_DECODED;
    } else {
        if(link_filter_state < LFS_SET_LOCAL_CALLED)
            return 0;
        link_filter_state = LFS_ENCODED;
    } /* end else */

    return nbytes;
} /* end link_filter_filter */

static int
link_filters(hid_t fapl, hbool_t new_format)
{
    hid_t       fid = -1, fcpl = -1;
    hid_t       gid1 = -1, gid2 = -1, gcpl1 = -1, gcpl2 = -1;
    hid_t       lcpl = -1;
    size_t      cd_nelmts = 1;
    unsigned    cd_value = 2112;
    unsigned    cd_value_out;
    unsigned    flags_out;
    unsigned    filter_config_out;
    int         nfilters = 0;
    H5Z_class2_t filter_class;
    char        name_out[24];
    char	filename[NAME_BUF_SIZE];
    htri_t      tri_ret;
    herr_t      status;

    /* This test actually always uses the new group format for the main group.
     * The new format flag affects the version of object header messages,
     * etc., which are important for this test. */
    if(new_format)
        TESTING("group link filters (w/new group format)")
    else
        TESTING("group link filters")

    /* Initialize link filter state global */
    link_filter_state = LFS_INIT;

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        TEST_ERROR

    /* Create gcpl, force use of dense storage */
    if((gcpl1 = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR
    if(H5Pset_link_phase_change(gcpl1, 2, 2) < 0) TEST_ERROR

    /* Add deflate and checksum filters, if available */
    if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR
    if(tri_ret) {
        if(H5Pset_deflate(gcpl1, 6) < 0) TEST_ERROR
        nfilters++;
    } /* end if */
    if((tri_ret = H5Zfilter_avail(H5Z_FILTER_FLETCHER32)) < 0) TEST_ERROR
    if(tri_ret) {
        if(H5Pset_fletcher32(gcpl1) < 0) TEST_ERROR
        nfilters++;
    } /* end if */

    /* Register and add custom filter */
    filter_class.version = H5Z_CLASS_T_VERS;
    filter_class.id = H5Z_FILTER_RESERVED + 42;
    filter_class.encoder_present = TRUE;
    filter_class.decoder_present = TRUE;
    filter_class.name = "custom_link_filter";
    filter_class.can_apply = link_filter_can_apply;
    filter_class.set_local = link_filter_set_local;
    filter_class.filter = link_filter_filter;
    if(H5Zregister(&filter_class) < 0) TEST_ERROR
    if(H5Pset_filter(gcpl1, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0)
        TEST_ERROR
    nfilters++;

    /* Test various other filter functions for use on gcpl's */
    if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR
    if(H5Pall_filters_avail(gcpl1) != TRUE) TEST_ERROR

    /* Create a group using this filter, add some soft links to it */
    if((gid1 = H5Gcreate2(fid, "group1", H5P_DEFAULT, gcpl1, H5P_DEFAULT)) < 0)
        TEST_ERROR
    if(H5Lcreate_soft("/", gid1, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file and group */
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Verify the filter has been applied */
    if(link_filter_state != LFS_ENCODED) TEST_ERROR

    /* Reopen file and group */
    if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
    if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR

    /* Retrieve gcpl, verify number of filters */
    if((gcpl2 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR
    if(H5Pclose(gcpl2) < 0) TEST_ERROR

    /* Now try copying gcpl1, and verify number of filters */
    if((gcpl2 = H5Pcopy(gcpl1)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR
    if(H5Pclose(gcpl2) < 0) TEST_ERROR

    /* Add another soft link */
    if(H5Lcreate_soft("/", gid1, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Copy the group */
    if(H5Ocopy(fid, "group1", fid, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if((gid2 = H5Gopen2(fid, "group2", H5P_DEFAULT)) <0) TEST_ERROR

    /* Verify that all links have been copied */
    if(H5Lexists(gid2, "link1", H5P_DEFAULT) != TRUE) TEST_ERROR
    if(H5Lexists(gid2, "link2", H5P_DEFAULT) != TRUE) TEST_ERROR
    if(H5Lexists(gid2, "link3", H5P_DEFAULT) != TRUE) TEST_ERROR
    if(H5Lexists(gid2, "link4", H5P_DEFAULT) != TRUE) TEST_ERROR

    /* Retrieve gcpl, verify number of filters */
    if((gcpl2 = H5Gget_create_plist(gid2)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR

    /* Delete 3 links to force the group back into compact mode */
    if(H5Ldelete(gid1, "link2", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(gid1, "link3", H5P_DEFAULT) < 0) TEST_ERROR
    if(H5Ldelete(gid1, "link4", H5P_DEFAULT) < 0) TEST_ERROR

    /* Close file and groups */
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if(H5Gclose(gid2) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Reset link filter state */
    link_filter_state = LFS_INIT;

    /* Reopen file and group, add 2 links */
    if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
    if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR
    if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR

    /* Close file and group */
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if(H5Fclose(fid) < 0) TEST_ERROR

    /* Verify that the filter was reapplied */
    if(link_filter_state != LFS_ENCODED) TEST_ERROR

    /* Test H5Pget_filter_by_id2 and H5Pget_filter2 */
    if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out,
            &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0)
        TEST_ERROR
    if(flags_out != 0 || cd_value_out != cd_value
            || HDstrcmp(filter_class.name, name_out)
            || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED
            | H5Z_FILTER_CONFIG_DECODE_ENABLED))
        TEST_ERROR
    if(H5Pget_filter2(gcpl2, (unsigned)(nfilters - 1), &flags_out, &cd_nelmts,
            &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0)
        TEST_ERROR
    if(flags_out != 0 || cd_value_out != cd_value
            || HDstrcmp(filter_class.name, name_out)
            || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED
            | H5Z_FILTER_CONFIG_DECODE_ENABLED))
        TEST_ERROR

    /* Test H5Pmodify_filter */
    cd_value++;
    if(H5Pmodify_filter(gcpl2, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0)
        TEST_ERROR
    if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out,
            &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0)
        TEST_ERROR
    if(flags_out != 0 || cd_value_out != cd_value
            || HDstrcmp(filter_class.name, name_out)
            || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED
            | H5Z_FILTER_CONFIG_DECODE_ENABLED))
        TEST_ERROR

    /* Test H5Premove_filter */
    if(H5Premove_filter(gcpl2, H5Z_FILTER_RESERVED + 42) < 0) TEST_ERROR
    H5E_BEGIN_TRY {
        status = H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42,
                &flags_out, &cd_nelmts, &cd_value_out, (size_t)24, name_out,
                &filter_config_out);
    } H5E_END_TRY
    if(status >= 0) TEST_ERROR

    /* Close remaining ids */
    if(H5Pclose(gcpl1) < 0) TEST_ERROR
    if(H5Pclose(gcpl2) < 0) TEST_ERROR

    /* Now create an object in the compressed group, creating intermediate
     * groups, to verify that the filter pipeline is inherited for the groups
     * that are created along the way */
    /* Reopen file */
    if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Create lcpl, setting the "create intermediate groups" flag */
    if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
    if(H5Pset_create_intermediate_group(lcpl, (unsigned)TRUE) < 0) TEST_ERROR

    /* Create new group, with missing intermediate groups, in compressed group */
    if((gid1 = H5Gcreate2(fid, "group1/group2/group3/group4", lcpl, H5P_DEFAULT, H5P_DEFAULT)) < 0)
        TEST_ERROR

    /* Close LCPL ID */
    if(H5Pclose(lcpl) < 0) TEST_ERROR

    /* Verify that new group doesn't have filters */
    if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl1) != 0) TEST_ERROR

    /* Close group & GCPL IDs */
    if(H5Pclose(gcpl1) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR

    /* Open intermediate groups that were created and verify that they have filters */
    if((gid1 = H5Gopen2(fid, "group1/group2", H5P_DEFAULT)) < 0) TEST_ERROR
    if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR
    if(H5Pclose(gcpl1) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR
    if((gid1 = H5Gopen2(fid, "group1/group2/group3", H5P_DEFAULT)) < 0) TEST_ERROR
    if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR
    if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR
    if(H5Pclose(gcpl1) < 0) TEST_ERROR
    if(H5Gclose(gid1) < 0) TEST_ERROR

    /* Close file */
    if(H5Fclose(fid) < 0) TEST_ERROR


    /* Now create the same file with and without deflate, and verify that the
     * file size is smaller with deflate */
    /* But only if the deflate filter is available */
    if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR
    if(tri_ret) {
        h5_stat_size_t filesize_filtered;
        h5_stat_size_t filesize_unfiltered;

        /* Create gcpl, force use of dense storage */
        if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR
        if(H5Pset_link_phase_change(fcpl, 2, 2) < 0) TEST_ERROR

        /* Create file */
        if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
            TEST_ERROR

        /* Create links in file */
        if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR
        if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR
        if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR

        /* Close file, get file size */
        if(H5Fclose(fid) < 0) TEST_ERROR
        filesize_unfiltered = h5_get_file_size(filename, fapl);

        /* Set deflate fitler */
        if(H5Pset_deflate(fcpl, 6) < 0) TEST_ERROR

        /* Recreate the same file with the deflate filter */
        if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
            TEST_ERROR
        if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR
        if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR
        if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0)
            TEST_ERROR

        /* Close file, get file size */
        if(H5Fclose(fid) < 0) TEST_ERROR
        filesize_filtered = h5_get_file_size(filename, fapl);

        /* Check that the file size is smaller with the filter */
        if((double)filesize_filtered
                > ((double)filesize_unfiltered * FILTER_FILESIZE_MAX_FRACTION))
            TEST_ERROR

        /* Close */
        if(H5Pclose(fcpl) < 0) TEST_ERROR
    } /* end if */

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid1);
        H5Gclose(gid2);
        H5Fclose(fid);
        H5Pclose(lcpl);
        H5Pclose(gcpl1);
        H5Pclose(gcpl2);
        H5Pclose(fcpl);
    } H5E_END_TRY;
    return -1;
} /* end link_filters() */


/*-------------------------------------------------------------------------
 * Function:    obj_exists
 *
 * Purpose:     Test the 'object exists' routine
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, February 2, 2010
 *
 *-------------------------------------------------------------------------
 */
static int
obj_exists(hid_t fapl, hbool_t new_format)
{
    char filename[NAME_BUF_SIZE];       /* Buffer for file name */
    hid_t fid = -1;     /* File ID */
    hid_t gid = -1;     /* Group ID */
    herr_t status;      /* Generic return value */

    if(new_format)
        TESTING("object exists (w/new group format)")
    else
        TESTING("object exists")

    /* Set up filename and create file*/
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        FAIL_STACK_ERROR

/* Hard links */
    /* Verify that H5Oexists_by_name() fails for non-existent link in root group */
    H5E_BEGIN_TRY {
        status = H5Oexists_by_name(fid, "foo", H5P_DEFAULT);
    } H5E_END_TRY
    if(status >= 0) TEST_ERROR

    /* Create a group, as a destination for testing */
    if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
        FAIL_STACK_ERROR
    if(H5Gclose(gid) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() succeeds for hard linked object */
    if(TRUE != H5Oexists_by_name(fid, "group", H5P_DEFAULT))
        TEST_ERROR

    /* Verify that H5Oexists_by_name() fails for non-existent link in non-root group */
    H5E_BEGIN_TRY {
        status = H5Oexists_by_name(fid, "group/foo", H5P_DEFAULT);
    } H5E_END_TRY
    if(status >= 0) TEST_ERROR


/* Soft links */
    /* Create dangling soft-link in root group */
    if(H5Lcreate_soft("dangle", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling soft-link in root group */
    if(FALSE != H5Oexists_by_name(fid, "soft1", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to object */
    if(H5Lcreate_soft("/group", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE for soft-link in root group that points to object */
    if(TRUE != H5Oexists_by_name(fid, "soft2", H5P_DEFAULT))
        TEST_ERROR

    /* Create dangling soft-link in non-root group */
    if(H5Lcreate_soft("dangle", fid, "group/soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling soft-link in non-root group */
    if(FALSE != H5Oexists_by_name(fid, "group/soft1", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to object */
    if(H5Lcreate_soft("/group", fid, "group/soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE for soft-link in non-root group that points to object */
    if(TRUE != H5Oexists_by_name(fid, "group/soft2", H5P_DEFAULT))
        TEST_ERROR


/* External links */
    /* Create dangling (file doesn't exist) external link in root group */
    if(H5Lcreate_external("nofile", "dangle", fid, "external1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling (file doesn't exist) external link in root group */
    if(FALSE != H5Oexists_by_name(fid, "external1", H5P_DEFAULT))
        TEST_ERROR

    /* Create dangling (object doesn't exist) external link in root group */
    if(H5Lcreate_external(filename, "dangle", fid, "external2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling (object doesn't exist) external link in root group */
    if(FALSE != H5Oexists_by_name(fid, "external2", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in root group that points to object */
    if(H5Lcreate_external(filename, "group", fid, "external3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE for external link in root group that points to object */
    if(TRUE != H5Oexists_by_name(fid, "external3", H5P_DEFAULT))
        TEST_ERROR

    /* Create dangling (file doesn't exist) external link in non-root group */
    if(H5Lcreate_external("nofile", "dangle", fid, "group/external1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling (file doesn't exist) external link in non-root group */
    if(FALSE != H5Oexists_by_name(fid, "group/external1", H5P_DEFAULT))
        TEST_ERROR

    /* Create dangling (object doesn't exist) external link in non-root group */
    if(H5Lcreate_external(filename, "dangle", fid, "group/external2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE for dangling (object doesn't exist) external link in non-root group */
    if(FALSE != H5Oexists_by_name(fid, "group/external2", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in non-root group that points to object */
    if(H5Lcreate_external(filename, "group", fid, "group/external3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE for external link in non-root group that points to object */
    if(TRUE != H5Oexists_by_name(fid, "group/external3", H5P_DEFAULT))
        TEST_ERROR


/* Soft->External links */
    /* Create soft-link in root group that points to dangling (file doesn't exist) external link */
    if(H5Lcreate_soft("external1", fid, "soft-elink1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "soft-elink1", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to dangling (object doesn't exist) external link */
    if(H5Lcreate_soft("external2", fid, "soft-elink2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "soft-elink2", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to external link that points to object */
    if(H5Lcreate_soft("external3", fid, "soft-elink3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "soft-elink3", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to dangling (file doesn't exist) external link in non-root group */
    if(H5Lcreate_soft("group/external1", fid, "soft-elink4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "soft-elink4", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to dangling (object doesn't exist) external link in non-root group */
    if(H5Lcreate_soft("group/external2", fid, "soft-elink5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "soft-elink5", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in root group that points to external link in non-root group that points to object */
    if(H5Lcreate_soft("group/external3", fid, "soft-elink6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "soft-elink6", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to dangling (file doesn't exist) external link */
    if(H5Lcreate_soft("/external1", fid, "group/soft-elink1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/soft-elink1", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to dangling (object doesn't exist) external link */
    if(H5Lcreate_soft("/external2", fid, "group/soft-elink2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/soft-elink2", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to external link that points to object */
    if(H5Lcreate_soft("/external3", fid, "group/soft-elink3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "group/soft-elink3", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to dangling (file doesn't exist) external link in non-root group */
    if(H5Lcreate_soft("/group/external1", fid, "group/soft-elink4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/soft-elink4", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to dangling (object doesn't exist) external link in non-root group */
    if(H5Lcreate_soft("/group/external2", fid, "group/soft-elink5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/soft-elink5", H5P_DEFAULT))
        TEST_ERROR

    /* Create soft-link in non-root group that points to external link in non-root group that points to object */
    if(H5Lcreate_soft("/group/external3", fid, "group/soft-elink6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "group/soft-elink6", H5P_DEFAULT))
        TEST_ERROR


/* External->Soft links */
    /* Create external link in root group that points to dangling soft link in root group */
    if(H5Lcreate_external(filename, "soft1", fid, "elink-soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "elink-soft1", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in root group that points to soft link in root group that points to object */
    if(H5Lcreate_external(filename, "soft2", fid, "elink-soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "elink-soft2", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in root group that points to dangling soft link in non-root group */
    if(H5Lcreate_external(filename, "group/soft1", fid, "elink-soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "elink-soft3", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in root group that points to soft link in root group that points to object */
    if(H5Lcreate_external(filename, "group/soft2", fid, "elink-soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "elink-soft4", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in non-root group that points to dangling soft link in root group */
    if(H5Lcreate_external(filename, "soft1", fid, "group/elink-soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/elink-soft1", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in non-root group that points to soft link in root group that points to object */
    if(H5Lcreate_external(filename, "soft2", fid, "group/elink-soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "group/elink-soft2", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in non-root group that points to dangling soft link in non-root group */
    if(H5Lcreate_external(filename, "group/soft1", fid, "group/elink-soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns FALSE */
    if(FALSE != H5Oexists_by_name(fid, "group/elink-soft3", H5P_DEFAULT))
        TEST_ERROR

    /* Create external link in non-root group that points to soft link in non-root group that points to object */
    if(H5Lcreate_external(filename, "group/soft2", fid, "group/elink-soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify that H5Oexists_by_name() returns TRUE */
    if(TRUE != H5Oexists_by_name(fid, "group/elink-soft4", H5P_DEFAULT))
        TEST_ERROR


    /* Close file created */
    if(H5Fclose(fid) < 0) FAIL_STACK_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Fclose(fid);
    } H5E_END_TRY;
    return -1;
} /* end obj_exists() */


/*-------------------------------------------------------------------------
 * Function:    corder_create_empty
 *
 * Purpose:     Create an empty group with creation order indices
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, October 30, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
corder_create_empty(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    crt_order_flags;   	/* Status of creation order info for GCPL */
    herr_t      ret;                    /* Generic return value */
    char        filename[NAME_BUF_SIZE];/* File name */

    TESTING("creating empty group with creation order indexing")

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Set creation order indexing on group */
    if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != 0) TEST_ERROR

    /* Setting invalid combination of a group order creation order indexing on should fail */
    H5E_BEGIN_TRY {
        ret = H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_INDEXED);
    } H5E_END_TRY;
    if(ret > 0) {
	H5_FAILED();
	HDputs("    H5Pset_link_create_order() should have failed for a creation order index with no tracking.");
	TEST_ERROR
    } /* end if */

    /* Set creation order tracking & indexing on group */
    if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != 0) TEST_ERROR
    if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR
    if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) TEST_ERROR

    /* Create group with creation order indexing & tracking on */
    if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Check on group's status */
    if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open group created */
    if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Check on group's status */
    if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve group creation property list for group */
    if((gcpl_id = H5Gget_create_plist(group_id)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) TEST_ERROR
    if(crt_order_flags != (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end corder_create_empty() */


/*-------------------------------------------------------------------------
 * Function:    corder_create_compact
 *
 * Purpose:     Create a group with creation order indices and insert links
 *              in it when in compact form
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, October 30, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
corder_create_compact(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    unsigned	nlinks;		        /* Number of link messages in group's header */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    unsigned    u;                      /* Local index variable */

    TESTING("creating compact group with creation order indexing")

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Set creation order tracking & indexing on group */
    if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR

    /* Create group with creation order indexing & tracking on */
    if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Check on group's initial status */
    if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Create several links, but keep group in compact form */
    for(u = 0; u < max_compact; u++) {
        sprintf(objname, "filler %u", u);
        if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group_id2) < 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR
        if(nlinks != (u + 1)) TEST_ERROR
        if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
        if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR
    } /* end for */

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open group created */
    if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR
    if(nlinks != max_compact) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

    /* Loop through links, checking their creation order values */
    /* (the name index is used, but the creation order value is in the same order) */
    for(u = 0; u < max_compact; u++) {
        H5L_info_t linfo;           /* Link information */

        /* Retrieve information for link */
        sprintf(objname, "filler %u", u);
        if(H5Lget_info(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR

        /* Verify creation order of link */
        if(linfo.corder_valid != TRUE) TEST_ERROR
        if(linfo.corder != u) TEST_ERROR
    } /* end for */

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end corder_create_compact() */


/*-------------------------------------------------------------------------
 * Function:    corder_create_dense
 *
 * Purpose:     Create a group with creation order indices and insert links
 *              in it until it's in dense form
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, October 30, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
corder_create_dense(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    unsigned	nlinks;		        /* Number of link messages in group's header */
    hsize_t     name_count;             /* # of records in name index */
    hsize_t     corder_count;           /* # of records in creation order index */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    unsigned    u;                      /* Local index variable */

    TESTING("creating dense group with creation order indexing")

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Set creation order tracking & indexing on group */
    if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR

    /* Create group with creation order indexing & tracking on */
    if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Check on group's initial status */
    if(H5G__is_empty_test(group_id) != TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Create several links, up to limit of compact form */
    for(u = 0; u < max_compact; u++) {
        sprintf(objname, "filler %u", u);
        if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group_id2) < 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR
        if(nlinks != (u + 1)) TEST_ERROR
        if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
        if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR
    } /* end for */

    /* Create another link, to push group into dense form */
    sprintf(objname, "filler %u", max_compact);
    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(group_id2) < 0) TEST_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve & verify # of records in the name & creation order indices */
    if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
    if(name_count != corder_count) TEST_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open group created */
    if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Loop through links, checking their creation order values */
    /* (the name index is used, but the creation order value is in the same order) */
    for(u = 0; u < (max_compact + 1); u++) {
        H5L_info_t linfo;           /* Link information */

        /* Retrieve information for link */
        sprintf(objname, "filler %u", u);
        if(H5Lget_info(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR

        /* Verify creation order of link */
        if(linfo.corder_valid != TRUE) TEST_ERROR
        if(linfo.corder != u) TEST_ERROR
    } /* end for */

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end corder_create_dense() */


/*-------------------------------------------------------------------------
 * Function:    corder_transition
 *
 * Purpose:     Create a group with creation order indices and verify correct
 *              transitions between compact & dense forms
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, October 30, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
corder_transition(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    unsigned	nlinks;		        /* Number of link messages in group's header */
    hsize_t     name_count;             /* # of records in name index */
    hsize_t     corder_count;           /* # of records in creation order index */
    h5_stat_size_t       empty_size;             /* Size of empty file */
    h5_stat_size_t       file_size;              /* Size of file after operating on it */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    unsigned    u;                      /* Local index variable */

    TESTING("transitioning group with creation order indexing between dense & compact forms")

    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) FAIL_STACK_ERROR

    /* Set creation order tracking & indexing on group */
    if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) FAIL_STACK_ERROR

    /* Increase estimated link info, so the group's object header is large
     *      enough to hold all the link messages in one chunk
     */
    if(H5Pset_est_link_info(gcpl_id, max_compact, CORDER_EST_ENTRY_LEN) < 0) TEST_ERROR

    /* Create group with creation order indexing & tracking on */
    if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) FAIL_STACK_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) FAIL_STACK_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

    /* Get the size of the file with an empty group */
    if((empty_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

    /* Open group created */
    if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Create several links, up to limit of compact form */
    for(u = 0; u < max_compact; u++) {
        sprintf(objname, "filler %u", u);
        if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group_id2) < 0) TEST_ERROR
    } /* end for */

    /* Create another link, to push group into dense form */
    sprintf(objname, "filler %u", max_compact);
    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
    if(H5Gclose(group_id2) < 0) TEST_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve & verify # of records in the name & creation order indices */
    if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
    if(name_count != corder_count) TEST_ERROR

    /* Delete several links from group, until it resumes compact form */
    for(u = max_compact; u >= min_dense; u--) {
        sprintf(objname, "filler %u", u);
        if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
        if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
        if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

        /* Retrieve & verify # of records in the name & creation order indices */
        if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
        if(name_count != corder_count) TEST_ERROR
    } /* end for */

    /* Delete another link, to push group into compact form */
    sprintf(objname, "filler %u", (min_dense - 1));
    if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR
    if(nlinks != (min_dense - 1)) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

    /* Re-add links to get back into dense form */
    for(u = (min_dense - 1); u < (max_compact + 1); u++) {
        sprintf(objname, "filler %u", u);
        if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group_id2) < 0) TEST_ERROR
    } /* end for */

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve & verify # of records in the name & creation order indices */
    if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
    if(name_count != corder_count) TEST_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR

    /* Open group created */
    if((group_id = H5Gopen2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve & verify # of records in the name & creation order indices */
    if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
    if(name_count != corder_count) TEST_ERROR

    /* Delete several links from group, until it resumes compact form */
    for(u = max_compact; u >= min_dense; u--) {
        sprintf(objname, "filler %u", u);
        if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
        if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
        if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

        /* Retrieve & verify # of records in the name & creation order indices */
        if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
        if(name_count != corder_count) TEST_ERROR
    } /* end for */

    /* Delete another link, to push group into compact form */
    sprintf(objname, "filler %u", (min_dense - 1));
    if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR

    /* Verify state of group */
    if(H5G__has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR
    if(nlinks != (min_dense - 1)) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

    /* Re-add links to get back into dense form */
    for(u = (min_dense - 1); u < (max_compact + 1); u++) {
        sprintf(objname, "filler %u", u);
        if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
        if(H5Gclose(group_id2) < 0) TEST_ERROR
    } /* end for */

    /* Verify state of group */
    if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
    if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
    if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

    /* Retrieve & verify # of records in the name & creation order indices */
    if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
    if(name_count != corder_count) TEST_ERROR

    /* Delete all the links */
    for(u = max_compact; u > 0; u--) {
        sprintf(objname, "filler %u", u);
        if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR
    } /* end for */
    sprintf(objname, "filler %u", (unsigned)0);
    if(H5Ldelete(group_id, objname, H5P_DEFAULT) < 0) TEST_ERROR

    /* Close the group */
    if(H5Gclose(group_id) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR

    /* Get the size of the file now */
    if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR
    if(file_size != empty_size) TEST_ERROR

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end corder_transition() */


/*-------------------------------------------------------------------------
 * Function:    corder_delete
 *
 * Purpose:     Create a group with creation order indices and verify correct
 *              deletion of creation order index when the group is in dense
 *              storage form and the group is unlinked
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, October 30, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
corder_delete(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    hsize_t     name_count;             /* # of records in name index */
    hsize_t     corder_count;           /* # of records in creation order index */
    unsigned    reopen_file;            /* Whether to re-open the file before deleting group */
    h5_stat_size_t       empty_size;             /* Size of empty file */
    h5_stat_size_t       file_size;              /* Size of file after operating on it */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    unsigned    u;                      /* Local index variable */

    TESTING("deleting group with creation order indexing in dense form")

    /* Loop to leave file open when deleting group, or to close & re-open file
     *  before deleting group */
    for(reopen_file = FALSE; reopen_file <= TRUE; reopen_file++) {
        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

	/* Creating file with latest format will enable paged aggregation with persistent fs */
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR

        /* Close file */
        if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

        /* Get the size of an empty file */
        if((empty_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR

        /* Re-open the file */
        if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

        /* Create group creation property list */
        if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) FAIL_STACK_ERROR

        /* Set creation order tracking & indexing on group */
        if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) TEST_ERROR

        /* Query the group creation properties */
        if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) FAIL_STACK_ERROR

        /* Increase estimated link info, so the group's object header is large
         *      enough to hold all the link messages in one chunk
         */
        if(H5Pset_est_link_info(gcpl_id, max_compact, CORDER_EST_ENTRY_LEN) < 0) TEST_ERROR

        /* Create group with creation order indexing & tracking on */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

        /* Close the group creation property list */
        if(H5Pclose(gcpl_id) < 0) FAIL_STACK_ERROR

        /* Create links until the group is in dense form */
        for(u = 0; u < max_compact * 2; u++) {
            sprintf(objname, "filler %u", u);
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
            if(H5Gclose(group_id2) < 0) FAIL_STACK_ERROR
        } /* end for */

        /* Verify state of group */
        if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
        if(H5G__has_stab_test(group_id) == TRUE) TEST_ERROR
        if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

        /* Retrieve & verify # of records in the name & creation order indices */
        if(H5G__new_dense_info_test(group_id, &name_count, &corder_count) < 0) TEST_ERROR
        if(name_count != corder_count) TEST_ERROR

        /* Close the group */
        if(H5Gclose(group_id) < 0) FAIL_STACK_ERROR

        /* Check for deleting group without re-opening file */
        if(!reopen_file)
            /* Delete the group with the creation order index */
            if(H5Ldelete(file_id, CORDER_GROUP_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR

        /* Check for deleting group after re-opening file */
        if(reopen_file) {
            /* Re-open the file */
            if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR

            /* Delete the group with the creation order index */
            if(H5Ldelete(file_id, CORDER_GROUP_NAME, H5P_DEFAULT) < 0) FAIL_STACK_ERROR

            /* Close the file */
            if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR
        } /* end if */

        /* Get the size of the file now */
        if((file_size = h5_get_file_size(filename, fapl)) < 0) TEST_ERROR
        if(file_size != empty_size) TEST_ERROR
    } /* end for */

    PASSED();
    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end corder_delete() */


/*-------------------------------------------------------------------------
 * Function:    link_info_by_idx_check
 *
 * Purpose:     Support routine for link_info_by_idx, to verify the link
 *              info is correct for a link
 *
 * Note:	This routine assumes that the links have been inserted in the
 *              group in alphabetical order.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November  7, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n,
    hbool_t hard_link, hbool_t use_index)
{
    char tmpname[NAME_BUF_SIZE];        /* Temporary link name */
    char valname[NAME_BUF_SIZE];        /* Link value name */
    char tmpval[NAME_BUF_SIZE];         /* Temporary link value */
    H5L_info_t  linfo;                  /* Link info struct */

    /* Make link value for increasing/native order queries */
    sprintf(valname, "value %02u", (unsigned)n);

    /* Verify the link information for first link, in increasing creation order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != 0) TEST_ERROR

    /* Verify the link information for new link, in increasing creation order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != (int64_t)n) TEST_ERROR

    /* Verify value for new soft link, in increasing creation order */
    if(!hard_link) {
        HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE);
        if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
        if(HDstrcmp(valname, tmpval)) TEST_ERROR
    } /* end if */

    /* Verify the name for new link, in increasing creation order */
    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
    if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
    if(HDstrcmp(linkname, tmpname)) TEST_ERROR

    /* Don't test "native" order if there is no creation order index, since
     *  there's not a good way to easily predict the link's order in the name
     *  index.
     */
    if(use_index) {
        /* Verify the link information for first link, in native creation order (which is increasing) */
        HDmemset(&linfo, 0, sizeof(linfo));
        if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
        if(linfo.corder != 0) TEST_ERROR

        /* Verify the link information for new link, in native creation order (which is increasing) */
        HDmemset(&linfo, 0, sizeof(linfo));
        if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
        if(linfo.corder != (int64_t)n) TEST_ERROR

        /* Verify value for new soft link, in native creation order (which is increasing) */
        if(!hard_link) {
            HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE);
            if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(HDstrcmp(valname, tmpval)) TEST_ERROR
        } /* end if */

        /* Verify the name for new link, in native creation order (which is increasing) */
        HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
        if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
        if(HDstrcmp(linkname, tmpname)) TEST_ERROR
    } /* end if */

    /* Verify the link information for first link, in decreasing creation order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != 0) TEST_ERROR

    /* Verify the link information for new link, in decreasing creation order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != (int64_t)n) TEST_ERROR

    /* Verify value for new soft link, in decreasing creation order */
    if(!hard_link) {
        HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE);
        if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
        if(HDstrcmp(valname, tmpval)) TEST_ERROR
    } /* end if */

    /* Verify the name for new link, in decreasing creation order */
    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
    if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
    if(HDstrcmp(linkname, tmpname)) TEST_ERROR


    /* Verify the link information for first link, in increasing link name order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != 0) TEST_ERROR

    /* Verify the link information for new link, in increasing link name order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != (int64_t)n) TEST_ERROR

    /* Verify value for new soft link, in increasing link name order */
    if(!hard_link) {
        HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE);
        if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
        if(HDstrcmp(valname, tmpval)) TEST_ERROR
    } /* end if */

    /* Verify the name for new link, in increasing link name order */
    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
    if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
    if(HDstrcmp(linkname, tmpname)) TEST_ERROR

    /* Don't test "native" order queries on link name order, since there's not
     *  a good way to easily predict the order of the links in the name index.
     */

    /* Verify the link information for first link, in decreasing link name order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != 0) TEST_ERROR

    /* Verify the link information for new link, in decreasing link name order */
    HDmemset(&linfo, 0, sizeof(linfo));
    if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
    if(linfo.corder != (int64_t)n) TEST_ERROR

    /* Verify value for new soft link, in decreasing link name order */
    if(!hard_link) {
        HDmemset(tmpval, 0, (size_t)NAME_BUF_SIZE);
        if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
        if(HDstrcmp(valname, tmpval)) TEST_ERROR
    } /* end if */

    /* Verify the name for new link, in decreasing link name order */
    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
    if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
    if(HDstrcmp(linkname, tmpname)) TEST_ERROR

    /* Success */
    return(0);

error:
    /* Failure */
    return(-1);
} /* end link_info_by_idx_check() */


/*-------------------------------------------------------------------------
 * Function:    link_info_by_idx
 *
 * Purpose:     Create a group with creation order indices and test querying
 *              info by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November  6, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_info_by_idx(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    unsigned    hard_link;              /* Create hard or soft link? */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    H5L_info_t  linfo;                  /* Link info struct */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value name */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        tmpname[NAME_BUF_SIZE]; /* Temporary link name */
    unsigned    u;                      /* Local index variable */
    ssize_t     name_len;               /* Length of name */
    herr_t      ret;                    /* Generic return value */

    /* Loop over creating hard or soft links */
    for(hard_link = FALSE; hard_link <= TRUE; hard_link++) {
        /* Loop over using index for creation order value */
        for(use_index = FALSE; use_index <= TRUE; use_index++) {
            if(hard_link) {
                if(use_index)
                    TESTING("querying info by index w/creation order index, using hard links")
                else
                    TESTING("querying info by index w/o creation order index, using hard links")
            } /* end if */
            else {
                if(use_index)
                    TESTING("querying info by index w/creation order index, using soft links")
                else
                    TESTING("querying info by index w/o creation order index, using soft links")
            } /* end else */

            /* Create file */
            h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
            if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

            /* Create group creation property list */
            if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

            /* Set creation order tracking & indexing on group */
            if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

            /* Create group with creation order indexing & tracking on */
            if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Query the group creation properties */
            if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

            /* Check for query on empty group */
            H5E_BEGIN_TRY {
                ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT);
            } H5E_END_TRY;
            if(ret >= 0) TEST_ERROR
            H5E_BEGIN_TRY {
                name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT);
            } H5E_END_TRY;
            if(name_len >= 0) TEST_ERROR

            /* Create several links, up to limit of compact form */
            for(u = 0; u < max_compact; u++) {
                /* Make name for link */
                sprintf(objname, "filler %02u", u);

                /* Check for creating hard or soft link */
                if(hard_link) {
                    hid_t group_id2;	        /* Group ID */

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR
                } /* end if */
                else {
                    /* Make value for link */
                    sprintf(valname, "value %02u", u);

                    /* Create soft link */
                    if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end else */

                /* Verify link information for new link */
                if(link_info_by_idx_check(group_id, objname, (hsize_t)u, hard_link, use_index) < 0) TEST_ERROR
            } /* end for */

            /* Verify state of group */
            if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

            /* Check for out of bound offset queries */
            H5E_BEGIN_TRY {
                ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT);
            } H5E_END_TRY;
            if(ret >= 0) TEST_ERROR
            H5E_BEGIN_TRY {
                ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT);
            } H5E_END_TRY;
            if(ret >= 0) TEST_ERROR
            H5E_BEGIN_TRY {
                name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT);
            } H5E_END_TRY;
            if(name_len >= 0) TEST_ERROR

            /* Create more links, to push group into dense form */
            for(; u < (max_compact * 2); u++) {
                /* Make name for link */
                sprintf(objname, "filler %02u", u);

                /* Check for creating hard or soft link */
                if(hard_link) {
                    hid_t group_id2;	        /* Group ID */

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR
                } /* end if */
                else {
                    /* Make value for link */
                    sprintf(valname, "value %02u", u);

                    /* Create soft link */
                    if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end else */

                /* Verify state of group */
                if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                /* Verify link information for new link */
                if(link_info_by_idx_check(group_id, objname, (hsize_t)u, hard_link, use_index) < 0) TEST_ERROR
            } /* end for */

            /* Check for out of bound offset queries */
            H5E_BEGIN_TRY {
                ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT);
            } H5E_END_TRY;
            if(ret >= 0) TEST_ERROR
            H5E_BEGIN_TRY {
                ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT);
            } H5E_END_TRY;
            if(ret >= 0) TEST_ERROR
            H5E_BEGIN_TRY {
                name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT);
            } H5E_END_TRY;
            if(name_len >= 0) TEST_ERROR

            /* Close the group */
            if(H5Gclose(group_id) < 0) TEST_ERROR

            /* Close the group creation property list */
            if(H5Pclose(gcpl_id) < 0) TEST_ERROR

            /* Close the file */
            if(H5Fclose(file_id) < 0) TEST_ERROR

            PASSED();
        } /* end for */
    } /* end for */

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end link_info_by_idx() */


/*-------------------------------------------------------------------------
 * Function:    link_info_by_idx_old
 *
 * Purpose:     Create a old-format group and test querying
 *              info by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November  7, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_info_by_idx_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    unsigned    hard_link;              /* Create hard or soft link? */
    H5L_info_t  linfo;                  /* Link info struct */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value name */
    char        filename[NAME_BUF_SIZE];/* File name */
    haddr_t     objno[CORDER_NLINKS];   /* Addresses of the objects created */
    char        tmpname[NAME_BUF_SIZE]; /* Temporary link name */
    char        tmpval[NAME_BUF_SIZE];  /* Temporary link value */
    unsigned    u;                      /* Local index variable */
    ssize_t     name_len;               /* Length of name */
    herr_t      ret;                    /* Generic return value */

    /* Loop over creating hard or soft links */
    for(hard_link = FALSE; hard_link <= TRUE; hard_link++) {
        if(hard_link)
            TESTING("querying info by index in old-style group, using hard links")
        else
            TESTING("querying info by index in old-style group, using soft links")

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group to operate on */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Check for creating hard or soft link */
            if(hard_link) {
                H5O_info_t oi;                  /* Buffer for querying object's info */

                /* Create group */
                if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Retrieve group's address on disk */
                if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
                objno[u] = oi.addr;

                /* Close group */
                if(H5Gclose(group_id2) < 0) TEST_ERROR
            } /* end if */
            else {
                /* Make value for link */
                sprintf(valname, "value %02u", u);

                /* Create soft link */
                if(H5Lcreate_soft(valname, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
            } /* end else */
        } /* end for */

        /* Verify link information for created links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            unsigned dec_u = CORDER_NLINKS - (u + 1);       /* Decreasing mapped index */

            /* Make link name for increasing/native order queries */
            sprintf(objname, "filler %02u", u);

            /* Make link value for increasing/native order queries */
            sprintf(valname, "value %02u", u);

            /* Verify link information (in increasing order) */
            if(hard_link) {
                if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR
            } /* end if */
            else {
                if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                if(HDstrcmp(valname, tmpval)) TEST_ERROR
            } /* end else */

            /* Verify link name (in increasing order) */
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(HDstrcmp(objname, tmpname)) TEST_ERROR


            /* Verify link information (in native order - native is increasing) */
            if(hard_link) {
                if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR
            } /* end if */
            else {
                if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                if(HDstrcmp(valname, tmpval)) TEST_ERROR
            } /* end else */

            /* Verify link name (in native order - native is increasing) */
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(HDstrcmp(objname, tmpname)) TEST_ERROR


            /* Make link name for decreasing order queries */
            sprintf(objname, "filler %02u", dec_u);

            /* Make link value for decreasing order queries */
            sprintf(valname, "value %02u", dec_u);

            /* Verify link information (in decreasing order) */
            if(hard_link) {
                if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR
            } /* end if */
            else {
                if(H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                if(HDstrcmp(valname, tmpval)) TEST_ERROR
            } /* end else */

            /* Verify link name (in decreasing order) */
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(HDstrcmp(objname, tmpname)) TEST_ERROR
        } /* end for */

        /* Check for creation order index queries */
        H5E_BEGIN_TRY {
            ret = H5Lget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR
        H5E_BEGIN_TRY {
            name_len = H5Lget_name_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT);
        } H5E_END_TRY;
        if(name_len >= 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Close the group */
        if(H5Gclose(group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end link_info_by_idx_old() */


/*-------------------------------------------------------------------------
 * Function:    delete_by_idx
 *
 * Purpose:     Create a group with creation order indices and test deleting
 *              links by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 14, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
delete_by_idx(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    H5_index_t idx_type;               /* Type of index to operate on */
    H5_iter_order_t order;              /* Order within in the index */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    H5L_info_t  linfo;                  /* Link info struct */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        tmpname[NAME_BUF_SIZE]; /* Temporary link name */
    unsigned    u;                      /* Local index variable */
    herr_t      ret;                    /* Generic return value */

    /* Loop over operating on different indices on link fields */
    for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; H5_INC_ENUM(H5_index_t, idx_type)) {
        /* Loop over operating in different orders */
        for(order = H5_ITER_INC; order <=H5_ITER_DEC; H5_INC_ENUM(H5_iter_order_t, order)) {
            /* Loop over using index for creation order value */
            for(use_index = FALSE; use_index <= TRUE; use_index++) {
                /* Print appropriate test message */
                if(idx_type == H5_INDEX_CRT_ORDER) {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("deleting links by creation order index in increasing order w/creation order index")
                        else
                            TESTING("deleting links by creation order index in increasing order w/o creation order index")
                    } /* end if */
                    else {
                        if(use_index)
                            TESTING("deleting links by creation order index in decreasing order w/creation order index")
                        else
                            TESTING("deleting links by creation order index in decreasing order w/o creation order index")
                    } /* end else */
                } /* end if */
                else {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("deleting links by name index in increasing order w/creation order index")
                        else
                            TESTING("deleting links by name index in increasing order w/o creation order index")
                    } /* end if */
                    else {
                        if(use_index)
                            TESTING("deleting links by name index in decreasing order w/creation order index")
                        else
                            TESTING("deleting links by name index in decreasing order w/o creation order index")
                    } /* end else */
                } /* end else */

                /* Create file */
                h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
                if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

                /* Create group creation property list */
                if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

                /* Set creation order tracking & indexing on group */
                if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

                /* Create group with creation order tracking on */
                if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Query the group creation properties */
                if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR


                /* Delete links from one end */


                /* Check for deletion on empty group */
                H5E_BEGIN_TRY {
                    ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Check for deletion on non-existing group */
                H5E_BEGIN_TRY {
                    ret = H5Ldelete_by_idx(group_id, "None", idx_type, order, (hsize_t)0, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Create several links, up to limit of compact form */
                for(u = 0; u < max_compact; u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Verify link information for new link */
                    if(link_info_by_idx_check(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (compact) */
                if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

                /* Check for out of bound deletion */
                H5E_BEGIN_TRY {
                    ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Delete links from compact group */
                for(u = 0; u < (max_compact - 1); u++) {
                    /* Delete first link in appropriate order */
                    if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Verify the link information for first link in appropriate order */
                    HDmemset(&linfo, 0, sizeof(linfo));
                    if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC) {
                        if(linfo.corder != (u + 1)) TEST_ERROR
                    } /* end if */
                    else {
                        if(linfo.corder != (max_compact - (u + 2))) TEST_ERROR
                    } /* end else */

                    /* Verify the name for first link in appropriate order */
                    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
                    if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC)
                        sprintf(objname, "filler %02u", (u + 1));
                    else
                        sprintf(objname, "filler %02u", (max_compact - (u + 2)));
                    if(HDstrcmp(objname, tmpname)) TEST_ERROR
                } /* end for */

                /* Delete last link */
                if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                /* Verify state of group (empty) */
                if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR

                /* Create more links, to push group into dense form */
                for(u = 0; u < (max_compact * 2); u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Verify state of group (dense) */
                    if(u >= max_compact)
                        if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                    /* Verify link information for new link */
                    if(link_info_by_idx_check(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR
                } /* end for */

                /* Check for out of bound deletion again */
                H5E_BEGIN_TRY {
                    ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Delete links from dense group, in appropriate order */
                for(u = 0; u < ((max_compact * 2) - 1); u++) {
                    /* Delete first link in appropriate order */
                    if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Verify the link information for first link in appropriate order */
                    HDmemset(&linfo, 0, sizeof(linfo));
                    if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC) {
                        if(linfo.corder != (u + 1)) TEST_ERROR
                    } /* end if */
                    else {
                        if(linfo.corder != ((max_compact * 2) - (u + 2))) TEST_ERROR
                    } /* end else */

                    /* Verify the name for first link in appropriate order */
                    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
                    if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC)
                        sprintf(objname, "filler %02u", (u + 1));
                    else
                        sprintf(objname, "filler %02u", ((max_compact * 2) - (u + 2)));
                    if(HDstrcmp(objname, tmpname)) TEST_ERROR
                } /* end for */

                /* Delete last link */
                if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                /* Verify state of group (empty) */
                if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
                if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR

                /* Check for deletion on empty group again */
                H5E_BEGIN_TRY {
                    ret = H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR


                /* Delete links in middle */


                /* Create more links, to push group into dense form */
                for(u = 0; u < (max_compact * 2); u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Verify state of group (dense) */
                    if(u >= max_compact)
                        if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                    /* Verify link information for new link */
                    if(link_info_by_idx_check(group_id, objname, (hsize_t)u, TRUE, use_index) < 0) TEST_ERROR
                } /* end for */

                /* Delete every other link from dense group, in appropriate order */
                for(u = 0; u < max_compact; u++) {
                    /* Delete link */
                    if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Verify the link information for current link in appropriate order */
                    HDmemset(&linfo, 0, sizeof(linfo));
                    if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC) {
                        if(linfo.corder != ((u * 2) + 1)) TEST_ERROR
                    } /* end if */
                    else {
                        if(linfo.corder != ((max_compact * 2) - ((u * 2) + 2))) TEST_ERROR
                    } /* end else */

                    /* Verify the name for current link in appropriate order */
                    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
                    if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC)
                        sprintf(objname, "filler %02u", ((u * 2) + 1));
                    else
                        sprintf(objname, "filler %02u", ((max_compact * 2) - ((u * 2) + 2)));
                    if(HDstrcmp(objname, tmpname)) TEST_ERROR
                } /* end for */

                /* Delete remaining links from dense group, in appropriate order */
                for(u = 0; u < (max_compact - 1); u++) {
                    /* Delete link */
                    if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Verify the link information for first link in appropriate order */
                    HDmemset(&linfo, 0, sizeof(linfo));
                    if(H5Lget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC) {
                        if(linfo.corder != ((u * 2) + 3)) TEST_ERROR
                    } /* end if */
                    else {
                        if(linfo.corder != ((max_compact * 2) - ((u * 2) + 4))) TEST_ERROR
                    } /* end else */

                    /* Verify the name for first link in appropriate order */
                    HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
                    if(H5Lget_name_by_idx(group_id, ".", idx_type, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
                    if(order == H5_ITER_INC)
                        sprintf(objname, "filler %02u", ((u * 2) + 3));
                    else
                        sprintf(objname, "filler %02u", ((max_compact * 2) - ((u * 2) + 4)));
                    if(HDstrcmp(objname, tmpname)) TEST_ERROR
                } /* end for */

                /* Delete last link */
                if(H5Ldelete_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

                /* Verify state of group (empty) */
                if(H5G__has_links_test(group_id, NULL) == TRUE) TEST_ERROR
                if(H5G__is_new_dense_test(group_id) == TRUE) TEST_ERROR



                /* Close the group */
                if(H5Gclose(group_id) < 0) TEST_ERROR

                /* Close the group creation property list */
                if(H5Pclose(gcpl_id) < 0) TEST_ERROR

                /* Close the file */
                if(H5Fclose(file_id) < 0) TEST_ERROR

                PASSED();
            } /* end for */
        } /* end for */
    } /* end for */

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;
    return -1;
} /* end delete_by_idx() */


/*-------------------------------------------------------------------------
 * Function:    delete_by_idx_old
 *
 * Purpose:     Create a old-format group and test deleting
 *              links by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Wednesday, November 15, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
delete_by_idx_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1), group_id2 = (-1);	/* Group IDs */
    H5L_info_t  linfo;                  /* Link info struct */
    H5_iter_order_t order;              /* Order within in the index */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    haddr_t     objno[CORDER_NLINKS];   /* Addresses of the objects created */
    char        tmpname[NAME_BUF_SIZE]; /* Temporary link name */
    unsigned    u;                      /* Local index variable */
    herr_t      ret;                    /* Generic return value */

    /* Loop over operating in different orders */
    for(order = H5_ITER_INC; order <=H5_ITER_DEC; H5_INC_ENUM(H5_iter_order_t, order)) {
        /* Print test banner */
        if(order == H5_ITER_INC)
            TESTING("deleting links by index in increasing order in old-style group")
        else
            TESTING("deleting links by index in decreasing order in old-style group")

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group to operate on */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


        /* Delete links from one end */


        /* Check for deletion in empty group */
        H5E_BEGIN_TRY {
            ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            H5O_info_t oi;                  /* Buffer for querying object's info */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create group */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Retrieve group's address on disk */
            if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
            objno[u] = oi.addr;

            /* Close group */
            if(H5Gclose(group_id2) < 0) TEST_ERROR
        } /* end for */

        /* Check for bad index type deletion */
        H5E_BEGIN_TRY {
            ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)0, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Check for out of bounds deletion */
        H5E_BEGIN_TRY {
            ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Delete links, in appropriate order */
        for(u = 0; u < (CORDER_NLINKS - 1); u++) {
            unsigned dec_u = CORDER_NLINKS - (u + 2);       /* Decreasing mapped index */

            /* Delete first link in appropriate order */
            if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

            /* Verify the link information for first link in appropriate order */
            HDmemset(&linfo, 0, sizeof(linfo));
            if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC) {
                if(H5F_addr_ne(linfo.u.address, objno[u + 1])) TEST_ERROR
            } /* end if */
            else {
                if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR
            } /* end else */

            /* Verify the name for first link in appropriate order */
            HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC)
                sprintf(objname, "filler %02u", (u + 1));
            else
                sprintf(objname, "filler %02u", dec_u);
            if(HDstrcmp(objname, tmpname)) TEST_ERROR
        } /* end for */

        /* Delete last link */
        if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

        /* Check for deletion in empty group (again) */
        H5E_BEGIN_TRY {
            ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR


        /* Delete links in middle */


        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            H5O_info_t oi;                  /* Buffer for querying object's info */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create group */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Retrieve group's address on disk */
            if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
            objno[u] = oi.addr;

            /* Close group */
            if(H5Gclose(group_id2) < 0) TEST_ERROR
        } /* end for */

        /* Delete every other link from group, in appropriate order */
        for(u = 0; u < (CORDER_NLINKS / 2); u++) {
            unsigned dec_u = CORDER_NLINKS - ((u * 2) + 2);       /* Decreasing mapped index */

            /* Delete link */
            if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, H5P_DEFAULT) < 0) TEST_ERROR

            /* Verify the link information for current link in appropriate order */
            HDmemset(&linfo, 0, sizeof(linfo));
            if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC) {
                if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 1])) TEST_ERROR
            } /* end if */
            else {
                if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR
            } /* end else */

            /* Verify the name for current link in appropriate order */
            HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC)
                sprintf(objname, "filler %02u", ((u * 2) + 1));
            else
                sprintf(objname, "filler %02u", dec_u);
            if(HDstrcmp(objname, tmpname)) TEST_ERROR
        } /* end for */

        /* Delete remaining links from group, in appropriate order */
        for(u = 0; u < ((CORDER_NLINKS / 2) - 1); u++) {
            unsigned dec_u = CORDER_NLINKS - ((u * 2) + 4);       /* Decreasing mapped index */

            /* Delete link */
            if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

            /* Verify the link information for first link in appropriate order */
            HDmemset(&linfo, 0, sizeof(linfo));
            if(H5Lget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC) {
                if(H5F_addr_ne(linfo.u.address, objno[(u * 2) + 3])) TEST_ERROR
            } /* end if */
            else {
                if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR
            } /* end else */

            /* Verify the name for first link in appropriate order */
            HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE);
            if(H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR
            if(order == H5_ITER_INC)
                sprintf(objname, "filler %02u", ((u * 2) + 3));
            else
                sprintf(objname, "filler %02u", dec_u);
            if(HDstrcmp(objname, tmpname)) TEST_ERROR
        } /* end for */

        /* Delete last link */
        if(H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT) < 0) TEST_ERROR

        /* Verify state of group */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Close the group */
        if(H5Gclose(group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    return -1;
} /* end delete_by_idx_old() */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_cb
 *
 * Purpose:     Callback routine for iterating over links in group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_cb(hid_t group_id, const char *link_name, const H5L_info_t *info,
    void *_op_data)
{
    link_iter_info_t *op_data = (link_iter_info_t *)_op_data;   /* User data */
    char objname[NAME_BUF_SIZE]; /* Object name */
    H5L_info_t my_info;         /* Local link info */

    /* Increment # of times the callback was called */
    op_data->ncalled++;

    /* Get the link information directly to compare */
    if(H5Lget_info(group_id, link_name, &my_info, H5P_DEFAULT) < 0)
        return(H5_ITER_ERROR);

    /* Check more things for link iteration (vs. group iteration) */
    if(info) {
        /* Check for correct order of iteration */
        /* (if we are operating in increasing or decreasing order) */
        if(op_data->order != H5_ITER_NATIVE)
            if(info->corder != op_data->curr)
                return(H5_ITER_ERROR);

        /* Compare link info structs */
        if(info->type != my_info.type)
            return(H5_ITER_ERROR);
        if(info->corder_valid != my_info.corder_valid)
            return(H5_ITER_ERROR);
        if(info->corder != my_info.corder)
            return(H5_ITER_ERROR);
        if(info->cset != my_info.cset)
            return(H5_ITER_ERROR);
        if(H5F_addr_ne(info->u.address, my_info.u.address))
            return(H5_ITER_ERROR);
    } /* end if */

    /* Verify name of link */
    sprintf(objname, "filler %02u", (unsigned)my_info.corder);
    if(HDstrcmp(link_name, objname))
        return(H5_ITER_ERROR);

    /* Check if we've visited this link before */
    if((size_t)op_data->curr >= op_data->max_visit)
        return(H5_ITER_ERROR);
    if(op_data->visited[op_data->curr])
        return(H5_ITER_ERROR);
    op_data->visited[op_data->curr] = TRUE;

    /* Advance to next value, in correct direction */
    if(op_data->order != H5_ITER_DEC)
        op_data->curr++;
    else
        op_data->curr--;

    /* Check for stopping in the middle of iterating */
    if(op_data->stop > 0)
        if(--op_data->stop == 0)
            return(CORDER_ITER_STOP);

    return(H5_ITER_CONT);
} /* end link_iterate_cb() */

#ifndef H5_NO_DEPRECATED_SYMBOLS

/*-------------------------------------------------------------------------
 * Function:    group_iterate_cb
 *
 * Purpose:     Callback routine for iterating over links in group with
 *              H5Giterate()
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
group_iterate_cb(hid_t group_id, const char *link_name, void *_op_data)
{
    return(link_iterate_cb(group_id, link_name, NULL, _op_data));
} /* end group_iterate_cb() */
#endif /* H5_NO_DEPRECATED_SYMBOLS */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_fail_cb
 *
 * Purpose:     Callback routine for iterating over links in group that
 *              always returns failure
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_fail_cb(hid_t H5_ATTR_UNUSED group_id, const char H5_ATTR_UNUSED *link_name,
    const H5L_info_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data)
{
    return(H5_ITER_ERROR);
} /* end link_iterate_fail_cb() */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_check
 *
 * Purpose:     Check iteration over links in a group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_check(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order,
    unsigned max_links, link_iter_info_t *iter_info)
{
    unsigned    v;                      /* Local index variable */
    hsize_t     skip;                   /* # of links to skip in group */
#ifndef H5_NO_DEPRECATED_SYMBOLS
    int         gskip;                  /* # of links to skip in group, with H5Giterate */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
    herr_t      ret;                    /* Generic return value */

    /* Iterate over links in group */
    iter_info->nskipped = (unsigned)(skip = 0);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(skip != max_links) TEST_ERROR
    for(v = 0; v < max_links; v++)
        if(iter_info->visited[v] == FALSE) TEST_ERROR


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Iterate over links in group, with H5Giterate */
    iter_info->nskipped = (unsigned)(gskip = 0);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Giterate(group_id, ".", &gskip, group_iterate_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(gskip != (int)max_links) TEST_ERROR
    for(v = 0; v < max_links; v++)
        if(iter_info->visited[v] == FALSE) TEST_ERROR
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Skip over some links in group */
    iter_info->nskipped = (unsigned)(skip = max_links / 2);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip));
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(skip != max_links) TEST_ERROR
    if(order == H5_ITER_INC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR
    } /* end if */
    else if(order == H5_ITER_DEC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v] == FALSE) TEST_ERROR
    } /* end if */
    else {
        unsigned nvisit = 0;        /* # of links visited */

        HDassert(order == H5_ITER_NATIVE);
        for(v = 0; v < max_links; v++)
            if(iter_info->visited[v] == TRUE)
                nvisit++;

        if(nvisit != (max_links / 2)) TEST_ERROR
    } /* end else */


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Skip over some links in group, with H5Giterate */
    iter_info->nskipped = (unsigned)(gskip = (int)(max_links / 2));
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? (unsigned)gskip : ((max_links - 1) - (unsigned)gskip);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Giterate(group_id, ".", &gskip, group_iterate_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(gskip != (int)max_links) TEST_ERROR
    if(order == H5_ITER_INC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR
    } /* end if */
    else if(order == H5_ITER_DEC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v] == FALSE) TEST_ERROR
    } /* end if */
    else {
        unsigned nvisit = 0;        /* # of links visited */

        HDassert(order == H5_ITER_NATIVE);
        for(v = 0; v < max_links; v++)
            if(iter_info->visited[v] == TRUE)
                nvisit++;

        if(nvisit != (max_links / 2)) TEST_ERROR
    } /* end else */
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Iterate over links in group, stopping in the middle */
    iter_info->nskipped = (unsigned)(skip = 0);
    iter_info->order = order;
    iter_info->stop = 3;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if((ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, iter_info)) < 0) TEST_ERROR
    if(ret != CORDER_ITER_STOP) TEST_ERROR
    if(iter_info->ncalled != 3) TEST_ERROR


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Iterate over links in group, stopping in the middle, with H5Giterate() */
    iter_info->nskipped = (unsigned)(gskip = 0);
    iter_info->order = order;
    iter_info->stop = 3;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if((ret = H5Giterate(group_id, ".", &gskip, group_iterate_cb, iter_info)) < 0) TEST_ERROR
    if(ret != CORDER_ITER_STOP) TEST_ERROR
    if(iter_info->ncalled != 3) TEST_ERROR
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Check for iteration routine indicating failure */
    skip = 0;
    H5E_BEGIN_TRY {
        ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_fail_cb, NULL);
    } H5E_END_TRY;
    if(ret >= 0) TEST_ERROR

    /* Success */
    return(0);

error:
    return(-1);
} /* end link_iterate_check() */


/*-------------------------------------------------------------------------
 * Function:    link_iterate
 *
 * Purpose:     Create a group with creation order indices and test iterating over
 *              links by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 14, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    H5_index_t idx_type;               /* Type of index to operate on */
    H5_iter_order_t order;              /* Order within in the index */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    link_iter_info_t iter_info;         /* Iterator info */
    hbool_t     *visited = NULL;        /* Array of flags for visiting links */
    hsize_t     skip;                   /* # of links to skip in group */
    unsigned    u;                      /* Local index variable */
    herr_t      ret;                    /* Generic return value */

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Allocate the "visited link" array */
    iter_info.max_visit = max_compact * 2;
    if(NULL == (visited = (hbool_t *)HDmalloc(sizeof(hbool_t) * iter_info.max_visit))) TEST_ERROR
    iter_info.visited = visited;

    /* Loop over operating on different indices on link fields */
    for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; H5_INC_ENUM(H5_index_t, idx_type)) {
        /* Loop over operating in different orders */
        for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
            /* Loop over using index for creation order value */
            for(use_index = FALSE; use_index <= TRUE; use_index++) {
                /* Print appropriate test message */
                if(idx_type == H5_INDEX_CRT_ORDER) {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("iterating over links by creation order index in increasing order w/creation order index")
                        else
                            TESTING("iterating over links by creation order index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("iterating over links by creation order index in decreasing order w/creation order index")
                        else
                            TESTING("iterating over links by creation order index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("iterating over links by creation order index in native order w/creation order index")
                        else
                            TESTING("iterating over links by creation order index in native order w/o creation order index")
                    } /* end else */
                } /* end if */
                else {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("iterating over links by name index in increasing order w/creation order index")
                        else
                            TESTING("iterating over links by name index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("iterating over links by name index in decreasing order w/creation order index")
                        else
                            TESTING("iterating over links by name index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("iterating over links by name index in native order w/creation order index")
                        else
                            TESTING("iterating over links by name index in native order w/o creation order index")
                    } /* end else */
                } /* end else */

                /* Create file */
                h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
                if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

                /* Set creation order tracking & indexing on group */
                if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

                /* Create group with creation order tracking on */
                if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                /* Check for iteration on empty group */
                /* (should be OK) */
                if(H5Literate(group_id, idx_type, order, NULL, link_iterate_cb, NULL) < 0) TEST_ERROR

                /* Create several links, up to limit of compact form */
                for(u = 0; u < max_compact; u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (compact) */
                if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

                /* Check for out of bound iteration on compact group */
                skip = (hsize_t)u;
                H5E_BEGIN_TRY {
                    ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, NULL);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Test iteration over links in compact group */
                if(link_iterate_check(group_id, idx_type, order, u, &iter_info) < 0) TEST_ERROR


                /* Create more links, to push group into dense form */
                for(; u < (max_compact * 2); u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
                    if(H5Gclose(group_id2) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (dense) */
                if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                /* Check for out of bound iteration on dense group */
                skip = (hsize_t)u;
                H5E_BEGIN_TRY {
                    ret = H5Literate(group_id, idx_type, order, &skip, link_iterate_cb, NULL);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Test iteration over links in dense group */
                if(link_iterate_check(group_id, idx_type, order, u, &iter_info) < 0) TEST_ERROR


                /* Close the group */
                if(H5Gclose(group_id) < 0) TEST_ERROR

                /* Close the file */
                if(H5Fclose(file_id) < 0) TEST_ERROR

                PASSED();
            } /* end for */
        } /* end for */
    } /* end for */

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Free resources */
    if(visited)
        HDfree(visited);

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    if(visited)
        HDfree(visited);

    return -1;
} /* end link_iterate() */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_old_cb
 *
 * Purpose:     Callback routine for iterating over [old] links in group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_old_cb(hid_t group_id, const char *link_name, const H5L_info_t *info,
    void *_op_data)
{
    link_iter_info_t *op_data = (link_iter_info_t *)_op_data;   /* User data */
    char objname[NAME_BUF_SIZE]; /* Object name */
    H5L_info_t my_info;         /* Local link info */

    /* Increment # of times the callback was called */
    op_data->ncalled++;

    /* Get the link information directly to compare */
    if(H5Lget_info(group_id, link_name, &my_info, H5P_DEFAULT) < 0)
        return(H5_ITER_ERROR);

    /* Check more things for link iteration (vs. group iteration) */
    if(info) {
        /* Compare link info structs */
        if(info->type != my_info.type)
            return(H5_ITER_ERROR);
        if(info->corder_valid != my_info.corder_valid)
            return(H5_ITER_ERROR);
        if(info->corder != my_info.corder)
            return(H5_ITER_ERROR);
        if(info->cset != my_info.cset)
            return(H5_ITER_ERROR);
        if(H5F_addr_ne(info->u.address, my_info.u.address))
            return(H5_ITER_ERROR);
    } /* end if */

    /* Verify name of link */
    sprintf(objname, "filler %02u", (info ? (unsigned)op_data->curr : (unsigned)((op_data->ncalled - 1) + op_data->nskipped)));
    if(HDstrcmp(link_name, objname))
        return(H5_ITER_ERROR);

    /* Check if we've visited this link before */
    if((size_t)op_data->curr >= op_data->max_visit)
        return(H5_ITER_ERROR);
    if(op_data->visited[op_data->curr])
        return(H5_ITER_ERROR);
    op_data->visited[op_data->curr] = TRUE;

    /* Advance to next value, in correct direction */
    if(op_data->order != H5_ITER_DEC)
        op_data->curr++;
    else
        op_data->curr--;

    /* Check for stopping in the middle of iterating */
    if(op_data->stop > 0)
        if(--op_data->stop == 0)
            return(CORDER_ITER_STOP);

    return(H5_ITER_CONT);
} /* end link_iterate_old_cb() */

#ifndef H5_NO_DEPRECATED_SYMBOLS

/*-------------------------------------------------------------------------
 * Function:    group_iterate_old_cb
 *
 * Purpose:     Callback routine for iterating over links in group with
 *              H5Giterate()
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
group_iterate_old_cb(hid_t group_id, const char *link_name, void *_op_data)
{
    return(link_iterate_old_cb(group_id, link_name, NULL, _op_data));
} /* end group_iterate_old_cb() */
#endif /* H5_NO_DEPRECATED_SYMBOLS */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_old_check
 *
 * Purpose:     Check iteration over [old] links in a group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 20, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_old_check(hid_t group_id, H5_iter_order_t order,
    unsigned max_links, link_iter_info_t *iter_info)
{
    unsigned    v;                      /* Local index variable */
    hsize_t     skip;                   /* # of links to skip in group */
#ifndef H5_NO_DEPRECATED_SYMBOLS
    int         gskip;                  /* # of links to skip in group, with H5Giterate */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
    herr_t      ret;                    /* Generic return value */

    /* Iterate over links in group */
    iter_info->nskipped = (unsigned)(skip = 0);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(skip != max_links) TEST_ERROR
    for(v = 0; v < max_links; v++)
        if(iter_info->visited[v] == FALSE) TEST_ERROR


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Iterate over links in group, with H5Giterate */
    iter_info->nskipped = (unsigned)(gskip = 0);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Giterate(group_id, ".", &gskip, group_iterate_old_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(gskip != (int)max_links) TEST_ERROR
    for(v = 0; v < max_links; v++)
        if(iter_info->visited[v] == FALSE) TEST_ERROR
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Skip over some links in group */
    iter_info->nskipped = (unsigned)(skip = max_links / 2);
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = (int64_t)(order != H5_ITER_DEC ? skip : ((max_links - 1) - skip));
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(skip != max_links) TEST_ERROR
    if(order == H5_ITER_INC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR
    } /* end if */
    else if(order == H5_ITER_DEC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v] == FALSE) TEST_ERROR
    } /* end if */
    else {
        unsigned nvisit = 0;        /* # of links visited */

        HDassert(order == H5_ITER_NATIVE);
        for(v = 0; v < max_links; v++)
            if(iter_info->visited[v] == TRUE)
                nvisit++;

        if(nvisit != (max_links / 2)) TEST_ERROR
    } /* end else */


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Skip over some links in group, with H5Giterate */
    iter_info->nskipped = (unsigned)(gskip = (int)(max_links / 2));
    iter_info->order = order;
    iter_info->stop = -1;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? (unsigned)gskip : ((max_links - 1) - (unsigned)gskip);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if(H5Giterate(group_id, ".", &gskip, group_iterate_old_cb, iter_info) < 0) TEST_ERROR

    /* Verify that we visited all the links */
    if(gskip != (int)max_links) TEST_ERROR
    if(order == H5_ITER_INC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v + (max_links / 2)] == FALSE) TEST_ERROR
    } /* end if */
    else if(order == H5_ITER_DEC) {
        for(v = 0; v < (max_links / 2); v++)
            if(iter_info->visited[v] == FALSE) TEST_ERROR
    } /* end if */
    else {
        unsigned nvisit = 0;        /* # of links visited */

        HDassert(order == H5_ITER_NATIVE);
        for(v = 0; v < max_links; v++)
            if(iter_info->visited[v] == TRUE)
                nvisit++;

        if(nvisit != (max_links / 2)) TEST_ERROR
    } /* end else */
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Iterate over links in group, stopping in the middle */
    iter_info->nskipped = (unsigned)(skip = 0);
    iter_info->order = order;
    iter_info->stop = 3;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if((ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, iter_info)) < 0) TEST_ERROR
    if(ret != CORDER_ITER_STOP) TEST_ERROR
    if(iter_info->ncalled != 3) TEST_ERROR


#ifndef H5_NO_DEPRECATED_SYMBOLS
    /* Iterate over links in group, stopping in the middle, with H5Giterate() */
    iter_info->nskipped = (unsigned)(gskip = 0);
    iter_info->order = order;
    iter_info->stop = 3;
    iter_info->ncalled = 0;
    iter_info->curr = order != H5_ITER_DEC ? 0 : (max_links - 1);
    HDmemset(iter_info->visited, 0, sizeof(hbool_t) * iter_info->max_visit);
    if((ret = H5Giterate(group_id, ".", &gskip, group_iterate_old_cb, iter_info)) < 0) TEST_ERROR
    if(ret != CORDER_ITER_STOP) TEST_ERROR
    if(iter_info->ncalled != 3) TEST_ERROR
#endif /* H5_NO_DEPRECATED_SYMBOLS */


    /* Check for iteration routine indicating failure */
    skip = 0;
    H5E_BEGIN_TRY {
        ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL);
    } H5E_END_TRY;
    if(ret >= 0) TEST_ERROR

    /* Check for iteration w/bad location ID */
    skip = 0;
    H5E_BEGIN_TRY {
        ret = H5Literate((hid_t)(-1), H5_INDEX_NAME, order, &skip, link_iterate_fail_cb, NULL);
    } H5E_END_TRY;
    if(ret >= 0) TEST_ERROR

#ifndef H5_NO_DEPRECATED_SYMBOLS
    H5E_BEGIN_TRY {
        ret = H5Giterate((hid_t)(-1), ".", &gskip, group_iterate_old_cb, iter_info);
    } H5E_END_TRY;
    if(ret >= 0) TEST_ERROR
#endif /* H5_NO_DEPRECATED_SYMBOLS */

    /* Success */
    return(0);

error:
    return(-1);
} /* end link_iterate_old_check() */


/*-------------------------------------------------------------------------
 * Function:    link_iterate_old
 *
 * Purpose:     Create a "old-style" group and test iterating over links by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 14, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
link_iterate_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    H5_iter_order_t order;              /* Order within in the index */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        filename[NAME_BUF_SIZE];/* File name */
    link_iter_info_t iter_info;         /* Iterator info */
    hbool_t     *visited = NULL;        /* Array of flags for visiting links */
    hsize_t     skip;                   /* # of links to skip in group */
    unsigned    u;                      /* Local index variable */
    herr_t      ret;                    /* Generic return value */

    /* Allocate the "visited link" array */
    iter_info.max_visit = CORDER_NLINKS;
    if(NULL == (visited = (hbool_t *)HDmalloc(sizeof(hbool_t) * iter_info.max_visit))) TEST_ERROR
    iter_info.visited = visited;

    /* Loop over operating in different orders */
    for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
        /* Print appropriate test message */
        if(order == H5_ITER_INC) {
            TESTING("iterating over links by name index in increasing order in old-style group")
        } /* end if */
        else if(order == H5_ITER_DEC) {
            TESTING("iterating over links by name index in decreasing order in old-style group")
        } /* end else */
        else {
            HDassert(order == H5_ITER_NATIVE);
            TESTING("iterating over links by name index in native order in old-style group")
        } /* end else */

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create group with creation order tracking on */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


        /* Check for iteration on empty group */
        /* (should be OK) */
        if(H5Literate(group_id, H5_INDEX_NAME, order, NULL, link_iterate_old_cb, NULL) < 0) TEST_ERROR

        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            hid_t group_id2;	        /* Group ID */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create hard link, with group object */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
            if(H5Gclose(group_id2) < 0) TEST_ERROR
        } /* end for */

        /* Verify state of group (symbol table) */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Check for out of bound iteration on old-style group */
        skip = (hsize_t)u;
        H5E_BEGIN_TRY {
            ret = H5Literate(group_id, H5_INDEX_NAME, order, &skip, link_iterate_old_cb, NULL);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Check for iteration on creation order */
        /* (should fail) */
        skip = (hsize_t)0;
        H5E_BEGIN_TRY {
            ret = H5Literate(group_id, H5_INDEX_CRT_ORDER, order, &skip, link_iterate_old_cb, NULL);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Test iteration over links in group */
        if(link_iterate_old_check(group_id, order, u, &iter_info) < 0) TEST_ERROR


        /* Close the group */
        if(H5Gclose(group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    /* Free resources */
    if(visited)
        HDfree(visited);

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    if(visited)
        HDfree(visited);

    return -1;
} /* end link_iterate_old() */


/*-------------------------------------------------------------------------
 * Function:    open_by_idx_check
 *
 * Purpose:     Check opening by index in a group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 21, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id,
    H5_index_t idx_type, H5_iter_order_t order, unsigned max_links,
    haddr_t *objno)
{
    char        mntname[NAME_BUF_SIZE]; /* Link value */
    hid_t       group_id = (-1); /* ID of group to test */
    H5O_info_t  oi;             /* Buffer for querying object's info */
    haddr_t     mnt_root_addr;  /* Address of root group in file to mount */
    hid_t       obj_id;         /* ID of object opened */
    unsigned    mnt_idx;        /* Index to mount group on */
    unsigned    u, v;           /* Local index variables */

    /* Work through main & soft link groups */
    for(v = 0; v < 2; v++) {
        /* Choose appropriate group to open links within */
        if(0 == v)
            group_id = main_group_id;
        else
            group_id = soft_group_id;

        /* Open each object in main group by index and check that it's the correct one */
        for(u = 0; u < max_links; u++) {
            /* Open the object */
            if((obj_id = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Get the object's information */
            if(H5Oget_info(obj_id, &oi) < 0) TEST_ERROR

            /* Check that the object is the correct one */
            if(order == H5_ITER_INC) {
                if(H5F_addr_ne(oi.addr, objno[u])) TEST_ERROR
            } /* end if */
            else if(order == H5_ITER_DEC) {
                unsigned dec_u = max_links - (u + 1);       /* Decreasing mapped index */

                if(H5F_addr_ne(oi.addr, objno[dec_u])) TEST_ERROR
            } /* end if */
            else {
                /* XXX: What to do about native order? */
            } /* end else */

            /* Close object */
            if(H5Oclose(obj_id) < 0) TEST_ERROR
        } /* end for */
    } /* end for */


    /*
     * Verify opening correct object by index when file mounting is present
     */

    /* Get the address of the root group in the file to mount */
    if(H5Oget_info(mount_file_id, &oi) < 0) TEST_ERROR
    mnt_root_addr = oi.addr;

    /* Mount a file over a group in main group */
    mnt_idx = 2;
    sprintf(mntname, "/%s/filler %02u", CORDER_GROUP_NAME, mnt_idx);
    if(H5Fmount(main_group_id, mntname, mount_file_id, H5P_DEFAULT) < 0) TEST_ERROR

    /* Open the object that the file is mounted on */
    if((obj_id = H5Oopen_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)mnt_idx, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Get the object's information */
    if(H5Oget_info(obj_id, &oi) < 0) TEST_ERROR

    /* Check that the object is the root of the mounted file and not in the previous file */
    if(H5F_addr_ne(oi.addr, mnt_root_addr)) TEST_ERROR
    if(H5F_addr_eq(oi.addr, objno[mnt_idx])) TEST_ERROR

    /* Close object */
    if(H5Oclose(obj_id) < 0) TEST_ERROR

    /* Unmount the file */
    if(H5Funmount(main_group_id, mntname) < 0) TEST_ERROR


    /* Success */
    return(0);

error:
    return(-1);
} /* end open_by_idx_check() */


/*-------------------------------------------------------------------------
 * Function:    open_by_idx
 *
 * Purpose:     Create a group with creation order indices and test opening
 *              objects by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 21, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
open_by_idx(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	mount_file_id = (-1); 	/* File ID for file to mount */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    H5_index_t idx_type;               /* Type of index to operate on */
    H5_iter_order_t order;              /* Order within in the index */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    H5O_info_t  oi;                     /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    haddr_t     *objno = NULL;          /* Addresses of the objects created */
    unsigned    u;                      /* Local index variable */
    hid_t       ret;                    /* Generic return value */

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Allocate object address array */
    if(NULL == (objno = (haddr_t *)HDmalloc(sizeof(haddr_t) * (max_compact * 2)))) TEST_ERROR

    /* Create file to mount */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((mount_file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Loop over operating on different indices on link fields */
    for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; H5_INC_ENUM(H5_index_t, idx_type)) {
        /* Loop over operating in different orders */
        for(order = H5_ITER_INC; order <= H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
            /* Loop over using index for creation order value */
            for(use_index = FALSE; use_index <= TRUE; use_index++) {
                /* Print appropriate test message */
                if(idx_type == H5_INDEX_CRT_ORDER) {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("open object by creation order index in increasing order w/creation order index")
                        else
                            TESTING("open object by creation order index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("open object by creation order index in decreasing order w/creation order index")
                        else
                            TESTING("open object by creation order index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("open object by creation order index in native order w/creation order index")
                        else
                            TESTING("open object by creation order index in native order w/o creation order index")
                    } /* end else */
                } /* end if */
                else {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("open object by name index in increasing order w/creation order index")
                        else
                            TESTING("open object by name index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("open object by name index in decreasing order w/creation order index")
                        else
                            TESTING("open object by name index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("open object by name index in native order w/creation order index")
                        else
                            TESTING("open object by name index in native order w/o creation order index")
                    } /* end else */
                } /* end else */

                /* Create file */
                h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
                if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

                /* Set creation order tracking & indexing on group */
                if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

                /* Create group with creation order tracking on */
                if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Create group with creation order tracking on for soft links */
                if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                /* Try to open on object in an empty group */
                H5E_BEGIN_TRY {
                    ret = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)0, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR


                /* Create several links, up to limit of compact form */
                for(u = 0; u < max_compact; u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                    /* Retrieve group's address on disk */
                    if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
                    objno[u] = oi.addr;

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (compact) */
                if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

                /* Check for out of bound open by index on compact group */
                H5E_BEGIN_TRY {
                    ret = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Verify opening objects by index */
                if(open_by_idx_check(group_id, soft_group_id, mount_file_id, idx_type, order, u, objno) < 0) TEST_ERROR


                /* Create more links, to push group into dense form */
                for(; u < (max_compact * 2); u++) {
                    hid_t group_id2;	        /* Group ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                    /* Retrieve group's address on disk */
                    if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
                    objno[u] = oi.addr;

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (dense) */
                if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                /* Check for out of bound open by index on compact group */
                H5E_BEGIN_TRY {
                    ret = H5Oopen_by_idx(group_id, ".", idx_type, order, (hsize_t)u, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Verify opening objects by index */
                if(open_by_idx_check(group_id, soft_group_id, mount_file_id, idx_type, order, u, objno) < 0) TEST_ERROR


                /* Close the groups */
                if(H5Gclose(group_id) < 0) TEST_ERROR
                if(H5Gclose(soft_group_id) < 0) TEST_ERROR

                /* Close the file */
                if(H5Fclose(file_id) < 0) TEST_ERROR

                PASSED();
            } /* end for */
        } /* end for */
    } /* end for */

    /* Close the file for mounting */
    if(H5Fclose(mount_file_id) < 0) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Free resources */
    if(objno)
        HDfree(objno);

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
        H5Fclose(mount_file_id);
    } H5E_END_TRY;

    if(objno)
        HDfree(objno);

    return -1;
} /* end open_by_idx() */


/*-------------------------------------------------------------------------
 * Function:    open_by_idx_old
 *
 * Purpose:     Create an old-style group and test opening
 *              objects by index.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Tuesday, November 21, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
open_by_idx_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	mount_file_id = (-1); 	/* File ID for file to mount */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    H5_iter_order_t order;              /* Order within in the index */
    H5O_info_t  oi;                     /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    haddr_t     objno[CORDER_NLINKS];   /* Addresses of the objects created */
    unsigned    u;                      /* Local index variable */
    hid_t       ret;                    /* Generic return value */

    /* Create file to mount */
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
    if((mount_file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Loop over operating in different orders */
    for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
        /* Print appropriate test message */
        if(order == H5_ITER_INC) {
            TESTING("open object by name index in increasing order in old-style group")
        } /* end if */
        else if(order == H5_ITER_DEC) {
            TESTING("open object by name index in decreasing order in old-style group")
        } /* end else */
        else {
            HDassert(order == H5_ITER_NATIVE);
            TESTING("open object by name index in native order in old-style group")
        } /* end else */

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create old-style group */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create old-style group for soft links */
        if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


        /* Try to open on object in an empty group */
        H5E_BEGIN_TRY {
            ret = H5Oopen_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR


        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            hid_t group_id2;	        /* Group ID */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create hard link, with group object */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Retrieve group's address on disk */
            if(H5Oget_info(group_id2, &oi) < 0) TEST_ERROR
            objno[u] = oi.addr;

            /* Close group created */
            if(H5Gclose(group_id2) < 0) TEST_ERROR

            /* Create soft link in another group, to objects in main group */
            sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
            if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
        } /* end for */

        /* Verify state of group (symbol table) */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Check for out of bound open by index */
        H5E_BEGIN_TRY {
            ret = H5Oopen_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Check for creation order index open */
        H5E_BEGIN_TRY {
            ret = H5Oopen_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)(u - 1), H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Verify opening objects by index */
        if(open_by_idx_check(group_id, soft_group_id, mount_file_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR


        /* Close the groups */
        if(H5Gclose(group_id) < 0) TEST_ERROR
        if(H5Gclose(soft_group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    /* Close the file for mounting */
    if(H5Fclose(mount_file_id) < 0) TEST_ERROR

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
        H5Fclose(mount_file_id);
    } H5E_END_TRY;

    return -1;
} /* end open_by_idx_old() */


/*-------------------------------------------------------------------------
 * Function:    object_info_check
 *
 * Purpose:     Check querying object info in a group
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 26, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
object_info_check(hid_t main_group_id, hid_t soft_group_id, H5_index_t idx_type,
    H5_iter_order_t order, unsigned max_links, haddr_t *objno)
{
    char        objname[NAME_BUF_SIZE]; /* Object name */
    hid_t       group_id = (-1); /* ID of group to test */
    H5O_info_t  oinfo;          /* Buffer for querying object's info */
    unsigned    u, v;           /* Local index variables */

    /* Work through main & soft link groups */
    for(v = 0; v < 2; v++) {
        /* Choose appropriate group to open links within */
        if(0 == v)
            group_id = main_group_id;
        else
            group_id = soft_group_id;

        /* Open each object in group by name and check that it's the correct one */
        for(u = 0; u < max_links; u++) {
            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Query the object's information, by name */
            if(H5Oget_info_by_name(group_id, objname, &oinfo, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check that the object is the correct one */
            if(H5F_addr_ne(oinfo.addr, objno[u])) TEST_ERROR
            if(H5F_addr_ne(oinfo.num_attrs, u)) TEST_ERROR

            /* Query the object's information, by index */
            if(H5Oget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)u, &oinfo, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check that the object is the correct one */
            if(order == H5_ITER_INC) {
                if(H5F_addr_ne(oinfo.addr, objno[u])) TEST_ERROR
                if(H5F_addr_ne(oinfo.num_attrs, u)) TEST_ERROR
            } /* end if */
            else if(order == H5_ITER_DEC) {
                unsigned dec_u = max_links - (u + 1);       /* Decreasing mapped index */

                if(H5F_addr_ne(oinfo.addr, objno[dec_u])) TEST_ERROR
                if(H5F_addr_ne(oinfo.num_attrs, dec_u)) TEST_ERROR
            } /* end if */
            else {
                /* XXX: What to do about native order? */
            } /* end else */

        } /* end for */
    } /* end for */

    /* Success */
    return(0);

error:
    return(-1);
} /* end object_info_check() */


/*-------------------------------------------------------------------------
 * Function:    object_info
 *
 * Purpose:     Create a group with creation order indices and test querying
 *              object info.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 26, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
object_info(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    hid_t       space_id = (-1);        /* Dataspace ID (for attributes) */
    H5_index_t idx_type;               /* Type of index to operate on */
    H5_iter_order_t order;              /* Order within in the index */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    H5O_info_t  oinfo;                  /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    char        attrname[NAME_BUF_SIZE]; /* Attribute name */
    haddr_t     *objno = NULL;          /* Addresses of the objects created */
    herr_t      ret;                    /* Generic return value */
    unsigned    u, v;                   /* Local index variables */

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Allocate object address array */
    if(NULL == (objno = (haddr_t *)HDmalloc(sizeof(haddr_t) * (max_compact * 2)))) TEST_ERROR

    /* Create dataspace for attributes */
    if((space_id = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR

    /* Loop over operating on different indices on link fields */
    for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; H5_INC_ENUM(H5_index_t, idx_type)) {
        /* Loop over operating in different orders */
        for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
            /* Loop over using index for creation order value */
            for(use_index = FALSE; use_index <= TRUE; use_index++) {
                /* Print appropriate test message */
                if(idx_type == H5_INDEX_CRT_ORDER) {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("query object info by creation order index in increasing order w/creation order index")
                        else
                            TESTING("query object info by creation order index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("query object info by creation order index in decreasing order w/creation order index")
                        else
                            TESTING("query object info by creation order index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("query object info by creation order index in native order w/creation order index")
                        else
                            TESTING("query object info by creation order index in native order w/o creation order index")
                    } /* end else */
                } /* end if */
                else {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("query object info by name index in increasing order w/creation order index")
                        else
                            TESTING("query object info by name index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("query object info by name index in decreasing order w/creation order index")
                        else
                            TESTING("query object info by name index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("query object info by name index in native order w/creation order index")
                        else
                            TESTING("query object info by name index in native order w/o creation order index")
                    } /* end else */
                } /* end else */

                /* Create file */
                h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
                if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

                /* Set creation order tracking & indexing on group */
                if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

                /* Create group with creation order tracking on */
                if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Create group with creation order tracking on for soft links */
                if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                /* Check for out of bound query by index on empty group */
                H5E_BEGIN_TRY {
                    ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Create several links, up to limit of compact form */
                for(u = 0; u < max_compact; u++) {
                    hid_t group_id2;	        /* Group ID */
                    hid_t attr_id;              /* Attribute ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                    /* Retrieve group's address on disk */
                    if(H5Oget_info(group_id2, &oinfo) < 0) TEST_ERROR
                    objno[u] = oinfo.addr;

                    /* Create attributes on new object */
                    for(v = 0; v < u; v++) {
                        /* Make name for attribute */
                        sprintf(attrname, "attr %02u", v);

                        /* Create attribute */
                        if((attr_id = H5Acreate2(group_id2, attrname, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                        /* Close attribute */
                        if(H5Aclose(attr_id) < 0) TEST_ERROR
                    } /* end for */

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (compact) */
                if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

                /* Check for out of bound query by index */
                H5E_BEGIN_TRY {
                    ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Verify querying objects by name */
                if(object_info_check(group_id, soft_group_id, idx_type, order, u, objno) < 0) TEST_ERROR


                /* Create more links, to push group into dense form */
                for(; u < (max_compact * 2); u++) {
                    hid_t group_id2;	        /* Group ID */
                    hid_t attr_id;              /* Attribute ID */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                    /* Retrieve group's address on disk */
                    if(H5Oget_info(group_id2, &oinfo) < 0) TEST_ERROR
                    objno[u] = oinfo.addr;

                    /* Create attributes on new object */
                    for(v = 0; v < u; v++) {
                        /* Make name for attribute */
                        sprintf(attrname, "attr %02u", v);

                        /* Create attribute */
                        if((attr_id = H5Acreate2(group_id2, attrname, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                        /* Close attribute */
                        if(H5Aclose(attr_id) < 0) TEST_ERROR
                    } /* end for */

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR

                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end for */

                /* Verify state of group (dense) */
                if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                /* Check for out of bound query by index */
                H5E_BEGIN_TRY {
                    ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Verify querying objects by name */
                if(object_info_check(group_id, soft_group_id, idx_type, order, u, objno) < 0) TEST_ERROR


                /* Close the groups */
                if(H5Gclose(group_id) < 0) TEST_ERROR
                if(H5Gclose(soft_group_id) < 0) TEST_ERROR

                /* Close the file */
                if(H5Fclose(file_id) < 0) TEST_ERROR

                PASSED();
            } /* end for */
        } /* end for */
    } /* end for */

    /* Free resources */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR
    if(H5Sclose(space_id) < 0) TEST_ERROR
    if(objno)
        HDfree(objno);

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Sclose(space_id);
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    if(objno)
        HDfree(objno);

    return -1;
} /* end object_info() */


/*-------------------------------------------------------------------------
 * Function:    object_info_old
 *
 * Purpose:     Create an old-style group test querying object info.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Sunday, November 26, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
object_info_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    hid_t       space_id = (-1);        /* Dataspace ID (for attributes) */
    H5_iter_order_t order;              /* Order within in the index */
    H5O_info_t  oinfo;                  /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    char        attrname[NAME_BUF_SIZE]; /* Attribute name */
    haddr_t     objno[CORDER_NLINKS];   /* Addresses of the objects created */
    herr_t      ret;                    /* Generic return value */
    unsigned    u, v;                   /* Local index variables */

    /* Create dataspace for attributes */
    if((space_id = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR

    /* Loop over operating in different orders */
    for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
        /* Print appropriate test message */
        if(order == H5_ITER_INC) {
            TESTING("query object info by name index in increasing order in old-style group")
        } /* end if */
        else if(order == H5_ITER_DEC) {
            TESTING("query object info by name index in decreasing order in old-style group")
        } /* end else */
        else {
            HDassert(order == H5_ITER_NATIVE);
            TESTING("query object info by name index in native order in old-style group")
        } /* end else */

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create old-style group */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create old-style group for soft links */
        if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


        /* Check for out of bound query by index on empty group */
        H5E_BEGIN_TRY {
            ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &oinfo, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            hid_t group_id2;	        /* Group ID */
            hid_t attr_id;              /* Attribute ID */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create hard link, with group object */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

            /* Retrieve group's address on disk */
            if(H5Oget_info(group_id2, &oinfo) < 0) TEST_ERROR
            objno[u] = oinfo.addr;

            /* Create attributes on new object */
            for(v = 0; v < u; v++) {
                /* Make name for attribute */
                sprintf(attrname, "attr %02u", v);

                /* Create attribute */
                if((attr_id = H5Acreate2(group_id2, attrname, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Close attribute */
                if(H5Aclose(attr_id) < 0) TEST_ERROR
            } /* end for */

            /* Close group created */
            if(H5Gclose(group_id2) < 0) TEST_ERROR

            /* Create soft link in another group, to objects in main group */
            sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
            if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
        } /* end for */

        /* Verify state of group (symbol table) */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Check for out of bound query by index */
        H5E_BEGIN_TRY {
            ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &oinfo, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Check for creation order index query */
        H5E_BEGIN_TRY {
            ret = H5Oget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)(u - 1), &oinfo, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Verify querying objects by name */
        if(object_info_check(group_id, soft_group_id, H5_INDEX_NAME, order, u, objno) < 0) TEST_ERROR


        /* Close the groups */
        if(H5Gclose(group_id) < 0) TEST_ERROR
        if(H5Gclose(soft_group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    /* Free resources */
    if(H5Sclose(space_id) < 0) TEST_ERROR

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Sclose(space_id);
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    return -1;
} /* end object_info_old() */


/*-------------------------------------------------------------------------
 * Function:    group_info
 *
 * Purpose:     Create a group with creation order indices and test querying
 *              group info.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 27, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
group_info(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    H5_index_t idx_type;               /* Type of index to operate on */
    H5_iter_order_t order;              /* Order within in the index */
    unsigned    use_index;              /* Use index on creation order values */
    unsigned    max_compact;            /* Maximum # of links to store in group compactly */
    unsigned    min_dense;              /* Minimum # of links to store in group "densely" */
    H5G_info_t  grp_info;               /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        objname2[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    herr_t      ret;                    /* Generic return value */
    unsigned    u, v;                   /* Local index variables */

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Query the group creation properties */
    if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR

    /* Loop over operating on different indices on link fields */
    for(idx_type = H5_INDEX_NAME; idx_type <= H5_INDEX_CRT_ORDER; H5_INC_ENUM(H5_index_t, idx_type)) {
        /* Loop over operating in different orders */
        for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
            /* Loop over using index for creation order value */
            for(use_index = FALSE; use_index <= TRUE; use_index++) {
                /* Print appropriate test message */
                if(idx_type == H5_INDEX_CRT_ORDER) {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("query group info by creation order index in increasing order w/creation order index")
                        else
                            TESTING("query group info by creation order index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("query group info by creation order index in decreasing order w/creation order index")
                        else
                            TESTING("query group info by creation order index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("query group info by creation order index in native order w/creation order index")
                        else
                            TESTING("query group info by creation order index in native order w/o creation order index")
                    } /* end else */
                } /* end if */
                else {
                    if(order == H5_ITER_INC) {
                        if(use_index)
                            TESTING("query group info by name index in increasing order w/creation order index")
                        else
                            TESTING("query group info by name index in increasing order w/o creation order index")
                    } /* end if */
                    else if(order == H5_ITER_DEC) {
                        if(use_index)
                            TESTING("query group info by name index in decreasing order w/creation order index")
                        else
                            TESTING("query group info by name index in decreasing order w/o creation order index")
                    } /* end else */
                    else {
                        HDassert(order == H5_ITER_NATIVE);
                        if(use_index)
                            TESTING("query group info by name index in native order w/creation order index")
                        else
                            TESTING("query group info by name index in native order w/o creation order index")
                    } /* end else */
                } /* end else */

                /* Create file */
                h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
                if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

                /* Set creation order tracking & indexing on group */
                if(H5Pset_link_creation_order(gcpl_id, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))) < 0) TEST_ERROR

                /* Create group with creation order tracking on */
                if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Create group with creation order tracking on for soft links */
                if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                /* Check for out of bound query by index on empty group */
                H5E_BEGIN_TRY {
                    ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &grp_info, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR

                /* Create several links, up to limit of compact form */
                for(u = 0; u < max_compact; u++) {
                    hid_t group_id2, group_id3;	        /* Group IDs */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                    /* Retrieve group's information */
                    if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR

                    /* Retrieve group's information */
                    if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR

                    /* Retrieve group's information */
                    if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR


                    /* Create objects in new group created */
                    for(v = 0; v <= u; v++) {
                        /* Make name for link */
                        sprintf(objname2, "filler %02u", v);

                        /* Create hard link, with group object */
                        if((group_id3 = H5Gcreate2(group_id2, objname2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                        /* Close group created */
                        if(H5Gclose(group_id3) < 0) TEST_ERROR
                    } /* end for */


                    /* Retrieve group's information */
                    if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve group's information */
                    if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve group's information */
                    if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


                    /* Retrieve group's information */
                    if(order != H5_ITER_NATIVE) {
                        if(order == H5_ITER_INC) {
                            if(H5Gget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)u, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                        } /* end if */
                        else {
                            if(H5Gget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                        } /* end else */

                        /* Check (new) group's information */
                        if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                        if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                        if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
                    } /* end if */

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR


                    /* Retrieve main group's information */
                    if(H5Gget_info(group_id, &grp_info) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve main group's information, by name */
                    if(H5Gget_info_by_name(file_id, CORDER_GROUP_NAME, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve main group's information, by name */
                    if(H5Gget_info_by_name(group_id, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Retrieve soft link group's information, by name */
                    if(H5Gget_info(soft_group_id, &grp_info) < 0) TEST_ERROR

                    /* Check soft link group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
                } /* end for */

                /* Verify state of group (compact) */
                if(H5G__has_links_test(group_id, NULL) != TRUE) TEST_ERROR

                /* Check for out of bound query by index */
                H5E_BEGIN_TRY {
                    ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &grp_info, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR


                /* Create more links, to push group into dense form */
                for(; u < (max_compact * 2); u++) {
                    hid_t group_id2, group_id3;	        /* Group IDs */

                    /* Make name for link */
                    sprintf(objname, "filler %02u", u);

                    /* Create hard link, with group object */
                    if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR


                    /* Retrieve group's information */
                    if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR

                    /* Retrieve group's information, by name */
                    if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR

                    /* Retrieve group's information, by name */
                    if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new/empty) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_COMPACT) TEST_ERROR
                    if(grp_info.max_corder != 0) TEST_ERROR
                    if(grp_info.nlinks != 0) TEST_ERROR


                    /* Create objects in new group created */
                    for(v = 0; v <= u; v++) {
                        /* Make name for link */
                        sprintf(objname2, "filler %02u", v);

                        /* Create hard link, with group object */
                        if((group_id3 = H5Gcreate2(group_id2, objname2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                        /* Close group created */
                        if(H5Gclose(group_id3) < 0) TEST_ERROR
                    } /* end for */


                    /* Retrieve group's information */
                    if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve group's information, by name */
                    if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve group's information, by name */
                    if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check (new) group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


                    /* Retrieve group's information */
                    if(order != H5_ITER_NATIVE) {
                        if(order == H5_ITER_INC) {
                            if(H5Gget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)u, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                        } /* end if */
                        else {
                            if(H5Gget_info_by_idx(group_id, ".", idx_type, order, (hsize_t)0, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                        } /* end else */

                        /* Check (new) group's information */
                        if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                        if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                        if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
                    } /* end if */

                    /* Close group created */
                    if(H5Gclose(group_id2) < 0) TEST_ERROR


                    /* Retrieve main group's information */
                    if(H5Gget_info(group_id, &grp_info) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve main group's information, by name */
                    if(H5Gget_info_by_name(file_id, CORDER_GROUP_NAME, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

                    /* Retrieve main group's information, by name */
                    if(H5Gget_info_by_name(group_id, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Check main group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


                    /* Create soft link in another group, to objects in main group */
                    sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
                    if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

                    /* Retrieve soft link group's information, by name */
                    if(H5Gget_info(soft_group_id, &grp_info) < 0) TEST_ERROR

                    /* Check soft link group's information */
                    if(grp_info.storage_type != H5G_STORAGE_TYPE_DENSE) TEST_ERROR
                    if(grp_info.max_corder != (int64_t)(u + 1)) TEST_ERROR
                    if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
                } /* end for */

                /* Verify state of group (dense) */
                if(H5G__is_new_dense_test(group_id) != TRUE) TEST_ERROR

                /* Check for out of bound query by index */
                H5E_BEGIN_TRY {
                    ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &grp_info, H5P_DEFAULT);
                } H5E_END_TRY;
                if(ret >= 0) TEST_ERROR


                /* Close the groups */
                if(H5Gclose(group_id) < 0) TEST_ERROR
                if(H5Gclose(soft_group_id) < 0) TEST_ERROR

                /* Close the file */
                if(H5Fclose(file_id) < 0) TEST_ERROR

                PASSED();
            } /* end for */
        } /* end for */
    } /* end for */

    /* Free resources */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    return -1;
} /* end group_info() */


/*-------------------------------------------------------------------------
 * Function:    group_info_old
 *
 * Purpose:     Create an old-style group and test querying
 *              group info.
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Monday, November 27, 2006
 *
 *-------------------------------------------------------------------------
 */
static int
group_info_old(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	soft_group_id = (-1);	/* Group ID for soft links */
    H5_iter_order_t order;              /* Order within in the index */
    H5G_info_t  grp_info;               /* Buffer for querying object's info */
    char        filename[NAME_BUF_SIZE];/* File name */
    char        objname[NAME_BUF_SIZE]; /* Object name */
    char        objname2[NAME_BUF_SIZE]; /* Object name */
    char        valname[NAME_BUF_SIZE]; /* Link value */
    herr_t      ret;                    /* Generic return value */
    unsigned    u, v;                   /* Local index variables */

    /* Loop over operating in different orders */
    for(order = H5_ITER_INC; order <=H5_ITER_NATIVE; H5_INC_ENUM(H5_iter_order_t, order)) {
        if(order == H5_ITER_INC) {
            TESTING("query group info by name index in increasing order in old-style group")
        } /* end if */
        else if(order == H5_ITER_DEC) {
            TESTING("query group info by name index in decreasing order in old-style group")
        } /* end else */
        else {
            HDassert(order == H5_ITER_NATIVE);
            TESTING("query group info by name index in native order in old-style group")
        } /* end else */

        /* Create file */
        h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
        if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

        /* Create old-style group */
        if((group_id = H5Gcreate2(file_id, CORDER_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

        /* Create old-style group for soft links */
        if((soft_group_id = H5Gcreate2(file_id, CORDER_SOFT_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


        /* Check for out of bound query by index on empty group */
        H5E_BEGIN_TRY {
            ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &grp_info, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Create several links */
        for(u = 0; u < CORDER_NLINKS; u++) {
            hid_t group_id2, group_id3;	        /* Group IDs */

            /* Make name for link */
            sprintf(objname, "filler %02u", u);

            /* Create hard link, with group object */
            if((group_id2 = H5Gcreate2(group_id, objname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR


            /* Retrieve group's information */
            if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

            /* Check (new/empty) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != 0) TEST_ERROR

            /* Retrieve group's information, by name */
            if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check (new/empty) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != 0) TEST_ERROR

            /* Retrieve group's information, by name */
            if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check (new/empty) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != 0) TEST_ERROR


            /* Create objects in new group created */
            for(v = 0; v <= u; v++) {
                /* Make name for link */
                sprintf(objname2, "filler %02u", v);

                /* Create hard link, with group object */
                if((group_id3 = H5Gcreate2(group_id2, objname2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

                /* Close group created */
                if(H5Gclose(group_id3) < 0) TEST_ERROR
            } /* end for */


            /* Retrieve group's information */
            if(H5Gget_info(group_id2, &grp_info) < 0) TEST_ERROR

            /* Check (new) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

            /* Retrieve group's information, by name */
            if(H5Gget_info_by_name(group_id, objname, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check (new) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

            /* Retrieve group's information, by name */
            if(H5Gget_info_by_name(group_id2, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check (new) group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


            /* Retrieve group's information */
            if(order != H5_ITER_NATIVE) {
                if(order == H5_ITER_INC) {
                    if(H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end if */
                else {
                    if(H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)0, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR
                } /* end else */

                /* Check (new) group's information */
                if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
                if(grp_info.max_corder != 0) TEST_ERROR
                if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
            } /* end if */

            /* Close group created */
            if(H5Gclose(group_id2) < 0) TEST_ERROR


            /* Retrieve main group's information */
            if(H5Gget_info(group_id, &grp_info) < 0) TEST_ERROR

            /* Check main group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

            /* Retrieve main group's information, by name */
            if(H5Gget_info_by_name(file_id, CORDER_GROUP_NAME, &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check main group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR

            /* Retrieve main group's information, by name */
            if(H5Gget_info_by_name(group_id, ".", &grp_info, H5P_DEFAULT) < 0) TEST_ERROR

            /* Check main group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR


            /* Create soft link in another group, to objects in main group */
            sprintf(valname, "/%s/%s", CORDER_GROUP_NAME, objname);
            if(H5Lcreate_soft(valname, soft_group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR

            /* Retrieve soft link group's information, by name */
            if(H5Gget_info(soft_group_id, &grp_info) < 0) TEST_ERROR

            /* Check soft link group's information */
            if(grp_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) TEST_ERROR
            if(grp_info.max_corder != 0) TEST_ERROR
            if(grp_info.nlinks != (hsize_t)(u + 1)) TEST_ERROR
        } /* end for */

        /* Verify state of group (old-style) */
        if(H5G__has_stab_test(group_id) != TRUE) TEST_ERROR

        /* Check for out of bound query by index */
        H5E_BEGIN_TRY {
            ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_NAME, order, (hsize_t)u, &grp_info, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR

        /* Check for bad index query by index group */
        H5E_BEGIN_TRY {
            ret = H5Gget_info_by_idx(group_id, ".", H5_INDEX_CRT_ORDER, order, (hsize_t)0, &grp_info, H5P_DEFAULT);
        } H5E_END_TRY;
        if(ret >= 0) TEST_ERROR


        /* Close the groups */
        if(H5Gclose(group_id) < 0) TEST_ERROR
        if(H5Gclose(soft_group_id) < 0) TEST_ERROR

        /* Close the file */
        if(H5Fclose(file_id) < 0) TEST_ERROR

        PASSED();
    } /* end for */

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Gclose(group_id);
        H5Gclose(soft_group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    return -1;
} /* end group_info_old() */


/*-------------------------------------------------------------------------
 * Function:    timestamps
 *
 * Purpose:     Verify that disabling tracking timestamps for an object
 *              works correctly
 *
 * Return:      Success:        0
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
 *              Saturday, March 3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
timestamps(hid_t fapl)
{
    hid_t	file_id = (-1); 	/* File ID */
    hid_t	group_id = (-1);	/* Group ID */
    hid_t	group_id2 = (-1);	/* Group ID */
    hid_t       gcpl_id = (-1); 	/* Group creation property list ID */
    hid_t       gcpl_id2 = (-1); 	/* Group creation property list ID */
    H5O_info_t  oinfo, oinfo2;          /* Object info for groups created */
    char        filename[NAME_BUF_SIZE];/* File name */
    hbool_t     track_times;            /* The object timestamp setting */

    /* Print test message */
    TESTING("timestamps on objects")

    /* Create group creation property list */
    if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR

    /* Query the object timestamp setting */
    if(H5Pget_obj_track_times(gcpl_id, &track_times) < 0) TEST_ERROR

    /* Check default timestamp information */
    if(track_times != TRUE) TEST_ERROR

    /* Set a non-default object timestamp setting */
    if(H5Pset_obj_track_times(gcpl_id, FALSE) < 0) TEST_ERROR

    /* Query the object timestamp setting */
    if(H5Pget_obj_track_times(gcpl_id, &track_times) < 0) TEST_ERROR

    /* Check default timestamp information */
    if(track_times != FALSE) TEST_ERROR


    /* Create file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR

    /* Create group with non-default object timestamp setting */
    if((group_id = H5Gcreate2(file_id, TIMESTAMP_GROUP_1, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Close the group creation property list */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR

    /* Create group with default object timestamp setting */
    if((group_id2 = H5Gcreate2(file_id, TIMESTAMP_GROUP_2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR

    /* Retrieve the new groups' creation properties */
    if((gcpl_id = H5Gget_create_plist(group_id)) < 0) TEST_ERROR
    if((gcpl_id2 = H5Gget_create_plist(group_id2)) < 0) TEST_ERROR

    /* Query & verify the object timestamp settings */
    if(H5Pget_obj_track_times(gcpl_id, &track_times) < 0) TEST_ERROR
    if(track_times != FALSE) TEST_ERROR
    if(H5Pget_obj_track_times(gcpl_id2, &track_times) < 0) TEST_ERROR
    if(track_times != TRUE) TEST_ERROR

    /* Query the object information for each group */
    if(H5Oget_info(group_id, &oinfo) < 0) TEST_ERROR
    if(H5Oget_info(group_id2, &oinfo2) < 0) TEST_ERROR

    /* Sanity check object information for each group */
    if(oinfo.atime != 0) TEST_ERROR
    if(oinfo.mtime != 0) TEST_ERROR
    if(oinfo.ctime != 0) TEST_ERROR
    if(oinfo.btime != 0) TEST_ERROR
    if(oinfo.atime == oinfo2.atime) TEST_ERROR
    if(oinfo.mtime == oinfo2.mtime) TEST_ERROR
    if(oinfo.ctime == oinfo2.ctime) TEST_ERROR
    if(oinfo.btime == oinfo2.btime) TEST_ERROR
    if((oinfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR
    if((oinfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR
    if(oinfo.hdr.space.total >= oinfo2.hdr.space.total) TEST_ERROR
    if(oinfo.hdr.space.meta >= oinfo2.hdr.space.meta) TEST_ERROR

    /* Close the property lists */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR
    if(H5Pclose(gcpl_id2) < 0) TEST_ERROR

    /* Close the groups */
    if(H5Gclose(group_id) < 0) TEST_ERROR
    if(H5Gclose(group_id2) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR


    /* Re-open the file */
    if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR

    /* Open groups */
    if((group_id = H5Gopen2(file_id, TIMESTAMP_GROUP_1, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
    if((group_id2 = H5Gopen2(file_id, TIMESTAMP_GROUP_2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR

    /* Retrieve the groups' creation properties */
    if((gcpl_id = H5Gget_create_plist(group_id)) < 0) TEST_ERROR
    if((gcpl_id2 = H5Gget_create_plist(group_id2)) < 0) TEST_ERROR

    /* Query & verify the object timestamp settings */
    if(H5Pget_obj_track_times(gcpl_id, &track_times) < 0) TEST_ERROR
    if(track_times != FALSE) TEST_ERROR
    if(H5Pget_obj_track_times(gcpl_id2, &track_times) < 0) TEST_ERROR
    if(track_times != TRUE) TEST_ERROR

    /* Query the object information for each group */
    if(H5Oget_info(group_id, &oinfo) < 0) TEST_ERROR
    if(H5Oget_info(group_id2, &oinfo2) < 0) TEST_ERROR

    /* Sanity check object information for each group */
    if(oinfo.atime != 0) TEST_ERROR
    if(oinfo.mtime != 0) TEST_ERROR
    if(oinfo.ctime != 0) TEST_ERROR
    if(oinfo.btime != 0) TEST_ERROR
    if(oinfo.atime == oinfo2.atime) TEST_ERROR
    if(oinfo.mtime == oinfo2.mtime) TEST_ERROR
    if(oinfo.ctime == oinfo2.ctime) TEST_ERROR
    if(oinfo.btime == oinfo2.btime) TEST_ERROR
    if((oinfo.hdr.flags & H5O_HDR_STORE_TIMES) != 0) TEST_ERROR
    if((oinfo2.hdr.flags & H5O_HDR_STORE_TIMES) == 0) TEST_ERROR
    if(oinfo.hdr.space.total >= oinfo2.hdr.space.total) TEST_ERROR
    if(oinfo.hdr.space.meta >= oinfo2.hdr.space.meta) TEST_ERROR

    /* Close the property lists */
    if(H5Pclose(gcpl_id) < 0) TEST_ERROR
    if(H5Pclose(gcpl_id2) < 0) TEST_ERROR

    /* Close the groups */
    if(H5Gclose(group_id) < 0) TEST_ERROR
    if(H5Gclose(group_id2) < 0) TEST_ERROR

    /* Close the file */
    if(H5Fclose(file_id) < 0) TEST_ERROR

    PASSED();

    return 0;

error:
    /* Free resources */
    H5E_BEGIN_TRY {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Fclose(file_id);
    } H5E_END_TRY;

    return -1;
} /* end timestamps() */


/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Test links
 *
 * Return:	Success:	exit(EXIT_SUCCESS)
 *
 *		Failure:	exit(EXIT_FAILURE)
 *
 * Programmer:	Robb Matzke
 *              Friday, August 14, 1998
 *
 *-------------------------------------------------------------------------
 */
int
main(void)
{
    hid_t	fapl, fapl2;    /* File access property lists */
    int	nerrors = 0;
    unsigned new_format;    /* Whether to use the new format or not */
    unsigned efc;           /* Whether to use the external file cache */
    const char  *env_h5_drvr;      /* File Driver value from environment */

    env_h5_drvr = HDgetenv("HDF5_DRIVER");
    if(env_h5_drvr == NULL)
        env_h5_drvr = "nomatch";

    h5_reset();
    fapl = h5_fileaccess();

    /* Copy the file access property list */
    if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR

    /* Set the "use the latest version of the format" bounds for creating objects in the file */
    if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR

    /* Loop over using new group format */
    for(new_format = FALSE; new_format <= TRUE; new_format++) {
        hid_t my_fapl;

        /* Check for FAPL to use */
        if(new_format)
            my_fapl = fapl2;
        else
            my_fapl = fapl;

        /* General tests... (on both old & new format groups */
        nerrors += mklinks(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += cklinks(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += new_links(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += ck_new_links(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += long_links(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += toomany(my_fapl, new_format) < 0 ? 1 : 0;

        /* Test new H5L link creation routine */
        nerrors += test_lcpl(my_fapl, new_format);
        nerrors += test_move(my_fapl, new_format);
        nerrors += test_copy(my_fapl, new_format);
        nerrors += test_move_preserves(my_fapl, new_format);
#ifndef H5_NO_DEPRECATED_SYMBOLS
        nerrors += test_deprec(my_fapl, new_format);
#endif /* H5_NO_DEPRECATED_SYMBOLS */

        /* tests for external link */
        /* Test external file cache first, so it sees the default efc setting on
         * the fapl */
        nerrors += external_file_cache(my_fapl, new_format) < 0 ? 1 : 0;

        /* This test cannot run with the EFC because it assumes that an
         * intermediate file is not held open */
        nerrors += external_link_mult(my_fapl, new_format) < 0 ? 1 : 0;

        /* This test cannot run with the EFC because the EFC cannot currently
         * reopen a cached file with a different intent */
        nerrors += external_set_elink_acc_flags(env_h5_drvr, my_fapl, new_format) < 0 ? 1 : 0;

        /* Try external link tests both with and without the external file cache
         */
        for(efc = FALSE; efc <= TRUE; efc++) {
            if(efc) {
                if(H5Pset_elink_file_cache_size(my_fapl, 8) < 0)
                    TEST_ERROR
                printf("\n---Testing with external file cache---\n");
            } /* end if */
            else {
                if(H5Pset_elink_file_cache_size(my_fapl, 0) < 0)
                    TEST_ERROR
                printf("\n---Testing without external file cache---\n");
            } /* end else */

            nerrors += external_link_root(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_path(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_self(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_pingpong(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_toomany(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_dangling(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_recursive(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_query(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_unlink_compact(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_unlink_dense(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_move(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_ride(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_closing(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_endian(new_format) < 0 ? 1 : 0;
            nerrors += external_link_strong(my_fapl, new_format) < 0 ? 1 : 0;

            nerrors += external_link_prefix(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_abs_mainpath(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_rel_mainpath(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_cwd(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_abstar(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_abstar_cur(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_reltar(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_chdir(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_set_elink_fapl1(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_set_elink_fapl2(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_set_elink_fapl3(new_format) < 0 ? 1 : 0;
            nerrors += external_set_elink_cb(my_fapl, new_format) < 0 ? 1 : 0;
#ifdef H5_HAVE_WINDOW_PATH
            nerrors += external_link_win1(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win2(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win3(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win4(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win5(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win6(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win7(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win8(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_link_win9(my_fapl, new_format) < 0 ? 1 : 0;
#endif
            nerrors += external_symlink(env_h5_drvr, my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_copy_invalid_object(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_dont_fail_to_source(my_fapl, new_format) < 0 ? 1 : 0;
            nerrors += external_open_twice(my_fapl, new_format) < 0 ? 1 : 0;
	    nerrors += external_link_with_committed_datatype(my_fapl, new_format) < 0 ? 1 : 0;
        } /* end for */

        /* These tests assume that external links are a form of UD links,
         * so assume that everything that passed for external links
         * above has already been tested for UD links.
         */
        if(new_format == TRUE) {
            nerrors += ud_hard_links(fapl2) < 0 ? 1 : 0;     /* requires new format groups */
            nerrors += ud_link_reregister(fapl2) < 0 ? 1 : 0;        /* requires new format groups */
        } /* end if */
        nerrors += ud_callbacks(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += ud_link_errors(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += lapl_udata(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += lapl_nlinks(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += linkinfo(my_fapl, new_format) < 0 ? 1 : 0;

        /* Misc. extra tests, useful for both new & old format files */
        nerrors += link_visit(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += link_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += obj_visit(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += obj_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += obj_visit_stop(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += link_filters(my_fapl, new_format) < 0 ? 1 : 0;
        nerrors += obj_exists(my_fapl, new_format) < 0 ? 1 : 0;

        /* Keep this test last, it's testing files that are used above */
        /* do not do this for files used by external link tests */
        nerrors += check_all_closed(my_fapl, new_format, EXTSTOP) < 0 ? 1 : 0;
    } /* end for */

    /* New group revision feature tests */
    nerrors += corder_create_empty(fapl2) < 0 ? 1 : 0;
/* XXX: when creation order indexing is fully working, go back and add checks
*      to these tests to make certain that the creation order values are
*      correct.
*/
    nerrors += corder_create_compact(fapl2) < 0 ? 1 : 0;
    nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0;
    nerrors += corder_transition(fapl2) < 0 ? 1 : 0;
    nerrors += corder_delete(fapl2) < 0 ? 1 : 0;
    nerrors += link_info_by_idx(fapl2) < 0 ? 1 : 0;
    nerrors += delete_by_idx(fapl2) < 0 ? 1 : 0;
    nerrors += link_iterate(fapl2) < 0 ? 1 : 0;
    nerrors += open_by_idx(fapl2) < 0 ? 1 : 0;
    nerrors += object_info(fapl2) < 0 ? 1 : 0;
    nerrors += group_info(fapl2) < 0 ? 1 : 0;
    nerrors += timestamps(fapl2) < 0 ? 1 : 0;

    /* Test new API calls on old-style groups */
    nerrors += link_info_by_idx_old(fapl) < 0 ? 1 : 0;
    nerrors += delete_by_idx_old(fapl) < 0 ? 1 : 0;
    nerrors += link_iterate_old(fapl) < 0 ? 1 : 0;
    nerrors += open_by_idx_old(fapl) < 0 ? 1 : 0;
    nerrors += object_info_old(fapl) < 0 ? 1 : 0;
    nerrors += group_info_old(fapl) < 0 ? 1 : 0;

    /* Close 2nd FAPL */
    H5Pclose(fapl2);

    /* Verify symbol table messages are cached */
    nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);

    h5_cleanup(FILENAME, fapl);

    /* Test that external links can be used after a library reset.  MUST be
     * called last so the reset doesn't interfere with the property lists.  This
     * routine will delete its own file. */
    nerrors += external_reset_register() < 0 ? 1 : 0;

    /* Results */
    if(nerrors) {
        printf("***** %d LINK TEST%s FAILED! *****\n",
                nerrors, 1 == nerrors ? "" : "S");
        HDexit(EXIT_FAILURE);
    }
    printf("All link tests passed.\n");

    /* clean up symlink created by external link tests */
    HDremove(SYMLINK1);
    HDremove(SYMLINK2);

    /* clean up tmp directory created by external link tests */
    HDrmdir(TMPDIR);
    HDrmdir(TMPDIR2);

    return 0;

error:
    HDputs("*** TESTS FAILED ***");
    return 1;
}